Callbacks interrupt flashing of device

Hello everyone,

i had a couple of problems trying to flash new code on my Photon…

i have a servo motor and a 16x32 LED matrix display connected to it.

i use thethingbox on a raspberry pi mith mosquitto and Nodered to send end receive mqtt messages…

nodered sends continuously a couple of messages a second to the photon to see if he reacts correctly (it has to put some shapes on the matrix and scroll them to the side. the shapes are triggered by the messages)

everything worked fine until yesterday:

now everytime i flash new code it gets stuck breathing green. when i reset the photon no new code is on it.
the only way to flash something new is to set it in to safe mode.
but this only happens when it gets the messages.

when i stop the messages from nodered it seems to work just fine…

at least for now…

i halfed the ammount of messages per second… now i only send 1 or 2 per second… but shouldnt it be abled to take on a way higher load? or is my code occupying the photon so much?

to clarify:
i haxe a servo with an arm that holds a little ship in front of a matrix panel. on the panel there are planets that move towards the ship at 1 led in 200ms.
ship movement and planets are controled by mqtt commands

 //deviceID:rocketgame

//Includes & Defines-------------------------------------------------------------------------------
#include "MQTT/MQTT.h"
#include "SparkIntervalTimer/SparkIntervalTimer.h"
#include "Adafruit_mfGFX/Adafruit_mfGFX.h"
//#include "gamma.h"
#include "RGBmatrixPanel.h"
#include "math.h"
#include <stdlib.h>  
#include <string.h>
#define RGBSHIELDVERSION		4
#if (RGBSHIELDVERSION == 4)		// Newest shield with SD socket onboard
//	#warning "new shield"
	#define CLK	D6
	#define OE	D7
	#define LAT	TX
	#define A  	A0
	#define B  	A1
	#define C  	A2
	#define D	RX
#else
//	#warning "old shield"
	#define CLK	D6
	#define OE 	D7
//	#define LAT	A4
	#define A  	A0
	#define B  	A1
	#define C  	A2
	#define D	A3
#endif

#define leaflet1 "L1/2 ID:rocketgame; device:Particle-Photon; sensors:none; acuators:MC-1811servomotor,32x16LEDMatrix; pubTo:device/arthur/status; subTo:device/arthur/order,device/arthur/input/game; orders:leaflet;"
#define leaflet2 "L2/2 behaves: reacts to input commands for the game: up, down, obstacle1, obstacle2, obstacle3, which will move the ship and generate obstacles to avoid;---"
#define upper matrix.Color333(0,1,0)
#define middle matrix.Color333(0,1,1)
#define lower matrix.Color333(1,0,1)
#define red matrix.Color333(1,0,1)
#define planet1 matrix.Color333(1,0,1)
#define planet2 matrix.Color333(1,0,1)
#define planet3 matrix.Color333(1,0,1)


//Variables-------------------------------------------------------------------------------
RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
uint8_t r=0, g=0, b=0;

Servo ship;

Timer ticker(100, tick);
bool itstime=false;
bool background_toggle=false;

int spawn_horizont=35;
int event_horizont=5;

bool star1_active=false;
int star1_pos_x=spawn_horizont;
int star1_pos_y=2;

bool star2_active=false;
int star2_pos_x=spawn_horizont;
int star2_pos_y=5;

bool star3_active=false;
int star3_pos_x=spawn_horizont;
int star3_pos_y=8;

bool star4_active=false;
int star4_pos_x=spawn_horizont;
int star4_pos_y=12;

bool star5_active=false;
int star5_pos_x=spawn_horizont;
int star5_pos_y=14;

bool obst1_active=false;
int obst1_pos_x = spawn_horizont;
int obst1_pos_y = 3;
int obst1_width = 1;

bool obst2_active=false;
int obst2_pos_x = spawn_horizont;
int obst2_pos_y = 7;
int obst2_width = 2;

bool obst3_active=false;
int obst3_pos_x = spawn_horizont;
int obst3_pos_y = 12;
int obst3_width = 3;

int ship_pos_y=8;
int ship_pos_servo[16]={130,125,120,115,110,100,95,90,80,75,70,60,55,50,45,40};
bool collision=false;

//MQTT relevant
byte server[] = { 192,168,2,111 };
MQTT client(server, 1883, callback);
char buffer [33];

//Functions-------------------------------------------------------------------------------

void tick(){
        itstime=true;
}
// recieve message
void callback(char* topic, byte* payload, unsigned int length) {
    //indicator for received message
    RGB.control(true);
    
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    
    //orders
    if(!strcmp(topic,"device/rocketgame/order")){
        
        if(!strcmp(message,"leaflet")){
            client.publish("device/rocketgame/status",leaflet1,MQTT::QOS0,false);
            client.publish("device/rocketgame/status",leaflet2,MQTT::QOS0,false);
        }
        
    }
    
    //Test
    if(!strcmp(topic,"device/rocketgame/output/servo")){
        ship.write(atoi(message));
    }


    //GAME
    if(!strcmp(topic,"device/rocketgame/output/game")){
        if(!strcmp(message,"up")){
            if(ship_pos_y>0)ship_pos_y--;
        }
        if(!strcmp(message,"down")){
            if(ship_pos_y<15)ship_pos_y++;
        }
        
        if(!strcmp(message,"obstacle1")){
            obst1_active=true;
        }
        
        if(!strcmp(message,"obstacle2")){
            obst2_active=true;
        }
        
        if(!strcmp(message,"obstacle3")){
            obst3_active=true;
        }
        
        if(!strcmp(message,"star1")){
            star1_active=true;
        }
        
        if(!strcmp(message,"star2")){
            star2_active=true;
        }
        
        if(!strcmp(message,"star3")){
            star3_active=true;
        }
        
        if(!strcmp(message,"star4")){
            star4_active=true;
        }
        
        if(!strcmp(message,"star5")){
            star5_active=true;
        }
    }

    
    //end rgb indicator
    RGB.color(0,0,0);
    RGB.control(false);
}


void setup() {
    //servo
    //pinMode(servo, OUTPUT);
    
    ship.attach(A4);
    
    //matrix
    matrix.begin();
    matrix.fillScreen(0);   
    
    ticker.start();
    
 
 
    //mqtt
    // connect to the server
    client.connect("rocketgame","device/rocketgame/status",MQTT::QOS0,false,"rocketgame: OFFLINE");
    // publish/subscribe
    if (client.isConnected()) {
        client.publish("device/rocketgame/status","rocketgame: ONLINE",MQTT::QOS0,false);
        client.subscribe("device/rocketgame/output/#");
        client.subscribe("device/rocketgame/order");
    }
    
    ship.write(90);
    //delay(100);
    ship.write(80);
    //delay(100);
    ship.write(90);

}

void loop() {
    Particle.connect();
    client.loop();
    
    if(itstime){
        //Level Creation
        matrix.fillScreen(0);
        
        background_toggle=!background_toggle;
        //drawing background stars
        if(star1_active){
            //obstacle create
            matrix.drawPixel(star1_pos_x,star1_pos_y,matrix.Color333(1,1,1));
        
            //obstacle shift
            if(background_toggle)star1_pos_x--;
            if(star1_pos_x<-3)
            {
                star1_active=false;
                star1_pos_x=spawn_horizont;
            }
        }
        if(star2_active){
            //obstacle create
            matrix.drawPixel(star2_pos_x,star2_pos_y,matrix.Color333(1,1,1));
        
            //obstacle shift
            star2_pos_x--;
            if(star2_pos_x<-3)
            {
                star2_active=false;
                star2_pos_x=spawn_horizont;
            }
        }
        if(star3_active){
            //obstacle create
            matrix.drawPixel(star3_pos_x,star3_pos_y,matrix.Color333(1,1,1));
        
            //obstacle shift
            if(background_toggle)star3_pos_x--;
            if(star3_pos_x<-3)
            {
                star3_active=false;
                star3_pos_x=spawn_horizont;
            }
        }
        
        if(star4_active){
            //obstacle create
            matrix.drawPixel(star4_pos_x,star4_pos_y,matrix.Color333(4,4,3));
        
            //obstacle shift
            star4_pos_x--;
            if(star4_pos_x<-3)
            {
                star4_active=false;
                star4_pos_x=spawn_horizont;
            }
        }
        
        if(star5_active){
            //obstacle create
            matrix.drawPixel(star5_pos_x,star5_pos_y,matrix.Color333(3,3,7));
        
            //obstacle shift
            if(background_toggle)star5_pos_x--;
            if(star5_pos_x<-3)
            {
                star5_active=false;
                star5_pos_x=spawn_horizont;
            }
        }
    
        
        //drawing obstacles
        if(obst1_active){
            //obstacle create
            matrix.fillCircle(obst1_pos_x,obst1_pos_y,obst1_width,matrix.Color333(7,2,3));
        
            //obstacle shift
            obst1_pos_x--;
            if(obst1_pos_x<-3)
            {
                obst1_active=false;
                obst1_pos_x=spawn_horizont;
            }
        }
        if(obst2_active){
            //obstacle create
            matrix.fillCircle(obst2_pos_x,obst2_pos_y,obst2_width,matrix.Color333(1,2,0));
        
            //obstacle shift
            obst2_pos_x--;
            if(obst2_pos_x<-3)
            {
                obst2_active=false;
                obst2_pos_x=spawn_horizont;
            }
        }
        if(obst3_active){
            //obstacle create
            matrix.fillCircle(obst3_pos_x,obst3_pos_y,obst3_width,matrix.Color333(2,3,1));
        
            //obstacle shift
            obst3_pos_x--;
            if(obst3_pos_x<-3)
            {
                obst3_active=false;
                obst3_pos_x=spawn_horizont;
            }
        }
        
        //draw ship
        matrix.drawPixel(event_horizont,ship_pos_y,matrix.Color333(7,0,0));
        
        //move ship
        ship.write(ship_pos_servo[ship_pos_y]);    
        
           
        //collision detection and reaction
        if((obst1_pos_x==event_horizont)&&(ship_pos_y>=obst1_pos_y-obst1_width && ship_pos_y<=obst1_pos_y+obst1_width)){
                    collision=true;
        }
        if(obst2_pos_x==event_horizont&&(ship_pos_y>=obst2_pos_y-obst2_width && ship_pos_y<=obst2_pos_y+obst2_width)){
                    collision=true;
        }
        if((obst3_pos_x==event_horizont)&&(ship_pos_y>=obst3_pos_y-obst3_width && ship_pos_y<=obst3_pos_y+obst3_width)){
                    collision=true;
        }
        
        if(collision)matrix.fillCircle(event_horizont,ship_pos_y,2,matrix.Color333(0,3,4));
        collision=false;
        
        //print on LED Matrix
        matrix.swapBuffers(false);
        itstime=false;
    }
}

The breathing green indicates that your code may be blocking the cloud housekeeping from being done for more than 10sec somewhere.

As a quickfix try adding SYSTEM_THREAD(ENABLED) and for a proper fix, try to find the place where the blocking happens.

I’d also wrap the Particle.connect() statement in your loop() into something like this

void loop()
{
  if (!Particle.connected())
  {
    Particle.connect();
    waitUntil(Particle.connected);
  }
  ...
}

Otherwise if you actually lose connection the permanent retriggering a connection attempt while another one is still running will prevent the connection for a long time.
But in default AUTOMATIC mode Particle.connect() will not be required, unless you’ve got a Particle.disconnect() or WiFi.off() somewhere.

BTW, using arrays in your code instead of all these dedicated but sameish variables (starX_… & obstY_…) would help making that code a lot more flexible and maintainable :wink:

2 Likes

Thx for the quick answer… i will tr it out

1 Like