ESP8266 Huzzah to Arduino MEGA2560

I recently purchased the Adafruit ESP8266 Huzzah Breakout Board, instead of having to deal with logic level shifters and what not. Anyways, the reason I need some kind of wifi capabilities in my project, is to be able to control a robot through a webpage, or phone app. Me and a few guys are working on a robot that has an arm, powered by servos, and wheels that are powered by DC motors. I have all the necessities for these motors. I have everything I need, except the knowledge to control these parts wirelessly.

I have an Arduino MEGA, and would like to control it's digital pins using buttons on a webpage hosted by the ESP8266 Huzzah board. I followed a tutorial explaining how to make a webpage produce temperature and humidity data. I understood most of that, but now I need to connect the ESP8266 to the MEGA, and am totally lost. Must the RX and TX pins on the ESP be connected to the TX and RX pins on the MEGA, respectively? How exactly does that work? Is it possible someone can refer me to a document explaining why that is, or show me some example code of the ESP communicating with the MEGA?

I appreciate it!

Must the RX and TX pins on the ESP be connected to the TX and RX pins on the MEGA, respectively?

If you want to do communication over serial, yes. There are other options but that might be the easiest.

How exactly does that work?

That's up to you.

Typically in this sort of AVR-ESP8266 configuration people will have the AT firmware on the ESP8266 and use the AVR (the Mega in your case) as the master. The ESP8266 is used only as a WiFi adapter. The benefit of this is that the official and community support for the AVR architecture is the best by far so you have lots of libraries, sketches, tutorials, and people here on the forum who can help you. So in this case the Mega would be serving the webpage and interpreting HTTP requests. For this option I would recommend this library:

The other option would be to write a custom firmware for the ESP8266 that handles serving the webpage and interpreting HTTP requests and then sends the control commands to the Mega. The benefit of this is that the ESP8266 is much more powerful than the Mega and this should be more efficient than transferring all the data back and forth between the Mega, through the ESP8266, and to the phone. It's a bit more complex because you will be writing code for the ESP8266 and also for the Mega and the ESP8266 is a bit more difficult to work with than the Mega, but not too bad, especially for this application. In this case you will be using the esp8266 core for Arduino to program the ESP8266:

So I tried that first library, using the MEGA as the master. I am using an example from that WiFiEsp.h library to test out the esp8266. This is the example I attempted to use: WiFiEsp/WebServer.ino at master · bportaluri/WiFiEsp · GitHub

So, I get this:

[WiFiEsp] Initializing ESP module
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] Cannot initialize ESP module
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] No tag found
WiFi shield not present

I went into the library to find where this error was called, and I am a little confused.

This error call comes from the EspDrv.h library. In the constructor for initializing the wifi driver, it declares a bool initOK as false. Then it sends an AT command to check if it responds. If it did respond, it sets initOK to true. Then I get the message you see above in the next if statement. The way I interpreted the if statement, was if initOK is not false, return that 'Cannot initialize ESP module' error. So, does this mean the esp is not responding to any AT commands?

Also, what is that AT firmware you're talking about? Is that what this model of the esp should come flashed with? How can one make their own custom firmware? That sounds interesting.

Thanks for helping out again, Pert!

I forgot to mention which pins I have the serial connected to. I have the ESP8266's TX connected to pin 17 on the mega, and ESP8266's RX pin connected to pin 16 on the mega. I am powering the ESP8266 Huzzah board with the 5V pin from the mega. I heard that probably isn't enough current, but that's all I have to test it right now. I will try and get a better power supply soon.

The Arduino MEGA is being powered by my laptop through USB.

Here is a fritzing diagram of the esp and mega we have right now:

So, does this mean the esp is not responding to any AT commands?

The problem is that you don't have the AT firmware installed on the ESP8266 board.

Also, what is that AT firmware you're talking about?

The AT firmware was written by the company that created the ESP8266, Espressif. AT commands are used to control the ESP8266 as a WiFi interface. The firmware is available in the bin/at subfolder of the NONOS SDK releases. Which you can download from:

The latest of which at this time is v2.1.0:

Here is the AT Instruction Set documentation, which will give you a good understanding of how the AT firmware works:

It is listed at:

Is that what this model of the esp should come flashed with?


Each module comes pre-loaded with NodeMCU's Lua interpreter (NodeMCU 0.9.5 build 20150318 / Lua 5.1.4 to be specific)

So in this case, no the Huzzah does not come with the AT firmware installed so you would need to install it if you wanted to use the WifiEsp library. I can provide detailed instructions for doing this if necessary. There are also some tutorials for doing it available online.

How can one make their own custom firmware?

Firmware is just a fancy term for a program running on a microcontroller. In the Arduino world this means you will install the ESP8266 core for Arduino:

and then upload a sketch to the ESP8266. If you uploaded the Blink sketch then you could say the ESP8266 is running the Blink firmware. For your application you would write a sketch that serves a webpage, interprets incoming HTTP requests, then sends commands to the Mega. You also need to write a sketch for the Mega that receives the commands from the ESP8266 and acts accordingly.

I have the ESP8266's TX connected to pin 17 on the mega, and ESP8266's RX pin connected to pin 16 on the mega.

That's Serial2. The WifiEsp example sketches are written with the assumption that if you have a board with multiple hardware serial ports (which the Mega does) the ESP8266 will be connected to Serial1. It's easy enough to change this to Serial2 if you prefer to use that one. Just change the two mentions of Serial1 in the code to Serial2.

I am powering the ESP8266 Huzzah board with the 5V pin from the mega. I heard that probably isn't enough current, but that's all I have to test it right now. I will try and get a better power supply soon.

That is actually not so bad as long as you don't try to run a lot of other things off the Mega's 5 V. When you power the Mega over the USB you have the 500 mA allowed by the USB port on your computer to work with. If you change to powering the Mega through the barrel jack or Vin pin it will be more problematic because then you are limited to the current the voltage regulator on the Mega can supply, which is much less than 500 mA. Often the power problems come when people try to power the ESP8266 from the 3.3 V pin on the Arduino, which can't supply the current to make the ESP8266 run reliably.

Ah, that would make sense. We were continuously uploading code the ESP8266, not knowing that would overwrite the firmware already on there. What I did was go back and flash it with this code to be able to use the Arduino IDE: Using Arduino IDE | Adafruit HUZZAH ESP8266 breakout | Adafruit Learning System I don't really know what that software from Adafruit did, but it doesn't look like it was meant for AT commands.

If possible, could you please provide details on installing these bin files? I looked into the bin/at subfolder of the NONOS SDK release folder, and there were a bunch of bin files. These bin files are just very foreign to me. I have a flash tool, but I don't know which bit version I should use. I don't know if I stated that correctly. There are two folders inside the 'at' folder. One is 512+512, and the other is 1024+1024. I don't know which to choose. I also don't really know how to use the flashing tool. If you could, may you please link some tutorials on this?

Thanks for all the information! You're teaching me a lot, and I appreciate it!

Instructions for flashing the Huzzah with the AT firmware:

You will need some sort of USB-serial adapter, such as an FTDI FT232 breakout board. It is possible to use an Arduino for this purpose but it's easiest to use an adapter specifically designed for this. They can be purchased very cheaply on Aliexpress or eBay.

  • Connect the USB-serial adapter to the Huzzah.
  • Hold down the button marked GPIO0
  • Press the button marked reset - this should put the ESP8266 in bootloader mode
  • Note the COM port of the Huzzah, as shown in Arduino IDE > Tools > Ports
  • Download ESP8266 NONOS SDK, which are listed here: The current version, V2.1.0 is available here:
  • Unzip the downloaded file
  • Download Flash Download Tools, which is listed here: Tools | Espressif Systems. The current version, V3.4.8 is available here:
  • Unzip the downloaded file
  • Open the unzipped folder and run the program ESPFlashDownloadTool_v3.4.8.exe
  • Click the "ESP8266 Download Tool" button
  • In the "Download Panel 1" section, select the Huzzah's USB serial adapter's COM port from the COM PORT menu
  • In the SpiFlashConfig section, check the SpiAutoSet checkbox
  • In the Download Path Config section, make sure all checkboxes on the left side are unchecked
  • Click the START button.
  • After a little while you should see text appear in the "DETECTED INFO" box.
  • Note the selection in the FLASH SIZE radio button menu of the "SpiFlashConfig" section of the "Flash Download Tool" GUI.
  • Download and open the "ESP8266 AT Instruction Set" PDF from the "Getting Started" section of: Technical Documents | Espressif Systems. The latest version is available here:
  • In section 1.2 ("Downloading AT firmware into Flash") of that document you will see a table of the files and addresses to use for the FLASH SIZE configuration that was automatically detected by the "Flash Download Tool".
  • Configure the Download Path Config section of the "Flash Download Tool" according to that table, using the files found in the bin subfolder of the NONOS SDK you downloaded from and the addresses listed in the "ESP8266 AT Instruction Set" PDF. When you get to boot.bin you will have an unpleasant surprise. There is no file named boot.bin included with the NONOS SDK. Instead you will find multiple similarly named files (e.g. boot_v1.2.bin, boot_v1.6.bin, boot_v1.7.bin). You can use whichever of these files you like, I would tend to use the one with the newest version but I really don't know which is best.
  • Click the checkboxes on the left side of each of the files you configured in the Download Path Config section of the "Flash Download Tool".
  • Click the START button. You should see the progress of the flashing in the bar at the bottom of the tool window
  • Wait until the Download Panel 1 shows a green box that says FINISH
  • Start the Arduino IDE
  • Select the COM port of the USB-serial adapter from the Tools > Port menu
  • Tools > Serial Monitor
  • Select 115200 from the baud rate menu at the bottom right corner of the Serial Monitor window
  • Select "Both NL & CR" from the menu next to the baud rate menu at the bottom right corner of the Serial Monitor window
  • Click on the text input box at the top of the Serial Monitor window
  • Type AT+GMR
  • Press Enter
  • You should now see a listing of the AT firmware version, SDK version, and compile time shown in the Serial Monitor. This indicates that the AT firmware was installed successfully.

Thanks for laying out such a detailed set of instructions! That actually gave me different results when using the ESP flash tool. It looked like it worked, and said the esp8266 was successfully flashed. Now, when we try to send AT commands, it still doesn't respond. What I am now thinking is we're using the wrong FTDI cable.

This is similar to the cable I'm using. It's a FTDI console cable meant for windows. Here is the cable I currently own. Would getting this FTDI cable work much better than this FTDI FT232 breakout board? Are they virtually the same things?

Everything you listed in the instructions works, but we may be using the wrong cable. Again, I appreciate you helping out so much!

The cable you have should work. The only limitation of those is they don't break out the DTR or CTS pin, which is used for auto reset but the Huzzah doesn't support auto reset and that's only necessary for uploading sketches anyways so that's not important in this case.

If the firmware flashing was successful it shows that serial communication is working. I actually haven't used the latest AT firmware version, the version was at 2.0.0 the last time I did this. I also haven't used the Huzzah. My experience with AT firmware is limited to those ESP8266 shields. The instructions above were originally written for the shield but I modified them to account for the Huzzah having GPIO0 and reset buttons and also I wasn't sure about the flash configuration so I made that part of the instructions generic so it could be used to determine the appropriate firmware files and addresses for any flash configuration.

So, here are the results from flashing the esp8266 huzzah with the NONOS SDK v2.0.0. This pretty much states the AT commands are working as intended, right? Should I be using some kind of program that reads serial data like Putty or Realterm? I've tried using both those programs, but they are a little difficult to use with all the buttons on there.

I think I spotted the problem. You forgot to check the boxes to the left of each of the firmware files in the "Download Path Config" section.

This pretty much states the AT commands are working as intended, right?

No, it states that the flashing process was successful, which means that the serial communication is working correctly but doesn't tell you anything about the functionality of the AT commands.

Should I be using some kind of program that reads serial data like Putty or Realterm? I've tried using both those programs, but they are a little difficult to use with all the buttons on there.

You can use those if you like. I recommended Serial Monitor in the instructions because every Arduino user already has that installed.

Oh, I forgot to show the image of the esp flasher with the checked downloaded boxes. I did actually check all the boxes, up until the DeviceMasterKey Folder Path. That option was left blank.

That console output is what resulted after I checked the boxes for the downloads.

Is there any reason why the AT+GMR command didn't work from the arduino serial monitor? Could the esp module be broken?

Try uploading this sketch to it using the Arduino IDE and the ESP8266 core for Arduino:

void setup() {

void loop() {

If it uploads and repeatedly prints "hello" to the Serial Monitor that indicates it's working. Keep in mind that after you upload a sketch the AT firmware you flashed is erased.

Ok, we tried that piece of code, and it for sure prints out Hello. Although, it prints out some garbage first. Is this normal, or does it indicate any kind of malfunction?

We're currently gonna take a break for the weekend, but will try some kind of AT command testing on Monday.

It's normal for the ESP8266 to print some stuff to serial when it starts up and at other times. There is some debug output from the bootloader at startup but that's at 74800 baud, which should be gibberish at 9600.

It will print a crash dump at whatever baud rate you set in Serial.begin() if it crashes.

It will also print some debug output at 115200 baud after it crashes.

I have solved the issue, and the esp Huzzah now responds to AT commands.

This post is for those who are having problems with their esp8266 Huzzah communicating to an Arduino Mega. What worked were the above steps laid out by Pert for flashing. His code to send AT commands through the arduino serial monitor also works. Just follow what he posted.

The firmware version we used was the NONOS SDK v2.0.0, which is not the latest version. Here is the fritzing diagram on how we set up the esp Huzzah with the mega:

Below is the code that worked for creating a web client that controls an LED. We tweaked it a little to test some servos and motors out, and it works well. There is a little lag, but that requires more research.

#include <WiFiEsp.h>
#include <WiFiEspClient.h>
#include <WiFiEspServer.h>
#include <WiFiEspUdp.h>
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

 WiFiEsp example: WebServerLed
 A simple web server that lets you turn on and of an LED via a web page.
 This sketch will print the IP address of your ESP8266 module (once connected)
 to the Serial monitor. From there, you can open that address in a web browser
 to turn on and off the LED on pin 13.

 For more details see:

// Emulate Serial1 on pins 6/7 if not present
#include <SoftwareSerial.h>
SoftwareSerial Serial2(17, 16); // RX, TX


char ssid[] = "SSID";            // your network SSID (name)
char pass[] = "password";        // your network password
int status = WL_IDLE_STATUS;

int ledStatus = LOW;
int RED_LED = 6;

WiFiEspServer server(80);

Servo servo1;
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor1 = AFMS.getMotor(1);
Adafruit_DCMotor *myMotor2 = AFMS.getMotor(3);
int pos = 0;

// use a ring buffer to increase speed and reduce memory allocation
RingBuffer buf(8);

void setup()
  pinMode(RED_LED, OUTPUT);  // initialize digital pin LED_BUILTIN as an output.
  Serial.begin(115200);   // initialize serial for debugging
  Serial2.begin(115200);    // initialize serial for ESP module
  WiFi.init(&Serial2);    // initialize ESP module

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);

  // attempt to connect to WiFi network
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);

  Serial.println("You're connected to the network");
  // start the web server on port 80


  // turn on motor

void loop()
  WiFiEspClient client = server.available();  // listen for incoming clients

  if (client) {                               // if you get a client,
    Serial.println("New client");             // print a message out the serial port
    buf.init();                               // initialize the circular buffer
    while (client.connected()) {              // loop while the client's connected
      if (client.available()) {               // if there's bytes to read from the client,
        char c =;               // read a byte, then
        buf.push(c);                          // push it to the ring buffer

        // printing the stream to the serial monitor will slow down
        // the receiving of data from the ESP filling the serial buffer
        // you got two newline characters in a row
        // that's the end of the HTTP request, so send a response
        if (buf.endsWith("\r\n\r\n")) {

        // Check to see if the client request was "GET /H" or "GET /L":
        if (buf.endsWith("GET /H")) {
          Serial.println("Turn led ON");
          ledStatus = HIGH;
          digitalWrite(RED_LED, HIGH);   // turn the LED on (HIGH is the voltage level)
        else if (buf.endsWith("GET /L")) {
          Serial.println("Turn led OFF");
          ledStatus = LOW;
          digitalWrite(RED_LED, LOW);    // turn the LED off by making the voltage LOW
        }/* else if (buf.endsWith("GET /SR")) { //Turning the servo to the right
            while (pos < 180) {
        } else if (buf.endsWith("GET /SL")) {   //Just testing turning the servo to the left
            while(pos > 3) {
        }*/ else if (buf.endsWith("GET /M")) {  //this command moves the DC motor forward
          } else if (buf.endsWith("GET /MS")) { //this command moves the DC motor backwards
      // close the connection
      Serial.println("Client disconnected");

void sendHttpResponse(WiFiEspClient client)
  // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
  // and a content-type so the client knows what's coming, then a blank line:
  client.println("HTTP/1.1 200 OK");
  // the content of the HTTP response follows the header:
  client.print("The LED is ");
  client.println("Click <a href=\"/H\">here</a> turn the LED on
  client.println("Click <a href=\"/L\">here</a> turn the LED off
  //client.println("Click <a href=\"/SR\">here</a> to turn servo right
  //client.println("Click <a href=\"/SL\">here</a> to turn servo left
  client.println("Click <a href=\"/M\">here</a> turn motor
  client.println("Click <a href=\"/MS\">here</a> stop motor
  // The HTTP response ends with another blank line:

void printWifiStatus()
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");

  // print where to go in the browser
  Serial.print("To see this page in action, open a browser to http://");

Other than that, the entirety of this post should be helpful. I just came back to show what worked for me. All thanks to Pert!

Glad to hear it's working! Do you know what was the cause of the HUZZAH not responding to AT commands after you installed the AT firmware?

I believe my friend changed the address to a specific bin file when flashing. That might've been it. We looked into the documents further and found some addresses.

Other than that, I believe we had everything connected correctly. I'll come back to reply once I find out what exactly was the difference.