MQTT network with ESP8266

It’s possible to generate a network of ESP8266 and ESP32 using the MQTT protocol without using a RaspberryPI such as a broker.

On a ESP8266 is installed a micro broker called uMQTT-broker:https://github.com/martin-ger/esp_wifi_repeater/tree/uMQTT_broker

UPDATE=> A new version has been developed https://github.com/martin-ger/esp_mqtt with a dedicated Git.

This node could be considered the Master or the Server and it’s called Broker in the MQTT protocol.
The Server node is a Access Point (AP) with address 192.168.4.1 but also it is able to connect to a local Wifi network as a Station (STA).
The Server node shares together the MQTT messagges coming from the 2 networks.

The precompiled binaries are available at:
https://github.com/martin-ger/esp_wifi_repeater/tree/uMQTT_broker/firmware
They can be flashed with:
esptool.py --port /dev/ttyUSB0 write_flash -fs 32m 0x00000 0x00000.bin 0x10000 0x10000.bin
For ESP-01:
esptool.py --port /dev/ttyUSB0 write_flash -fs 8m 0x00000 0x00000.bin 0x10000 0x10000.bin

The Server node could be configurated by the UART console or a telnet connection:
nc 192.168.4.1 7777
or using the local wifi network:
nc 192.168.xxx.yyy 7777

When the connection is started sending “help” is possible to see all the commands to log or set the server.
More details are available at:
https://github.com/martin-ger/esp_wifi_repeater/blob/master/README.md#usage

A MQTT client for ESP8266 is:
https://github.com/256dpi/arduino-mqtt
The MQTT library for Arduino IDE is based on the Eclipse Paho projects

Another MQTT client for ESP8266 is:
https://github.com/knolleary/pubsubclient
http://pubsubclient.knolleary.net/
The MQTT clients uses the MQTT V3.1.1

To test the MQTT broker on the PC I suggest MQTT-Spy GUI:
https://github.com/eclipse/paho.mqtt-spy/wiki

A more complex system could be built using a RaspberryPI (RPI) where is installed the Monsquitto MQTT broker:
https://github.com/mqtt/mqtt.github.io/wiki
Some instruction how to install Monsquitto on RPI:
https://oshlab.com/install-mqtt-mosquitto-raspberry-pi/
Node-Red could run inside the RPI
Node-Red manages the MQTT messagges and generate actions between the IoT objects (RPI, ESP8266s. ESP32s, Arduinos, Telegram Bots..):
https://nodered.org/
http://noderedguide.com/tag/mqtt/

There is MQTT broker for Node-Red:
https://flows.nodered.org/node/node-red-contrib-mqtt-broker

Esempi Arduino e ESP8266

Ho aggiornato il mio repository GitHub con esempi per Arduino e ESP8266

 

Si consiglia la lettura del seguente esempio:

ESP8266 , DS1820, SPIFFS, Gauge con ArduinoIDE

Questo esempio legge la temperatura da un termometro DS1820.

Utilizza la libreria SPIFFS per salvare le pagine nella flash memory del ESP.

La pagina è aggiornata dinamicamente tramite AJAX e XML.

La temperatura è mostrata nella pagina internet del server ESP su un display (gauge) scritto in Javascript.

Arduino_IDE_Browser_Gauge

ESP8266 Web Server

Questo articolo è superato

Si consiglia di utilizzare l’Arduino-IDE per ESP

 

Io e Carlo abbiamo sviluppato un primo esempio per Arduino Uno (ARD1) di Web Server utilizzando i moduli Wifi ESP8266 (ESP).

La connessione tra ARD1 e ESP avviene tramite SoftwareSerial a 9600baud.
Il codice è disponibile su Gist

/*ESP8266_arduino_Gio_08.ino
*
* ====== ESP8266 Demo ======
* Print out analog values
* ==========================
*
* Change SSID and PASS to match your WiFi settings.
* The IP address is displayed to soft serial upon successful connection.
*
/*ESP8266_arduino_Gio_02.ino
*
* ====== ESP8266 Demo ======
* Print out time from start
* ==========================
*
* Change SSID and PASS to match your WiFi settings.
* The IP address is displayed to soft serial upon successful connection.
*
* Ray Wang @ Rayshobby LLC
* http://rayshobby.net/?p=9734
* Modificato da Carlo e Giorgio
* Versione per Arduino Uno con SoftSerial
*/
#include <SoftwareSerial.h>
SoftwareSerial ESP(9,10); // RX,TX collegati a ESP8266
enum {WIFI_ERROR_NONE=0, WIFI_ERROR_AT, WIFI_ERROR_RST, WIFI_ERROR_SSIDPWD, WIFI_ERROR_SERVER, WIFI_ERROR_UNKNOWN};
#define BUFFER_SIZE 128
#define SSID "xxx_Network" // change this to match your WiFi SSID
#define PASS "xxxxxx" // change this to match your WiFi password
#define PORT "8080" // using port 8080 by default
char buffer[BUFFER_SIZE];
unsigned long time;
int led = 13; // Led Webserver ON
//----------------------------
void setup() {
digitalWrite(led, LOW);
ESP.begin(9600);
ESP.setTimeout(15000);
Serial.begin(9600);
Serial.println("ESP8266_arduino_Gio_02.ino");
Serial.println("begin...");
pinMode(led, OUTPUT);
while(1){
byte err = setupWiFi();
if(err){
// error, print error code
Serial.print("setup error:");
Serial.println((int)err);
}else{
// success, print IP
Serial.print("ip addr:");
char *ip = getIP();
if (ip) {
Serial.println(ip);
digitalWrite(led, HIGH);
break;
}
else {
Serial.println("none");
}
maxTimeout();
}
}
}
//------------------------------
bool maxTimeout(){
// send AT command
ESP.println("AT+CIPSTO=0");
if(ESP.find("OK")){
return true;
}else{
return false;
}
}
//-----------------------------
char* getIP(){
// send AT command
ESP.println("AT+CIFSR");
// the response from the module is:
// AT+CIFSR\n\n
// 192.168.x.x\n
// so read util \n three times
ESP.readBytesUntil('\n', buffer, BUFFER_SIZE);
ESP.readBytesUntil('\n', buffer, BUFFER_SIZE);
ESP.readBytesUntil('\n', buffer, BUFFER_SIZE);
buffer[strlen(buffer)-1]=0;
return buffer;
}
//----------------------------
void loop() {
int ch_id, packet_len;
char *pb;
ESP.readBytesUntil('\n', buffer, BUFFER_SIZE);
if(strncmp(buffer, "+IPD,", 5)==0) { //Compara.
// request: +IPD,ch,len:data
sscanf(buffer+5, "%d,%d", &ch_id, &packet_len);
if(packet_len > 0){
// read serial until packet_len character received
// start from :
pb = buffer+5;
while(*pb!=':') pb++;
pb++;
if (strncmp(pb, "GET /", 5) == 0) {
serve_homepage(ch_id);
}
}
}
delay(1000);
}
//----------------------------
void serve_homepage(int ch_id) {
//String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n";
String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\nRefresh: 20\r\n";
String content="Hello ESP!!!: Sono attivo da: ";
time = millis()/1000;
content += time;
content += "secondi!!!";
/*
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 2; analogChannel++) {
int sensorReading = analogRead(analogChannel);
content += "analog input ";
content += analogChannel;
content += " is ";
content += sensorReading;
content += "<br />\n";
} */
header += "Content-Length:";
header += (int)(content.length());
header += "\r\n\r\n";
ESP.print("AT+CIPSEND=");
ESP.print(ch_id);
ESP.print(",");
ESP.println(header.length()+content.length());
if (ESP.find(">")) {
ESP.print(header);
ESP.print(content);
delay(20);
}
/*Serial.print("AT+CIPCLOSE=");
Serial.println(ch_id);*/
}
//-------------------------------
byte setupWiFi() {
ESP.println("AT");
delay(500);
if(!ESP.find("OK")) {
delay(300);
return WIFI_ERROR_AT;
}
//delay(1500);
// reset WiFi module
ESP.println("AT+RST");
delay(500);
if(!ESP.find("ready")) {
delay(300);
return WIFI_ERROR_RST;
}
delay(500);
// set mode 3
ESP.print("AT+CWJAP=\"");
ESP.print(SSID);
ESP.print("\",\"");
ESP.print(PASS);
ESP.println("\"");
delay(2000);
if(!ESP.find("OK")) {
delay(300);
return WIFI_ERROR_SSIDPWD;
}
delay(500);
// start server
ESP.println("AT+CIPMUX=1");
delay(500);
if(!ESP.find("OK")){
delay(200);
return WIFI_ERROR_SERVER;
}
delay(500);
ESP.print("AT+CIPSERVER=1,"); // turn on TCP service
delay(500);
ESP.println(PORT);
delay(500);
if(!ESP.find("OK")){
delay(200);
return WIFI_ERROR_SERVER;
}
return WIFI_ERROR_NONE;
}
Ho utilizzato gli ESP8266 con il firmware > 0.9.2 che comunicano a 9600 baud .
Ho connesso ESP8266 attraverso un Level Converter Bidirezionale ad Arduino per avere le tensioni a 3.3 V.
Alimento ESP8266 con un alimentatore esterno a 3.3V.
ESP8266 comunica attraverso la SoftwareSerial sui pin 9 (Rx Arduino) e 10 (Tx Arduino) di Arduino.
Per il debug posso quindi usare la comunicazione USB di Arduino, come caricare gli sketch senza problemi, come di norma faccio con i moduli BT.L’esempio di codice allegato crea un web server (WS) con una pagina dinamica che ogni 20 secondi si connette al WS e riceve i secondi dall’accensione del WS.Commentato c’è anche il codice per visualizzare 2 segnali analogici.Questo codice è frutto dell’elaborazione dell’esempio di http://rayshobby.net/?p=9734
Consiglio di visitare il sito di Ray per maggiori dettagli. Ray ha inoltre sviluppato un nuovo sketch che dovrebbe gestire meglio gli ESP. La mia versione non è stata ancora aggiornata.
ATTENZIONE:
L’esempio di Ray è stato sviluppato per Arduino Mega che dispone di due seriali Hardware.
Per un esempio più complesso consiglio invece di consultare il Blog di Peter
E’ sempre in costante aggiornamento:
Peter usa un Arduino Mega per avere due seriali Hardware

Manuali Programmazione Arduino

Vi segnalo alcuni manuali di programmazione di Arduino scritti in Italiano

Principali Funzioni del linguaggio Arduino Cheat Sheet oppure link2 , link3, link4

Principali Componenti Ellettronici Electronics Reference Sheet

 

Libreria UIPEthernet per ENC28J60 – Arduino

La libreria UIPEthernet consente di utilizzare gli sketch Arduino pensati per l’ethernet shield ufficiale anche con il chip ENC28J60.
E’ possibile creare un webserver che per esempio consente di cambiare lo stato a 4 uscite utilizzando una interfaccia AJAX
Il tutto è descritto nel seguente tutorial di Luca Dentella sviluppato con la mia partecipazione.

Consiglio inoltre di leggere tutti gli altri tutorial di Luca a riguardo.