Cayenne-MQTT-Arduino icon indicating copy to clipboard operation
Cayenne-MQTT-Arduino copied to clipboard

Hanging on Cayenne.begin on Arduino MKR WiFi 1010

Open max-mayorov opened this issue 5 years ago • 11 comments

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!

max-mayorov avatar Dec 12 '19 21:12 max-mayorov

We aren't able to reproduce the issue here currently, but there are a few options you could try.

  1. 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.
  2. 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.
  3. 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/

jburhenn avatar Dec 13 '19 20:12 jburhenn

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

franx74it avatar Oct 04 '20 08:10 franx74it

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.

jburhenn avatar Oct 05 '20 18:10 jburhenn

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

franx74it avatar Oct 05 '20 19:10 franx74it

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().

franx74it avatar Oct 06 '20 19:10 franx74it

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

franx74it avatar Oct 10 '20 09:10 franx74it

Hi, with AWS IoT Core and PubNub works fine.

franx74it avatar Oct 11 '20 08:10 franx74it

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

jburhenn avatar Oct 14 '20 22:10 jburhenn

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.

franx74it avatar Oct 17 '20 05:10 franx74it

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);

jburhenn avatar Oct 23 '20 22:10 jburhenn

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.

sahlex avatar Sep 19 '22 15:09 sahlex