You could also uncomment the publish in the spark code.
client.publish("led","hello world");
Monitor the topic from mosquitto_sub and then power up the Core. This will at least tell you wether the core is connecting to the broker at all.
You could also uncomment the publish in the spark code.
client.publish("led","hello world");
Monitor the topic from mosquitto_sub and then power up the Core. This will at least tell you wether the core is connecting to the broker at all.
Hello @mrOmatic how did your broker test go?
Iām hoping to have some time to try it all again tonight
Okay, Iāve about had it with this broker then. Nothing is working when I try it with the Core. Does anyone else have a recommendation for a good, stable broker that I can use? I need to get sensor data from a remote device (LightBlue Bean and cell phone) to my Core, and I figured an MQTT broker would be the best way.
Iām not physically near a core but Iāve tested this with one thatās online.
First Subscribe to the debug topic to recive messages from your core.
mosquitto_sub -h 198.41.30.241 -t sparkcore/debug
Then flash the following code to your core
#include "MQTT/MQTT.h"
void callback(char* topic, byte* payload, unsigned int length);
byte server[] = { 198,41,30,241 };
MQTT client(server, 1883, callback);
byte bytebuffer[30];
// 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);
String message = "RED";
message.getBytes(bytebuffer, 4);
client.publish("sparkcore/debug",bytebuffer, 4);
}
else if (message.equals("GREEN")) {
RGB.color(0, 255, 0);
String message = "GREEN";
message.getBytes(bytebuffer, 6);
client.publish("sparkcore/debug",bytebuffer, 6);
}
else if (message.equals("BLUE")) {
RGB.color(0, 0, 255);
String message = "BLUE";
message.getBytes(bytebuffer, 5);
client.publish("sparkcore/debug",bytebuffer, 5);
}
else
RGB.color(255, 255, 255);
delay(1000);
}
void setup() {
RGB.control(true);
// connect to the server
client.connect("spark_client");
// publish/subscribe
if (client.isConnected()) {
String message = "SparkCore Connected";
message.getBytes(bytebuffer, 20);
client.publish("sparkcore/debug",bytebuffer, 20);
client.subscribe("sparkcore/RGBled");
}
}
void loop() {
if (client.isConnected())
client.loop();
}
After a short while you monitoring terminal should receive a message.
SparkCore Connected
Then send it messages via the broker.
mosquitto_pub -h 198.41.30.241 -t sparkcore/RGBled -m BLUE
mosquitto_pub -h 198.41.30.241 -t sparkcore/RGBled -m GREEN
mosquitto_pub -h 198.41.30.241 -t sparkcore/RGBled -m RED
The corresponding colour is also echoād to the debug topic sparkcore/debug
Finally Enjoy
I see what you did there with two different topics. I ran this tonight on my core, and I get nothing. No āSparkCore Connectedā message in the debug topic, and no control via the RGBled topic. When I change to publish my own messages in terminal to the debug topic, I can see what I publish.
I even changed wireless routers tonight, but it did not help. I can open a port in my firewall if I could figure out what the IP address is for my Core.
As you suggest I think you have a networking / firewall issue. You can usually get the cores IP address from by looking at the dhcp leases in your router. if your firewall is locked down that tight you might see if your router will allow you to assign a static IP address based on the devices MAC. Then whatever firewall rules you change to allow MQTT wont be affected by the dhcp assigning you core a different IP in the future.
I think we can say we have solved the specific MQTT problems with the tutorial you where following. Perhaps any further networking problems could go to a new topic so this one can stay on topic about MQTT on the Sparkcore.
mhwing,
I have run into the same hang problem (after about 6 hrs of constant communication between cores) and didnāt see any benefit from your change to the library files. Any further thoughts?
@bpr, No, Iāve stopped using the spark because of thisā¦
FWIW,
Iāve stumbled upon what seems like a stable means of communicating between 2 cores with the MQTT IDE library. As far as I can tell,the two critical elements appears to be 1) omitting client.loop() from the loop section of the receiving core and 2) using the retain flag version of the client.publish function. I donāt know why this gets it to be stable but itās managed to stay stable after over 3000 transmissions. (also #include āMQTT/MQTT.hā didnāt work for me). Code for both cores below:
// This #include statement was automatically added by the Spark IDE.
#include "MQTT.h"
/* mqttreceiver.ini
employs MQTT library Version 0.1: initial version 2014 Hirotaka Niisato in spark core IDE
This core receives messages, from another core running mqttsender.ino, to cycle it's rgb led through red-green-blue
using mosquitto broker on raspberry pi
Can also display messages on the broker terminal using:
mosquitto_sub -v -h 192.168.1.99 -t sparkcore/RGBled //192.168.1.99 is ip of rpi broker
*/
// receive 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);
}//callback
byte server[] = { 192,168,1,99 }; //address of rpi mosquitto server
MQTT client(server, 1883, callback);
void setup() {
RGB.control(true);
// connect to the server
client.connect("spark_client"); //works with local
// publish/subscribe
if (client.isConnected())
client.subscribe("sparkcore/RGBled");
}//setup
void loop() {
//NOTE: client.loop() NOT USED
}//loop
Now the Sender code
// This #include statement was automatically added by the Spark IDE.
#include "MQTT.h"
/* mqttsender.ino
employs MQTT library Version 0.1: initial version 2014 Hirotaka Niisato in spark core IDE
mqttsender.ino on this core sends messages to another core running mqttreceiver.ino
to cause that core to cycle it's rgb led to cycle through red-green-blue
via the mosquitto broker running on a raspberry pi
*/
void callback(char* topic, byte* payload, unsigned int length);
byte server[] = { 192,168,1,99 }; //address of mosquitto server on raspberry pi
MQTT client(server, 1883,callback);
byte bytebuffer[30];
long loopcounter;
// receive message nothing to do here - we're only sending
void callback(char* topic, byte* payload, unsigned int length) {
}//callback
void setup() {
// connect to the server and send message to mosquitto and other core
client.connect("spark_client2"); //works with local
Time.zone(-7);
loopcounter = 0;
}//setup
void loop() {
if (client.isConnected()) {
String message3 = "RED";
message3.getBytes(bytebuffer, 4);
client.publish("sparkcore/RGBled",bytebuffer, 6, true);
}
delay(500);
if (client.isConnected()) {
String message4 = "GREEN";
message4.getBytes(bytebuffer, 6);
client.publish("sparkcore/RGBled",bytebuffer, 6, true);
}
delay(500);
if (client.isConnected()) {
String message5 = "BLUE";
message5.getBytes(bytebuffer, 5);
client.publish("sparkcore/RGBled",bytebuffer, 6, true);
}
delay(500);
if (client.isConnected()) {
String message6 = Time.timeStr();
char cstr[24];
strcpy(cstr, message6.c_str());
client.publish("sparkcore/lasttime", (uint8_t *)cstr,24,true); //publish time message sent
}
delay(500);
if (client.isConnected()) {
loopcounter++;
String string2(loopcounter,(uint8_t)10);
string2.getBytes(bytebuffer, string2.length()+1);
client.publish("sparkcore/loopcounter",bytebuffer,string2.length()+1,true); //publish number of loop cycles
}
delay(500);
}//loop
well, I spoke too soon. A simple brief wifi outage completely shuts it down and only a hard rest of both cores resuscitates it. System.reset programmatically doesnāt even restore the connection. Cannot figure out why.
Not wanting to give up on MQTT, I fiddled around some more and now have some code that has been quite stable for over 350,000 loops and can recover from wifi outages after adding the reconnect() code and a few other things. Still not clear what changes made the difference (sorry). I restored the client.loop() call, threw in some Spark.process() calls and left the variable declarations in the callback in mqttsender.ino. Using the persistence flag didnāt seem to be important. (Wish I knew more!). In case it will help anyone else the code for the two coresā is below:
// This #include statement was automatically added by the Spark IDE.
#include "MQTT.h"
/* mqttsender.ino
employs MQTT library Version 0.1: initial version 2014 Hirotaka Niisato in spark core IDE
mqttsender.ino on this core sends messages to another core running mqttreceiver.ino
to cause that core to cycle it's rgb led to cycle through red-green-blue
via the mosquitto broker running on a raspberry pi
Can also display messages on the broker terminal using:
mosquitto_sub -v -h 192.168.1.xx -t RGBled //192.168.1.xx is ip of rpi mosquitto broker
*/
void callback(char* topic, byte* payload, unsigned int length);
byte server[] = { 192,168,1,81 }; //192.168.1.xx is ip of rpi mosquitto broker
MQTT client(server, 1883, callback);
byte bytebuffer[30];
long loopcounter;
// 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);
}//callback
void reconnect() {
while (Spark.connected() == false) {
Spark.connect();
delay(1000);
}//while (Spark.connected()
}//reconnect()
void setup() {
Spark.syncTime();
Time.zone(-7);
// connect to the server
client.connect("clientS");
Spark.process();
// publish/subscribe
if (client.isConnected()) {
//String message = "SparkCore Connected";
Spark.process();
String message6 = Time.timeStr();
char cstr[24];
strcpy(cstr, message6.c_str());
Spark.process();
client.publish("lasttime", (uint8_t *)cstr,24,true); //publish time starts up
delay(100);
}//if (client.isConnected())
loopcounter=0;
}//setup
void loop() {
Spark.process();
if (client.isConnected()) {
client.loop();
delay(100);
String message = "RED";
message.getBytes(bytebuffer, 4);
client.publish("RGBled",bytebuffer, 4);
delay(100);
message = "GREEN";
message.getBytes(bytebuffer, 6);
client.publish("RGBled",bytebuffer, 6);
delay(100);
Spark.process();
message = "BLUE";
message.getBytes(bytebuffer, 5);
client.publish("RGBled",bytebuffer, 5);
delay(100);
loopcounter++;
String string2(loopcounter,(uint8_t)10);
string2.getBytes(bytebuffer, string2.length()+1);
client.publish("loopcounter",bytebuffer,string2.length()+1,true); //publish number of loop cycles
delay(100);
}
else
{
Spark.process();
reconnect();
Spark.process();
client.connect("clientS");
Spark.process();
String message7 = Time.timeStr();
char cstr[24];
strcpy(cstr, message7.c_str());
Spark.process();
client.publish("lasttime", (uint8_t *)cstr,24,true); //publish time core reconnected
delay(100);
}//else
}//loop
// This #include statement was automatically added by the Spark IDE.
#include "MQTT.h"
/* mqttreceiver.ini
employs MQTT library Version 0.1: initial version 2014 Hirotaka Niisato in spark core IDE
This core receives messages, from another core running mqttsender.ino, to cycle it's rgb led through red-green-blue
using mosquitto broker on raspberry pi
Can also display messages on the broker terminal using:
mosquitto_sub -v -h 192.168.1.xx -t sparkcore/RGBled //192.168.1.xx is ip of rpi mosquitto broker
*/
// receive 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);
}//callback
void reconnect() {
while (Spark.connected() == false) {
Spark.connect();
delay(1000);
}
}//reconnect
byte server[] = { 192,168,1,81 }; //address of rpi mosquitto server
MQTT client(server, 1883, callback);
void setup() {
RGB.control(true);
// connect to the server
client.connect("clientR");
//subscribe
if (client.isConnected())
client.subscribe("RGBled");
}//setup
void loop() {
if (client.isConnected()) {
client.loop();
}//if (client.isConnected())
else
{
Spark.process();
reconnect();
Spark.process();
client.connect("clientR");
Spark.process();
delay(100);
}
}//loop
Any update if your changes fixed the problem? I have this same problem. My code will run for about a day before it stops communicating with the broker. My loop does includes a client.isConnected check:
if(client.isConnected()) {
// set the LED green
RGB.color(0,255,0);
} else {
// set the LED red
RGB.color(255,0,0);
}
And the light stays green even though it is no longer sending messages to the broker.
Wifi is still connected, because I can reprogram the Spark Core, so I donāt see how the reconnect() is going to help. Besides the reconnect() and the liberal use of Spark.process(), what other changes did you make?
Has anyone had long term connections using the Spark MQTT library and any broker?
My full code is here: https://github.com/ctung/plant-monitor/blob/master/spark_core_client.ino
@kyngston , I havenāt used this in awhile, but what Iād do is something like my reconnect function above and Iād also replace all the delays I had in my last code samples above with :
lastTime = millis();
while(millis() - lastTime < 1000) {Spark.process();}
The 1000 would be for 1 sec delay. Use 100 for 100 ms delay, etc. lastTime is defined as
uint32_t lastTime;
Also Iāve found my photons are extremely sensitive to my microwave oven and so Iāve had to devise a way for them to gracefully connect back up w/ the cloud. I think I more or less solved that (
Microwave hardening). Some of my photons would go into fast cyan blink when the microwave is used. Are you using the cloud at all?
Let me know if this helps
Thanks, I tried that and it didnāt help. However I wrote a simple MQTT example that sends packets I log into my SQL server.
// This #include statement was automatically added by the Spark IDE.
#include "elapsedMillis/elapsedMillis.h"
// This #include statement was automatically added by the Spark IDE.
#include "MQTT/MQTT.h"
void callback(char* topic, byte* payload, unsigned int length);
byte server[] = { 192,168,1,116 }; //192.168.1.xx is ip of rpi mosquitto broker
MQTT client(server, 1883, callback);
elapsedMillis elapsed = 0;
unsigned int interval = 1000*60;
// recieve message
void callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
}//callback
void setup() {
client.connect("test_core");
client.publish("test", "3"); //3 indicates a connection
}//setup
void loop() {
if (elapsed > interval) {
client.publish("test","1"); // 1 indicates a heartbeat
elapsed = 0; // reset interval timer
}
if (!client.loop()) {
client.connect("test_core");
client.publish("test","2"); // 2 indicates a reconnect
}
}//loop
So far itās run for over a day without losing connection. If this continues to work, I can slowly add features to it until it stops working. Then I can identify the code that causes the problem.
Has anyone tried to use MQTT with TLS yet?
@kyngston, So Iāve been having the same problem as you since way back in February of last year. I eventually shut that project down due to the disconnects, but would like to try working on it again. Have you had any further success with not having it disconnect after a day?
Thanks.
Iāve started playing with Particle and MQTT again.
Iāve got two projects with very similar code running at the moment.
One is running on a Core and is needing to be physically reset every 12 hours or so.
The other one is running on a Photon and has been up for a week with no sign of problems.
I intend to post more on this shortly.
Hi,
Iām pretty new to particle but have been playing with mqtt for a while. I have a photon and have followed through the examples in this thread connecting to my mqtt server which is on a public address but it fails to connect every time. Iāve got it down to the
client.Connect(mqtt_client);
if(client.isConnected) {
ā¦
}
else {
This is where I end up
}
Iām using MQTTlens and am subscribed to the same topic with or without the same credentials (tried both with and without). I can send messages and see them arriving in MQTTlens and have also had no issue with arduinos doing the same thing, but canāt for the life of me get my photon to connect.
Does anyone have any clues?
Many thanks
Andy
I think Iāve figured it outā¦
So whenever I tried connecting using the public url for my server my photon was failing to connect. So I tried my internal IP and that was fine. Knowing there are no firewall issues I tested with my public IP addressā¦ Again I had no problem.
So my conclusion is that there is a problem resolving urls in the connect method.
Can anyone else confirm this or has anyone else had success connecting to a url and if so what format are you using?
tcp://mymqttserver.com
mymqttserver.com
http://mymqttserver.com
etc
Below is the code I used to connect successfully (taken from a previous post and tweaked).
Many thanks
Andy
// This #include statement was automatically added by the Spark IDE.
#include "MQTT/MQTT.h"
void callback(char* topic, byte* payload, unsigned int length);
byte server[] = { 192,168,1,3 }; //192.168.1.xx is ip of rpi mosquitto broker
MQTT client(server, 1883, callback);
//elapsedMillis elapsed = 0;
unsigned int interval = 1000*60;
// 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);
}//callback
void reconnect() {
while (Spark.connected() == false) {
RGB.color(255, 0, 0);
Spark.connect();
delay(1000);
}
RGB.color(0, 255, 0);
delay(1000);
}//reconnect
void setup() {
RGB.control(true);
// connect to the server
client.connect("clientR");
//subscribe
if (client.isConnected())
client.subscribe("test");
client.publish("test", "hello"); //3 indicates a connection
}//setup
void loop() {
if (client.isConnected()) {
client.loop();
}//if (client.isConnected())
else
{
Spark.process();
reconnect();
Spark.process();
client.connect("clientR");
Spark.process();
delay(100);
}
}//loop
Hi @mcinnes01
Seems the library asks for an IP or hostname, not an URL.
I tried with an hostname and it works, but your examples are domains, not FQDNs.
What happens trying with mymqttserver.mydomain.com ?
Claudio