Best choice for adding wifi to arduino Mega?

Hello,

I am looking to add wifi to a Mega. I see that this hat from adafruit is retired - what is the best choice for adding wifi to a mega these days?

Thanks!
Chris

What do you want to do with it?
Generally speaking, I'd recommend the ESP8266. You can either use AT commands or program it directly (I prefer the latter). Don't waste your money (and mostly time) on an ESP-01. Get a dev board that can do both, like the WeMos D1 mini or NodeMCU.

A Beginner's Guide to the ESP8266

Pieter

I need the mega to be able to receive commands from an MQTT topic. I am operating under the assumption that if I add Wifi to the Mega and can subscribe to an MQTT topic. using code similar to this that is running on a Yun:

#include <BridgeClient.h>
#include <PubSubClient.h>

// Network Values
byte mac[]    = { 0x90, 0xA2, 0xDA, 0xF7, 0x0A, 0xEC };
IPAddress ip(192, 168, 1, 128);
IPAddress server(192, 168, 1, 45);
BridgeClient ethClient;
PubSubClient client(ethClient);

void setup()
{
  //Start the Serial monitor
  Serial.begin(57600);
  Bridge.begin();
  
 
  //Start Mosquitto
  client.setServer(server, 1883);
  client.setCallback(callback);
  
  // Allow the hardware to sort itself out
  delay(1500);
}


void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic","hello world");
      // ... and resubscribe
      Serial.println("Subscribing to REPL topic");
      client.subscribe("REPL");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  // Memory pool for JSON object tree.
  String jsonStr;
  StaticJsonBuffer<200> jsonBuffer;
  Serial.print("REPL instruction set arrived [");
  Serial.print(topic);
  Serial.println("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
    jsonStr += (char)payload[i];
  }
  Serial.println();
  
  char json[length + 1];
  jsonStr.toCharArray(json,sizeof(json));
  JsonObject& root = jsonBuffer.parseObject(json);
  if (!root.success()) {
    Serial.println("parseObject() failed");
  }
  //const char* type = root["type"];
  //String type = root["type"];
  //const char* side = root["side"];
  //String side = root["side"];
  //const char* dir = root["direction"];
  String dir = root["direction"];
  double speed = root["speed"];
  double duration = root["duration"];

  if(dir == "stop"){
    allstop();
  }
  else if(dir == "right")
  {
    //if direction = right or left, duration = .25,.5,.75 or 1.0
    //.25 = quarter turn
    //.50 = half turn
    turn(dir, duration);
  }
  else
  {
    propel(dir,speed,duration);
  }
}

PubSubClient is supported on the ESP8266, so programming should be pretty straightforward.

Pieter

Thanks PieterP. One more quick question, I am using pins #22, #23, #52, #53 on the mega (as well as other pins in the other digital ports). If I use a hat like this:

Will those pins above #22 still work? I am uncertain if I add a hat to a mega, what happens to the pins that are not connected with the hat.

Thanks again.

christopheraburns:
If I use a hat like this:

SparkFun WiFi Shield - ESP8266 - WRL-13287 - SparkFun Electronics

I wouldn't use a shield like that.
First of all, you can't easily use it to program the ESP directly, so you can't use it with PubSubClient. Programming a development board is many times easier than programming a shield like this, because dev boards have a USB interface for programming, and they automatically reset and enter programming mode when you hit upload in the IDE. You'll need quite a lot of external components if you want the same functionality on this shield.

Secondly, it's not made for the Arduino MEGA. It connects the ESP's serial connection to UART0 on the Arduino, or to pins 8 and 9 for using SoftwareSerial.
UART0 is used for programming the Arduino MEGA over USB, so if you use this serial port for communication with the ESP, you have to unplug the shield every time you upload a new program.
SoftwareSerial uses quite a lot of resources, and it's really slow compared to a hardware UART.
On the MEGA, you have three other hardware UARTs that are not in use. It makes sense to connect the ESP to one of these UARTs instead of UART0. This shield doesn't support that.

You really don't need a shield for this, you just need 4 connections (ground, Vcc, RX and TX) and two resistors for a voltage divider, if you use a development board like the WeMos D1 mini. You can easily do that with jumper wires and a breadboard.

It's about 5 times cheaper as well. $15 dollar for a shield like that is just a rip-off. You can get WeMos D1 mini - like boards for a little over $3. They have the same hardware on board as the SparkFun shield, AND a USB interface for programming.

On top of that, you could use any interface you like to communicate with the MEGA (I²C, SPI, ...), not just Serial.

Pieter

I agree a ESP8266 is the best way to go and cheapest, i use a esp8266-01 and run the code on my mega then send it over hardware serial "serial 2" rx2 17 and tx2 16 which is available on all megas, being in the communication row of inputs. a good library to run the code on the arduino side rather than flashing the esp is GitHub - bportaluri/WiFiEsp: Arduino WiFi library for ESP8266 modules

Just a note the ESP is juicy, running at 200Ma to 300Ma and will draw most of your current, meaning if you have other devices connected your arduino may not have enough power and will crash, so you may need external power added to the esp directly.

example of hardware serial with the WiFiEsp library , note no need for the softwareSerial library or softwareSerial connection, also the esp8266 comes at 115200 and the library is made for 9600 buad rate else your get time outs so when you get your esp follow this tutorial http://www.instructables.com/id/Getting-Started-With-the-ESP8266-ESP-01/ and enter this command AT+UART_DEF=9600,8,1,0,0 after you get OK from sending AT then change the serial monitor rate to 9600 and re do the tutoiral:

Serial.begin(115200); // initialize serial
Serial2.begin(9600); // initialize serial for ESP module with HardWare Serial2 on pins 17 (RX2) and 16 (TX2) "Mega2560"
WiFi.init(&Serial2); // initialize ESP module
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");// check for the presence of the shield
while (true); // don't continue
}

KawasakiZx10r:
Just a note the ESP is juicy, running at 200Ma to 300Ma and will draw most of your current, meaning if you have other devices connected your arduino may not have enough power and will crash, so you may need external power added to the esp directly.

That's not an issue if you use development boards, they have their own 3.3V regulator.

KawasakiZx10r:
example of hardware serial with the WiFiEsp library , note no need for the softwareSerial library or softwareSerial connection, also the esp8266 comes at 115200 and the library is made for 9600 buad rate else your get time outs so when you get your esp follow this tutorial http://www.instructables.com/id/Getting-Started-With-the-ESP8266-ESP-01/ and enter this command AT+UART_DEF=9600,8,1,0,0 after you get OK from sending AT then change the serial monitor rate to 9600 and re do the

I don't see a reason to use 9600 baud over 115200.

I really don't recommend AT commands for anything other than really simple stuff (and even then programming it directly is easier).
If you need more advanced functions like MQTT, programming it directly is the way to go.
The AT vs direct programming matter has been discussed many times on this forum.

AT commands and complex networking protocols
AT commands are a convoluted way to communicate with the ESP, and all code executes on the Arduino. AT commands only really support raw TCP and UDP, if you want to use protocols on top of that (e.g. HTTP, MQTT, OSC ...), all that code executes on your Arduino, using a lot of resources. Especially if you need to parse text-based requests requiring large or dynamic buffers.
It's also much, much harder to debug or to check for errors. If you program the ESP directly, you have high-level functions and classes for these protocols, that provide a simple interface and you can easily check if a function completed successfully by checking if it returned true or false. This makes error handling much simpler.
These libraries do not exist for AT commands, and even if they do exist, they are much less mature. Their documentation is often very poor, and the online resources are limited, because pretty much nobody uses them.

If you have to do multiple protocols at once (e.g. a HTTP web server and an OSC client), you can just about forget about it if you try to use AT commands.
Pretty much all code is blocking, because it uses the same Serial connection, and you can really only do one thing at once.

If you program the ESP directly, you can have many services running "in parallel". (e.g. a HTTP web server, an OSC client, a DNS server, mDNS server, OTA service ... all at once.)

Resource management
The Arduino has limited resources (32KiB flash, 2KiB or RAM and an 8-bit 16MHz CPU in case of the UNO) while the ESP is much faster and has many times more memory (4MiB flash, 64 KiB of instruction RAM, 96 KiB of data RAM, 32-bit CPU up to 160MHz).
So if you've got the choice, it makes sense to run all heavy networking code and text processing/parsing on the ESP, and save the resources of the Arduino for your actual microcontroller sketch.

Abstraction and code quality
My preferred approach is to have one piece of code on the ESP that connects to WiFi, sets up mDNS services, OTA update services, web servers, UDP listeners, MQTT clients ... whatever you need.
All code that receives and parses network requests runs on the ESP as well. If the ESP receives a command (e.g. "Turn on the lights"), it sends a command over serial to the Arduino (e.g. "Pin 16, HIGH").

On the other hand, if the Arduino wants to send something over the internet (e.g. to post the temperature to a database), it just sends it over serial to the ESP (e.g. "Temperature=21.3°C"), and the ESP takes this data, establishes a connection to the server, constructs a request, adds the right data, sends the request, checks the response, etc.

This greatly improves the readability and abstraction of both pieces of code. Having to mix networking stuff and microcontroller logic in one sketch is just really cumbersome.

For communication between the two MCUs, take a look at Robin2's Serial Input Basics.

Debugging
Another advantage is that you can test the microcontroller code without the ESP, by just using the Serial Monitor. The Arduino doesn't care if it's talking to an ESP8266 or to a human with a serial console.

You can also use UART1 on the ESP for printing debug information from the ESP, and UART0 on the Arduino for printing debug information from the Arduino.
If you use AT commands, debugging becomes a whole lot harder, especially if you use an UNO, where the only UART that is used for debugging over USB is also used for AT communication. This means that you can't read the responses from the AT firmware, only the commands sent by the Arduino.

Please don't take my word for it, try it yourself, and pick the approach you like the most.
I used AT commands when I got my first ESP8266, but ever since I discovered the ESP8266 Arduino Core for programming it directly, I've never touched AT commands again.

Whichever approach you pick, I'd recommend to get a dev board that supports both approaches.
At $3.50, there's really no valid argument against a WeMos D1 mini (clone).
Even if you decide to use AT commands, it will still be easier because you have a decent power supply on-board, and you can use the USB interface to update the AT firmware really easily.

Pieter

Great advice here, listen to Pieter. I started with arduino's, nano's, mega's. But once I found the Node MCU, I do everything on that board. It's a micro controller like the arduino. The ESP8266 was a real pain, until I worked for a bit with the Node MCU. The Node MCU makes programming easier. I setup upload speed to 921600, and that solved the slow firmware flash.

I use this block in all of my Node MCU programming to standardize on some of the differences between the arduino and the 8266:

// NODE MCU
#define D0 16
#define D1   5 // I2C Bus SCL (clock)
#define D2   4 // I2C Bus SDA (data)
#define D3   0
#define D4   2 // Same as "LED_BUILTIN", but inverted logic
#define D5 14 // SPI Bus SCK (clock)
#define D6 12 // SPI Bus MISO 
#define D7 13 // SPI Bus MOSI
#define D8 15 // SPI Bus SS (CS)
#define D9   3 // RX0 (Serial console)
#define D10 1 // TX0 (Serial console)

#define BUILTIN_LED D4  // GPIO2 of ESP8266

#define ON  LOW
#define OFF HIGH

Only other pain is the IO pins are all 3.3volt. But simply add a .40 cent digital logic converter and you're in business. The Node MCU provides both 5v and 3.3v lines. This also solves the power draw issue with the output pins.

Vinnie