Particle Photon's loop function locks over time up when using particle.subscribe

Hello,

I’m running the code below to drive an LED display using data published from a remove Photon. Everything runs fine for a day or two, then the display Photon locks up (i.e., it stops running through the loop function, which is supposed to blink the LED display). What’s odd is that after locking up, resetting the display Photon doesn’t fix the problem … i.e., the LEDs blink until the first remote publish command, then they freeze. Eventually, sometimes minutes or hours later, resetting the Photon works and it goes back to normal operation. The publish/subscribe functions seem to work for a while, but glitch out over time. Any ideas on what might be causing this?

Thanks!

// This #include statement was automatically added by the Particle IDE.
#include <adafruit-led-backpack.h>
#include <string>

int water_level_int = 0; 
String water_level_string;
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();

void myHandler(String event, String data)
{
  water_level_int = data.toInt();
  water_level_string = data; 
}


static const uint8_t PROGMEM
  full1[] =
    { B01010101,
    B11111111,
    B11111111,
    B11111111,
    B11111111,
    B11111111,
    B11111111,
    B11111111 },
 full2[] =
    { B10101010,
    B11111111,
    B11111111,
    B11111111,
    B11111111,
    B11111111,
    B11111111,
    B11111111 },
  half_full1[] =
    { B00000000,
    B00000000,
    B00000000,
    B01010101,
    B11111111,
    B11111111,
    B11111111,
    B11111111 },
 half_full2[] =
    { B00000000,
    B00000000,
    B00000000,
    B10101010,
    B11111111,
    B11111111,
    B11111111,
    B11111111 };


void setup() {
  Serial.begin(9600);
  Serial.println("8x8 LED Matrix Test");
  matrix.begin(0x70);  // pass in the address
  Particle.subscribe("WaterLevelPublish", myHandler, ALL_DEVICES);
}


void loop() {

matrix.setRotation(0);

    if (water_level_int > 8) {
        matrix.clear();
        matrix.drawBitmap(0, 0, full1, 8, 8, LED_ON);
        matrix.writeDisplay();
        delay(1000);

        matrix.clear();
        matrix.drawBitmap(0, 0, full2, 8, 8, LED_ON);
        matrix.writeDisplay();
        delay(1000);

    }; 
  
  
   if (water_level_int < 8) {
        matrix.clear();
        matrix.drawBitmap(0, 0, half_full1, 8, 8, LED_ON);
        matrix.writeDisplay();
        delay(1000);

        matrix.clear();
        matrix.drawBitmap(0, 0, half_full2, 8, 8, LED_ON);
        matrix.writeDisplay();
        delay(1000);
    }; 

}

First of this is not how a subscribe handler function signature should look like

The docs do state otherwise
https://docs.particle.io/reference/device-os/firmware/photon/#particle-subscribe-

String and const char* may be implicitly convertable/castable but they are fundamentally different. The latter is a trivial type refering to a static buffer in RAM the former is an object that uses dynamic memory allocation.
So each trigger of you even handler will create two copies of the incoming data on the heap and your assignment water_level_string = data; may cause a relocation of water_level_string again potentially causing another fragment on the heap.

Try replacing String with classic C strings and see if that helps.

BTW, there is no need for PROGMEM in the Particle world - there is only one address space.

This is also adding a minor overhead on the heap

Adafruit_8x8matrix matrix;

is enough and doesn't create and immediately destroy a temporary object.

2 Likes

Thanks @ScruffR! I’ve update the code and will give it a day or so to see what happens. I appreciate the guidance!