Cayenne-MQTT-Arduino
Cayenne-MQTT-Arduino copied to clipboard
Hanging on Cayenne.begin on Arduino MKR WiFi 1010
Hi.
I'm trying to use Cayenne with on Arduino MKR WiFi 1010 but it hangs on Cayenne.begin...
Here's the code for library version 1.3.1
#define CAYENNE_DEBUG // Uncomment to show debug messages
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space
#include <CayenneMQTTMKR1010.h>
const char ssid[] = "WiFi-2.4-C9FC"; // WiFI ssid
const char wifiPassword[] = "wifiPassword"; //WiFI password
char username[] = "0000000-0000-0000-0000-000000000";
char password[] = "0000000-0000-0000-0000-000000000";
char clientID[] = "0000000-0000-0000-0000-000000000";
void setup() {
Serial.begin(9600);
Cayenne.begin(username, password, clientID, ssid, wifiPassword);
// Blink 3 times when back from begin
for(int i=0; i<3; ++i)
{
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
}
}
void loop() {
Cayenne.loop();
}
CAYENNE_CONNECTED()
{
for(int i=0; i<10; ++i){
digitalWrite(LED_BUILTIN, HIGH);
delay(50);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
}
}
bool ledStatus = HIGH;
// Default function for sending sensor data at intervals to Cayenne.
// You can also use functions for specific channels, e.g CAYENNE_OUT(1) for sending channel 1 data.
CAYENNE_OUT_DEFAULT()
{
digitalWrite(LED_BUILTIN, ledStatus);
if(ledStatus == HIGH)
ledStatus = LOW;
else
ledStatus = HIGH;
// Write data to Cayenne here. This example just sends the current uptime in milliseconds on virtual channel 0.
Cayenne.virtualWrite(0, millis());
// Some examples of other functions you can use to send data.
//Cayenne.celsiusWrite(1, 22.0);
//Cayenne.luxWrite(2, 700);
//Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
}
// Default function for processing actuator commands from the Cayenne Dashboard.
// You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_IN_DEFAULT()
{
CAYENNE_LOG("Channel %u, value %s", request.channel, getValue.asString());
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
The debug log from Cayenne says that WiFi is connected and MQTT client is connected and built-in led blinks as expected. But it never gets back from Cayenne.begin and never blinks 3 times.
I did some print-debug ;) and found that it hangs when subscribing, line 68 in CayenneArduinoMQTTClient.h:
CayenneMQTTSubscribe(&_mqttClient, NULL, COMMAND_TOPIC, CAYENNE_ALL_CHANNELS, NULL);
I tried to print debug deeper, but couldn't make CAYENNE_LOG
work in CayenneMQTTClient.c ...
Can you have a look? Thanks!
We aren't able to reproduce the issue here currently, but there are a few options you could try.
- If you don't need to use the command functionality to send commands from the Cayenne dashboard to your device you can try just commenting out that CayenneMQTTSubscribe call.
- You might try experimenting by setting different WRITE_CHUNK_SIZE values in CayenneMQTTMKR1010.h like it is set in CayenneMQTTWiFi.h and see if that helps.
- If you would like to do more debugging I've made a branch at https://github.com/myDevicesIoT/Cayenne-MQTT-Arduino/tree/fix/mkr1010-hang with some changes that should allow you to use CAYENNE_LOG calls in CayenneMQTTClient.cpp (this replaces CayenneMQTTClient.c). If you have issues with CAYENNE_LOG you can also try using Serial.print calls instead.
You might also try checking with the Cayenne Community to see if anyone else is seeing this issue and has a fix for it. https://community.mydevices.com/
Hello, i have the same error with my MKR1000 board with example sketch. if i comment line 68 in CayenneArduinoMQTTClient.h, millis() works fine otherwise hangs. from library version 1.0.0 to 1.3.0 nothing changes. I have updated modem with new one, changed firewall rules, opened ports 1883 and 8883 but nothing.
Which firewall's ports are used by Cayenne MQTT library?
Thanks
You comment out the while (error != MQTT_SUCCESS)
line and the library works?
The ports used by the library are 1883 and 8883. You might try using another MQTT library, like the PubSubClient, and connecting to a test server to see if you also get issues. If so it's possibly a firewall or network issue.
sorry library crashes in line 72 CayenneMQTTSubscribe(&_mqttClient, NULL, COMMAND_TOPIC, CAYENNE_ALL_CHANNELS, NULL); if i comment this line millis() works fine. Problem are ingoing commands. now i'm checking firewall rules.
thanks
Hi, i have tested with library ArduinoMqttClient and everything is ok, i suppose:
Attempting to connect to WPA SSID: ********** You're connected to the network
Attempting to connect to the MQTT broker: test.mosquitto.org You're connected to the MQTT broker!
Sending message to topic: arduino/simple hello 0
Sending message to topic: arduino/simple hello 1
Sending message to topic: arduino/simple hello 2 now i'm checking function cayenneMQTTSubscribe() with deeper debug with serial.print().
Hi, library MQTTSubscribeClient.c hangs into for() loops, line 74, on function writeChar(&ptr, requestedQoSs[i]);, i suppose, because requestedQoSs is NULL. following function debug
[5508] Connecting to ****************** [7031] Connected to WiFi [7031] IP: ..*.** [7031] Connecting to mqtt.mydevices.com:1883 [7297] Connected MQTTSerialize_subscribe i: 0
writeMQTTString(&ptr, topicFilters[i]) topicFilters[i].cstring: v1/1cba6fe0-21bf-11e7-abe0-73b922b9fe51/things/de40e390-0610-11eb-a2e4-b32ea624e442/cmd/+ topicFilters[i].lenstring.len: 0 topicFilters[i].lenstring.data:
writeChar(&ptr, requestedQoSs[i]) requestedQoSs[i]: <---- hangs
can you help me? thanks
Hi, with AWS IoT Core and PubNub works fine.
It hangs when you try to print out requestedQoSs[i]
? Are you doing that after the writeChar(&ptr, requestedQoSs[i]);
? Does it also hang there if you try to print it out at the top of the MQTTSerialize_subscribe
function?
If you replace writeChar(&ptr, requestedQoSs[i]);
with writeChar(&ptr, 0);
does that also hang?
Are you able to subscribe to topics using the ArduinoMqttClient? Or the Paho Embedded C client, which is what this library is using? https://github.com/eclipse/paho.mqtt.embedded-c
Hi, it hangs on function writeChar(&ptr, requestedQoSs[i]); not print out. if i replace writeChar(&ptr, requestedQoSs[i]); with writeChar(&ptr, 0); everything works fine. ArduinoMqttClient works both WiFisimplereceive and WiFisimplesender.
Strange that setting it to 0 works, but not using the enum 0 value that is cast to an (int*)
. Maybe there's some issue with that cast on a MKR1000.
Will just manually setting the value to 0 like that work for you? If not, you could also try experimenting with not using the (int*)
cast when calling MQTTSerialize_subscribe
.
Something like this might work in MQTTClient.c (I haven't actually tested this compiles and runs).
int requestedQoS = qos;
len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, &requestedQoS);
or maybe
int requestedQoS[1];
requestedQoS[0] = qos;
len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, requestedQoS);
I had the same issue and fixed it like this:
int qos_array[1];
qos_array[0] = (int) qos;
len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, &qos_array);
Seems some compilers optimize the enum type into short
/byte
instead of int
so the cast doesn't work.