Mega2560 + ESP8266 + MQTT (PubSubClient error)

Hi,

I making a project with the mega connected with ESP8266 via hardware serial1.
Without the PubSubClient liberary i have managed to connect to my wifi.

Now i want to publish something to my own (rasbarryPi) Hassio MQTT server.
For that i need the PubSubCient liberary.
But this liberary asks for a PubSubClient client("???");
What ever i put in stead of the questionsmarks i get errors.

When connecting to MQTT via wemosD1 i use the <ESP8266WiFi.h>
But on the mega that doesn’t work. On the mega i have to use <ESP8266_Lib.h>
Different liberary so copie - past from one skatch to the other doesn’t work.

Kan some please take a look? Maybe PubSub liberary doesn’t work with hardware serial com with esp8266?

Working code on wemosD1 and MQTT:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
const char* ssid = "******;
const char* password = "******";
const char* mqtt_server = "******";

WiFiClient espClient;
PubSubClient client(espClient);

int SwitchedPin = D4;
String afzuiging;
String strTopic;
String strPayload;

void setup_wifi() {
 Serial.begin(115200);
  delay(100);
 
  // We start by connecting to a WiFi network
 
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  strTopic = String((char*)topic);
Serial.println(strTopic);
  
  if(strTopic == "ha/afzuiging")
    {
    afzuiging = String((char*)payload);
    if(afzuiging == "ON")
      {
        Serial.println("ON");
        digitalWrite(SwitchedPin, LOW);
      }
    else
      {
        Serial.println("OFF");
        digitalWrite(SwitchedPin, HIGH);
      }
    }
}
 
 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient","admin","admin")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.subscribe("ha/#");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
 
void setup()
{
  setup_wifi(); 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  pinMode(SwitchedPin, OUTPUT);
  digitalWrite(SwitchedPin, LOW);
}
 
void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

And this is the Mega NOT working code:

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <PubSubClient.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "************";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "*****";
char pass[] = "********";

//Hardware Serial on Mega, Leonardo, Micro...
#define EspSerial Serial1
#define ESP8266_BAUD 115200

ESP8266 wifi(&EspSerial);


///////////////////////////////////MQTT//////////////////////////////////
PubSubClient client(ESP8266 wifi);
String afzuiging;
String strTopic;
String strPayload;


////////////////////////////////////TFT/////////////////////////////////

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <TouchScreen.h>
#define MINPRESSURE 200
#define MAXPRESSURE 1000


#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <FreeDefaultFonts.h>

// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
const int XP = 8, XM = A2, YP = A3, YM = 9; //320x240 ID=0x9341
const int TS_LEFT = 73, TS_RT = 896, TS_TOP = 124, TS_BOT = 910;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

Adafruit_GFX_Button on1_btn, on2_btn, on3_btn, off_btn;

int pixel_x, pixel_y;     //Touch_getXY() updates global vars
bool Touch_getXY(void)
{
  TSPoint p = ts.getPoint();
  pinMode(YP, OUTPUT);      //restore shared pins
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);   //because TFT control pins
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
  if (pressed) {
    pixel_x = map(p.y, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
    pixel_y = map(p.x, TS_TOP, TS_BOT, 0, tft.height());
  }
  return pressed;
}

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define Speed1Pin 31
#define Speed2Pin 32

void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  strTopic = String((char*)topic);
Serial.println(strTopic);
  
  if(strTopic == "ha/afzuiging")
    {
    afzuiging = String((char*)payload);
    if(afzuiging == "ON")
      {
        Serial.println("ON");
       // digitalWrite(SwitchedPin, LOW);
      }
    else
      {
        Serial.println("OFF");
       // digitalWrite(SwitchedPin, HIGH);
      }
    }
}

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

void setup(void)
{
  Serial.begin(115200);
  pinMode(Speed1Pin, OUTPUT);
  pinMode(Speed2Pin, OUTPUT);
  uint16_t ID = 0x9341;
  tft.begin(ID);
  tft.setRotation(1);            //PORTRAIT
  tft.fillScreen(BLACK);
  tft.drawRect(0, 0, 319, 240, WHITE);

  tft.setFont(&FreeSans9pt7b);
  
  tft.setCursor(50, 30);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.print("WIFI CONNECTING...");

///////////////////////////////WIFI/////////////////////
    EspSerial.begin(ESP8266_BAUD);
    Blynk.begin(auth, wifi, ssid, pass);
    
  /////////////////////////MQTT///////////////////////

   client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

//////////////////////////////////////////////////


  
  tft.fillScreen(BLACK);
  tft.drawRect(0, 0, 319, 240, WHITE);
  tft.setCursor(50, 30);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.print("CENTRALE AFZUIGING");





  tft.fillRect(150, 50, 155, 100, RED);
}

void loop(void)
{
  /////////////////////WIFI////////////////////////////
  Blynk.run();
  
  ////////////////////MQTT////////////////////////////
 if (!client.connected()) {
    reconnect();
  }
  client.loop();
////////////////////////////////////////////////////


  //__________________________________________________

  }


}

this is the error:

Arduino:1.8.9 (Mac OS X), Board:“Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)”

/var/folders/wf/4vz3b4_x6658s321739l7vjc0000gn/T/arduino_modified_sketch_921032/Afzuiging_TFT_side_V4_test_HASSio.ino: In function ‘void reconnect()’:
Afzuiging_TFT_side_V4_test_HASSio:158:18: error: request for member ‘connected’ in ‘client’, which is of non-class type ‘PubSubClient(ESP8266)’
while (!client.connected()) {
^

^
exit status 1
request for member ‘connected’ in ‘client’, which is of non-class type ‘PubSubClient(ESP8266)’

PubSubClient client(ESP8266 wifi);

This is the declaration of a function "client" that takes one object of type "ESP8266" as a parameter, and returns an object of type "PubSubClient".

I don't know what "ESP8266_Lib" is, but my guess would be that it doesn't work if you upload your own firmware to the ESP.

Pieter

hoi Pieter,

Is there any other way around esp8266_lib?

Esp8266_lib is one from blynk examples ->boards wifi -> ESP8266 shield.

Thanks for the help

It all depends on what you want your system to do. The ESP8266 is a very powerful processor on its own. If it has enough pins to read/drive all sensors/actuators you need, just don't use the Arduino MEGA at all.

If you need more IO, there are two main options: use I²C or SPI IO expanders or shift registers connected to the ESP, or use the MEGA as an IO expander.
In both scenarios, the ESP8266 does all the heavy lifting, and the MEGA doesn't have to worry about anything MQTT or WiFi related: it just listens to commands given by the ESP8266. For example, if you have a temperature sensor, the ESP can request the temperature from the MEGA, the MEGA reads the sensor, and responds to the ESP with the measurement. Finally the ESP adds the measurement in a network packet as suited.

I think this is a clean solution, because the ESP only has to worry about networking stuff, not interfacing with sensors, and the MEGA only has to know how to read the sensors, it doesn't know anything about WiFi.

Using off-the-shelf IO expanders is easier, because then you only have to worry about a single program, and you don't have to handle the ESP-MEGA communication.

Communication between ESP and MEGA can happen any way you like (SPI, I²C, UART ...) just keep in mind that you need level shifters, because the ESP8266 is a 3.3V device, and you will damage it if you supply 5V to one of its pins.

hi Pieter,

Thank for the info.

Im using a nice tft (UNO/MEGA) shield for the setting speeds for my fan.

Now without the mqtt stuff in the skatch i connect to wifi via hardware serial on the mega and esp8266 just fine..

im stuck now... :frowning:

thanks for your help

Kumalix:

PubSubClient client(ESP8266 wifi);

Change that line to:

PubSubClient client(wifi);

This line declares an object of the PubSubClient class named client and passes a Client object to the constructor. It's incorrect syntax to specify the type name on an argument.

This line allows the PubSubClient to work with any networking library that uses Arduino’s standard API. Instead of writing the PubSubClient library for a specific networking library or set of libraries, the author made it much more flexible. This means you could use it with libraries like Ethernet, WiFi, ESP8266WiFi, WiFiNINA, WiFi101, WiFiEsp, and so on. Some of those libraries didn’t even exist when the PubSubClient library was written, yet it’s still compatible with them!