Howto: ArduinoMega + ESP8266 to MQTT Server (Great for multi-sensor monitoring)

I recently purchased an Arduino clone from Aliexpress as the price was cheap. $10 for the ArduinoMEGA with built in ESP8266 for wifi connectivity.

The item is: Mega +WiFi R3 ATmega2560+ESP8266 {4 Mt bytes (32 Mt bit) memory},USB-TTL CH340G.

I’m writing this documentation here to hopefully help and better anyone else that is looking for a cheap alternative as there was no documentation out there and it took me many of hours to get this unit to work though trial and error.

The ArduinoMEGA has 53GPIO’s which is why i chose this to become my central hub to connect all my wired sensors; door sensors, window sensors and motion sensors. I did not one a single ESP8266 for each sensor.

To get the Arduino to talk to the ESP8266 over serial which then allows it to be networked via wifi takes some work. I will make it short and sweet:

  1. You need to flash the ESP8266 with the WiFiLink Firmware. This allows communication between the two units ESP and Arduino without having to flip dip switches.

Restart Arduino IDE, check Tools menu:
image
Library to enable upload: https://github.com/jandrassy/arduino-library-wifilink
DOWNLOAD THIS!!! https://github.com/jandrassy/arduino-library-wifilink/archive/master.zip
IT DOESN’T WORK WITH WIFILINK FROM LIBRARY MANAGER OR ANY OTHER VERSION!!!
Firmware itself: https://github.com/jandrassy/arduino-firmware-wifilink
Install Arduino Json from menu Install Libraries (otherwise you’ll get an error message upon compilation)

  • Step 2.
    – OPEN: Your sketchbook\libraries\arduino-firmware-wifilink-master\ArduinoFirmwareEsp\ArduinoFirmwareEsp.ino -> this will open all the necessary files which you need to upload (upload only ONCE, do not try to upload every file!)
    • Key things to note are to uncomment the #define for GENERIC_ESP8266 on config.h tab, Setting your board in the Arduino IDE to “Generic ESP8266”, sending the baud rate to 115200.
    • Also change the baud rate at Generic ESP8266 from 9600 to 115200
    #define BAUDRATE_COMMUNICATION 115200

  • Step 3. Flip the dip switches 5,6,7 to ON, and the rest to OFF. This is for flashing the ESP8266’s firmware.

  • Step 4. Compile and Upload
    Once complete your ESP8266 will be running WiFi Link.

  1. Flip the dip switches 1,2,3,4 to ON, the rest OFF. This allows you to upload your sketch to the Arduino board as well as allows communication between both the ESP8266 and Arduino

  2. Create a new sketch in Arduino IDE, set the board to “Arduino/Genuino mega or Mega 2560” and copy/paste my sketch below and upload:

#include <PubSubClient.h>
#include <WiFiLink.h>
//#include <UnoWiFiDevEdSerial3.h> // change Serial3.begin to 115200

#if !defined(ESP_CH_SPI) && !defined(HAVE_HWSerial3)
#include "SoftwareSerial.h"
//SoftwareSerial Serial3(6, 7); // RX, TX
#endif


char ssid[] = "MyWirelessSSID;     //  your network SSID (name)
char pass[] = "MyWirelessPassword";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status


IPAddress server(192, 168, 1, 3);


void callback(char* topic, byte* payload, unsigned int length) {
  // handle message arrived
}


//*** OFFICE SENSORS ***
int vOfficeDoor = 2;              // Office Entrance Door
int vOfficeCloset_Left = 3;       // Office Closet Door (Left)
int vOfficeCloset_Right = 4;      // Office Closet Door (Right)
String officedoor;
String OfficeCloset_Left;
String OfficeCloset_Right;

// *** MASTER BEDROOM SENSORS ***
int vMBRDoor = 5;
String MBRdoor;

WiFiClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);



void setup() {
  pinMode(LED_BUILTIN, OUTPUT);   //built in led to show activity

  //*** OFFICE SENSORS ***
  pinMode(vOfficeDoor, INPUT);
  digitalWrite(vOfficeDoor, HIGH);
  pinMode(vOfficeCloset_Left, INPUT);
  digitalWrite(vOfficeCloset_Left, HIGH);
  pinMode(vOfficeCloset_Right, INPUT);
  digitalWrite(vOfficeCloset_Right, HIGH);

  // *** MASTER BEDROOM SENSORS ***
  pinMode(vMBRDoor, INPUT);
  digitalWrite(vMBRDoor, HIGH);

  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  //INITIALIZE WIRELESS COMMUNICATION BETWEEN ARDUINO <-> ESP OVER SERIAL 1 AND SERIAL 3
  //DO NOT EDIT ANYTHING BELOW
#if !defined(ESP_CH_SPI)
  Serial3.begin(115200); // speed must match with BAUDRATE_COMMUNICATION setting in firmware config.h
  WiFi.init(&Serial3);
#endif
  if (WiFi.checkFirmwareVersion("1.1.0")) {
    WiFi.resetESP(); // to clear 'sockets' after sketch upload
    delay(500); // let firmware initialize
  }

  //Check if communication with the wifi module has been established
  if (WiFi.status() == WL_NO_WIFI_MODULE_COMM) {
    Serial.println("Communication with WiFi module not established.");
    while (true);// don't continue:
  }

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

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  startup();

  if (client.connect("Smartduino", "AuthUsername", "AuthPassword")) {
    client.publish("Connection/Connected", "1");
    client.subscribe("inTopic");
    Serial.print("Publishing Connection Message to Broker");
  }

}

//STARTUP SEQUENCE TO DETERMINE CURRENT SENSOR STATE AND ASSIGN VARIABLE ACCORDINGLY.
//THIS IS NEEDED FOR PROPER OPEN/CLOSED DETERMINATION
void startup() {
  Serial.println("Preconfiguring Sensor States...");
  if (digitalRead(vOfficeDoor) == HIGH) {
    officedoor = "closed";
    Serial.println("- Office Door = CLOSED");
  } else {
    officedoor = "open";
    Serial.println("- Office Door = OPEN");
  }
  if (digitalRead(vOfficeCloset_Left) == HIGH) {
    OfficeCloset_Left = "closed";
    Serial.println("- Office Closet Door (Left) = CLOSED");
  } else {
    OfficeCloset_Left = "open";
    Serial.println("- Office Closet Door (Right) = OPEN");
  }
  if (digitalRead(vOfficeCloset_Right) == HIGH) {
    OfficeCloset_Right = "closed";
    Serial.println("- Office Closet Door (Right) = CLOSED");
  } else {
    OfficeCloset_Right = "open";
    Serial.println("- Office Closet Door (Right) = OPEN");
  }

  //MASTER BEDROOM VARIABLES
  if (digitalRead(vMBRDoor) == HIGH) {
    MBRdoor = "closed";
    Serial.println("- MBR Door = CLOSED");
  } else {
    MBRdoor = "open";
    Serial.println("- MBR Door = OPEN");
  }
}




/*
   loop
*/

void loop() {
  //***********************************************************************************
  //***                       OFFICE DOOR SENSORS                                   ***
  //***********************************************************************************
  //CURRENTLY MONITORING:
  //  1. OFFICE DOOR
  //  2. CLOSET DOOR LEFT SIDE
  //  3. CLOSET DOOR RIGHT SIDE
  //***********************************************************************************

  //  1. OFFICE DOOR
  if (digitalRead(vOfficeDoor) == LOW && officedoor == "open") {
    client.publish("house/office/door", "CLOSED");
    officedoor = "closed";
    blink();
  } else if (digitalRead(vOfficeDoor) == HIGH && officedoor == "closed") {
    client.publish("house/office/door", "OPEN");
    officedoor = "open";
    blink();
  }
  //  2. CLOSET DOOR LEFT SIDE
  if (digitalRead(vOfficeCloset_Left) == LOW && OfficeCloset_Left == "open") {
    client.publish("house/office/ClosetDoorL", "CLOSED");
    OfficeCloset_Left = "closed";
    blink();
  } else if (digitalRead(vOfficeCloset_Left) == HIGH && OfficeCloset_Left == "closed") {
    client.publish("house/office/ClosetDoorL", "OPEN");
    OfficeCloset_Left = "open";
    blink();
  }
  //  3. CLOSET DOOR RIGHT SIDE
  if (digitalRead(vOfficeCloset_Right) == LOW && OfficeCloset_Right == "open") {
    client.publish("house/office/ClosetDoorR", "CLOSED");
    OfficeCloset_Right = "closed";
    blink();
  } else if (digitalRead(vOfficeCloset_Right) == HIGH && OfficeCloset_Right == "closed") {
    client.publish("house/office/ClosetDoorR", "OPEN");
    OfficeCloset_Right = "open";
    blink();
  }

  //***********************************************************************************
  //***                      MASTER BEDROOM SENSORS                                 ***
  //***********************************************************************************
  //CURRENTLY MONITORING:
  //  1. MBR DOOR
  //***********************************************************************************
  //  1. MBR DOOR
  if (digitalRead(vMBRDoor) == LOW && MBRdoor == "open") {
    client.publish("house/MBR/door", "CLOSED");
    MBRdoor = "closed";
    blink();
  } else if (digitalRead(vMBRDoor) == HIGH && MBRdoor == "closed") {
    client.publish("house/MBR/door", "OPEN");
    MBRdoor = "open";
    blink();
  }

  client.loop();
}








//BLINK BUILT IN LED TO SHOW SENSOR ACTIVITY
void blink() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);
}






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

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  Serial.print(mac[5], HEX);
  Serial.print(":");
  Serial.print(mac[4], HEX);
  Serial.print(":");
  Serial.print(mac[3], HEX);
  Serial.print(":");
  Serial.print(mac[2], HEX);
  Serial.print(":");
  Serial.print(mac[1], HEX);
  Serial.print(":");
  Serial.println(mac[0], HEX);

}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  Serial.print(bssid[5], HEX);
  Serial.print(":");
  Serial.print(bssid[4], HEX);
  Serial.print(":");
  Serial.print(bssid[3], HEX);
  Serial.print(":");
  Serial.print(bssid[2], HEX);
  Serial.print(":");
  Serial.print(bssid[1], HEX);
  Serial.print(":");
  Serial.println(bssid[0], HEX);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

Edit the following for your wireless information:

char ssid[] = "MyWirelessSSID;     //  your network SSID (name)
char pass[] = "MyWirelessPassword";  // your network password

The IP Address of your Mosquitto or MQTT Broker:

IPAddress server(192, 168, 1, 3);

The following line used for Authentication to your MQTT Broker:

  if (client.connect("Smartduino", "AuthUsername", "AuthPassword")) {

You can see in my code i have 4 door sensors pre-coded so you can use them as an example, my Office door, my two Office Closet Doors and my Master Bedroom Door.

Hope this helps anyone out that is thinking to tackle a project like this as there was nothing found on the Arduino forums/Openhab/Google pertaining to using the arduino GPIO’s with an ESP8266.

Any questions - ask away!

6 Likes

Hi Cris,

I have a problem when triing to compile on ATMEGA.

Message error is: ‘static void WiFiClass::init()’ is private within this context

on line 66.

Can you help me to understand why?

You should go ask that question in an Arduino forum.

Little late to the party but for anyone else with the issue you have the stock library installed you need to install the library thats linked in instruction.