A Guide To Using ESP8266 With TEENSY 3

Status
Not open for further replies.
I hooked up my board to FTDI serial and put in baudrate of 74880 and got a bunch of gibberish but among the jibberish was room 16, room 12, and (3,6) so it looks like something was indeed there.

I just tried the esp flash tool from post #58. It seemed to work, here is a screen capture of the end of the process:

test1.png

Then I looked again with teraterm and this is what I see (first one with gpio0 still low).


test2.png

I loaded a bunch of binaries like blank.bin, user1.bin. etc that came with the flash tool and reflashed, now I am getting this in teraterm...closer!

test3.png

I still don't know what I need for the various binaries to flash; can anyone tell me and how can I know when the board is "working"? I am going to try AT commands next.



So it looks like the board might work after all and now i just need to get the right files to flash with. Anyone know where these might be?
 
Last edited:
Is the quad SPI mode supported by the flash chip? I've checked the datasheet and could only find the dual mode.

This is how I think the flash process should work:

Download: https://dl.dropboxusercontent.com/u/2486346/pjrc/uart_wifi_00160910.zip

Open the ESP FLASH DOWNLOAD TOOL and load the two bin files. Set ADR to 0x000000 for eagle.app.v6.flash.bin and to 0x40000 for eagle.app.v6.irom0text.bin. Set SPI Mode to DOUT.

Set GPIO0 to GND (GPIO15 to GND and GPIO2 to 3.3V). Connect and power up the ESP8266 board. Start flash. Wait... . Set GPIO0 to VCC. Reset the board.
 
Excellent. That seemed to work. That is, when I looked in teraterm I got sensible results and there was no checksum error.

Now then, how can I test whether the board actually "works"? Can I use AT commands or run the Teensy serial example? Is there an easy way to tell if the board works?

Thank you hardware guy!
 
The firmware is old (0.91). You probably want to upgrade to a newer Espressif AT - firmware or switch to nodemcu.

I think you can use the AT commands and try to connect to an access point.
 
I ran the Teensy serial program at the start of this thread, and while the AT commands are echoed to the serial monitor now (they weren't before for some reason) there is no response from the ESP8266. Still something wrong.
 
OK

test4.png

I did it twice, and tried AT+GMR but I get nothing here too.

Holy S*balls!

I switched to Hyperterminal and I am talking with the module using AT commands!

Thanks HWGuy!
 
Last edited:
Maybe it is (or was) the wrong line ending in teraterm. Espressif changed it from CR to CRLF at some time.
 
Good Morning! Ah great news to read read here !
The newer flash files need more space than the old 9.x
They must be flashed differently, to other adresses. There is a readme from espressif how to flash them!
 
I was able to set the mode to AP, and read the IP address of the ESP8266 module, but I haven't been able to connect to my wifi network yet. Could be I still don't know how to use the ESP8266 and the AT commands are new (just learned them in the last hour) or there is something wrong with my antenna or RF reception. I'll keep trying. But this is great progress so far! Thanks everyone for the help.

Yes, the latest SDK seems to need 1 Mbyte instead of the 512 kbyte I have. It will be hard to upgrade since i have no space to spare on my little board. I used 12 pF caps on the 26 MHz crystal for this assembly; I am wondering if this might be too much to keep a stable time base for the chip and that might be why the wifi doesn't connect right away? I'll build some more boards with the recommended 10 pF caps and see if this makes a difference.
 
Can you set it to client (station) mode and tell it to "survey" and report SSIDs it hears?
That tells a lot about the RF section.
In AP mode it would not architecturally be able to connect to your WiFi network.
 
Last edited:
What is the AT command for survey?

I tried AT+CWLAP, which is supposed to list available access points, and I got the response:

AT+CWLAP
+CWLAP:(0,"",0)
+CWLAP:(3,"NETGEAR16",-54)

I assume this means it has found my home router (NETGEAR16) and the signals strength is -54 dbm, which is just what it should be. So the wifi antenna seems to be working well. Whew!

I was able to establish a link to the openweathermap.org web page but couldn't type in the long list of junk to have weather data sent over before the connection timed out. I would conclude the ESP8266 add-on board is working and I just have to get some experience using it. Thank goodness!

Now I have to find a simple tutorial showing me how to connect it to something!

This starting to be fun. If I can keep making progress at this rate, I will have these add-ons on Tindie by the end of the month.
 
Last edited:
change to station mode
AT+CWMODE=0
list all access points
AT+CWLAP

But I'm not sure it's working with 0.91. There were reports of crashed/hung up modules with the AT+CWLAP command and 0.91. Sometimes it was just a not very stable power supply.
 
Last edited:
change to station mode
AT+CWMODE=0
list all access points
AT+CWLAP

But I'm not sure it's working with 0.91. There were reports of crashed/hung up modules with the AT+CWLAP command and 0.91. Sometimes it was just a not very stable power supply.

Yup, the old version were not good.
The newer can be updated (flashed) "over the air" from the espressif-servers, are more stable, have commands to store the settings in the flash, can change the baudrate and can be set to do hardware-handshake. But they need more room.
 
So you are getting there: good for you!

Could you make a summary of all the settings and hyperterm used or telnet etc so that the essence or conclusion of this thread is captured for `human mankind`?


I would also suggest that you try out to eliminate as many as possible of these weird pullup and pilldowns as possible so that you get the simplest howto talk to an ESP wifi board description. Also the wierd current load would be nice to know if this is really needed.
 
I designed my own board; anyone can download the EAGLE design files (including schematic) here.

The board pulls GPIO15 down with a 4K7 resistor, CH_EN, GPIO0, GPIO2 HIGH with a 4K7 resistor by default. To program using the tool Frank B recommended in post #58 above and firmware files HWGuy recommended in post #77 above, I simply connect GPIO0 to GND to put the module in boot mode. Then flashing after choosing 26 MHz crystal (on my board), Dout for SPI mode, 4 Mbit SPI flash (Macronix on my board) works. I used a 3V3 FTDI-to-Serial adapter with FTDI GND connected to the board GND, and FTDI RX/TX connected to board TX/RX. When flashing all of the leds on the RX/TX lines flash and blink.

After flashing is complete, I remove the GND connection from GPIO0, open up hyperterm, choose the correct COM port for the FTDI adapter, choose 115200 for Baud rate (for the 0.91 version of firmware I am using from HWGuy) and none for hardware parity. Then type AT (return) or any other AT command and it works!

I have redesigned the board to make it smaller, I went to a four-layer rather than the current two-layer design. I also found a supply of 8 Mbit Winbond SPI flash in the same 2 x 3 USON-8 package so I can upgrade to the newest firmware and even get OTA firmware update to work (may need some help here too!).

I will be assembling a dozen or so of the new boards with the 8 Mbit flash and will be selling them at Tindie before the end of November. These will be more expensive (~$15) than the $4 boards you can get from ebay, since they will be hand built with lard (I mean love!), break out all of the pins, and are designed to fit on top of the Teensy to provide wifi-to-serial capability to Teensy 3.X-based projects; meaning they are appallingly small! Here is a link to the newest board design.
 
Last edited:
@onehorse,
here's an old sketech, you may need to change the pin-defintions. it allowes to flash the esp-boards when they are connected to the teensy.
this way, i don't have to remove the esp from the teensy when i want to re-flash it with a different firmware.
its tested only with my olimex, but should work with yours too with a few changes.

as you can see, it is very very simple.
Code:
#define ESP8266_RST        16
//#define ESP8266_CH_PD      3
#define ESP8266_GPIO0      17
//#define ESP8266_GPIO2      2

//Serial Port
#define ESP8266_SERIAL Serial1
#define ESP8266_SERIAL_BAUD_INIT 115200


void setup() {  
  ESP8266_SERIAL.begin(ESP8266_SERIAL_BAUD_INIT);   
  pinMode(ESP8266_RST, OUTPUT);

  pinMode(ESP8266_GPIO0, OUTPUT);
  digitalWrite(ESP8266_GPIO0, LOW);  //LOW for flashmode
  
  //Reset:
  digitalWrite(ESP8266_RST,LOW); 
  delay(2);
  digitalWrite(ESP8266_RST,HIGH);
}

void serialProxy() {
  
    if (ESP8266_SERIAL.available()) {
        Serial.write( ESP8266_SERIAL.read() );          
    }
    
    if (Serial.available()) {
      ESP8266_SERIAL.write(Serial.read());          
    }    
    
}

void loop() {
  serialProxy();
}
 
Last edited:
Thanks Frank,

I will test something like this later today. When I tried the serial read code at the top of this thread I got nothing in return. I wonder if this is because I had the carriage return setting incorrect in the serial window?

The last step is repeating my success with the FTDI-to-serial adapter with the Teensy direct connection instead.
 
perhaps yes, i use some thing like Serial1.print("ATE1\r\n");

Edit: this switches the "ECHO" on. The ESP echoes back every command this way, and it's somtimes easier to debug the sent commands.
 
Last edited:
OK, I changed the no line control to carriage return and now I am able to talk to the module through the Teensiduino IDE Serial port. Yay!

Still have one weird thing. When I query AT+CIFSR I sometimes get 192.168.4.1 and sometimes 10.0.0.5. Not sure why it seems to change. I need to get more experience using the ESP8266 to understand what is normal. I'm learnng.

I soldered on female headers to the board VIN, GND, RX/TX and I stuck it onto the Teensy 3.1. It's not real pretty but at least I don't have any wires and the original concept is now realized. I will work to make the module smaller (done), double the flash memory (done), and find a more natural way to mount/mate it to the Teensy (working on it!).

Here is what the package looks like:

IMG_8315.JPG

It's not the most elegant solution but it beats a Huzzah with lots of wires on a breadboard! I intend to add one or two sensor add-on boards to this rig and a battery charger add-on and see if I can get remote, wireless reporting of sensor output to my iPhone through the internet. Wow, what a great time to be a maker!
 
Last edited:
Now that I am able to make the ESP8266 work I am looking forward to the next challenge!

With dual core it will be twice the waste as a Teensy wifi gateway, but might be very interesting as a standalone...
 
Excellent thread, very helpful!

I have modified the code from Wozzy to create a web server, but I would like to get the page updated with AJAX instead of a refresh timer. Im having problems getting the ESP to update the page with the XML data in the loop() function. Any ideas?

Code:
#define LED1 11
#define LED2 12

#define BUFFER_SIZE 4096
#define SSID "xxxxx" // change this to match your WiFi SSID
#define PASS "xxxxx" // change this to match your WiFi password
#define PORT "8080" //  Port 8080 is default webserver port

char buffer[BUFFER_SIZE];
int n = 0;

String webSite, javaScript, XML, header, content;

void buildWebsite() {

  header = "HTTP/1.1 200 OK\r\n";
  header += "Content-Type: text/html\r\n";
  header += "Connection: close\r\n";
  //header += "Refresh: 5\r\n";

  buildJavascript();
  content = "<!DOCTYPE HTML>\n";
  content += javaScript;
  content += "<BODY onload='process()'>\n";
  content += "<BR>This is the ESP website ...<BR>\n";
  content += "Runtime = <A id='runtime'></A>\n";
  content += "</BODY>\n";
  content += "</HTML>\n";

  header += "Content-Length:";
  header += (int)(content.length());
  header += "\r\n\r\n";

  webSite = header + content;

}

void buildJavascript() {
  javaScript = "<SCRIPT>\n";
  javaScript += "var xmlHttp = createXmlHttpObject();\n";

  javaScript += "function createXmlHttpObject() {\n";
  javaScript += " if(window.XMLHttpRequest) {\n";
  javaScript += "    xmlHttp = new XMLHttpRequest();\n";
  javaScript += " } else {\n";
  javaScript += "    xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');\n";
  javaScript += " }\n";
  javaScript += " return xmlHttp;\n";
  javaScript += "}\n";

  javaScript += "function process(){\n";
  javaScript += " if(xmlHttp.readyState == 0 || xmlHttp.readyState == 4){\n";
  javaScript += "   xmlHttp.open('GET','xml',true);\n";
  javaScript += "   xmlHttp.onreadystatechange = handleServerResponse();\n"; // no brackets?????
  javaScript += "   xmlHttp.send();\n";
  javaScript += " }\n";
  javaScript += " setTimeout('process()',1000);\n";
  javaScript += "}\n";

  javaScript += "function handleServerResponse(){\n";
  javaScript += " if(xmlHttp.readyState == 4 && xmlHttp.status == 200){\n";
  javaScript += "   xmlResponse = xmlHttp.responseXML;\n";
  javaScript += "   xmldoc = xmlResponse.getElementsByTagName('response');\n";
  javaScript += "   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript += "   document.getElementById('runtime').innerHTML = message;\n";
  javaScript += " }\n";
  javaScript += "}\n";
  javaScript += "</SCRIPT>\n";
}

void buildXML() {
  XML = "<?xml version='1.0' encoding='UTF-8'?>\n";
  XML += "<response>\n";
  XML += millis2time();
  XML += "</response>\n";
}

String millis2time() {
  String Time = "";
  unsigned long ss;
  byte mm, hh;
  ss = millis() / 1000;
  hh = ss / 3600;
  mm = (ss - hh * 3600) / 60;
  ss = (ss - hh * 3600) - mm * 60;
  if (hh < 10)Time += "0";
  Time += (String)hh + ":";
  if (mm < 10)Time += "0";
  Time += (String)mm + ":";
  if (ss < 10)Time += "0";
  Time += (String)ss;
  return Time;
}

/*******************************************************************
* PROGRAM SETUP
********************************************************************/

void setup() {

  delay(1000);

  Serial1.begin(115200); // Teensy to ESP8266
  Serial.begin(115200); // Teensy to USB Serial
  Serial.println("Begin program.");

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);

  // Initialize ESP8266.
  setupWiFi();

}

/*******************************************************************
* DEVICE FUNCTIONS
********************************************************************/

// Read line responses from ESP8266.
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;
}

// Listen for ESP8266 response. By default we are looking for OK\r\n
char OK[] = "OK\r\n";
byte wait_for_esp_response(int timeout, char* term = OK) {
  unsigned long t = millis();
  bool found = false;
  int i = 0;
  int len = strlen(term); // compute length of (string)
  // wait for at most timeout milliseconds, or if OK\r\n is found
  while (millis() < t + timeout) {
    if (Serial1.available()) {
      digitalWrite(LED2, HIGH);
      buffer[i++] = Serial1.read();
      if (i >= len) {
        if (strncmp(buffer + i - len, term, len) == 0) {
          found = true;
          break;
        }
      }
      digitalWrite(LED2, LOW);
    }
  }
  buffer[i] = 0;
  Serial.print(buffer);
  return found;
}

/*******************************************************************
* LOOP
********************************************************************/

void loop() {
  // String content;
  int ch_id, packet_len;
  char *pb;
  // Look for received IDP (unsolicited data packet) from browser refresh.
  if (read_till_eol()) {
    if (strncmp(buffer, "+IPD,", 5) == 0) // If strings match...
    {
      // Request: (+IPD, connection channel, data length)
      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++;
        if (strncmp(pb, "GET / HTTP", 10) == 0)
        {
          // Send HTML data.
          wait_for_esp_response(2000);
          Serial.println("Serving HTML ->");
          buildWebsite();
          serve(webSite, ch_id);
        }
        else if (strncmp(pb, "GET /xml", 8) == 0)
        {
          // Send XML data.
          wait_for_esp_response(2000);
          Serial.println("Serving XML ->");
          buildXML();
          serve(XML, ch_id);
          Serial.println(millis2time());
        }
      }
    }
  }
}

/*******************************************************************
* SEND DATA
********************************************************************/

// Send the data to the ESP8266.
void serve(String data, int ch_id)
{
  Serial1.print("AT+CIPSEND=");
  Serial1.print(ch_id);
  Serial1.print(",");
  Serial1.println(data.length());
  if (wait_for_esp_response(1000)) {
    Serial1.print(data);
  }
  else {
    Serial1.print("AT+CIPCLOSE=");
    Serial1.println(ch_id);
  }
}

/*******************************************************************
* SETUP WIFI
********************************************************************/

void setupWiFi() {

  // Turn on echo.
  Serial1.println("ATE1");
  wait_for_esp_response(1000);

  // Set mode 3 (client + AP).
  Serial1.println("AT+CWMODE=3");
  wait_for_esp_response(1000);

  // 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.
  Serial1.print("AT+CIPSERVER=1,");
  Serial1.println(PORT);
  wait_for_esp_response(1000);

  // Set the automatic socket client disconnection timeout from 1 to 28800 seconds.
  Serial1.println("AT+CIPSTO=6000");
  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);

  Serial1.println("AT+CIPSTATUS");
  wait_for_esp_response(5000);

  Serial.println("------------------------------------");

}
 
I wonder if it would be worth your trouble to jump to Arduino native code on the ESP8266?

I ended up there and got off to an easy start - never dealt with AT commands. Now I have the Teensy and the ESP8266 fully programmable.

My work is here: ArduinoTeensyESP8266

I was easy to get it OTA programmable for (faster) updates and it directly handles the web - and your code should drop right in. I also found SPIFFS to work to give access to any spare flash on the ESP unit to provide read/write FS storage.

Your AT commands are foreign to me - but the server operations would be native on the ESP - the WebServer sample I started with are just functions called for pages where you generate your response buildWebsite(); would be called directly. That might let you better handle process. I just got some books to relearn scripting assumed it would be client side - you should be able to look at handleNotFound() or handleRoot() and have your problem solved in short order putting your code in there. If you do I'd love to see your results.

My GitHub has the key steps/links to putting your ESP8266 up and running on Arduino IDE - hopefully I didn't miss anything. If you try it and get stuck say so.
 
I wonder if it would be worth your trouble to jump to Arduino native code on the ESP8266?

I ended up there and got off to an easy start - never dealt with AT commands. Now I have the Teensy and the ESP8266 fully programmable.

My work is here: ArduinoTeensyESP8266

I was easy to get it OTA programmable for (faster) updates and it directly handles the web - and your code should drop right in. I also found SPIFFS to work to give access to any spare flash on the ESP unit to provide read/write FS storage.

Your AT commands are foreign to me - but the server operations would be native on the ESP - the WebServer sample I started with are just functions called for pages where you generate your response buildWebsite(); would be called directly. That might let you better handle process. I just got some books to relearn scripting assumed it would be client side - you should be able to look at handleNotFound() or handleRoot() and have your problem solved in short order putting your code in there. If you do I'd love to see your results.

My GitHub has the key steps/links to putting your ESP8266 up and running on Arduino IDE - hopefully I didn't miss anything. If you try it and get stuck say so.

Yes, I dropped the AT command set and made the switch to Arduino programming on the ESP8266 some time ago. So much better!

I have 8 sensors gathering data on the Teensy and sending it to the ESP8266 via Serial. I made a mobile-friendly site that uses touch gestures to view information and refresh data. I also have OTA updates and SPIFFS working on the ESP8266 over wifi. I would also like a way to update the Teensy code over wifi, but havent figured that part out yet. I will post my project when I have a stable release.
 
Status
Not open for further replies.
Back
Top