hirotakaster / mqtt Goto Github PK
View Code? Open in Web Editor NEWMQTT for Photon, Spark Core
License: Other
MQTT for Photon, Spark Core
License: Other
When using the online Particle IDE and attempting to build a project including this libary, if the device firmware (for the photon) is set to "0.6.2" or "Default(0.6.2)", the compiler throws an error:
/workspace/lib/MQTT/src/MQTT.cpp:83:18: error: ambiguous overload for 'operator=' (operand types are 'String' and 'int')
this->domain = NULL;
This appears to have just started today; I'm assuming that 0.6.2 was released yesterday.
Hi,
it appears this library is based largely on my PubSubClient library.
However this library makes no reference that I can see of my library or the appropriate copyright. Please refer to the license I share my library under; you are free to use the code, you just have to acknowledge where it came from.
https://github.com/knolleary/pubsubclient/blob/master/LICENSE.txt
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
Nick
Hello,
Recently I used an accelerometer with photon running at 100 Hz. Every output value was sent to MQTT broker to see the result. However when I compared the result from MQTT broker with serial monitor many entries were missed. The issue might be that the publish rate is not fast enough while using this library. Is there any way that the library can be tweaked to increase the publish rate.
Hello @hirotakaster ,
first of all, great work with this client.
It's not clear to me if it is possible to reuse the allocated client object changing ip address.
Use case:
I have two independent mqtt clusters, and would switch to cluster2 if cluster1 is unreachable (and vice-versa).
True, I could have two client objects, but the program would be a lot less linear, ram usage would be higher and scalability would be ugly (what if I add another cluster in the mix ? Third client ?).
Thank you for your time and efforts
Claudio
To support the Particle Library Manager all new publishes should feature v2.0 structure.
The easiest to get there is via CLI
particle library migrate
MQTT_MAX_PACKET_SIZE is too small for my application. Would it be a big deal to make it configurable with the constructor or a setter?
The constant is used four times in MQTT.cpp. Could be replaced with sizeof(buffer) ?
Hello,
I am trying to use your library on a Particle Core, to connect to cloudmqtt server. It seems like it connects initially, but when I issue the first publish() command, the broker never gets any data, and the next time through loop isConnected() returns false. Any ideas? Have you ever tried using cloudmqtt?
if (client.isConnected())
{
sprintf(publishString,"%f.1",sht1x.readHumidity());
client.publish("/output/humidity",publishString);
Spark.publish("/output/humidity",publishString);
}
else
{
Spark.publish("mqtt-down");
}
Veryfing code using this library in Particle Build fails with this error:
MQTT/MQTT.h:97:4: error: 'boolean' does not name a type
boolean write(uint8_t header, uint8_t* buf, uint16_t length)
Hi,
Thanks for the awesome library! I have some problems with my photons disconnecting from the broker and never connecting again. In your example you show that you should run if (client.isConnected()) client.loop();
in loop()
. I'm doing that but my photons lose their connection and client.loop()
will never try to reconnect. I'm guessing that the photons loose their connection to the wireless router or something and then disconnect from the broker. In order to solve that problem I try to reconnect the client if client.loop()
returns false. ie. something like if (!client.loop()) client.connect()
Do you know if there's something I should fix on my photons or mqtt broker to stop it from disconnecting? Maybe there should be a mode of the client which will try and keep it connected to the broker even if it disconnects for longer than the keepalive time after it sends MQTTPINGREQ? thanks.
I'm using particle photons with firmware 0.5.3, version 0.4.1 of your library, and mosquitto version 1.4.10 (build date 2016-10-25 21:29:55-0400).
Lack of documentation makes this library difficult to use.
Is it possible to add add a constructor overload that accepts a context for the callback so we can have non static callback functions?
If not, do you now of a workaround?
Cheers,
Paul
Would it be possible to support changing the server address after constructing the mqtt object? This would be useful if one wants to change the mqtt broker address without reflashing.
Thank you very much, @hirotakaster, for this library; I've been using this now for a few weeks, and it looks very solid.
Is there any chance we could convince you to add (optional) TLS support to it? I believe that, in this day and age, we should communicate securely whenever possible.
Veryfing code using this library in Particle Build fails with this error:
MQTT/MQTT.h:167:10: error: initializing argument 4 of 'bool MQTT::publish(const char*, const uint8_t*, unsigned int, MQTT::EMQTT_QOS, bool, uint16_t*)' [-fpermissive]
bool publish(const char *, const uint8_t *, unsigned int, EMQTT_QOS, bool, uint16_t *messageid = NULL)
I believe the following is needed in just after this line:
this->ip = NULL;
Without this, the if()
on line 43 is false, and the code never connects.
I try to run a small GPS .ino on an Electron 2G.
The same .ino works great on a Photon.
any hints?
mosquitto server logs:
Apr 7 12:52:14 pi2 mosquitto[22768]: New connection from 176.83.137.98 on port 9001.
Apr 7 12:52:14 pi2 mosquitto[22768]: New client connected from 176.83.137.98 as 3a0021000c51343334363138 (c1, k15).
Apr 7 12:52:14 pi2 mosquitto[22768]: Sending CONNACK to 3a0021000c51343334363138 (0, 0)
Apr 7 12:52:36 pi2 mosquitto[22768]: Client 3a0021000c51343334363138 has exceeded timeout, disconnecting.
Apr 7 12:52:36 pi2 mosquitto[22768]: Socket error on client 3a0021000c51343334363138, disconnecting.
Can you please add MQTT authentication with username/password or just point me where to start for adding that so that I can help you and send a pull request about this.
I traced though the implementation of the clean session. I don't believe it was implemented correctly
By default the clean session is set by the time you get to line 132 of mqtt.cpp, you need to clear it to get a persistent session if the clean session flag is false
uint8_t v;
if (willTopic) {
v = 0x06|(willQos<<3)|(willRetain<<5); // the 0x06 sets the clean session flag here
} else {
v = 0x02; // clean session flag
}
if (!cleanSession) { // need to reset the flag which is already set
v = v & 0xfd; // clear the clean session flag RH
}
I haven´t found a possibility to use persistent session which is highly interesting for IoT projects. Is there any plan if or when it will be integrated?
Hi. is it also compatible with Particle Electron?
Sometimes I do not receive an MQTT event on a given topic. Events are received by other clients, I checked it with mosquitto_sub.
So I tried to modify qos in :
mqttClient.connect("roomba_photon", NULL, MQTTQOS2, 0, NULL);
But problem still remains, so I tried :
mqttClient.subscribe(topic, MQTTQOS1);
but in this case no messages are received on topic, changing to MQTTQOS0 works fine.
Hello,
I tried this library and it doesn't seem to work with firmware 0.4.9 and above. Works fine with 0.4.7
Is this normal ?
To avoid errors like error: previous definition of 'class MQTT'
I've got a Photon that keeps losing and regaining wifi. It wouldn't be a problem except that it seems like it cannot re-connect to the MQTT broker after that. It's difficult to troubleshoot because I'm having trouble logging the information necessary.
But, in looking at the MQTT.cpp code, I notice that the same TCPClient object is used and re-used when you connect and re-connect. So, if you connect and then disconnect and then connect again, it is still using the same object (_client
) Is that okay? Is that safe? I honestly don't know and I'm just trying to figure out what could be going wrong in my code.
When sending with QOS2, I don't receive the messages in other clients. I use a mosquitto broker.
QOS0 and QOS1 work fine.
mqtt.publish("testTopic",(uint8_t*)"test",4, false, MQTT::QOS2, NULL);
Weirdly enough, the only difference is MQTTQOS2_HEADER_MASK...
when copying the content of the spark library files verbatim ('MQTT.cpp', 'MQTT.h', 'mqtttest.ino'), the compile fails with the error below.
The same error occurs when forking files directly from https://github.com/hirotakaster/MQTT files.
Has the spark firmware changed enough to break the example code?
Using SPARK FIRMWARE V0.3.4. Thanks!
"Error: Could not compile. Please review your code."
In file included from ../inc/spark_wiring.h:29:0,
from ../inc/spark_wiring_stream.h:36,
from ../inc/spark_wiring_client.h:24,
from ../inc/spark_wiring_tcpclient.h:29,
from MQTT.cpp:56:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ../../core-common-lib/CC3000_Host_Driver/evnt_handler.h:38:0,
from ../inc/spark_wlan.h:33,
from ../inc/main.h:38,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:33,
from ../inc/spark_wiring_stream.h:36,
from ../inc/spark_wiring_client.h:24,
from ../inc/spark_wiring_tcpclient.h:29,
from MQTT.cpp:56:
../../core-common-lib/CC3000_Host_Driver/socket.h:146:0: warning: "fd_set" redefined [enabled by default]
#define fd_set _types_fd_set_cc3000
^
In file included from /opt/gcc_arm/arm-none-eabi/include/stdio.h:47:0,
from ../inc/spark_wiring_print.h:30,
from ../inc/spark_wiring_string.h:33,
from MQTT.cpp:55:
/opt/gcc_arm/arm-none-eabi/include/sys/types.h:256:0: note: this is the location of the previous definition
#define fd_set _types_fd_set
^
In file included from ../../core-common-lib/CC3000_Host_Driver/evnt_handler.h:38:0,
from ../inc/spark_wlan.h:33,
from ../inc/main.h:38,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:33,
from ../inc/spark_wiring_stream.h:36,
from ../inc/spark_wiring_client.h:24,
from ../inc/spark_wiring_tcpclient.h:29,
from MQTT.cpp:56:
../../core-common-lib/CC3000_Host_Driver/socket.h:162:0: warning: "FD_SET" redefined [enabled by default]
#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
^
In file included from /opt/gcc_arm/arm-none-eabi/include/stdio.h:47:0,
from ../inc/spark_wiring_print.h:30,
from ../inc/spark_wiring_string.h:33,
from MQTT.cpp:55:
/opt/gcc_arm/arm-none-eabi/include/sys/types.h:258:0: note: this is the location of the previous definition
# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
^
In file included from ../../core-common-lib/CC3000_Host_Driver/evnt_handler.h:38:0,
from ../inc/spark_wlan.h:33,
from ../inc/main.h:38,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:33,
from ../inc/spark_wiring_stream.h:36,
from ../inc/spark_wiring_client.h:24,
from ../inc/spark_wiring_tcpclient.h:29,
from MQTT.cpp:56:
../../core-common-lib/CC3000_Host_Driver/socket.h:163:0: warning: "FD_CLR" redefined [enabled by default]
#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp)
^
In file included from /opt/gcc_arm/arm-none-eabi/include/stdio.h:47:0,
from ../inc/spark_wiring_print.h:30,
from ../inc/spark_wiring_string.h:33,
from MQTT.cpp:55:
/opt/gcc_arm/arm-none-eabi/include/sys/types.h:259:0: note: this is the location of the previous definition
# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
^
In file included from ../../core-common-lib/CC3000_Host_Driver/evnt_handler.h:38:0,
from ../inc/spark_wlan.h:33,
from ../inc/main.h:38,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:33,
from ../inc/spark_wiring_stream.h:36,
from ../inc/spark_wiring_client.h:24,
from ../inc/spark_wiring_tcpclient.h:29,
from MQTT.cpp:56:
../../core-common-lib/CC3000_Host_Driver/socket.h:164:0: warning: "FD_ISSET" redefined [enabled by default]
#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp)
^
In file included from /opt/gcc_arm/arm-none-eabi/include/stdio.h:47:0,
from ../inc/spark_wiring_print.h:30,
from ../inc/spark_wiring_string.h:33,
from MQTT.cpp:55:
/opt/gcc_arm/arm-none-eabi/include/sys/types.h:260:0: note: this is the location of the previous definition
# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
^
In file included from ../../core-common-lib/CC3000_Host_Driver/evnt_handler.h:38:0,
from ../inc/spark_wlan.h:33,
from ../inc/main.h:38,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:33,
from ../inc/spark_wiring_stream.h:36,
from ../inc/spark_wiring_client.h:24,
from ../inc/spark_wiring_tcpclient.h:29,
from MQTT.cpp:56:
../../core-common-lib/CC3000_Host_Driver/socket.h:165:0: warning: "FD_ZERO" redefined [enabled by default]
#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
^
In file included from /opt/gcc_arm/arm-none-eabi/include/stdio.h:47:0,
from ../inc/spark_wiring_print.h:30,
from ../inc/spark_wiring_string.h:33,
from MQTT.cpp:55:
/opt/gcc_arm/arm-none-eabi/include/sys/types.h:261:0: note: this is the location of the previous definition
# define FD_ZERO(p) (__extension__ (void)({ \
^
In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from mqtttest.cpp:2:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
mqtttest.cpp:5:42: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
#line 1
^
mqtttest.cpp: In function 'void callback(char*, byte*, unsigned int)':
mqtttest.cpp:11:15: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
^
mqtttest.cpp: In function 'void setup()':
mqtttest.cpp:30:33: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
^
mqtttest.cpp:34:48: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
// connect to the server
^
mqtttest.cpp:34:48: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
mqtttest.cpp:35:35: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
client.connect("sparkclient");
^
mqtttest.o: In function `setup':
/spark/compile_server/shared/workspace/2_compile-server2/core-firmware/build/mqtttest.cpp:30: undefined reference to `MQTT::connect(char*)'
/spark/compile_server/shared/workspace/2_compile-server2/core-firmware/build/mqtttest.cpp:33: undefined reference to `MQTT::isConnected()'
/spark/compile_server/shared/workspace/2_compile-server2/core-firmware/build/mqtttest.cpp:34: undefined reference to `MQTT::publish(char*, char*)'
/spark/compile_server/shared/workspace/2_compile-server2/core-firmware/build/mqtttest.cpp:35: undefined reference to `MQTT::subscribe(char*)'
mqtttest.o: In function `loop':
/spark/compile_server/shared/workspace/2_compile-server2/core-firmware/build/mqtttest.cpp:40: undefined reference to `MQTT::isConnected()'
/spark/compile_server/shared/workspace/2_compile-server2/core-firmware/build/mqtttest.cpp:41: undefined reference to `MQTT::loop()'
mqtttest.o: In function `__static_initialization_and_destruction_0':
/spark/compile_server/shared/workspace/2_compile-server2/core-firmware/build/mqtttest.cpp:5: undefined reference to `MQTT::MQTT(char*, unsigned short, void (*)(char*, unsigned char*, unsigned int))'
collect2: error: ld returned 1 exit status
make: *** [b43d8f930b22f0b9b2e8154ddd3da59ac91e0edc109424a182be4a17143d.elf] Error 1
our team has started using this code in some of our sensors, and we came across an issue with the max size of messages you can publish. Our messages were getting cut off at around 238 characters and we couldn't figure out how until we looked at the code in MQTT.h
and found this variable: MQTT_MAX_PACKET_SIZE
that was set to 255. In our fork, we modified the value to be something more appropriate for us, and didn't suffer any other bugs as a result.
I was curious, was there a specific reason this was set to 255? We are trying to figure out if there might be any repercussions to this change, although we haven't discovered any yet.
I am interested in adding a custom keep alive interval to this library. A recent project requires a near real-time notification of disconnected client. A keep-alive interval of 1 second should be fine.
I imagine something like:
#include "MQTT.h"
// Optional third arg of the constructor is an Int representing number of seconds
MQTT client(server, 1883, 1, callback);
void setup() {
client.connect("ClientName");
if (client.isConnected()) client.publish("test","Hello World");
}
void loop() {
if (client.isConnected()) client.loop();
}
PR ready for comment: #49
Hello!
After removing #include "application.h"
from MQTT.cpp
, the application fails to compile:
In member function 'bool MQTT::connect(const char*, const char*, const char*, const char*, MQTT::EMQTT_QOS, uint8_t, const char*)':
MQTT/MQTT.cpp:156:55: error: 'millis' was not declared in this scope
lastInActivity = lastOutActivity = millis();
^
In member function 'bool MQTT::loop()':
MQTT/MQTT.cpp:237:34: error: 'millis' was not declared in this scope
unsigned long t = millis();
^
In member function 'bool MQTT::write(uint8_t, uint8_t*, uint16_t)':
MQTT/MQTT.cpp:419:30: error: 'millis' was not declared in this scope
lastOutActivity = millis();
^
In member function 'void MQTT::disconnect()':
MQTT/MQTT.cpp:467:47: error: 'millis' was not declared in this scope
lastInActivity = lastOutActivity = millis();
This is a known topic, as Particle build requires application.h
. Including the header fix the problem
Having a heck of a time trying to use the MQTT library in Particle with integer values coming off of a moisture sensor.
Veryfing code using this library in Particle Build fails with this error:
MQTT/MQTT.h:140:10: error: initializing argument 2 of 'bool MQTT::publish(const char*, const uint8_t*, unsigned int)' [-fpermissive]
bool publish(const char *, const uint8_t *, unsigned int)
Here's the code that's giving me the problems:
` if (client.isConnected()) {
int sensorValue = 0; // variable to store the value coming from the sensor
// read the value from the sensor:
Serial.println("Reading sensor value...");
sensorValue = analogRead(sensorPin);
Serial.println(sensorValue);
Serial.println("Attempting to publish a reading...");
client.publish("rayterrill/feeds/moisture",(uint8_t)sensorValue,4);
//client.subscribe("/inTopic");t
Trying to cast the integer value to uint8_t, but that gives the error above. Switching it to (uint8_t*) clears the issue, but I get blank or garbage data in the Adafruit IO dashboard feed I'm using, depending what I have the plength set to.
Am I just doing something totally wrong here?
It would be great it this code can be compatible with the wino board
This board has an ESP8266EX Wifi chip but uses it's own wino.h library. So the standard ethernet lib cannot be used. I guess the difference is not too big to change it to work with this library.
best regards,
Christian
There is no way to set the "retain" flag on any message other than the "Will" on initial connect
Hi, i have many problem to connect the spark to cloudmqtt. I'm using your example (mqtttest.ino)
suppose that my complete cloud mqtt url is: "mqtt://username:password@host:port"
where i can put the connection string in your code?
here ? if yes, how?
MQTT client("server_name", 1883, callback);
or, (from instructables.com) here? if yes, how?
++
In the "mqtttest.ino" Line 29 :
client.connect("sparkclient");
change it to :
client.connect("cloudmqtt-url", "userid", "password");
++
thank you
I am using redbear duo as my device to receive messages from the IBM IOT platform. I am able to send messages to the platform, but not able to receive messages. The callback function is never invoked.
The MQTT broker seems fine without any issues. Is there any problem with the MQTT client in receiving the messages that it has earlier subscribed for?
My code is here
#include <MQTT.h>
char *IOT_CLIENT = "d:<orgid>:<type>:<device_id>";
char *IOT_HOST = "<orgid>.messaging.internetofthings.ibmcloud.com";
char *IOT_PUBLISH = "iot-2/evt/count/fmt/json";
char *IOT_SUBSCRIBE = "iot-2/cmd/channel/fmt/json";
char *IOT_USERNAME = "xxx";
char *IOT_PASSWORD = "yyyy";
#if defined(ARDUINO)
SYSTEM_MODE(SEMI_AUTOMATIC);
#endif
// your network name also called SSID
//char ssid[] = "TP-LINK_1CE8";
char ssid[] = "D-Link_DIR-524";
// your network password (key)
char password[] = "xxxx";
void printCurrentNet();
void printWifiData();
int count = 0;
void callback(char* topic, byte* payload, unsigned int length);
MQTT client(IOT_HOST, 1883, callback);
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
Serial.println(PLATFORM_ID);
// attempt to connect to Wifi network:
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid);
WiFi.on();
WiFi.setCredentials(ssid,password);
WiFi.connect();
while ( WiFi.connecting()) {
// print dots while we wait to connect
Serial.print(".");
delay(300);
}
Serial.println("\nYou're connected to the network");
Serial.println("Waiting for an ip address");
IPAddress localIP = WiFi.localIP();
while (localIP[0] == 0) {
localIP = WiFi.localIP();
Serial.println("waiting for an IP address");
delay(1000);
}
Serial.println("\nIP Address obtained");
printCurrentNet();
printWifiData();
client.connect(IOT_CLIENT, IOT_USERNAME, IOT_PASSWORD);
if( client.isConnected() ) {
Serial.println( "Connected." );
client.subscribe(IOT_SUBSCRIBE);
}
}
void loop() {
if( !client.isConnected() ) {
Serial.println("Reconnecting...");
client.connect(IOT_CLIENT, IOT_USERNAME, IOT_PASSWORD);
client.subscribe(IOT_SUBSCRIBE);
}
//
count = count + 1;
client.publish(IOT_PUBLISH, getJson(count));
client.loop();
Serial.print( "Count: " );
Serial.println( count );
delay( 10000 );
}
void printWifiData() {
// print your WiFi IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
Serial.println(ip);
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
Serial.print(mac[5], HEX);
Serial.print(":");
Serial.print(mac[4], HEX);
Serial.print(":");
Serial.print(mac[3], HEX);
Serial.print(":");
Serial.print(mac[2], HEX);
Serial.print(":");
Serial.print(mac[1], HEX);
Serial.print(":");
Serial.println(mac[0], HEX);
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
Serial.print("Encryption Type:");
Serial.println(WEP, HEX);
Serial.println();
}
String getJson(int no){
String message = "{";
message += "\"no\":";
message += no;
message += "}";
return message;
}
void callback( char* topic, byte* payload, unsigned int length ) {
Serial.println("Message Received by Device");
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
Serial.println(message);
}
Hello and thanks for your MQTT library.
I´ve been testing your library on one Photon without any problem. I ran your example and I am able to switch the LED color by publishing from another MQTT user/client successfully.
Nevertheless, if I use the same code (of course changing the user and password) simultaneously on another photon, the first photon will loose its connection. In other words, only the last photon that connects to the server will keep its connection. All of these photons are connected through the same WiFi.
This is the code I´m testing, I just added a LED indicator to your example to see if the connection is alive:
#include "MQTT/MQTT.h"
int led = D7;
void callback(char* topic, byte* payload, unsigned int length);
/**
* if want to use IP address,
* byte server[] = { XXX,XXX,XXX,XXX };
* MQTT client(server, 1883, callback);
* want to use domain name,
* MQTT client("www.sample.com", 1883, callback);
**/
MQTT client("m13.cloudmqtt.com", #####, callback);
// recieve message
void callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
if (message.equals("RED")){
RGB.color(255, 0, 0);
}
else if (message.equals("GREEN"))
RGB.color(0, 255, 0);
else if (message.equals("BLUE"))
RGB.color(0, 0, 255);
else
RGB.color(255, 255, 255);
delay(1000);
}
void setup() {
RGB.control(true);
pinMode(led, OUTPUT);
// connect to the server
client.connect("m13.cloudmqtt.com","User1","Password1");
// publish/subscribe
if (client.isConnected()) {
client.publish("TopicTest","hello world2");
client.subscribe("TopicTest");
}
}
void loop() {
if (client.isConnected()){
client.loop();
digitalWrite(led,HIGH);
}else{
digitalWrite(led,LOW);
}
}
I thought it was an issue concerning the wifi connection so I added this code to restart the connection if it is lost:
void loop() {
if (client.isConnected()){
client.loop();
digitalWrite(led,HIGH);
}else{
digitalWrite(led,LOW);
client.connect("m13.cloudmqtt.com","User1","Password1");
client.subscribe("TopicTest");
}
}
But still the last photon to connect to the server is the one that keeps the connection. I observe the LEDs switching on and of in the inverse signal of each other each time one of them opens the connection with the server.
I´ve tested this situation with up to 3 photons simultaneously and only one is able to connect to the server at each time.
The mqtt broker lives in mqttcloud with a 100 connections, 100 Kbit/s capability.
One might suspect on the MQTT broker but I´ve checked with another non-Photon clients and they are able to keep the connection without making the first photon loose its connection.
Am I using your library in a wrong way?
Thank you in advance.
It's possible I'm missing something - but how would I publish a message with a QOS of 2, and the retain flag set?
Would it be possible to update the version on the particle web-ide to the latest version in the repo? Thanks!
In MQTT.h there is:
// MQTT_MAX_PACKET_SIZE : Maximum packet size
#define MQTT_MAX_PACKET_SIZE 128
You can increase this to increase the maximum packet size. On a Particle Photon you might want to send a much bigger payload. However values above 255 fail to work.
In the MQTT.cpp in there is:
bool MQTT::write(uint8_t header, uint8_t* buf, uint16_t length) {
uint8_t lenBuf[4];
uint8_t llen = 0;
uint8_t digit;
uint8_t pos = 0;
uint8_t rc;
uint8_t len = length;
do {
digit = len % 128;
len = len / 128;
if (len > 0) {
digit |= 0x80;
}
lenBuf[pos++] = digit;
llen++;
} while(len > 0);
buf[4-llen] = header;
for (int i = 0; i < llen; i++) {
buf[5-llen+i] = lenBuf[i];
}
rc = _client->write(buf+(4-llen), length+1+llen);
lastOutActivity = millis();
return (rc == 1+llen+length);
}
The method argument length is of type uint16_t in the function signature. However when the local variable len is of type uint8_t. The length type is reduced from a 16 bit value to an 8 bit value and length precision above 255 is lost on this line:
uint8_t len = length;
I was able to send data packets greater than 255 bytes on the Photon by changing all of the method's local variable types from uint8_t to uint16_t like this:
bool MQTT::write(uint8_t header, uint8_t* buf, uint16_t length) {
uint16_t lenBuf[4];
uint16_t llen = 0;
uint16_t digit;
uint16_t pos = 0;
uint16_t rc;
uint16_t len = length;
do {
digit = len % 128;
len = len / 128;
if (len > 0) {
digit |= 0x80;
}
lenBuf[pos++] = digit;
llen++;
} while(len > 0);
buf[4-llen] = header;
for (int i = 0; i < llen; i++) {
buf[5-llen+i] = lenBuf[i];
}
rc = _client->write(buf+(4-llen), length+1+llen);
lastOutActivity = millis();
return (rc == 1+llen+length);
}
I tried as suggested in example but not getting any messages in Paho Client, but for MQTT::QOS1, its working fine.
uint16_t messageId;
client.publish(topic, (uint8_t*)message_buff, strlen(message_buff), true, MQTT::QOS2, &messageId);
Serial.println(messageId);
Veryfing code using this library in Particle Build fails with this error:
MQTT/MQTT.h:163:10: error: initializing argument 2 of 'bool MQTT::publish(const char*, const char*, MQTT::EMQTT_QOS, uint16_t*)' [-fpermissive]
bool publish(const char *, const char *, EMQTT_QOS, uint16_t *messageid = NULL)
When using MQTT library, I lost some notifications. I added logs and discovered MQTT client often disconnects. I have another client that is connected to broker on same topic : it does not disconnect.
Here is code that runs on photon : https://github.com/OpHaCo/roomba_wifi/blob/master/roomba-control.ino
Mosquitto server is :
mosquitto version 1.4.3 (build date 2015-10-02 12:31:25+0200)
Here are mosquitto logs :
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: Client roomba_photon disconnected.
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: New client connected from 192.168.132.63 as roomba_photon (c1, k15).
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: New connection from 192.168.132.64 on port 1883.
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: Client roomba_photon already connected, closing old connection.
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: Client roomba_photon disconnected.
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: New client connected from 192.168.132.64 as roomba_photon (c1, k15).
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: New connection from 192.168.132.63 on port 1883.
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: Client roomba_photon already connected, closing old connection.
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: Client roomba_photon disconnected.
nov. 03 10:59:50 remi-hp9470m mosquitto[548]: 1446544790: New client connected from 192.168.132.63 as roomba_photon (c1, k15)
Here are photon logs :
connected to mqtt
mqtt client not connected - id=42938
connect mqtt
connected to mqtt
mqtt client not connected - id=43127
connect mqtt
connected to mqtt
mqtt client not connected - id=43314
connect mqtt
connected to mqtt
mqtt client not connected - id=43499
connect mqtt
connected to mqtt
mqtt client not connected - id=43680
connect mqtt
connected to mqtt
mqtt client not connected - id=43864
connect mqtt
connected to mqtt
mqtt client not connected - id=44056
connect mqtt
connected to mqtt
mqtt client not connected - id=44241
connect mqtt
connected to mqtt
mqtt client not connected - id=44430
connect mqtt
connected to mqtt
mqtt client not connected - id=44623
connect mqtt
connected to mqtt
mqtt client not connected - id=44812
connect mqtt
connected to mqtt
mqtt client not connected - id=44999
connect mqtt
connected to mqtt
mqtt client not connected - id=45195
connect mqtt
connected to mqtt
mqtt client not connected - id=45380
connect mqtt
connected to mqtt
mqtt client not connected - id=45572
connect mqtt
connected to mqtt
mqtt client not connected - id=45760
connect mqtt
connected to mqtt
mqtt client not connected - id=45940
I tried with iot.eclipse.org and
mosquitto version 1.2.3 (build date 2015-10-07 16:19:36+0200)
and it works fine. No messages are lost, photon client is not disconnected.
I've found out about this and explained it further here: https://community.particle.io/t/photon-device-name-not-returning-anymore/28088/4
I'm using the following code to connect to mqtt:
void callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
Particle.publish("MQTT: " + message);
}
MQTT client("m13.cloudmqtt.com", 18561, callback, 512);
unsigned long lastConnection = 0;
void loop() {
if (client.isConnected()) {
client.loop();
} else {
if(lastConnection == 0 || (millis() - lastConnection) > 5000) {
lastConnection = millis();
Particle.publish("MQTT Connection loop");
client.connect("m13.cloudmqtt.com", "xxxx", "xxxxx");
return;
}
}
}
For some reason, when I am running this code in the loop Particle's Particle.publish("spark/device/name");
does not reply anymore.
I am trying to send some data to my mqtt broker and I have found that as soon as the message contains a 0, the rest of it is not paid attention.
For example:
char a[10];
a[0] = 3;
a[1] = 2;
a[2] = 0;
a[3] = 4;
The message received in broker seems to be 32 and nothing else.
I trying with photon 0.5.3
Is there a way to specify the length of the message so it can contains whatever I want?
in publish
// was: for (i=0;i<plength;i++) {
for (i=0;i<plength && length < MQTT_MAX_PACKET_SIZE;i++) { // new
buffer[length++] = payload[i];
}
and writeString
pos += 2;
// was: while (*idp) {
while (*idp && pos < MQTT_MAX_PACKET_SIZE) { // new
buf[pos++] = *idp++;
i++;
}```
Currently , it seems only QOS 0 is supported by the library. The problem is that even if you're subscribing with a client and a persistent connection, the broker never sends the offline messages because of QOS0 used for publishing. But it's often needed to store the sensor data at the broker level , and then be able to retrieve all data from a client.
So, QOS1 at leasdt is needed to fulfill that.
Complete implementation of QOS1 could be complicated due to RAM limitation (but it shoud be possible if we know the average payload length and limit the number of messages that can be stored).
But maybe one trick could be used : just be able to add the flag for QOS1 when a message is published . If the message is received by broker , a PUBACK is sent back , and we do not even need to process it . If it's not received by the broker , it's lost.
But the received messages with QOS1 flag are stored on the broker and then can be used with persistent connections at the other end.
Hi!
Great library.
I just wanted to let you know that in MQTT.cpp all the parameters referring to QOS in client.publish() function are hard-coded to QOS0. This is resulting in qos0 for all messages even if someone sets different QOS with the public class MQTT::QOS.
bool MQTT::publish(const char * topic, const char* payload, EMQTT_QOS qos, uint16_t *messageid) {
return publish(topic, (uint8_t*)payload, strlen(payload), false, QOS0, messageid);
}
Cheers!
Simone
I don't see any support for cleanSession. Given that microcontrollers spend a lot of time offline, I would like to make sure any "commands" that I want to send to the device while it's offline are received when the device comes back online.
Any recommendations on how to add this support?
Your samples do feature this callback
void callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
if (message.equals("RED"))
RGB.color(255, 0, 0);
else if (message.equals("GREEN"))
RGB.color(0, 255, 0);
else if (message.equals("BLUE"))
RGB.color(0, 0, 255);
else
RGB.color(255, 255, 255);
delay(1000);
}
Could you clarify why char p[]
is created, populated and terminated but never used?
Also in order to keep the system stable for a long time String
should be avoided as it may lead to heap fragmentation.
If I had the choice, I'd keep p[]
and drop String message
and do the string compare like this
if (!strcmp(p, "RED"))
RGB.color(255, 0, 0);
else if (!strcmp(p, "GREEN"))
RGB.color(0, 255, 0);
else if (!strcmp(p, "BLUE"))
RGB.color(0, 0, 255);
else
RGB.color(255, 255, 255);
Veryfing code using this library in Particle Build fails with this error:
MQTT/MQTT.h:113:9: error: initializing argument 2 of 'bool MQTT::publish(char*, char*)' [-fpermissive]
bool publish(char *, char *)
Here is the line that is causing it trouble:
client.publish("hello/world", (topic == "/home/test")?"TRUE":"FALSE");
I don't know if the conditional operator is doing something unexpected, but it should just show up as "TRUE" or "FALSE", as far as the function call can see.
MQTT test firmware compiles (and flashed Photon) in Particle cloud but not in desktop Particle Dev.
Changing the include to just #include "MQTT.h" allowed compiling/flashing in Particle Dev.
Note program and includes all located in same flat directory.
Could someone validate this change as a correct solution and not really changing some other parameter.
Particle Dev on MacBook Pro with El Capitan 10.11.1
David
RavenTT / MiqroMeq
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.