esp 32 with esp now and mqtt connection - arduino

i trying to acheive some home automation with esp 32. my project is like following
i have several end points with esp 8266 acting likes slave switches sending Id datas to an esp 32 who is my gateway.
both slaves (esp8266) and master gateway (esp 32, are communicating
with espnow library
the gateway should be connected to an mqtt server ( rasperry pi) who
dispatches automation command depending on endpoint Id.
For now i succesfully have communication between esp8266 slaves and esp 32 gateway
i also have succesfully setted my rasperry pi as mqtt broker with home automation command
But i'm blocked when i need to add wifi connection and mqtt messaging to my ESP 32 gateway
My code on the esp32 gateway is
#include <esp_now.h>
#include <WiFi.h>
#include <PubSubClient.h>
#define LED 2
int myData;
char ssid[] = "my ssid";
char password[] = "mypass";
char mqtt_server[] = "192.168.1.55";
WiFiClient espClient;
PubSubClient MQTTclient(espClient);
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("data: ");
Serial.println(myData);
/*
if(myData == 1){
String reponse="device1";
MQTTclient.publish("homecommand",reponse.c_str());
}
*/
for (int t=0; t<3; t++)
{
digitalWrite(LED,HIGH);
delay(50);
digitalWrite(LED,LOW);
delay(50);
}
}
void MQTTconnect() {
while (!MQTTclient.connected()) {
Serial.print("Attente MQTT connection...");
String clientId = "TestClient-";
clientId += String(random(0xffff), HEX);
// test connexion
if (MQTTclient.connect(clientId.c_str(),"","")) {
Serial.println("connected");
} else { // si echec affichage erreur
Serial.print("ECHEC, rc=");
Serial.print(MQTTclient.state());
Serial.println(" nouvelle tentative dans 5 secondes");
delay(5000);
}
}
}
void setup() {
// Initialize Serial Monitor
Serial.begin(115200);
pinMode(LED,OUTPUT);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_register_recv_cb(OnDataRecv);
/*
Serial.println("Connect to Wifi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Connected");
MQTTclient.setServer(mqtt_server, 1883);
if (!MQTTclient.connected()) {
MQTTconnect();
}*/
}
void loop() {
// put your main code here, to run repeatedly:
}
The code works well, when i trigger one of my slaves i receive the message print it in serial an blink 3 times
But when i uncomment the part about connecting to my home router and my mqtt broker i lost the 'On DataRecv' callback
So my question is "Is it possible to have an Esp working as espnow gateway to gather messages and at the same time being connected to my home router for mqtt publishing ?"
If yes i would appreciate some help to implement it.
Thanks a lot.

Swap
WiFi.mode(WIFI_STA);
for
WiFi.mode(WIFI_AP_STA);
re:
https://www.electrosoftcloud.com/en/esp32-wifi-and-esp-now-simultaneously/

Related

MQTT Mosquitto and two ESP8266

My problem:
I have a Raspberry Pi, and I have installed the Mosquitto MQTT broker on it. My objective is to make 2 MQTT clients communicate over the Mosquitto broker, so I have installed the code below on two ESP8266 (WeMos D1 mini)
and I have created this MQTT command: mosquitto_pub -h 192.168.1.20 -t /wassim/led -m "on".
So, when I connect only one ESP client, I see the message "on" in the serial monitor. But when I connect the second ESP client, I can't see any message on the serial monitor... (But if on the terminal of the Raspberry, then I can see everything. On the clients I can't see anything). The code:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <MQTTClient.h>
float temp;
float lm;
String aw="";
const char* host = "192.168.1.20";
const char* ssid = "THOMSON1121";
const char* password = "Wassim";
WiFiClient net;
MQTTClient mqtt;
void connect();
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("Booting...");
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
mqtt.begin(host, net);
connect();
if(mqtt.subscribe("/wassim/led")) {
Serial.println("Subscription Valid !");
}
Serial.println("Setup completed...");
}
void loop() {
if (!mqtt.connected()) {
connect();
}
mqtt.loop();
delay(3000);
}
void connect() {
while(WiFi.waitForConnectResult() != WL_CONNECTED) {
WiFi.begin(ssid, password);
Serial.println("WiFi connection failed. Retry.");
}
Serial.print("Wifi connection successful - IP-Address: ");
Serial.println(WiFi.localIP());
while (!mqtt.connect(host)) {
Serial.print(".");
}
Serial.println("MQTT connected!");
}
void messageReceived(String topic, String payload, char * bytes, unsigned int length) {
Serial.print("incoming: ");
Serial.print(topic);
Serial.print(" - ");
Serial.print(payload);
Serial.println();
}
The change from one client to another is if(mqtt.subscribe("/wassim/tmp")).
MQTT is a 'message bus' application....in order to have multiple 'subscribers' receive the same message that is being put on the bus by a 'publisher', they both have to subscribe to the same topic...or at least enough of the topic + wildcard...in order to get sent that published message. You only have one of your two clients listening to the topic that your 'mosquitto_pub' command is sending out. For it to receive, you either specify the full topic (mqtt.subscribe("/wassim/led")), or a wildcard to pick up all the 'wassim' messages sent out (mqtt.subscribe("/wassim/#")).

Unable to use DS18B20 temperature sensor with a GSM shield on an Arduino UNO

I'm trying every solution but no way....
I have the official Antenova GSM shield and the sensor DS18B20.
If I connect only the GSM shield without the sensor, I get -127 from the sensor and the shield is able to do the HTTP post to my server successfully. If the sensor is connected, it returns the right temperature, but the client.connect(server, port) never returns. I set the sensor pin to 12 instead of 2 to avoid problems, but seem like they are in conflict. I'm already using the external power supply.
// libraries
#include <GSM.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// PIN Number
#define PINNUMBER "1218"
// APN data
#define GPRS_APN "web.omnitel.it" // replace your GPRS APN
#define GPRS_LOGIN "" // replace with your GPRS login
#define GPRS_PASSWORD "" // replace with your GPRS password
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 12
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess;
// URL, path & port (for example: arduino.cc)
char server[] = "mancioboxblog.altervista.org";
char path[] = "/add.php";
int port = 80; // port 80 is the default for HTTP
// check the connection status
int con = 0;
// string to save the temp
String data = "";
// temp random
long temp;
void setup() {
//file version
Serial.println("Version: 1.6");
// initialize serial communications and wait for port to open:
Serial.begin(9600);
/* only for old USB usually not required
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}*/
Serial.println("Starting Arduino web client.");
// connection state
boolean notConnected = true;
// After starting the modem with GSM.begin()
// attach the shield to the GPRS network with the APN, login and password
while (notConnected) {
Serial.println("I'm trying to connect");
if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &
(gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
notConnected = false;
} else {
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("I'm connected");
// this operation is faster than connect to sim card
// Start up the temperature sensor library
Serial.println("initialize sensors");
sensors.begin();
// wait the the gsm shield is initialized
delay(1000);
}
void loop() {
/* GET THE TEMPERATURE */
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print(" Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
Serial.print("Temperature for Device 1 is: ");
temp = sensors.getTempCByIndex(0);
Serial.print(temp); // Why "byIndex"?
// You can have more than one IC on the same bus.
// 0 refers to the first IC on the wire
//only for test
//temp = random(33);
data = "temp=" + (String)temp;
Serial.println("temp stored = " + data);
delay(2000);
con = client.connect(server, port);
// wait connection engaged
delay(2000);
// if you get a connection, report back via serial:
if (con == 1) {
Serial.println("connected");
// Make a HTTP request:
client.print("POST ");
client.print(path);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
client.println("Connection: close");
client.print("Content-Length: ");
client.println(data.length());
client.println("");
client.println(data);
client.println("");
//what I'm sending
Serial.print("POST ");
Serial.print(path);
Serial.println(" HTTP/1.1");
Serial.print("Host: ");
Serial.println(server);
Serial.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
Serial.println("Connection: close");
Serial.print("Content-Length: ");
Serial.println(data.length());
Serial.println("");
Serial.println(data);
Serial.println("");
// if you didn't get a connection to the server:
} else if(con == -1){
Serial.println("connection failed: TIMED_OUT -1");
} else if(con == -2){
Serial.println("connection failed: INVALID_SERVER -2");
} else if(con == -3){
Serial.println("connection failed: TRUNCATED -3");
} else if(con == -4){
Serial.println("connection failed: INVALID_RESPONSE -4");
}
if(client.connected()){
client.stop(); // DISCONNECT FROM THE SERVER
Serial.println("enter in the if and stop the client");
}else{
Serial.println("the client is not connected");
}
//keep over 2 second otherwise is not able to close and reopen connection
delay(2000); // WAIT MINUTES BEFORE SENDING AGAIN
Serial.println("code repeat");
}
Is there a problem with my code? Maybe I shouldn't read the sensor before the client connects?

Not able to Receive subscribed Message with PubSubClient.h in Arduino Uno R3

#include "SPI.h"
#include “WiFiEsp.h”
#include <WiFiEspClient.h>
#include “SoftwareSerial.h”
#include <PubSubClient.h>
#include <WiFiEspUdp.h>
float temp=0;
int tempPin = 0;
int isClientConnected = 0;
char data[80];
char ssid[] = “SSID”; // your network SSID (name)
char pass[] = “PASSWORD”; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio’s status
char deviceName = “ArduinoClient1”;
IPAddress server(xxx,xxx,xxx,xxx); //MQTT server IP
IPAddress ip(192,168,43,200);
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print(“Message arrived [“);
Serial.print(topic);
Serial.print(“] “);
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
Serial.println("-");
}
// Emulate Serial1 on pins 6/7 if not present
WiFiEspClient espClient;
PubSubClient client(espClient);
SoftwareSerial Serial1(6,7); // RX, TX
void setup(){
Serial.begin(9600);
Serial1.begin(9600);
WiFi.init(&Serial1);
WiFi.config(ip);
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
while (true);
}
while ( status != WL_CONNECTED) {
Serial.print("Attemptingonnect to WPA SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
Serial.print("WiFius : ");
Serial.println(status);
}
//connect to MQTT server
client.setServer(server, 1883);
client.setCallback(callback);
isClientConnected = client.connect(deviceName);
Serial.println("+++++++");
Serial.print("isClientConnected;
Serial.println(isClientConnected);
Serial.print("client.state");
Serial.println(client.state());
if (isClientConnected) {
Serial.println("Connected…..");
client.publish("status","Welcome to ISG");
client.subscribe("isg/demoPublish/rpi/ardTempWarn");
//Not able to recieve for this subscribed topic on Arduino Uno Only if I
//print it returns 1
}
}
void loop() {
temp = (5.0 * analogRead(tempPin) * 100.0) / 1024;
Serial.print(" temp : " );
Serial.println(temp);
Serial.print("client.connected);
Serial.println(client.connected());
if (!client.connected()) {
reconnect();
}
client.publish("isg/demoPublish/ard1/tempLM35",String(temp).c_str());
// able to receive data at other
// clients like RPI,Web using Mosquitto broker
client.loop();
delay(5000);
}
void reconnect() {
Serial.println("Device is trying to connect to server ");
while (!client.connected()) {
if (client.connect(deviceName)) {
} else {
delay(5000);
}
}
}
I am using Arduino Uno R3 and ESP8266-01 as wifi connector.
I have to read temperature data and send to Mosquitto ,MongoDB and Raspberry Pi and receive a data on specific condition for that i have subscribed a topic in Arduino.
I am able to receive data from Arduino to all other clients but I am not able to receive data on Subscribed topic in Arduino. But all other deviced like MongoDB able to receive data from Raspberry Pi.
I have used Arduino Uno R3, ESP8266-01 devices and liberary for to connect and send/receive data WiFiEsp.h, WiFiEspClient.h, WiFiEspUdp.h, SoftwareSerial.h, PubSubClient.h
client.subscribe("topic"); returns 1
Also callback function implemented but not able to get call.
So can any one help me why I am not getting subscribed topic message in Arduino?
I have follow https://sonyarouje.com/2016/03/15/mqtt-communication-with-arduino-using-esp8266-esp-01/#comment-111773
The library that you are using has bug in callback hence it would be better that you use other library my preference would be
https://github.com/vshymanskyy/TinyGSM
this library include almost all variants of SIM800(A,C,L,H,808), variants of SIM900(A,D,908,968), ESP8266 (mounted on arduino), Ethernet shield etc. It worked for me, as same issue bugged me for almost 1-2 weeks but latter was able to receive all subscribed message irrespective of mode of communication(GSM,Ethernet,WiFi)

mqtt between esp8266 and arduino with PubSubclient

I am using ESP8266 with arduino using WiFiEsp library.I want to make MQTT connection with arduino so I use PubSubclient library.i got error:
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
my code is:
#include <WiFiEsp.h>
#include <WiFiEspClient.h>
#include <WiFiEspUdp.h>
#include "SoftwareSerial.h"
#include <PubSubClient.h>
IPAddress server(212, 72, 74, 21);
char ssid[] = "atmel"; // your network SSID (name)
char pass[] = "bets56789"; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio's status
// Initialize the Ethernet client object
WiFiEspClient espClient;
PubSubClient client(espClient);
SoftwareSerial soft(2,3); // RX, TX
void setup() {
// initialize serial for debugging
Serial.begin(9600);
// initialize serial for ESP module
soft.begin(115200);
// initialize ESP module
WiFi.init(&soft);
// 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: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network
status = WiFi.begin(ssid, pass);
}
// you're connected now, so print out the data
Serial.println("You're connected to the network");
//delay(2000);
//connect to MQTT server
client.setServer(server, 1883);
client.setCallback(callback);
}
//print any message received for subscribed topic
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
if (!client.connected()) {
reconnect();
}
client.loop();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect, just a name to identify the client
if (client.connect("arduinoClient")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outSHADAB","hello world");
// ... and resubscribe
client.subscribe("inShadab");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
I am using ESP8266 with arduino using WiFiEsp library.I want to make MQTT connection with arduino so I use PubSubclient library
I don't think the PubSubClient supports the WiFiEsp as a network layer from an arduino.
While the doc list the ESP8266 I believe this is running the PubSubClient directly on the ESP8266 hardware.

MQTT on Arduino not working

I'm using Arduino Uno and Wi-Fi shield. I'm trying to implement MQTT protocol for communication and I tried two libraries for Arduino. First one is Knolleary's PubSubClient: http://pubsubclient.knolleary.net/ . I modified original example a little bit to use WiFi module instead of ethernet. Sending works but not every time (sometimes, the message is sent and sometimes not). But receiving via callback function doesn't work at all.
Here is my code:
/*
Basic MQTT example with Authentication
- connects to an MQTT server, providing username
and password
- publishes "hello world" to the desired topic
- subscribes to the desired topic
*/
#include <WiFi.h>
#include <PubSubClient.h>
char ssid[] = "[DELETED]"; // your network SSID (name)
char pass[] = "[DELETED]"; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio's status
// Update these with values suitable for your network.
IPAddress server(85, 119, 83, 194);
WiFiClient WifiClient;
void callbackFunc(char* topic, byte* payload, unsigned int length) {
Serial.println("test message received");
/*Serial.println();
Serial.println("=============== MESSAGE RECEIVED ================================");
Serial.print("Topic: ");
Serial.print(topic);
Serial.println();
Serial.println((const char *) payload);*/
}
PubSubClient client(server, 1883, callbackFunc, WifiClient);
void setup()
{
delay(2000);
Serial.begin(9600);
Serial.println("Starting....");
Serial.println("Initializing Wifi...");
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
}
// attempt to connect using WPA2 encryption:
Serial.println("Attempting to connect to WPA network...");
status = WiFi.begin(ssid, pass);
// if you're not connected, stop here:
if (status != WL_CONNECTED) {
Serial.println("Couldn't get a wifi connection");
while(true);
}
// If you are connected, print out success message
else
Serial.println("Connected to network");
if (client.connect("arduinoClient")) {
Serial.println("Connected to server! Sending message...");
client.publish("randy/test","hello world");
client.subscribe("randy/test");
Serial.println("Sent!");
}
else
{
Serial.println("ERROR: Cannot connect to MQTT server!");
Serial.println(client.state());
}
}
void loop()
{
client.loop();
delay(1000);
if (!client.connected())
{
if(!client.connect("arduinoClient"))
{
Serial.println("ERROR: Cannot connect to MQTT server!");
Serial.println(client.state());
}
else
{
client.subscribe("randy/test");
Serial.println("INFO: reconnected!");
}
}
}
As you can see, I'm using http://test.mosquitto.org/ for testing. I'm also using mosquitto on Ubuntu where I'm subscribed to the same topic and from where (another terminal window) I'm publishing to the same topic. Here is the picture of both windows:
As you can see, "hello world" message from Arduino is received successfully (but not every time), and when I publish "bla" message from another window, it's successfully received on mosquitto (on image) but NOT on Arduino. Is there something wrong with my code or? I found similar problem here: Arduino Knolleary PubSubClient will publish messages but can't receive them
It's worth noticing that it keeps getting reconnected all the time. As you can see, in loop() I put a part of code which will connect and subscribe again if connection is lost. On Serial Monitor I get "INFO: Reconnected!" message every 2-3 seconds.
Adafruit library
Then I tried the Adafruit library, but it won't connect at all! I tried with test.mosquitto.org and with io.adafruit.com from their example, but I just keep getting "Connection failed!" error. I tried making many changes and combinations but no luck so far. Once I managed to get "Failed to subscribe" instead of "Connection failed" but this was only once and next time with the same code I get "Connection failed" again.
Here's my code:
/*
Basic MQTT example with Authentication
- connects to an MQTT server, providing username
and password
- publishes "hello world" to the topic "outTopic"
- subscribes to the topic "inTopic"
*/
#include <WiFi.h>
#include <PubSubClient.h>
char ssid[] = "[DELETED]"; // your network SSID (name)
char pass[] = "[DELETED]"; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio's status
// Update these with values suitable for your network.
IPAddress server(85, 119, 83, 194);
WiFiClient WifiClient;
void callbackFunc(char* topic, byte* payload, unsigned int length) {
Serial.println("test message received");
/*Serial.println();
Serial.println("=============== MESSAGE RECEIVED ================================");
Serial.print("Topic: ");
Serial.print(topic);
Serial.println();
Serial.println((const char *) payload);*/
}
PubSubClient client(server, 1883, callbackFunc, WifiClient);
void setup()
{
delay(2000);
Serial.begin(9600);
Serial.println("Starting....");
Serial.println("Initializing Wifi...");
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
}
// attempt to connect using WPA2 encryption:
Serial.println("Attempting to connect to WPA network...");
status = WiFi.begin(ssid, pass);
// if you're not connected, stop here:
if (status != WL_CONNECTED) {
Serial.println("Couldn't get a wifi connection");
while(true);
}
// Ff you are connected, print out success message
else
Serial.println("Connected to network");
if (client.connect("arduinoClient")) {
Serial.println("Connected to server! Sending message...");
client.publish("randy/test","hello world");
client.subscribe("randy/test");
Serial.println("Sent!");
}
else
{
Serial.println("ERROR: Cannot connect to MQTT server!");
Serial.println(client.state());
}
}
void loop()
{
client.loop();
delay(1000);
if (!client.connected())
{
if(!client.connect("arduinoClient"))
{
Serial.println("ERROR: Cannot connect to MQTT server!");
Serial.println(client.state());
}
else
{
client.subscribe("randy/test");
Serial.println("INFO: reconnected!");
}
}
}
Any idea what's wrong with those libraries or my code?
As mentioned in the comments
When using example code on public brokers make sure you change the client id to something random as the odds of clashing with somebody else are pretty high. Because client ids have to be unique else they will cause a reconnection storm

Resources