Arduino - Web Server (Mega 2560 R3 built-in ESP8266)

Arduino Aug 10, 2020

This tutorial goes over how to use the Mega 2560 R3 built-in ESP8266 and create a web server by flashing the onboard ESP8266 with AT firmware which only requires programming only the ATmega2560. 📶


This boards has a lot of spotty information circulating around the internet. It is important to know that this board contains two chips and because of that requires uploading two different programs to each of the chips. The onboard ESP8266 has 4MiB of flash memory and the ATmega2560 has 256kb. For my use cases I wanted to be able to take advantage only having to upload my program to one chip. The way I accomplished this is by flashing the ESP8266 chip with AT firmware so that the ATmega2560 could communicate with it using the Mega2560+ESP8266 DIP switch configuartion that provides access via the onboard Serial3 communication.

The board is sold by multiple sellers and schematics can be found for it here

The following chart represents the DIP switch configurations that can be used on the board. I will post the specific configurations that are used in the sections below. These DIP switches are not very durable, as they fall apart if they are switched frequently.

1 2 3 4 5 6 7 8
CH340 connect to ESP8266 (upload sketch) OFF OFF OFF OFF ON ON ON NoUSE
CH340 connect to ESP8266 (connect) OFF OFF OFF OFF ON ON OFF NoUSE
CH340 connect to ATmega2560 (upload sketch) OFF OFF ON ON OFF OFF OFF NoUSE
CH340 connect to Mega2560 COM3 connect to ESP8266 ON ON ON ON OFF OFF OFF NoUSE
All modules work independent OFF OFF OFF OFF OFF OFF OFF NoUSE

Flashing AT firmware for onboard ESP8266

In order to flash the AT firmware please ensure you have installed esptool. Running the follow command should show connected devices so that we can identify which device should be targeted with esptool.

ls /dev/tty.*
# /dev/tty.Bluetooth-Incoming-Port	/dev/tty.URT2
# /dev/tty.usbserial-1450	        /dev/tty.URT1
Gets the list of devices connected to your Mac
In order to flash the ESP8266 please ensure that you have the DIP switches in the follow locations.
1 2 3 4 5 6 7 8
CH340 connect to ESP8266 (upload sketch) OFF OFF OFF OFF ON ON ON NoUSE

If you have the mega2560 connected to power, please disconnected it and as you reconnect it back to power please press the mode button. This procedure will make the ESP8266 goes into flashing mode.

Ensure that you download and cd into extracted folder. This contains the AT firmware version

Ensure that if you have a serial monitor open for this device that you close it so that esptool can open up a connection with it. write_flash --flash_mode dio  --flash_size 2MB-c1 0x0 bin/boot_v1.7.bin 0x01000 bin/at/1024+1024/ 0x1fb000 bin/blank.bin 0x1fc000 bin/esp_init_data_default_v08.bin 0xfe000 bin/blank.bin 0x1fe000 bin/blank.bin

Flash AT firmware to the onboard ESP8266v

After running the command above in the terminal, it should yield Hard resetting via RTS pin.... Once this is displayed in the terminal please disconnect the Arduino and set it to the following DIP switch configurations:

1 2 3 4 5 6 7 8
CH340 connect to ESP8266 (connect) OFF OFF OFF OFF ON ON OFF NoUSE

Opening up a serial monitor session with the device you should see the following output when running the following commands:

  1. AT (Tests the startup)
  2. AT+GMR (Checks the version information)
For more commands that AT can respond to, please visit

Creating Web Server

Now that we have the ESP8266 working with AT commands we now only have to program mega2560 for any future work. To program the mega2560 please set the following DIP switch configurations:

1 2 3 4 5 6 7 8
CH340 connect to ATmega2560 (upload sketch) OFF OFF ON ON OFF OFF OFF NoUSE

We will need to install the WiFiEspAT library to make communicating with AT commands easier.

For information on how to install the libraries above please visist

Once you have done that upload the following program through Arduino IDE. Please change NAME_OF_SSID and PASSWORD_OF_SSID to your network you are currently connected to.

#include <WiFiEspAT.h>

WiFiServer server(80);

void setup() {

  while (!Serial);


  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);

  Serial.println("Waiting for connection to WiFi");
  while (WiFi.status() != WL_CONNECTED) {


  IPAddress ip = WiFi.localIP();
  Serial.println("Connected to WiFi network.");
  Serial.print("To access the server, enter \"http://");
  Serial.println("/\" in web browser.");

void loop() {

  WiFiClient client = server.available();
  if (client) {
    IPAddress ip = client.remoteIP();
    Serial.print("new client ");

    while (client.connected()) {
      if (client.available()) {
        String line = client.readStringUntil('\n');

        // if you've gotten to the end of the HTTP header (the line is blank),
        // the http request has ended, so you can send a reply
        if (line.length() == 0) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println("<!DOCTYPE HTML>");
          // output the value of analog input pins
          for (int analogChannel = 0; analogChannel < 4; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(" is ");
            client.println("<br />");

    // close the connection:
    Serial.println("client disconnected");

Once you have successfully upload the previous code to your mega2560 please set the DIP switches to the following positions.

1 2 3 4 5 6 7 8

Lastly you need to set the RX and TX switch to the RXD3 and TXD3. Please look at the following image to see the final configuration.

Final configuration setup to have Atmega2560 and ESP8266 working together correctly
As you can see the 3 and 4 pins are in the on position, this is needed to keep the Serial output passing to the USB so that the Serial Monitor would get printed values.
Final output in the Serial Monitor

When navigating to the address provided in the Serial Monitor, for this specific example it was you should be met with the following output!

If you have any questions please create an issue at


Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.