martin-ger / umqttbroker Goto Github PK
View Code? Open in Web Editor NEWMQTT Broker library for ESP8266 Arduino
License: MIT License
MQTT Broker library for ESP8266 Arduino
License: MIT License
Thanks for this great work firstly, but I have some problem with it. Let me try to explain it please. I can connect successfully to the broker, and with latest release I can successfully disconnect I suppose. But after a couple of connect-disconnect sequence (usually 4-6) ESP is not accepts new connections. It throws this immediatelly when I try to connect :
java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
Until I restart (power off then on) the ESP, I cannot connect to the mqtt broker from any client on any platform
#using the latest commit of this library as a broker
#using the paho.mqtt.android as a client (tried on other platforms as well, client is not problem I think)
Hello,
great work! Unfortunately, I get an error message when compiling (Arduino IDE 1.8.7, I also tested 1.8.5 and 1.6.11). The error occurs as soon as I add #include "uMQTTBroker.h" to any project (even uMQTTBroker-Example).
Here is the complete error message. Maybe you have some advice for me.
In file included from C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include/os_type.h:10:0,
from C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include/user_interface.h:9,
from C:\Users\xxx\Documents\Arduino\libraries\uMQTTBroker\src\uMQTTBroker.h:4,
from C:\Users\xxx\Documents\Arduino\libraries\uMQTTBroker\src\uMQTTBroker.cpp:2:
C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include/ets_sys.h:168:5: error: previous declaration of 'int atoi(const char*)' with 'C++' linkage
int atoi(const char *nptr);
^
In file included from c:\users\xxx\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\stdint.h:12:0,
from c:\users\xxx\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\lib\gcc\xtensa-lx106-elf\4.8.2\include\stdint.h:9,
from C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include/c_types.h:8,
from C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include/ets_sys.h:11,
from C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include/os_type.h:10,
from C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include/user_interface.h:9,
from C:\Users\xxx\Documents\Arduino\libraries\uMQTTBroker\src\uMQTTBroker.h:4,
from C:\Users\xxx\Documents\Arduino\libraries\uMQTTBroker\src\uMQTTBroker.cpp:2:
c:\users\xxx\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\stdlib.h:70:5: error: conflicts with new declaration with 'C' linkage
int _EXFUN(atoi,(const char *__nptr));
^
exit status 1
Fehler beim Kompilieren für das Board Generic ESP8266 Module.
Can This Broker be stable with a “Tasmota” implemented Sonoff Devices?
I have invested probably over 70 hours reading and attempting a solution to this... I am ready to ask questions before I give up: PLEASE.
This broker successfully connects and communicates with several “Tasmota loaded” Sonoff devices. Broker to 4 devices to existing HomeSEER operating application. However, connection to the BROKER typically REQUIRE the Sonoff devices to be active BEFORE starting the broker.
#1 Does the broker boot and send an MQTT initialize sequence that triggers the Sonoff devices to come alive and respond? If yes, then I can use a timer to force recovery should any devices power cycle during the day.
This timeout to a broker session is what the Sonoff device shows:
01:33:22 MQT: Attempting connection...
01:33:38 MQT: Connect failed to 10.0.0.8:1883, rc -4. Retry in 10 sec
Reboot the broker; the Sonoff finds success and we get:
received topic 'broker/counter' with data '100'
received topic 'tele/SONOFF_Device1/LWT' with data 'Offline'
The broker code is below, but except for my configuration it should be right from the example.
Any help will be appreciated.
`*
#include <ESP8266WiFi.h>
#include "uMQTTBroker.h"
/*
bool WiFiAP = false; // Do yo want the ESP as AP?
unsigned int mqttPort = 1883; // the standard MQTT broker port
/*
Custom broker class with overwritten callback functions
*/
class myMQTTBroker : public uMQTTBroker
{
public:
virtual bool onConnect(IPAddress addr, uint16_t client_count) {
Serial.println(addr.toString() + " connected");
return true;
}
virtual bool onAuth(String username, String password) {
Serial.println("Username/Password: " + username + "/" + password);
return true;
}
virtual void onData(String topic, const char *data, uint32_t length) {
char data_str[length + 1];
os_memcpy(data_str, data, length);
data_str[length] = '\0';
Serial.println("received topic '" + topic + "' with data '" + (String)data_str + "'");
}
};
myMQTTBroker myBroker;
/*
const char* Zssid[] = "AA_HOME-xxxx"; // your network SSID (name)
const char* Zpass[] = "12345678"; // your network password
IPAddress Zip(10, 0, 0, 8);
IPAddress Zgateway(10, 0, 0, 1); // set gateway to match your network
IPAddress Zsubnet(255, 255, 255, 0); // set subnet mask to match your network
**_WiFi.config(Zip, Zgateway, Zsubnet); // Added this_**
Serial.println("Connecting to " + (String)Zssid);
WiFi.mode(WIFI_STA);
WiFi.begin(Zssid, Zpassword);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: " + WiFi.localIP().toString());
}
void startWiFiAP()
{
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, pass);
Serial.println("AP started");
Serial.println("IP address: " + WiFi.softAPIP().toString());
}
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println();
// Start WiFi
if (WiFiAP)
startWiFiAP();
else
startWiFiClient();
// Start the broker
Serial.println("Starting MQTT broker");
myBroker.init();
/*
* Subscribe to anything
*/
myBroker.subscribe("#");
}
int counter = 0;
void loop()
{
/*
* Publish the counter value as String
*/
myBroker.publish("broker/counter", (String)counter++);
// wait a second
delay(1000);
}
`
myBroker.off()
this is needed to turn it off and clear memory.
This is for having this Broker optionally on and off.
for myBroker.init() or init(port) (that would turn it back on) this is my code, backward compatible
uMQTTBroker.h
void init(uint16_t aaport=0);
uMQTTBroker.cpp
void uMQTTBroker::init(uint16_t aaport) {
if (aaport==0) aaport=_portno;
MQTT_server_start(aaport, _max_subscriptions, _max_retained_topics);
}
Hi, I have Wemos D1 Mini,
I can subscribe from mosquitto but when i publish anything can just 3 time. After mosquitto says Connection was lost.
Am getting a lot of ESP resets. Using the Serial port messaging, most happen when managing the call in onAuth() function. None of my Tasmota devices use passwords. All the devices and Broker are ESP "pre built" PCBs with port bias and are on a test bench.
Have not found any threads here that help with this specific function; any advice is appreciated.
OBSERVATIONS
Most of the time the ESP chip "auto-restarts". Have not been able to get the Crash-analyzer installed, so am looking manually at the dumps.
Exception codes show... 2 3 and occasionally 29
If the ESP Crashes and DOES NOT restart....
Exception codes show... 3
Looking for advice to set additional debugging points using the Serial port.
THanks
I want to thank you for you code. I tried using it when you first published your code but I was unsuccessful then but I am successfully using it now in my simple project. I am learning to code so it is not sophisticated. My project link is below:
https://github.com/happytm/ESPCoreRules
Thanks again.
When I had it not accepting external subscription in #40 , free heap was 34K.
With DoorOpen subscripting one topic, mosquito on PC subscribing same topic, and ESP-with-broker itself subscribed to one topic, heap is around 24K.
This is a huge amount of RAM used.
IDEAS TO SAVE RAM
I think that it is a waste of memory to subscribe topic "within myself", e.g. myBroker.subscribe() better to subscribe to "#" and then make some compare within onData so you do not duplicate some user defined strings you already have in RAM, and you can store fixed topics in PROGMEM.
Maybe in C instead of C++ so you do strCmp or strCmp_P to save time??
I suppose that each topic string is stored once, with a list of the subscribers - so using small topic strings and small client names will improve RAM. Correct?
to support more topics and verbose devices that subscribes to tons of long topics, maybe the only chance would be to offer the option to use SPIFFS to store, maybe files as
/topic/1
/topic/2
being each file say topic_name \n client1 \n client2 \n
???
is there any "cleaning" of subscriptions, or you subscribe and subscribe forever? (forever = while I am on)
Other ideas?
Ok meantime while I am here thank you for your great work!
Hi,
Noob here.
The downloaded zip file contains 2 directories (examples, src).
you mention "Just clone (or download the zip-file and extract it) into the libraries directory of your Arduino ESP8266 installation."
Where is that exactly? There are 3 Arduino directories on my system (C:\program files (86), \Documents, \Appdata\Local\Arduino15)
Do I also need to create a directory to put these 2 directories in?
Can you elaborate on the installation in the README.md for us noobs?
I am very interested in your project, but I come from PIC background and not too familiar with Arduino yet.
Thanks.
I have been working on a simple very low power IOT application using uMQTT broker. It is a template for a standalone star network of few battery powered sensors which can be customized easily. If you like you can add it to your example folder after testing it so people can try it and hopefully improve my amateurish code. There are 2 sketches ProbeSender and ProbeReceiver. ProbeReceiver is using uMQTT broker to connect to outside world and it is up all the time using mains power. All ProbeSendor devices are not directly connected to internet. I have implemented basic 2 way communication between ProbeReceiver and all ProbeSender device on the network. For issuing commands to ProbeSender devices on network I use android app called MQTT Dash. Only requirement for this code to work efficiently (less power consumption) is to have same access point channel as home's main access point across all devices. The link to code is below:
https://github.com/happytm/BatteryNode
Thanks.
Hello,
I want to thank you for creation and sharing this very good library. I am new in this problematic - so sorry - maybe my question or idea is basically wrong.
I have a question regarding Mqtt broker IP address.
My conception is to have some ESP8266 clients as temperature sensors, and one ESP8266 which is running as broker and which controlls the heating thermostat relay.
Temperature sensors reports only temperatures. The broker receives the temperatures and decides, if it is necessary to start the heating. The heating start levels could be configured from outside app.
I want to run the ESP broker in mode WIFI_AP_STA, it means the ESP will be the access point for temperature sensors, and it will be independent on other wifi connection.
As a feature it could be connected to home wifi ( to have access over android app)
But now is the broker IP address the same as it receives from home wifi router (DHCP).
Is it possible to set the broker address as AP IP?
I tried mDNS, to check if there is possible to connect the broker via hostname, (independent on IP)
but also without success. Do you have any idea?
Thank you very much.
Best regards Jan Jindra
Hi ...
okay, i m playing around a little bit with the mqtt broker examples.
but how can i evaluate the received date in the void loop function?
if recevied a Message eval to a string do publish anything?
(ok, publishing isn't the problem myBroker.publish("", "") but how to get the recieved Value to a String?)
Is it possible to use the precompiled binaries on a 4MB ESP12E Chip?
What i need is a small MQTT Broker like the Bondar one, but with a configureable Cloud MQTT-Server
I flashed the binaries to a ESP12E but seems not to work ...
The broker is quite shy and does not expose much of himself ! only onConnect and onAuth.
(onData is actually not exposed by the server but the local client subscriptions.)
Obvisouly, the server stores internally a lot more. Maybe it could share some :
Would it be possible to expose
I could do the first myself. I tried the others but my skills are too limited to succeed.
In uMQTTBroker.h , add
virtual uint16_t getClientCount();
in uMQTTBroker.cpp, add
uint16_t uMQTTBroker::getClientCount() {
return MQTT_server_countClientCon();
}
The program defines a custom broker class with callbacks,
I connect from a remote client and publish as below. After 6 iterations, I have the following message "Error: The connection was lost"
MQTT client:
root@MT300N-V2: mosquitto_pub -h 192.168.7.237 -p 1883 -t "MQTT_ref" -m "400"
After 1st iteration, program works well
root@MT300N-V2: mosquitto_pub -h 192.168.7.237 -p 1883 -t "MQTT_ref" -m "400"
root@MT300N-V2: mosquitto_pub -h 192.168.7.237 -p 1883 -t "MQTT_ref" -m "400"
root@MT300N-V2: mosquitto_pub -h 192.168.7.237 -p 1883 -t "MQTT_ref" -m "400"
root@MT300N-V2: mosquitto_pub -h 192.168.7.237 -p 1883 -t "MQTT_ref" -m "400"
root@MT300N-V2: mosquitto_pub -h 192.168.7.237 -p 1883 -t "MQTT_ref" -m "400"
after 6 iteration, MQTT broker is down with the following message
Error: The connection was lost.
MQTT broker running on ESP8266:
#include "uMQTTBroker.h"
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
int ref_index=0;
char ssid[] = "your SSID"; // your network SSID (name)
char password[] = "your password"; // your network password
class myMQTTBroker: public uMQTTBroker
{
public:
virtual bool onConnect(IPAddress addr, uint16_t client_count) {
Serial.println(addr.toString()+" connected");
return true;
}
virtual bool onAuth(String username, String password) {
Serial.println("Username/Password: "+username+"/"+password);
return true;
}
virtual void onData(String topic, const char *data, uint32_t length) {
String temp;
char data_str[length+1];
os_memcpy(data_str, data, length);
data_str[length] = '\0';
Serial.println("received topic '"+topic+"' with data '"+(String)data_str+"'");
if (topic == "MQTT_ref") {
temp = String(data_str);
ref_index= temp.toInt();
Serial.println("MQTT OK");
}
}
};
myMQTTBroker myBroker;
void setup()
{
Serial.begin(9600);
WiFi.begin ( ssid, password );
// Attente de la connexion au réseau WiFi / Wait for connection
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 ); // Connexion WiFi établie / WiFi connexion is OK
}
Serial.println("Starting MQTT broker"); //// Start the broker
myBroker.init();
myBroker.subscribe("#"); //Subscribe to anything
}
void loop()
{
Serial.println("loop");
delay ( 3000 );
}
I understand that the onData() function calls when the broker receives a topic data, but does it call the function at the end the void loop() or whenever a delay() is used? I have read that the ESP8266 handles networking duties whenever it is inside delay() or yield(), but does this also apply to the onData() function? Or is it like how an Arduino handles interrupts?
Hello,
Are there any plans to support Websocket publishing in uMQTTBroker or any known forks that address this ?
I found a library that does it and supposedly supports Eclipse Paho :
https://github.com/xDWart/MQTTbroker
but it only forwards Binary data (problematic for Javascript).
If there are no ongoing plans, how one would tackle such a feature ? ( eg. specs for MQTT -> Websockets bridging compatible with Mosquitto, ideas on how to add this in uMQTTBroker codebase etc...)
hi,
I'm stuck... so I have to reopen this:
#47
However there is a difference now: my code works well when connected to my local WiFi (Fritzbox + Netgear Wifi-extender);
-> therefore I reported success and closed issue #47
However it only works on this particular WiFi network... If I try to span a hotspot with android phones (tried 3 different brands) or I use another WiFi Router (Huawai) it gets stuck, where the mqtt client connects to the local broker (i.e. the broker sits on the same 8266). WiFi.isConnected() reports success before trying to connect to the broker.
The behavior is deterministic: it always works on the one particular Wifi, and it fails on all others (even outside at the final place on another router).
I've tried many combinations on Wifi settings (different encryptions, etc.) but no success. I don't have an idea why a local (!) connection (i.e. a client connects to the broker on the same uController) shall fail dependent on the real WiFi connected...
Here the good case (logs from uMQTT enabled MQTT_INFO):
[...]
17:15:56.149 -> Wifi connecting...
17:15:56.645 -> Setting hostname fcce
17:15:56.645 -> MDNS add Service: 1
17:15:56.645 -> fcce IP = 192.168.188.34, GW = 192.168.188.1, DNS = 192.168.188.1
17:15:56.645 -> Mode: STA
17:15:56.645 -> PHY mode: N
17:15:56.645 -> Channel: 11
17:15:56.645 -> AP id: 0
17:15:56.645 -> Status: 5
17:15:56.645 -> Auto connect: 1
17:15:56.645 -> SSID (12): EXT
17:15:56.645 -> Passphrase (13): XXXXXX
17:15:56.645 -> BSSID set: 0
17:16:01.641 -> Starting MQTT server on port 1883
17:16:01.674 -> MQTT:InitConnection
17:16:01.674 -> MQTT:InitClient
17:16:01.674 -> MQTT: Client task activated - state 0
17:16:01.707 -> TCP: Connect to ip 192.168.188.34:1883
17:16:01.740 -> MQTT: queue subscribe, topic"fcce/config", id: 1
17:16:01.740 -> MQTT: queue subscribe, topic"fcc/#", id: 2
17:16:01.740 -> MQTT: queuing publish, length: 51, queue size(34/2048)
17:16:01.773 -> MQTT: Client task activated - state 12
see below, here the difference starts:
17:16:01.972 -> MQTT: Connected to broker 192.168.188.34:1883
17:16:01.972 -> MQTT: Sending, type: 1, id: 0000
17:16:01.972 -> MQTT: Client task activated - state 16
17:16:01.972 -> MQTT_ClientCon_connected_cb(): Client connected
17:16:01.972 -> MQTT: InitClientCon
17:16:02.005 -> MQTT_ClientCon_recv_cb(): 33 bytes of data received
17:16:02.005 -> MQTT: TCP: data received 33 bytes (State: 14)
17:16:02.005 -> MQTT: total_len: 33
17:16:02.005 -> MQTT: message_type: 1
17:16:02.005 -> MQTT: Connect received, message_len: 33
17:16:02.005 -> MQTT: Connect flags 6
17:16:02.005 -> MQTT: Keepalive 120
17:16:02.005 -> MQTT: Client id "fcce"
17:16:02.005 -> MQTT: LWT topic /lwt
17:16:02.005 -> MQTT: 7 bytes of LWT data
17:16:02.005 -> MQTT: Server task activated - state 19
17:16:02.005 -> MQTT: Sending, type: 2, id: 0000
17:16:02.005 -> TCP: Sent
[...]
and here the bad case (I have a second router with a different local IP range):
17:18:09.686 -> Wifi connecting...
17:18:10.183 -> Setting hostname fcce
17:18:10.183 -> MDNS add Service: 1
17:18:10.183 -> fcce IP = 10.0.0.2, GW = 10.0.0.138, DNS = 10.0.0.138
17:18:10.183 -> Mode: STA
17:18:10.183 -> PHY mode: N
17:18:10.183 -> Channel: 1
17:18:10.183 -> AP id: 0
17:18:10.183 -> Status: 5
17:18:10.183 -> Auto connect: 1
17:18:10.183 -> SSID (9): T
17:18:10.183 -> Passphrase (13): XXXXXXX
17:18:10.183 -> BSSID set: 0
17:18:15.177 -> Starting MQTT server on port 1883
17:18:15.210 -> MQTT:InitConnection
17:18:15.210 -> MQTT:InitClient
17:18:15.210 -> MQTT: Client task activated - state 0
17:18:15.288 -> TCP: Connect to ip 10.0.0.2:1883
17:18:15.288 -> MQTT: queue subscribe, topic"fcce/config", id: 1
17:18:15.288 -> MQTT: queue subscribe, topic"fcc/#", id: 2
17:18:15.288 -> MQTT: queuing publish, length: 51, queue size(34/2048)
17:18:15.288 -> MQTT: Client task activated - state 12
see above here the difference starts
17:18:18.286 -> MQTT: queuing publish, length: 21, queue size(87/2048)
17:18:18.286 -> MQTT: Client task activated - state 12
17:18:20.271 -> fcce - ping /uptime 00h:00m:19s, free mem = 35232
17:18:20.304 -> MQTT: queuing publish, length: 52, queue size(110/2048)
17:18:20.304 -> MQTT: Client task activated - state 12
17:18:21.296 -> MQTT: queuing publish, length: 21, queue size(164/2048)
17:18:21.296 -> MQTT: Client task activated - state 12
17:18:21.461 -> TCP: Reconnect to 10.0.0.2:1883
17:18:21.461 -> MQTT: Client task activated - state 10
17:18:22.321 -> MQTT: queuing publish, length: 20, queue size(187/2048)
17:18:22.321 -> MQTT: Client task activated - state 10
17:18:24.306 -> MQTT: queuing publish, length: 21, queue size(209/2048)
[...]
I could extract the code to relevant minimum to be able to ship it to someone - if this is needed, let me know and I'll invest the work to do this.
I went through the uMQTT-code and from the debug info I find that in mqtt.c:
[...]
espconn_regist_connectcb(mqttClient->pCon, mqtt_tcpclient_connect_cb);
espconn_regist_reconcb(mqttClient->pCon, mqtt_tcpclient_recon_cb);
[...]
the first callback seems never being called as
MQTT_INFO("MQTT: Connected to broker %s:%d\r\n"
is not seen in the bad case log above - seen in the good case, though.
Interesting is that the second callback registered to espconn is being called on reconnection:
MQTT_INFO("TCP: Reconnect to %s:%d\r\n"
is seen in the log above (bad case).
Any support would be much appreciated!
thanx in advance, pottendo
PS: I've tried several WiFi setups (e.g. AutoConnect) - now I'm back to hardwire the IP adresses - tried also with DHCP but no difference.
I also move the project to arduino 1.8.13 IDE - to rule out some issue with platformIO (my main dev. platform). There I've tried variants of LwIP - which made no difference. I couldn't enable the CORE platform debug flags, as the code won't build then (some missing snprintf(..)).
My code looks like this (If 'TEST' or 'MOBILE' is enable, connection fails, with 'EXT' it works)"
#include <ESP8266WiFi.h>
#include "defs.h"
//#define MOBILE
#define TEST
//#define EXT
void setup_wifi(void)
{
//WiFi.setPhyMode(WIFI_PHY_MODE_11N);
WiFi.mode(WIFI_STA);
#ifdef MOBILE
IPAddress ip(192, 168, 43, 67);
IPAddress gw(192, 168, 43, 1);
IPAddress dns(192, 168, 43, 1);
IPAddress subnet(255, 255, 255, 0);
WiFi.config(ip, gw, subnet, dns);
WiFi.begin("M2", "XXXXX");
#endif
#ifdef TEST
IPAddress ip(10,0,0,2);
IPAddress gw(10,0,0,138);
IPAddress dns(10,0,0,138);
IPAddress subnet(255, 255, 255, 0);
WiFi.config(ip, gw, subnet, dns);
WiFi.begin("T", "XXXXX");
#endif
#ifdef EXT
IPAddress ip(192, 168, 188, 34);
IPAddress gw(192, 168, 188, 1);
IPAddress dns(192, 168, 188, 1);
IPAddress subnet(255, 255, 255, 0);
WiFi.config(ip, gw, subnet, dns);
WiFi.begin("EXT", "XXXX");
#endif
while (!WiFi.isConnected())
{
log_msg("Wifi connecting...");
delay(500);
}
log_msg("Setting hostname " + hostname);
while (!MDNS.begin(hostname.c_str()))
{
log_msg("DNS setup failed.");
}
printf("MDNS add Service: %d\n", MDNS.addService("mqtt", "tcp", 1883));
printf("fcce IP = %s, GW = %s, DNS = %s\n",
WiFi.localIP().toString().c_str(),
WiFi.gatewayIP().toString().c_str(),
WiFi.dnsIP().toString().c_str());
WiFi.printDiag(Serial);
delay(2000);
mqtt_broker.init();
delay(2000);
}
and the client connects then like this on the same esp8266:
#define MQTT_SERVER WiFi.localIP().toString().c_str()
void setup_mqtt(void)
{
mqtt_client = new MQTT{my_clientID.c_str(), MQTT_SERVER, 1883};
// setup callbacks
mqtt_client->onConnected(myConnectedCb);
mqtt_client->onDisconnected(myDisconnectedCb);
mqtt_client->onPublished(myPublishedCb);
mqtt_client->onData(myDataCb);
log_msg("connect mqtt client...");
delay(20);
mqtt_client->connect();
delay(20);
mqtt_client->subscribe("fcce/config");
mqtt_client->subscribe("fcc/#");
log_msg("mqtt setup done");
mqtt_publish("/sensor-alive", "Formicula embedded starting...");
fcc_last_seen = millis(); /* give fcc 10min to connect, otherwise restart */
}
thank you for your lib, looks very usefull, still I have very simple code like this what does not work and I have no idea what I do wrong
#include <ESP8266WiFi.h>
#include <uMQTTBroker.h>
const char *ssid = "myAP";
const char *password = "password123";
unsigned int mqttPort = 1883; // the standard MQTT broker port
unsigned int max_subscriptions = 30;
unsigned int max_retained_topics = 30;
void data_callback(uint32_t *client /* we can ignore this */, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh) {
char topic_str[topic_len+1];
os_memcpy(topic_str, topic, topic_len);
topic_str[topic_len] = '\0';
char data_str[lengh+1];
os_memcpy(data_str, data, lengh);
data_str[lengh] = '\0';
Serial.print("received topic '");
Serial.print(topic_str);
Serial.print("' with data '");
Serial.print(data_str);
Serial.println("'");
}
void setup() {
delay(1000);
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
MQTT_server_onData(data_callback);
Serial.println("Starting MQTT broker");
MQTT_server_start(mqttPort, max_subscriptions, max_retained_topics);
MQTT_local_subscribe((unsigned char *)"#", 0);
}
void loop() {
}
however I connect the AP from my computer I use mosquitto_pub
for send a simple message, all looks OK in terminal
$ mosquitto_pub -h 192.168.4.1 -t 'test' -m "Hi there" -d
Client mosqpub/15186-Think sending CONNECT
Client mosqpub/15186-Think received CONNACK
Client mosqpub/15186-Think sending PUBLISH (d0, q0, r0, m1, 'test', ... (8 bytes))
Client mosqpub/15186-Think sending DISCONNECT
on the serial console I see message like
AP IP address: 192.168.4.1
Starting MQTT broker
received topic 'test' with data 'Hi there'
Exception (9):
epc1=0x4021f89e epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000206 depc=0x00000000
ctx: sys
sp: 3ffff9c0 end: 3fffffb0 offset: 01a0
>>>stack>>>
3ffffb60: c9debd7f 00000004 3fff1894 4021f48b
3ffffb70: 00000000 3fffff90 3fff19d4 402050eb
3ffffb80: 00000000 3fffff90 3fff19d4 40203f89
3ffffb90: 00000220 3ffffbd0 3ffffd60 ffffffff
3ffffba0: 00000000 00000000 00000000 00000000
3ffffbb0: 00000000 00000000 00000000 00000000
3ffffbc0: 00000000 00000000 00000000 00000000
3ffffbd0: 00000000 00000000 00000000 00000000
3ffffbe0: b4add38b cb3afebd c8360c74 1e896969
3ffffbf0: dc0c6c40 4b75d3a4 a893c528 e32305aa
3ffffc00: 9f299337 ae589c17 72aa5526 4e242f35
3ffffc10: 4000b5f9 00000008 00000038 3ffffcf0
3ffffc20: 00000008 3ffffcf0 449a227d ea602601
3ffffc30: 8a1802a6 450c03f3 2568e749 7e947257
3ffffc40: 3cabe89c 7df31f6e c920a4c0 f67d45e4
3ffffc50: 7ff16bfe d0ced68c 49d0a471 a155f6b0
3ffffc60: c526af25 ecf858ec d59f58b4 02d556f9
3ffffc70: e3515695 ccf26100 28600fd8 7a269758
3ffffc80: a434a05a 4cae08f3 e520dca1 a1822d81
3ffffc90: ada9e487 a8c1b449 9ee49f5e 5851bb99
3ffffca0: 4000b62e 57e846a5 754f2b08 9c1c6eed
3ffffcb0: 4000b6c4 3ffffcf0 3ffffe80 ffffffff
3ffffcc0: 4000b72e 3ffffcd0 00000008 3ffffd50
3ffffcd0: 00000000 00000000 4000a333 3ffffdf8
3ffffce0: 3ffffe80 3ffffdd8 4020714b 00000001
3ffffcf0: ffffffff 00000000 4020714b 00000001
3ffffd00: ffffffff 00000000 3ffe9001 00000008
3ffffd10: 4020719e 3ffec648 3fff04fc 00020021
3ffffd20: 402072aa 3ffec648 3fff04fc 3ffec648
3ffffd30: 00000002 00000000 00000020 40101612
3ffffd40: 3ffe8eb2 402065f3 3ffec648 3fff08ef
3ffffd50: 00000000 4020e364 3fff12c4 00000100
3ffffd60: 00000002 00000000 00000000 3ffec648
3ffffd70: 3fff18ce 40225a6c 3fff18ce 3fff1894
3ffffd80: 3fff08bc 0bc01a22 00002200 4000050c
3ffffd90: 3fffc278 4010268c 3fffc200 00000000
3ffffda0: 3fff00fc 00000000 3fff08bc 40225d51
3ffffdb0: 3ffe8eb5 401048ef 3ffec918 ffffffff
3ffffdc0: 40102325 3ffec918 3fff03f8 3fff1894
3ffffdd0: 3fff1894 3fff17c8 3fff08bc 40225fb8
3ffffde0: 4010385c 00040000 7fffffff 00000000
3ffffdf0: 00000022 40103859 00040000 40226f00
3ffffe00: 3ffed078 40102836 00000000 401004d8
3ffffe10: 3fff17c8 3fff17c4 00002200 4000050c
3ffffe20: 3fffc278 4010268c 3fffc200 00000022
3ffffe30: 3ffffe40 00000001 3fff1894 00000080
3ffffe40: 4021fbd7 00000030 0000001c ffffffff
3ffffe50: 40203dc4 3fff198c 00000010 00000014
3ffffe60: 3ffee0b0 00000000 00000000 3fff1968
3ffffe70: ffffffff 3fffc6fc 0000005c 00000000
3ffffe80: 3fff1134 3fff0300 3fff193c 00000030
3ffffe90: 00000007 3fff1924 0000001a 00000000
3ffffea0: 3fff190c 3fff17c8 3fff17c4 40224aa6
3ffffeb0: 0000111c 3fff18f0 00000006 00000001
3ffffec0: 3fff17c4 3fff0208 00000000 3fff0200
3ffffed0: 3fff17c4 3fff0208 3fff0204 402287b8
3ffffee0: 00000003 0104a8c0 00000019 00000002
3ffffef0: 4021f73c 00000000 3ffeebb4 40223191
3fffff00: 40200000 00000000 3ffec648 3fff193c
3fffff10: 3fff0300 3fff198c 00000000 40220c3c
3fffff20: 3ffeeb68 000002b8 000002b8 4010020c
3fffff30: 3ffeeb68 000002a2 000002a2 4010020c
3fffff40: 00000000 3ffe8821 3fff1924 4010068c
3fffff50: 3fff0300 3ffe8821 3fff19d4 40106d24
3fffff60: 4021f0e2 3fff1134 3fff1924 402205a6
3fffff70: 3fff0300 3fff1134 3fff1924 40220765
3fffff80: 40100fae 00000002 00000000 3fff094c
3fffff90: 402062b2 3fffdab0 00000000 3fff0328
3fffffa0: 3fffdaf0 00000000 3fffdab0 40000f49
<<<stack<<<
ets Jan 8 2013,rst cause:2, boot mode:(1,6)
ets Jan 8 2013,rst cause:4, boot mode:(1,6)
wdt reset
so message was received, but it generates an exception what I don't understand, ESP decoder tool show me more info like this:
Exception 9: LoadStoreAlignmentCause: Load or store to an unaligned address
Decoding 48 results
0x4021f89e: espconn_disconnect at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn.c line 949
0x4021f48b: espconn_sent at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn.c line 415
0x402050eb: QUEUE_Gets at /home/rak/Arduino/libraries/uMQTTBroker/src/queue.c line 47
0x40203f89: MQTT_ServerTask at /home/rak/Arduino/libraries/uMQTTBroker/src/mqtt_server.c line 878
0x4020714b: pp_attach at ?? line ?
0x4020714b: pp_attach at ?? line ?
0x4020719e: pp_attach at ?? line ?
0x402072aa: pp_attach at ?? line ?
0x40101612: pp_post at ?? line ?
0x402065f3: ppTxPkt at ?? line ?
0x4020e364: ieee80211_output_pbuf at ?? line ?
0x40225a6c: etharp_send_ip at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 435
0x4010268c: wDev_ProcessFiq at ?? line ?
0x40225d51: etharp_output_to_arp_index at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 890
0x401048ef: lmacRxDone at ?? line ?
0x40102325: trc_NeedRTS at ?? line ?
0x40225fb8: etharp_output at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 995
0x4010385c: lmacProcessTXStartData at ?? line ?
0x40103859: lmacProcessTXStartData at ?? line ?
0x40226f00: ip_output_if_opt at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/ipv4/ip.c line 780
0x40102836: wDev_ProcessFiq at ?? line ?
0x401004d8: malloc at /home/rak/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/umm_malloc/umm_malloc.c line 1664
0x4010268c: wDev_ProcessFiq at ?? line ?
0x4021fbd7: espconn_delete at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn.c line 1225
0x40203dc4: MQTT_server_deleteClientCon at /home/rak/Arduino/libraries/uMQTTBroker/src/mqtt_server.c line 176
0x40224aa6: tcp_output at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/tcp_out.c line 990
0x402287b8: tcp_input at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/tcp_in.c line 423
0x4021f73c: espconn_get_connection_info at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn.c line 833
0x40223191: pbuf_alloc at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/pbuf.c line 388
0x40220c3c: espconn_tcp_delete at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn_tcp.c line 1372
0x4010020c: _umm_free at /home/rak/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/umm_malloc/umm_malloc.c line 1287
0x4010020c: _umm_free at /home/rak/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/umm_malloc/umm_malloc.c line 1287
0x4010068c: free at /home/rak/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/umm_malloc/umm_malloc.c line 1733
0x40106d24: vPortFree at /home/rak/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/heap.c line 18
0x4021f0e2: espconn_copy_partial at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn.c line 55
0x402205a6: espconn_tcp_memp_free at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn_tcp.c line 244
0x40220765: espconn_tcp_disconnect_successful at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn_tcp.c line 385
: (inlined by) espconn_Task at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/app/espconn_tcp.c line 424
0x40100fae: ppProcessTxQ at ?? line ?
0x402062b2: ppPeocessRxPktHdr at ?? line ?
but I could not see what is wrong, the code is very simple and if I'm publishing messages in loop
method all looks just fine. So problem is only if I receive message via WiFi.
Any idea what could be wrong?
Hi I am trying to find the MQTT broker for ESP32. Can I use this library with ESP 32 ? Thanks for the help in advance.
How to set keep alive is 0? have the funtion in code?
Hi there,
maybe someone can explain me this behavior:
Retained is disabled in the broker, respectively "0"
If i'm sending a toggle command by the uMQTT Broker, a listening mosquitto client, will show only this one toggle command, but the destination device (aTasmota Device) show the toggle twice in the log and it's also toggling twice ....
Is that a bug in the Broker? Or why the device get the command twice?
`Arduino: 1.8.4 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, 115200, 4M (3M SPIFFS)"
Build options changed, rebuilding all
C:\Users\James\Documents\Arduino\libraries\uMQTTBroker\src\mqtt_server.c: In function 'MQTT_server_deleteClientCon':
C:\Users\James\Documents\Arduino\libraries\uMQTTBroker\src\mqtt_server.c:156:2: warning: 'return' with no value, in function returning non-void [enabled by default]
return;
^
In file included from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/include/os_type.h:28:0,
from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/include/user_interface.h:28,
from C:\Users\James\Documents\Arduino\libraries\uMQTTBroker\src\uMQTTBroker.h:4,
from C:\Users\James\Documents\Arduino\libraries\uMQTTBroker\src\uMQTTBroker.cpp:2:
C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/include/ets_sys.h:193:5: error: previous declaration of 'int atoi(const char*)' with 'C++' linkage
int atoi(const char *nptr);
^
In file included from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/libc/xtensa-lx106-elf/include/string.h:10:0,
from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/include/osapi.h:28,
from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/lwip/include/arch/cc.h:40,
from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/lwip/include/lwip/arch.h:43,
from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/lwip/include/lwip/debug.h:35,
from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/lwip/include/lwip/opt.h:46,
from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/lwip/include/lwip/ip_addr.h:35,
from C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/include/user_interface.h:30,
from C:\Users\James\Documents\Arduino\libraries\uMQTTBroker\src\uMQTTBroker.h:4,
from C:\Users\James\Documents\Arduino\libraries\uMQTTBroker\src\uMQTTBroker.cpp:2:
C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/libc/xtensa-lx106-elf/include/stdlib.h:78:36: error: conflicts with new declaration with 'C' linkage
int _EXFUN(atoi,(const char *__nptr));
^
C:\Users\James\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2/tools/sdk/libc/xtensa-lx106-elf/include/_ansi.h:65:35: note: in definition of macro '_EXFUN'
#define _EXFUN(name, proto) name proto
^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
`
When building the example program on Platformio, the following error is thrown:
*** Multiple ways to build the same target were specified for: C:\Users\username\Documents\PlatformIO\ESP8266_MQTT_Broker.pioenvs\esp12e\lib\uMQTTB
roker-master\MQTT.o (from ['C:\Users\username\Documents\PlatformIO\ESP8266_MQTT_Broker\lib\uMQTTBroker-master\src\MQTT.cpp'] and from ['C:
\Users\username\Documents\PlatformIO\ESP8266_MQTT_Broker\lib\uMQTTBroker-master\src\MQTT.c'])
File "C:\Users\username.platformio\penv\lib\site-packages\platformio\builder\tools\platformio.py", line 272, in BuildLibrary
This might be due to the same name (mqtt.c and MQTT.cpp) of the two files being referenced, due to the non-case-sensitive nature of files on Windows. Both mqtt.c and MQTT.cpp would make the same object file, MQTT.o.
Possible solution, change MQTT.cpp (and .h) to MQTT_Broker.cpp? Along with changing the class name and constructor and destructor? Or is that not a good way to deal with this issue?
The caller may set the user/pass flag to "present" but can meantime pass strings with just \0 so basically empty, even if non NULL.
This happens for example when you use Arduino Strings and you have user="" and you use user.c_str() with a MQTT client such as PubSubClient for example (it is compact so I believe widely used).
If you do this with Mosquito, it goes on without problems.
If you do this with current uMQTTBroker, it discards you and you can take some time to figure out what is happening (see #40 :-) !!!! ).
A possible fix would be to REMOVE the strict check that you are doing.
If Mosquito on PC does not check for this, why does a small ESP library should waste precious bytes to do these useless verification? The application using the library can also verify these user/pass if needed.
Hi
I added uMQTTBroker to my Sloeber project and I am receiving this error. Can please tell me what I am missing? (I managed to test PubSubClient succefully). also can I test on a ESP32?
Best regards
Hi,
I start to use the broker on an ESP8266 that is already hosting a webserver and doing other stuff.
Install and initial tests were fine but I face memory issues. At some point, the ESP crashed and I could see the error message about lack of memory.
My MQTT needs are quite limited : 2 simultaneous clients max. One client always connected (it is another ESP with PubSubClient) , the other clients are temporary connections from a smartphone, only one a time.
I need only 5 topics overall. The clients may publish to several but only subscribe to 1 topic.
The "local_client" subscribes to everything, but this one does not use extra ram.
The size of the messages published by the clients are small in size. The largest, (topic+json payload) is 50 char long.
The clients subscribe to a single topic where only the local_client publishes to. This topic will receive JSON messages up to 100 char long.
I could see two optimizations :
max_subscriptions and max_retained_topics
The broker is started with the defaults at 30.
Retained topics is easy to understand. I changed it to 5.
Max subscriptions is harder to understand. A client can subscribe to # or a single topic. Does it count for one or many subscriptions ?
When looking at the broker code, I see that "max subscriptions" is actually linked to the number of clients connected. I changed it to 10.
Unfortunately with these changes, the heap remains almost unchanged.
MQTT_BUF_SIZE and QUEUE_BUFFER_SIZE
defined in src/mqtt/defaults.h
MQTT_BUF_SIZE (default 1024) is the max size of pending inbound messages for one connection
QUEUE_BUFFER_SIZE (default 2048) is the max size of all pending outbound messages for one connection
At client init, the broker tries to allocate memory of both buffers size (3K bytes). If there is not enough heap left, the connection is rejected. (That is when my ESP crashed.)
I guess that I could lower buffer sizes which would significantly lower the memory used per active client connection.
Two questions :
in my situation, how much can I lower both buffer sizes : Is there a rule? educated guess ? or is it try and error process ?
The number of clients is exposed by onConnect. How can I "force reject" a 3rd connection request ?
Thank you
Hello, I am having trouble with my ESP8266 crashing when data is received by the broker.
Here is all the information I have, if you need anything more specific let me know, any help would be appreciated.
Payload
{
"o": "AA",
"d": "AA",
"s": "AAA",
"p": "AAA"
}
Exception
Exception 9: LoadStoreAlignmentCause: Load or store to an unaligned address
PC: 0x40209805: uMQTTBroker::_onData(unsigned int*, char const*, unsigned int, char const*, unsigned int) at C:\Users\agierens\Documents\Arduino\libraries\uMQTTBroker-master\src\uMQTTBroker.cpp line 30
EXCVADDR: 0x00000012
Decoding stack results
0x402097f5: uMQTTBroker::_onData(unsigned int*, char const*, unsigned int, char const*, unsigned int) at C:\Users\agierens\Documents\Arduino\libraries\uMQTTBroker-master\src\uMQTTBroker.cpp line 29
0x4021c542: new_linkoutput at glue-lwip/lwip-git.c line 260
0x4021cae4: ethernet_output at netif/ethernet.c line 312
0x40215340: uMQTTBroker::onAuth(String, String, String) at C:\Users\agierens\Documents\Arduino\libraries\uMQTTBroker-master\src\uMQTTBroker.cpp line 59
0x40100c6f: free(void*) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 398
0x402097cc: uMQTTBroker::_onData(unsigned int*, char const*, unsigned int, char const*, unsigned int) at C:\Users\agierens\Documents\Arduino\libraries\uMQTTBroker-master\src\uMQTTBroker.cpp line 26
0x40236c58: publish_topic at C:\Users\agierens\Documents\Arduino\libraries\uMQTTBroker-master\src\mqtt_server.c line 65
0x40100ca4: malloc(size_t) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x40237d34: find_topic at C:\Users\agierens\Documents\Arduino\libraries\uMQTTBroker-master\src\mqtt_topiclist.c line 73
0x40236c1c: publish_topic at C:\Users\agierens\Documents\Arduino\libraries\uMQTTBroker-master\src\mqtt_server.c line 58
0x40237984: MQTT_ClientCon_recv_cb at C:\Users\agierens\Documents\Arduino\libraries\uMQTTBroker-master\src\mqtt_server.c line 351
0x402267bc: mem_malloc at core/mem.c line 210
0x40225d10: ip4_output_if_opt at core/ipv4/ip4.c line 1577
0x40221101: tcp_create_segment at core/tcp_out.c line 190
0x40225d36: ip4_output_if at core/ipv4/ip4.c line 1550
0x402268c7: ip_chksum_pseudo at core/inet_chksum.c line 395
0x40221e16: tcp_output at core/tcp_out.c line 1361
0x4010017c: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x4010017c: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x4023f12f: espconn_sent at glue-lwip/espconn.c line 421
0x4010015b: ets_intr_unlock() at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 163
0x40220299: pbuf_free_LWIP2 at core/pbuf.c line 726
0x4021c551: new_linkoutput at glue-lwip/lwip-git.c line 265
0x4010017c: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x4021c2b5: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x4021c542: new_linkoutput at glue-lwip/lwip-git.c line 260
0x4021cae4: ethernet_output at netif/ethernet.c line 312
0x40224280: etharp_output_to_arp_index at core/ipv4/etharp.c line 770
0x4010017c: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x402244d4: etharp_output_LWIP2 at core/ipv4/etharp.c line 885
0x4010017c: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x4010017c: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x401009eb: umm_free_core(void*) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 351
0x40100c6f: free(void*) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 398
0x40100ca4: malloc(size_t) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x402267dc: mem_free at core/mem.c line 237
0x40100f02: calloc(size_t, size_t) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 908
0x4023fad5: espconn_server_recv at glue-lwip/espconn_tcp.c line 1189
0x4021ffc8: tcp_input at core/tcp_in.c line 501
0x4010060c: pvPortMalloc(size_t, char const*, int) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\heap.cpp line 271
0x40225a66: ip4_input at core/ipv4/ip4.c line 1467
0x40100c6f: free(void*) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 398
0x4021ca59: ethernet_input_LWIP2 at netif/ethernet.c line 188
0x4021c6f4: esp2glue_ethernet_input at glue-lwip/lwip-git.c line 469
0x4023e3de: ethernet_input at glue-esp/lwip-esp.c line 365
0x4023e3ef: ethernet_input at glue-esp/lwip-esp.c line 373
0x4010060c: pvPortMalloc(size_t, char const*, int) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\heap.cpp line 271
0x4021c2b5: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x40100ca4: malloc(size_t) at C:\Users\agierens\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x4021c542: new_linkoutput at glue-lwip/lwip-git.c line 260
0x4021cae4: ethernet_output at netif/ethernet.c line 312
0x40223f78: etharp_raw at core/ipv4/etharp.c line 1165
0x4022416e: etharp_request at core/ipv4/etharp.c line 1202
0x402207e2: netif_issue_reports at core/netif.c line 916
0x40220888: netif_set_addr_LWIP2 at core/netif.c line 717
Sample class
class TestMqttBroker: public uMQTTBroker
{
public:
virtual bool onConnect(IPAddress addr, uint16_t client_count) {
// Serial.println(addr.toString()+" connected");
return true;
}
virtual void onDisconnect(IPAddress addr, String client_id) {
// Serial.println(addr.toString()+" ("+client_id+") disconnected");
}
virtual void onData(String topic, const char *data, uint32_t length) {
}
};
Hello, thirst thank you for sharing this code who is very useful. I have a question, how the broker could response to the publisher (who isn't on the local network ) because i don't see any reference to the "client".
for example a mosquito "client" send this
mosquitto_pub -m "Relay ON" -t "/MyMQTT_Sub" -h "192.168.1.96"
The broker well receive the message
and now i want to send back (from the broker) a acknowledge message like "OK the Relay is switch ON".
thank you for your response
Martin....nice things first, I truly appreciate the uMQTT code. It has given me hours of “relaxation” (22 hours already this week on this issue). My wife asks why I would do this... I tell her my useless coding projects are much better use of time than crossword puzzles or Suduko.
I have been fighting this issue for over a year, put it away, tried to fix, put it away; now with covad19 providing more time, I try again. Anything you can recommend will help me fix this and move onto the next “project”? Together we are pushing off insanity.. I think.
Overview:
System
Observation:
Crash dump shows:
Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
PC: 0x4021ebee: append_string at C:\Users\r\Documents\Arduino\libraries\uMQTTBroker-master\src\mqtt_msg.c line 45
EXCVADDR: 0x00000003
which is in uMQTT code...
static int ICACHE_FLASH_ATTR append_string(mqtt_connection_t * connection, const char *string, int len) {
if (connection->message.length + len + 2 > connection->buffer_length)
return -1;
connection->buffer[connection->message.length++] = len >> 8; **THIS IS CRASH LINE 45**
connection->buffer[connection->message.length++] = len & 0xff;
os_memcpy(connection->buffer + connection->message.length, string, len);
connection->message.length += len;
return len + 2;
}
**The attached PDF has detailed code and more crash information.
I am not good enough with this code to understand what to look for next. Help is appreciated.
Full crash doc oct 21 2020.pdf
**
Hi,
I've run your broker on my esp and it works fine. I can use i.e Chrome's MQTTLens extension, subscribe to topics and receive messages, but when I try to use the client you've linked in the readme on another ESP, it cannot connect to the broker (connection callback is never called). Could you check if there is something wrong in my code? Maybe I need to provide some more configuration?
Broker
#include <ESP8266WiFi.h>
#include <uMQTTBroker.h>
/*
* Your WiFi config here
*/
char ssid[] = "artur"; // your network SSID (name)
char pass[] = "password"; // your network password
class myMQTTBroker: public uMQTTBroker
{
public:
virtual bool onConnect(IPAddress addr, uint16_t client_count) {
Serial.println(addr.toString()+" connected");
return true;
}
virtual bool onAuth(String username, String password) {
Serial.println("Username/Password: "+username+"/"+password);
return true;
}
virtual void onData(String topic, const char *data, uint32_t length) {
char data_str[length+1];
os_memcpy(data_str, data, length);
data_str[length] = '\0';
Serial.println("received topic '"+topic+"' with data '"+(String)data_str+"'");
}
};
myMQTTBroker myBroker;
void startWiFiAP()
{
WiFi.disconnect(true);
WiFi.softAP(ssid, pass);
Serial.println("AP started");
Serial.println("IP address: " + WiFi.softAPIP().toString());
}
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println("siema");
startWiFiAP();
// Start the broker
Serial.println("Starting MQTT broker");
myBroker.init();
myBroker.subscribe("#");
}
int counter = 0;
void loop()
{
/*
* Publish the counter value as String
*/
myBroker.publish("broker/counter", (String)counter++);
myBroker.publish("broker/test", (String)counter++);
// wait a second
delay(1000);
}
Client code (copied from example):
#include <ESP8266WiFi.h>
#include <MQTT.h>
void myDataCb(String& topic, String& data);
void myPublishedCb();
void myDisconnectedCb();
void myConnectedCb();
#define CLIENT_ID "client3"
#define TOPIC "broker/test"
// create MQTT
MQTT myMqtt(CLIENT_ID, "192.168.4.1", 1883);
const char* ssid = "artur";
const char* password = "password";
//
void setup() {
Serial.begin(115200);
delay(1000);
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());
Serial.println("Connecting to MQTT server");
// setup callbacks
myMqtt.onConnected(myConnectedCb);
myMqtt.onDisconnected(myDisconnectedCb);
myMqtt.onPublished(myPublishedCb);
myMqtt.onData(myDataCb);
Serial.println("connect mqtt...");
myMqtt.connect();
Serial.println("subscribe to topic...");
myMqtt.subscribe(TOPIC);
delay(10);
}
//
void loop() {
}
/*
*
*/
void myConnectedCb()
{
Serial.println("connected to MQTT server");
}
void myDisconnectedCb()
{
Serial.println("disconnected. try to reconnect...");
delay(500);
myMqtt.connect();
}
void myPublishedCb()
{
//Serial.println("published.");
}
void myDataCb(String& topic, String& data)
{
Serial.print(topic);
Serial.print(": ");
Serial.println(data);
}
Client's output:
Connecting to artur
........
WiFi connected
IP address:
192.168.4.2
Connecting to MQTT server
connect mqtt...
subscribe to topic...
Message "connected to MQTT server" is never displayed. Data are not received.
I also tried with this client https://github.com/knolleary/pubsubclient and its example code but it returns 2 : MQTT_CONNECT_BAD_CLIENT_ID - the server rejected the client identifier
from the state method, however I'm not sure how accurate this message is, because changing client id didn't help.
Hi Martin,
Firstly, I would like to thank you for the awesome work you've put into this library. Thumbs up!
I've loaded a nodeMCU with this code and it is working as the MQTT broker for my automation project. I've also flashed a few Sonoff S20 plugs with the Tasmota firmware and have successfully connected them to the broker and controlled their relay state with the correct MQTT message.
However while testing the plug (turning their power on/off to simulate reconnections to the broker), I've realised that on the 5th reset of a single plug, I was no longer able to connect it back to the broker. The Sonoff web console shows a rc=-4 error which refers to a MQTT_CONNECTION_TIMEOUT in the pubsubclient MQTT library. The broker is still running just that it is no longer accepting any new client connection. The last message received was the LWT offline message of the disconnected switch.
I've tried to replicate the issue by running 5 clients on a MQTTBox simulator and as I tried to connect the 5th client, the connection could not get through.
Has the nodeMCU broker reached its connection or memory limit or is there some configuration which I can change to rectify this problem?
Your help is very much appreciated. TIA!
I've compiled the thing inside another project but basically after wifi is connected I do:
myBroker.init()
myBroker.subscribe("hub-cmd-verde");
and basically I copied your CPP example:
class myMQTTBroker: public uMQTTBroker
{
public:
virtual bool onConnect(IPAddress addr, uint16_t client_count) {
logg(addr.toString());
return true;
}
virtual bool onAuth(String username, String password) {
//will add auth
return true;
}
virtual void onData(String topic, const char *data, uint32_t length) {
//
char data_str[length+1];
os_memcpy(data_str, data, length);
data_str[length] = '\0';
logg(topic+':'+(String)data_str);
//only subscribed topics arrive here
//doMQTTaction(topic,(String)data_str);
}
};
(where logg() is my log procedure)
When I send a message (STATE) from my PC with Mosquito, all right, I see from my log it receives the message AND from onConnect I see there is a connection from the PC 192.168.1.3 just before the message:
mosquitto_pub -h 192.168.1.20 -i nicename -t hub-cmd-verde -m STATE
This is OK! Log:
[2020-05-21 20:45.31] G 24<az
192.168.1.3
[2020-05-21 20:45.31] G 24<az
hub-cmd-verde:STATE
so it correctly calls onConnect and onData.
But, then, if I try with the PC to subscribe (for simplicity) to the same topic, it goes into timeout.
mosquitto_sub -h 192.168.1.20 -t hub-cmd-verde
and, also, I see no connections from 192.168.1.3 logged by my logg(). Nothing.
Also an ESP project that I already successfully tested as Client with other MQTT brokers (IP and external) when I point it to 192.168.1.20 (that's the IP of the ESP with the broker) does not connect and I get timeout error.
I'm really puzzled because I've basically copied the example.
If I run on the PC 192.168.1.3 a mosquitto broker, then I do
mosquitto_sub -h 192.168.1.3 -t hub-cmd-verde
it subscribes without errors and if I publish
mosquitto_pub -h 192.168.1.3 -i nicename -t hub-cmd-verde -m STATE
I receive it immediately on the dialog where I have the subscription.
Basically I expected the same from the ESP Broker running on 192.168.1.20......
I am trying to use your library in my project with an ESP32 (using arduino framework).
However, when I try to compile I get error missing the files:
user_config.h
c_types.h
fatal error: os_type.h:
....
etc
Is there something I am missing?
Thank you
it works well, however, I try to use umqtt lib to connect this broker, I don't think they both know each other, anyway hope Martin can fix the bug asap.
Martin,
This is very helpful ( & rare ) library. I was looking for something like this for long time.I have been using https://github.com/letscontrolit/ESPEasy for long time and it is very easy software with wide variety of sensors hardware supported. Unfortunately it is meant to be connected to outside broker only. Lack of local MQTT network without extra hardware is something I can use for my project. I am new to software so I am not capable of implementing your software in Espeasy but with your help I can do it.Please take a look at Espeasy if you have time.They use original pubsubclient library.Looking at their code they have following files related to MQTT:
https://github.com/letscontrolit/ESPEasy/blob/mega/src/ESPEasy.ino
https://github.com/letscontrolit/ESPEasy/blob/mega/src/Controller.ino
https://github.com/letscontrolit/ESPEasy/blob/mega/src/ESPEasy-Globals.h
Following are 3 plugin files related to MQTT . These are optional plugin you can choose in GUI but if your library work I can simply use it as a library and delete all these plugins or modify one of the plugins to use as uMQTT broker:
https://github.com/letscontrolit/ESPEasy/blob/mega/src/_C002.ino
https://github.com/letscontrolit/ESPEasy/blob/mega/src/_C005.ino
https://github.com/letscontrolit/ESPEasy/blob/mega/src/_C006.ino
I had proposed this on Espeasy forum when your library came out :
http://www.letscontrolit.com/forum/viewtopic.php?f=6&t=3573
The other library they were discussing is :
https://github.com/bcatalin/bondar
https://github.com/bcatalin/demoapp
but no one could resolve the issue.
Please help.
Thanks
Hi,
I'm trying to get all MQTT_INFO messages but without success. How can I get them on serial output?
Thanks a lot
I have been using your great library for few months. I have written some custom code around your library. In my application I require both AP & Station mode activated. Everything worked fine and I could connect to uMQTT broker using MQTT-Spy application but as soon as I add following line to startWiFiClient() function to start my AP I loose connection to broker.
WiFi.softAP(gateway, "<notused>", 7, 0, 0);
My whole code is below:
#include <ESP8266WiFi.h>
#if MQTTBROKER
#include "uMQTTBroker.h"
char ssid[] = "myssid"; // your network SSID (name)
char pass[] = "mypassword"; // your network password
char gateway[] = "ESP"; // your gateway name
#endif
// ==================== start of TUNEABLE PARAMETERS ====================
int device;
int voltage;
int temperature;
int humidity;
int pressure;
int light;
//int openClose = 0; // 0 or 1
//int level; // 0 to 255
//int presence = 0; // 0 or 1
//int motion = 0; // 0 to 6 (0=no motion, 1=up, 2=down, 3=right, 4=left, 5=on, 6=off).
/*
Predefined sensor type table is below:
volatage = 16, temperature = 26, humidity= 36, pressure= 46, light= 56, OpenClose = 66,
level = 76, presence = 86, motion = 96 etc.
*/
int sensorType1;
int sensorType2;
int sensorType3;
int sensorType4;
int sensorType5;
//uint8_t probeData[] = {temperature, humidity, pressure, voltage, light, unit};
int command1;
int command2;
int command3;
int command4;
int command5;
int command6;
//uint8_t mac[6] = {19,01,25,30,01,01};
//uint8_t mac[6] = {19,01,250,value4,value5,01};
uint8_t mac[6] = {command1, command2, command3, command4, command5, command6};
extern "C" void preinit() {
wifi_set_opmode(STATIONAP_MODE);
wifi_set_macaddr(SOFTAP_IF, mac);
}
/*/////////////////////////////////////////////////////////////////
Custom broker class with overwritten callback functions
*/
#if MQTTBROKER
class myMQTTBroker: public uMQTTBroker
{
public:
virtual bool onConnect(IPAddress addr, uint16_t client_count) {
Serial.println(addr.toString() + " connected");
return true;
}
virtual bool onAuth(String username, String password) {
Serial.println("Username/Password: " + username + "/" + password);
return true;
}
virtual void onData(String topic, const char *data, uint32_t length) {
char data_str[length+1];
os_memcpy(data_str, data, length);
data_str[length] = '\0';
Serial.println("received topic '" + topic + (String)data_str);
}
};
myMQTTBroker myBroker;
#endif
/////////////////////////////////////////////////////////////////////
WiFiEventHandler probeRequestPrintHandler;
//volatile boolean buttonPressed;
void setup() {
Serial.begin(115200);
Serial.println();
// WiFi.persistent(false);
Serial.println("MQTT Gateway");
Serial.println();
Serial.print("This Device MAC ID is: ");
Serial.println(WiFi.macAddress());
WiFi.hostname("Controller");
Serial.print("This Device's Host Name is: ");
Serial.println(WiFi.hostname());
Serial.print("This Device is connected to AP MAC: ");
Serial.println(WiFi.BSSIDstr());
Serial.println();
WiFi.persistent(false);
probeRequestPrintHandler = WiFi.onSoftAPModeProbeRequestReceived(&onProbeRequest);
delay(1);
wifi_set_macaddr(SOFTAP_IF, mac);
////////////////////////////////
#if MQTTBROKER
// Connect to a WiFi network
startWiFiClient();
// Start the broker
Serial.println("Starting MQTT broker");
myBroker.init();
/*
Subscribe to anything
*/
myBroker.subscribe("#");
#endif
////////////////////////////////////////////////////////////////////
} //END OF SETUP
void loop() {
command1 = 10; //random(25);
command2 = 20; //random(256);
command3 = 30; //random(256);
command4 = 40; //random(256);
command5 = random(256);
command6 = 01;
mac[0] = command1;
mac[1] = command2;
mac[2] = command3;
mac[3] = command4;
mac[4] = command5;
mac[5] = command6;
wifi_set_macaddr(SOFTAP_IF, mac);
yield();
} // End of main loop.
///////////////////////////////////////////////////////////////////////////////////////////////////
#if MQTTBROKER
void startWiFiClient()
{
Serial.println("Connecting to " + (String)ssid);
WiFi.persistent(false);
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi connected to: ");
Serial.println(WiFi.SSID());
Serial.println("IP address: " + WiFi.localIP().toString());
WiFi.softAP(gateway, "<notused>", 7, 0, 0); // when I remove this line I can connect to the broker.
}
#endif
////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#if MQTTBROKER
void mqttPublish() {
/*
Predefined sensor type table is below:
volatage = 16, temperature = 26, humidity= 36, pressure= 46, light= 56, OpenClose = 66,
level = 76, presence = 86, motion = 96 etc.
*/
char topic1[100];
sprintf(topic1,"%s%i%s%i%s", "Sensordata/", device, "/", device, "/");
char topic2[100];
sprintf(topic2,"%s%i%s%i%s", "Sensordata/", device, "/", sensorType1, "/");
char topic3[100];
sprintf(topic3,"%s%i%s%i%s", "Sensordata/", device, "/", sensorType2, "/");
char topic4[100];
sprintf(topic4,"%s%i%s%i%s", "Sensordata/", device, "/", sensorType3, "/");
char topic5[100];
sprintf(topic5,"%s%i%s%i%s", "Sensordata/", device, "/", sensorType4, "/");
char topic6[100];
sprintf(topic6,"%s%i%s%i%s", "Sensordata/", device, "/", sensorType5, "/");
// myBroker.publish(topic1, (String)device);
// myBroker.publish("SensorData/device/", (String)device);
myBroker.publish(topic2, (String)voltage);
myBroker.publish(topic3, (String)temperature);
myBroker.publish(topic4, (String)humidity);
myBroker.publish(topic5, (String)pressure);
myBroker.publish(topic6, (String)light);
// wait a second
//delay(1000);
}
#endif
//////////////////////////////////////////////////////////////////////////////
void onProbeRequest(const WiFiEventSoftAPModeProbeRequestReceived& dataReceived) {
if (dataReceived.mac[1] == 16) // only accept data from device with voltage as a sensor type at byte 1.
{
sensorType1 = (dataReceived.mac[1]);
sensorType2 = (dataReceived.mac[2]);
sensorType3 = (dataReceived.mac[3]);
sensorType4 = (dataReceived.mac[4]);
sensorType5 = (dataReceived.mac[5]);
}
if (dataReceived.mac[0] == 6 || dataReceived.mac[0] == 16 || dataReceived.mac[0] == 26 || dataReceived.mac[0] == 36 || dataReceived.mac[0] == 46 || dataReceived.mac[0] == 56 || dataReceived.mac[0] == 66 || dataReceived.mac[0] == 76 || dataReceived.mac[0] == 86 || dataReceived.mac[0] == 96 || dataReceived.mac[0] == 106 || dataReceived.mac[0] == 116 || dataReceived.mac[0] == 126 || dataReceived.mac[0] == 136 || dataReceived.mac[0] == 146 || dataReceived.mac[0] == 156 || dataReceived.mac[0] == 166 || dataReceived.mac[0] == 176 || dataReceived.mac[0] == 186 || dataReceived.mac[0] == 196 || dataReceived.mac[0] == 206 || dataReceived.mac[0] == 216 || dataReceived.mac[0] == 226 || dataReceived.mac[0] == 236 || dataReceived.mac[0] == 246) // only accept data from certain devices.
{
Serial.print("Probe Request:- ");
Serial.print(" Device ID: ");
Serial.print(dataReceived.mac[0], DEC);
device = dataReceived.mac[0];
Serial.print(" Voltage: ");
Serial.print(dataReceived.mac[1], DEC);
voltage = dataReceived.mac[1];
voltage = voltage * 2;
Serial.print(" Temperature: ");
Serial.print(dataReceived.mac[2], DEC);
temperature = dataReceived.mac[2];
Serial.print(" Humidity: ");
Serial.print(dataReceived.mac[3], DEC);
humidity = dataReceived.mac[3];
Serial.print(" Pressure: ");
Serial.print(dataReceived.mac[4], DEC);
pressure = dataReceived.mac[4];
pressure = pressure * 4;
Serial.print(" Light: ");
Serial.println(dataReceived.mac[5], DEC);
light = dataReceived.mac[5];
if (voltage < 295) // if voltage of battery gets to low, print the warning below.
{
myBroker.publish("SensorData/warning", "Battery Low");
Serial.println("**************Warning :- Battery Voltage low please change batteries********************" );
Serial.println();
}
if (dataReceived.mac[1] > 115 && dataReceived.mac[1] < 180) {
mqttPublish();
}
} else {
//Serial.println("Waiting for Data............");
}
}````
Can you please help me resolve this issue ?
Thanks.
Hello
I'm using 2 esp8266, 1 as server mqtt using your "uMQTTBrokerSampleOOFull" example, and the other with the mqtt_pub.ino example,
I came across the following:
when I first connect the client to the server everything works fine, but if for some reason the client restarts, the server gives me a Fatal exception 29 error (StoreProhibitedCause).
I will put my code on both the server and the client and the respective log with the error. I hope someone can help me to find out where the error for this happened
//------------ Client--------------------------
#include <ESP8266WiFi.h>
#include <MQTT.h>
void myDataCb(const char* topic, uint32_t length, const char* data, uint32_t Alength);
void myPublishedCb();
void myDisconnectedCb();
void myConnectedCb();
#define CLIENT_ID "client1"
#define CLIENT_RX_MQTT "RX"
// create MQTT object
MQTT myMqtt(CLIENT_ID, "192.168.4.1", 1883);
//
const char* ssid = "ESP8266";
const char* password = "123456789";
/*
WiFi init stuff
*/
void startWiFiClient()
{
Serial.println("Connecting to " + (String)ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(10);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: " + WiFi.localIP().toString());
Serial.println("Connecting to MQTT server");
// myMqtt.setUserPwd("ESP", "HELLO");
// setup callbacks
myMqtt.onConnected(myConnectedCb);
myMqtt.onDisconnected(myDisconnectedCb);
myMqtt.onPublished(myPublishedCb);
myMqtt.onData(myDataCb);
Serial.println("connect mqtt...");
myMqtt.connect();
while (myMqtt.isConnected() == false) {
delay(10);
}
/*
Subscribe to anything
*/
Serial.println("subscribe to topic...");
myMqtt.subscribe("#");
}
//
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
startWiFiClient();
delay(10);
}
//
void loop() {
/*
int value = analogRead(A0);
String topic = WiFi.macAddress();
char Socket_TX_buffer[255];
Socket_TX_buffer[0] = 170;
Socket_TX_buffer[1] = 10;
Socket_TX_buffer[2] = 1;
Socket_TX_buffer[3] = 0;
Socket_TX_buffer[4] = 49;
Socket_TX_buffer[5] = 0;
Socket_TX_buffer[6] = 1;
Socket_TX_buffer[7] = 6;
Socket_TX_buffer[8] = 100;
Socket_TX_buffer[9] = 0;
Socket_TX_buffer[10] = 0;
Socket_TX_buffer[11] = 0;
// publish value to topic
boolean result = myMqtt.publish(topic, Socket_TX_buffer, 11);
delay(1000);
*/
if (myMqtt.isConnected() == false) {
// startWiFiClient();
}
}
/*
*/
void myConnectedCb()
{
Serial.println("connected to MQTT server");
}
void myDisconnectedCb()
{
Serial.println("disconnected. try to reconnect...");
delay(500);
myMqtt.connect();
}
void myPublishedCb()
{
//Serial.println("published.");
}
//void myDataCb(String& topic, String& data)
void myDataCb(const char* topic, uint32_t length, const char* data, uint32_t Alength)
{
String Atopic = topic; // convert const char in String
/*
Serial.println(topic); //
Serial.println(length); // length topic
Serial.println(data);
Serial.println(Alength); // length data
*/
if (Atopic != WiFi.macAddress()) { // filtra para nao receber o que enviou
char data_str[Alength + 1];
os_memcpy(data_str, data, Alength);
for (int i = 0; i < Alength ; i++) {
Serial.write(data_str[i]);
}
Serial.println();
}
}
//------------Server-----------------
//---------------------
// Important: Use the setting "lwip Variant: 1.4 High Bandwidth" in the "Tools" menu
//----------------------------------
//https://github.com/martin-ger/uMQTTBroker
/*
uMQTTBroker demo for Arduino (C++-style)
The program defines a custom broker class with callbacks,
starts it, subscribes locally to anything, and publishs a topic every second.
Try to connect from a remote client and publish something - the console will show this as well.
*/
#include <ESP8266WiFi.h>
#include "uMQTTBroker.h"
#define SERVER_TX_MQTT "SERVER_TX"// esta invertido por causa os clientes
/*
Your WiFi config here
*/
char ssid[] = "ESP8266"; // your network SSID (name)
char pass[] = "123456789"; // your network password
bool WiFiAP = true; // Do yo want the ESP as AP?
/*
Custom broker class with overwritten callback functions
*/
class myMQTTBroker: public uMQTTBroker
{
public:
virtual bool onConnect(IPAddress addr, uint16_t client_count) {
Serial.println(addr.toString() + " connected");
return true;
}
virtual bool onAuth(String username, String password) {
Serial.println("Username/Password: " + username + "/" + password);
// Aqui pode ser vadidar o user e a pass
return true;
}
virtual void onData(String topic, const char *data, uint32_t length) {
if (topic != SERVER_TX_MQTT) { // filtra para nao receber o que enviou
char data_str[length + 1];
os_memcpy(data_str, data, length);
// data_str[length] = '\0';
for (int i = 0; i < length ; i++) {
Serial.write(data_str[i]);
}
}
}
};
myMQTTBroker myBroker;
/*
WiFi init stuff
*/
void startWiFiClient()
{
Serial.println("Connecting to " + (String)ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: " + WiFi.localIP().toString());
}
void startWiFiAP()
{
WiFi.softAP(ssid, pass);
Serial.println("AP started");
Serial.println("IP address: " + WiFi.softAPIP().toString());
}
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println();
// Start WiFi
if (WiFiAP)
startWiFiAP();
else
startWiFiClient();
// Start the broker
Serial.println("Starting MQTT broker");
myBroker.init();
/*
Subscribe to anything
*/
myBroker.subscribe("#");
}
int counter = 0;
void loop()
{
/*
Publish the counter value as String
*/
// myBroker.publish(SERVER_TX_MQTT, (String)counter++);
// wait a second
delay(1000);
MQTT_server_cleanupClientCons();
}
hi,
this may be related to
#16
but I couldn't try this yet.
My issue:
I've successfully got the broker running on a esp8266 / Arduino.
One can connect from other (Linux or Raspi) boxes flawlessly and use the broker (tried with mosquitto clients)
However connecting a client from the very same esp8266 won't connect - the client stays in stat 'TCP_CONNECTING' (state 12, see below).
I've tried to connect to '127.0.0.1' or the local IP (see below) - no difference.
Interesting is that if I let the esp8266 client connect to another broker (on a RPi) in my network it works as expected and the published messages are processed.
I wonder how the 'localhost' path can be any different - but I'm not really an expert on IP programming.
I've tried the 'fix' from the other post to add 'WiFi.mode(WIFI_STA)' ... but this didn't change anything.
Note that I'm using the 'AutoConnect' library to get the IP from the nvs, or offer the Wifi selection webserver on bootstrap + some goodies like OTA. All this works nicely. So the general IP connectivity (from outside) seems to be there.
Any hints would be very much appreciated.
thx, pottendo
Here the debug log:
[...]
Setting up Wifi...done.
Setting up local time...Sun Dec 6 20:00:10 2020
Setting hostname fcce
Starting MQTT broker
Starting MQTT server on port 1883
MQTT:InitConnection
MQTT:InitClient
connect mqtt client...
MQTT: Client task activated - state 0
TCP: Connect to ip 192.168.188.34:1883
MQTT: queue subscribe, topic"/mytopic", id: 1
MQTT: Client task activated - state 12
MQTT: queuing publish, length: 26, queue size(17/2048)
MQTT: Client task activated - state 12
MQTT: queuing publish, length: 26, queue size(45/2048)
MQTT: Client task activated - state 12
[...]
and the code (follows pretty much the example):
[...]
void setup_mqtt(void)
{
delay(100);
mqtt_client = new MQTT{my_clientID.c_str(), "192.168.188.34" /WiFi.localIP().toString().c_str()/, 1883};
// setup callbacks
mqtt_client->onConnected(myConnectedCb);
mqtt_client->onDisconnected(myDisconnectedCb);
mqtt_client->onPublished(myPublishedCb);
mqtt_client->onData(myDataCb);
log_msg("connect mqtt client...");
delay(100);
mqtt_client->connect();
delay(100);
mqtt_client->subscribe("/mytopic");
}
void mqtt_publish(String topic, String msg)
{
//log_msg("publishing: " + my_clientID + topic + msg);
mqtt_client->publish(my_clientID + topic, msg, 0, 0);
}
Hi, this is a feature request for implementation of this library for ESP32 based boards.
My mqtt broker has set user and password, I forgot about it and I tried the @i-n-g-o mqtt_pub example as is without setUserPwd...
Connecting to MyHomeNet
.......
WiFi connected
IP address:
192.168.0.117
Connecting to MQTT server
connect mqtt...
disconnected. try to reconnect...
in setup mqtt try connect to broker without success (because user/pass not set)
then jump to myDisconnectedCb and causer error on second myMqtt.connect():
Exception (9):
epc1=0x40104a44 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000003 depc=0x00000000
ctx: sys
sp: 3ffffd30 end: 3fffffb0 offset: 01a0
>>>stack>>>
3ffffed0: 3ffeeb80 0000037b 0000037b 4010020c
3ffffee0: 40104c70 001d573f 3ffee930 00000000
3ffffef0: 3ffee2b0 3ffee930 3ffee89c 401004f4
3fffff00: 00000001 0018928b 4021991a 3ffee89c
3fffff10: 3ffee930 3fff1d9c 3ffe8ab4 402198d1
3fffff20: 00000000 0018924e 40201340 3fff1e14
3fffff30: 3fff0310 3fff1ffc 3ffee89c 4020269c
3fffff40: 3ffeb87c 3fff1ffc 3ffee89c 40201f77
3fffff50: 0000005c 00000001 4010420a 40203145
3fffff60: 3ffec7c8 40100a91 00000000 40218f85
3fffff70: 40222a5f 00000000 3fff1dfc 40222a6c
3fffff80: 4010085e 00000002 00000002 3fff0944
3fffff90: 4021b9ba 3fffdab0 00000000 3fff0338
3fffffa0: 3fffdc60 00000000 3fffdab0 40000f49
<<<stack<<<
ets Jan 8 2013,rst cause:2, boot mode:(1,6)
ets Jan 8 2013,rst cause:4, boot mode:(1,6)
wdt reset
esp exception decoder show:
Exception 9: LoadStoreAlignmentCause: Load or store to an unaligned address
Decoding 15 results
0x40104a44: ets_timer_setfn at ?? line ?
0x40104c70: ets_timer_arm_new at ?? line ?
0x402029fd: Print::write(char const*) at C:\PROGRAMY\Arduino\hardware\esp8266com\esp8266\cores\esp8266/Print.cpp line 99
0x40201340: delay at C:\PROGRAMY\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring.c line 46
0x40202a74: Print::println(char const*) at C:\PROGRAMY\Arduino\hardware\esp8266com\esp8266\cores\esp8266/Print.cpp line 99
0x40201f71: myDisconnectedCb() at C:\PROGRAMY\arduino_projekty\mqtt_test1/mqtt_test1.ino line 87
0x4010420a: lmacTxFrame at ?? line ?
0x40203145: mqttDisconnectedCb at C:\PROGRAMY\arduino_projekty\libraries\uMQTTBroker\src/MQTT.cpp line 198
0x40100a91: ppEnqueueRxq at ?? line ?
0x40218f85: mqtt_tcpclient_discon_cb at C:\PROGRAMY\arduino_projekty\libraries\uMQTTBroker\src/mqtt.c line 497
0x40222a5f: espconn_tcp_disconnect_successful at app/espconn_tcp.c line 384
: (inlined by) espconn_Task at app/espconn_tcp.c line 439
0x40222a6c: espconn_tcp_disconnect_successful at app/espconn_tcp.c line 389
: (inlined by) espconn_Task at app/espconn_tcp.c line 439
0x4010085e: ppProcessTxQ at ?? line ?
0x4021b9ba: ppPeocessRxPktHdr at ?? line ?
when I set user/pass everything works fine
I'm trying that Mqtt server publishes the current datetime using the Ntpclient example code but it always starts initially with January, 1 1900.
Could it be due Ntpclient uses an UDP client?
Thanks in advance,
Hello martin,
I have forked your uMQTTBroker to using in one of my projects, I am looking to use it with Sonoff-Tasmota.
I have a number of Sonoffs running their firmware, but would like to one run your uMQTTBroker to0.
I have modified their sonof.ino to include your demo portion, what I would like to now add is user/password/ssl, but I am not sure how to do so.
I believe I Need to also add the following
typedef bool (MqttAuthCallback)(const char username, const char *password, struct espconn *pesp_conn);
void auth_callback(uint32_t client / we can ignore this /, const char topic, uint32_t topic_len, const char *data, uint32_t lengh)
so my question is first why the /* we can ignore this */ and then what is the expected structure for pesp_conn..
I am not a real programmer, I just dabble in it as a hobby, building automation things for my home. so most of my programming skills are from Googling and udemy free courses.
Cheers,
Pasquale
Hello,
Can you add a License term document in the git repository for uMQTTBroker ? I'm looking into contributing but I would like to know the terms of such a contribution.
https://help.github.com/articles/adding-a-license-to-a-repository/
thanks
I uploaded the examples to my NodeMCU. After updating my Arduino environment it worked like a charm, but connecting to the AP was not possible.
AP started
IP address: 192.168.4.1
Starting MQTT broker
received topic 'broker/counter' with data '0'
received topic 'broker/counter' with data '1'
received topic 'broker/counter' with data '2'
When adding WiFi.mode(WIFI_AP); to the startWiFiAP method, remote connection were possible. So I wanted to make a pull request from my branch, but I failed here :)
So here is my suggestion to update this method in your examples like so:
void startWiFiAP()
{
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, pass);
Serial.println("AP started");
Serial.println("IP address: " + WiFi.softAPIP().toString());
}
Thank you for that great work!
hy!
i am using this library a great effort by martin-ger thumbs up for him, now i want to high a gpio pin when ever client publishes the topic
I am using uMQTTBroker.h very successfully to create my networks, but have some issues to understand.
Can you point me to how to identify:
Number of CURRENTLY connected clients
Text of TOPICs connected
I do get this information once from the functions “onConnect” and “onData” but would benefit from the ability to print to the serial port in the LOOP, debug information as CLIENTS connect and disconnect .
Issue:
Two CLIENTS are connected. Power OFF #1; BROKER properly identifies the unit as “offline”.
However, the BROKER also gets a message that CLIENT #2 goes “offline” then quickly back “online”.
Is this “normal” MQTT functionality????
Thanks for any thought you can provide.
How do I add a interrupt to GPIO 0
This seems not to work (derived from user_basic/user_main.c):
#include "user_interface.h"
#include "mqtt/mqtt_server.h"
#include "user_config.h"
#include "easygpio.h"
static void sonoffBtnInterrupt(void* arg) {
uint8_t value = easygpio_inputGet(13);
easygpio_outputSet(13, !value);
}
int interruptOne = 42;
void ICACHE_FLASH_ATTR user_init() {
struct station_config stationConf;
// Initialize the UART
uart_div_modify(0, UART_CLK_FREQ / 115200);
os_printf("\r\n\r\nMQTT Broker starting\r\n");
// Setup STA
...
// Allow larger number of TCP (=MQTT) clients
...
easygpio_pinMode(13, EASYGPIO_PULLUP, EASYGPIO_OUTPUT);
easygpio_outputSet(13, 0); // turn on
//easygpio_pinMode(0, EASYGPIO_PULLUP, EASYGPIO_INPUT);
easygpio_attachInterrupt(0, EASYGPIO_PULLUP, &sonoffBtnInterrupt, &interruptOne);
//Start MQTT broker
MQTT_server_start(MQTT_PORT, MQTT_MAX_SUBSCRIPTIONS, MQTT_MAX_RETAINED_TOPICS);
}
Currently running the broker on an esp8266. The idea is to have a plethera of client devices where there is one device on each drum in my kit which is getting readings from a piezo vibration sensor.
The broker and everything seems to be running fine technically speaking however I have noticed when I have even just a short burst of publishes (issues even with three) they broker is seemingly slow to process them.
For example if I play quarter notes there is 0 noticeable latency and the broker recieves the velocity of the drum hit with near real time. Yet if I play a 16th bar. the messages lag into the server over a broader time. (If I hit 5 times in a second, it may take 2 seonds to play all the notes on the broker side, but when hitting one note every second there is 0 latency)
The debounce on the trigger is 80ms so in testing with jsut one client no messages are coming faster than 80ms and there is still almost a second of lag when a series of quick hits comes in.
Is there a way to optimize this. I cannot for the life of me understand why the lag happens considering this is basically a c++ FIFO buffer server similar to class projects I have done. This should be working at microsecond level, let alone 80ms cycle lvl, correct?
The LED on the transmitter is set to flash on each publish and operates perfectly even with rapid drumming. no lag, perfect timing.
I am not using any delays.
Should it lag this much just on 4 messages over 200ms?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.