Last active
September 27, 2020 19:17
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//**** 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