Skip to content

Instantly share code, notes, and snippets.

@smukkejohan
Last active September 27, 2020 19:17
Show Gist options
  • Save smukkejohan/2728a6aa01be3912a3ec1e365f0a9137 to your computer and use it in GitHub Desktop.
Save smukkejohan/2728a6aa01be3912a3ec1e365f0a9137 to your computer and use it in GitHub Desktop.
Using a Teensy 3.5 with ESP8266 to host a webserver and connect to a wifi network DMJX 2020
//**** Using a Teensy 3.5 to host a webserver on a wifi network using ESP8266 *******
#include <Arduino.h>
#define SSID "insert_SSID" //name of wireless access point to connect to
#define PASS "insert_password" //wifi password
#define RST_PIN 24 // Pull low to trigger reset
#define CH_PD_PIN 25 // Pull high for AT command mode, low for firmware flash mode
#define LED_PIN 14 // YELLOW LED - SENDING
int ledState = 0;
long lastTxTimestamp=0;
long lastRxTimestamp=0;
int counter = 0; //page reload counter for testing
void resetESP() {
digitalWriteFast(RST_PIN,LOW);
digitalWriteFast(LED_PIN,HIGH);
delay(100);
digitalWriteFast(RST_PIN,HIGH);
digitalWriteFast(LED_PIN,LOW);
}
#define BUFFER_SIZE 1024
#define PORT "80" // default port 15164
char buffer[BUFFER_SIZE];
// By default we are looking for OK\r\n
char OKrn[] = "OK\r\n";
byte wait_for_esp_response(int timeout, char* term=OKrn) {
unsigned long t=millis();
bool found=false;
int i=0;
int len=strlen(term);
// wait for at most timeout milliseconds
// or if OK\r\n is found
while(millis()<t+timeout) {
if(Serial1.available()) {
buffer[i++]=Serial1.read();
if(i>=len) {
if(strncmp(buffer+i-len, term, len)==0) {
found=true;
break;
}
}
}
}
buffer[i]=0;
Serial.print(buffer);
return found;
}
String homepage() {
String content = "<html>"
"<head>"
"<meta charset='UTF-8'>"
"<script src='https://unpkg.com/axios/dist/axios.min.js'></script>"
"<script src='https://unpkg.com/jquery@3.5.1/dist/jquery.min.js'></script>"
"<script>"
"$(function() {"
"axios.get('/getled').then(function (response) { console.log(response); $('#togglebtn').text( getBtnText(response.data.ledstate)); }) "
"});"
"function getBtnText(val) {"
"return ((val) ? 'sluk' : 'tænd');"
"}"
"function add(elmnt,clr) {"
" axios.get('/add').then(function (response) { console.log(response); $('#counter').text(response.data.counter); }) "
"}"
"function subtract(elmnt,clr) {"
" axios.get('/subtract').then(function (response) { console.log(response); $('#counter').text(response.data.counter); }) "
"}"
"function toggleLed(elmnt,clr) {"
" axios.get('/toggleled').then(function (response) { console.log(response); $('#togglebtn').text( getBtnText(response.data.ledstate)); }) "
"}"
"</script>"
"</head>"
"<body>"
"<h1> ESP8266 Homepage demo </h1>"
"<p>This message brought to you by - TEENSY 3.5 & ESP8266</p>"
"<p>Teensy server uptime: ";
content += String(millis());
content += " milliseconds</p>"
"<button "
"onClick='add()'"
">Add</button>"
"<button "
"onClick='subtract()'"
"> Subtract </button>"
"<p> Counter: <span id='counter'>";
content += String(counter);
content += "</span> times.</p>"
"<button id='togglebtn'"
"onClick='toggleLed()'"
">Toggle LED</button>"
"</body></html>";
return content;
}
void serve(int ch_id, String content, String response_code, String content_type) {
String header = "HTTP/1.1 ";
header += response_code;
header += "\r\n";
header += "Content-Type:";
header += content_type;
header += "\r\nConnection: close\r\n";
header += "Content-Length:";
header += (int)(content.length());
header += "\r\n\r\n";
Serial1.print("AT+CIPSEND=");
Serial1.print(ch_id);
Serial1.print(",");
Serial1.println(header.length()+content.length());
if(wait_for_esp_response(2000)) {
Serial1.print(header);
Serial1.print(content);
}
else {
Serial1.print("AT+CIPCLOSE=");
Serial1.println(ch_id);
}
}
void serve_json(int ch_id, String content) {
serve(ch_id, content, "200 OK", "application/json");
}
void serve_html(int ch_id, String content) {
serve(ch_id, content, "200 OK", "text/html");
}
void setupWiFi() {
// turn on echo
Serial1.println("ATE1");
wait_for_esp_response(1000);
// modes 1: station, 2 Soft Access Point (AP), 3 Station+SoftAP
Serial1.println("AT+CWMODE=3");
wait_for_esp_response(1000);
// DHCP
//Serial1.println("AT+CWDHCP=0,1");
//wait_for_esp_response(1000);
// create AP
Serial1.println("AT+CWSAP=\"esp_network\",\"dmjxdmjx\",1,4");
wait_for_esp_response(10000);
// reset WiFi module
Serial1.print("AT+RST\r\n");
wait_for_esp_response(1500);
//join AP
Serial1.print("AT+CWJAP=\"");
Serial1.print(SSID);
Serial1.print("\",\"");
Serial1.print(PASS);
Serial1.println("\"");
wait_for_esp_response(5000);
// start server
Serial1.println("AT+CIPMUX=1");
wait_for_esp_response(1000);
//Create TCP Server in
Serial1.print("AT+CIPSERVER=1,"); // turn on TCP service
Serial1.println(PORT);
wait_for_esp_response(1000);
// Set TCP timeout
Serial1.println("AT+CIPSTO=30");
wait_for_esp_response(1000);
Serial1.println("AT+GMR");
wait_for_esp_response(1000);
Serial1.println("AT+CWJAP?");
wait_for_esp_response(1000);
Serial1.println("AT+CIPSTA?");
wait_for_esp_response(1000);
Serial1.println("AT+CWMODE?");
wait_for_esp_response(1000);
Serial1.println("AT+CIFSR");
wait_for_esp_response(5000);
Serial1.println("AT+CWLAP");
wait_for_esp_response(5000);
Serial.println("---------------*****##### READY TO SERVE #####*****---------------");
}
void setup() {
delay(5000); //allow time for usb to enumerate - can remove this later
pinMode(CH_PD_PIN, OUTPUT);
digitalWriteFast(CH_PD_PIN, HIGH);
pinMode(LED_PIN, OUTPUT);
pinMode(RST_PIN, OUTPUT);
resetESP();
// assume esp8266 operates at 115200 baud rate
// change if necessary to match your modules' baud rate
Serial.begin(115200); // Teensy USB Serial Port
// Setup Teensy to ESP8266 serial
// Use baud rate 115200 during firmware update
Serial1.begin(115200); // Teensy Hardware Serial port 1 (pins 0 and 1)
Serial.println("ESP Demo");
delay(5000);
setupWiFi();
// print device IP address
Serial.print("device ip addr: ");
Serial1.println("AT+CIFSR");
wait_for_esp_response(1000);
}
bool read_till_eol() {
static int i=0;
if(Serial1.available()) {
buffer[i++]=Serial1.read();
if(i==BUFFER_SIZE) i=0;
if(i>1 && buffer[i-2]==13 && buffer[i-1]==10) {
buffer[i]=0;
i=0;
Serial.print(buffer);
return true;
}
}
return false;
}
void loop() {
int ch_id, packet_len;
char *pb;
if(read_till_eol()) {
if(strncmp(buffer, "+IPD,", 5)==0) {
// request: +IPD,ch,len:data
sscanf(buffer+5, "%d,%d", &ch_id, &packet_len);
if (packet_len > 0) {
// read serial until packet_len character received
// start from :
pb = buffer+5;
while(*pb!=':') pb++;
pb++;
Serial.println(pb);
char *verb = strtok(pb, " ");
char *request = strtok(NULL, " ");
char *rtype = strtok(NULL, " ");
if (strcmp(request, "/") == 0) {
wait_for_esp_response(200);
Serial.println("-> serve homepage");
serve_html(ch_id, homepage());
}
else if (strcmp(request, "/add") == 0) {
wait_for_esp_response(200);
counter++;
serve_json(ch_id, "{\"counter\":" + String(counter) + "}");
}
else if (strcmp(request, "/subtract") == 0) {
wait_for_esp_response(200);
counter--;
serve_json(ch_id, "{\"counter\":" + String(counter) + "}");
}
else if (strcmp(request, "/toggleled") == 0) {
wait_for_esp_response(200);
ledState = !ledState;
digitalWriteFast(LED_PIN,ledState);
serve_json(ch_id, "{\"ledstate\":" + String(ledState) + "}");
}
else if (strcmp(request, "/getled") == 0) {
wait_for_esp_response(200);
serve_json(ch_id, "{\"ledstate\":" + String(ledState) + "}");
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment