arduino-libraries / Arduino_MKRIoTCarrier

Use the features included with the Arduino MKR IoT Carrier
https://store.arduino.cc/mkr-iot-carrier
GNU Lesser General Public License v2.1
17 stars 12 forks source link

Light.colorAvailable() fails after cloud reconnection #25

Open alranel opened 3 years ago

alranel commented 3 years ago

Using the code from the Personal Weather Station project included in the Oplà IoT Kit, I noticed an issue that is consistently reproducible.

Steps:

  1. Run the code and let it establish a connection to the cloud.
  2. Interrupt the TCP connection to the cloud, while still leaving wifi connected (you can do this with a firewall rule or by simply unplugging the DSL cable, without turning the access point off).
  3. The library will try to reconnect, but the board becomes totally unresponsive.

I had initially thought about an out-of-memory issue, but I tried to profile memory usage using this library and usage looks pretty stable (about 4K free during operation and reconnection); there are no signs of saturation even during reconnection (but I didn't profile inside _mqttClient.connect() so it's still possible that a temporary non-fatal saturation occurs there).

This the relevant excerpt from code:

void loop() {
  ArduinoCloud.update();
  carrier.Buttons.update();

  while (!carrier.Light.colorAvailable()) {
    delay(5);
  }
  int none;
  carrier.Light.readColor(none, none, none, light);

  // other stuff...
}

After some debugging I noticed that the board is not crashing but it's live, just becoming unresponsive because this loop runs forever:

while (!carrier.Light.colorAvailable()) {
  delay(5);
}

Note that this block works correctly before the cloud reconnection. For every loop() it will need approximately 3 iterations before colorAvailable() is true, but this is stable and the sensor provides consistent data. However, just after the ArduinoIoTCloud library reconnects to MQTT, Arduino_APDS9960 fails forever at the r & 0b00000001 line:

int APDS9960::colorAvailable() {
  uint8_t r;

  enableColor();

  if (!getSTATUS(&r)) {
    return 0;
  }

  if (r & 0b00000001) {
    return 1;
  }

  return 0;
}

This happens as soon as Arduino_IoTCloud connects to MQTT and sets its internal state to State::SubscribeMqttTopics.

It looks like the _mqttClient.connect() function does something that disrupts getSTATUS() in colorAvailable().

marqdevx commented 3 years ago

Have you tried this sketch with the latests updates of the Cloud library?