Smartlamp FREEZE ISSUE

Having some trouble with a smartlamp I’ve created. It keeps freezing - i.e. won’t change function after 5 minutes on one function. Any suggestions?

// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>





SYSTEM_MODE(AUTOMATIC); //tell particle to use automatic WIFI mode.

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_COUNT 16
#define PIXEL_PIN D2
#define PIXEL_TYPE WS2812B

int buttonstate = 0;
int brightness = 0;
int i=0;
int n=0;
int button=D0;
int flashes=5;
//tell the photon about the strip we're using. In this case a 12 pixel ring
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

//The setup function runs once.
void setup()
{
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  allpixelsoff();
  Particle.subscribe("smartlight", myHandler);
  Particle.function("smartlight", smartlight);
  RGB.control(true); // take control of onboard RGB led
}


/*void loop(){
    
  RGB.color(0,50,0);
  checkbutton();
  if (buttonstate>0) lampon();
  else if (buttonstate==0) allpixelsoff();
}*/

int smartlight(String command)
{

  if(command == "lamp")
  {buttonstate=buttonstate+1;
  lampon();
    return 1;
  }
  if(command == "allpixelsoff")
  {buttonstate=buttonstate=0;
  allpixelsoff();
    return 1;
  }
  if(command == "doorbell")
  {doorbell();
    return 1;
  }
  if(command == "redmood")
  {mood_Red();
    return 1;
  }
  if(command == "greenmood")
  {mood_Green();
    return 1;
  }
  if(command == "yellowmood")
  {mood_Yellow();
    return 1;
  }
  if (command == "purplemood")
  {mood_Purple();
    return 1;
  }
  else if(command == "gmail")
  {gmail();
    return 1;
  }
  else if(command == "bright")
  {levelthree();
    return 1;
  }
  else if(command == "dim")
  {levelone();
    return 1;
  }
  else if(command == "phone")
  {phone();
    return 1;
  }
  else return -1;
}


void checkbutton(){
    if(button==HIGH){
    while (button==HIGH) {}
        buttonstate=buttonstate+1;
    }
    if (buttonstate>3){buttonstate=0;}
}


void lampon(){ //switches lamp on to one of three levels or off.
 if (buttonstate>3){buttonstate=0;}
 if (buttonstate==1){ brightness=100;}
 else if (buttonstate==2){ brightness=180;}
 else if (buttonstate==3){ brightness=250;}
 else if (buttonstate==0){ brightness=0;}


	delay(100);
 for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(brightness, brightness, brightness));
};
strip.show();
}


void allpixelsoff() { //this switches all the pixels off
    delay(100);
        for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(0, 0, 0));
      strip.setPixelColor(i, strip.Color(0, 0, 0));
      strip.setPixelColor(i, strip.Color(0, 0, 0));
      strip.setPixelColor(i, strip.Color(0, 0, 0));
      strip.setPixelColor(i, strip.Color(0, 0, 0));
    
};
strip.show();

}

void levelone() { //this switches to level one
	delay(100);
	allpixelsoff();
	delay(100);
        for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(100, 100, 100));
};
strip.show();

}

void leveltwo() { //this switches to level two
	delay(100);
	allpixelsoff();
	delay(100);
        for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(180, 180, 180));
};
strip.show();

}

void mood_Red() { //this switches to level two
	allpixelsoff();
	delay(100);
        for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(250, 0, 0));
};
strip.show();
delay(500);

}

void levelthree() { //this switches to level 3
	delay(100);
	allpixelsoff();
	delay(100);
        for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(250, 250, 250));
};
strip.show();

}

void doorbell() { 
    allpixelsoff();
	delay(100);
  for(n=0; n<flashes; n++) {
  
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(0, 0, 250));
    };
    strip.show();
    delay(500);
  
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(0, 0, 50));
    }
    strip.show();
    delay(500);
  }
allpixelsoff();
lampon();
}

void phone() { 
    allpixelsoff();
	delay(100);
  for(n=0; n<flashes; n++) {
  
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(0, 250, 0));
    };
    strip.show();
    delay(500);
    
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(0, 100, 0));
        }
    
    }
    strip.show();
    delay(500);
    allpixelsoff();
    lampon();

}

void gmail() { 
    allpixelsoff();
	delay(100);
  for(n=0; n<flashes; n++) {
  
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(250, 0, 0));
    };
    strip.show();
    delay(500);
    
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(100, 0, 0));
    }
    strip.show();
    delay(500);
    allpixelsoff();
    lampon();
    }
}

void mood_Yellow() {
    allpixelsoff();
	delay(100);
    for (n=0; n<flashes; n++) {
    
       for (i=0; i<strip.numPixels(); i++ ){
        strip.setPixelColor(i, strip.Color(250,250,0));
        };
    strip.show();
    delay(500);
    
}
}

void mood_Green() {
    allpixelsoff();
	delay(100);
    for (n=0; n<flashes; n++) {
        
        for (i=0; i<strip.numPixels(); i++){
            strip.setPixelColor(i, strip.Color(0,0, 250));
        };
    strip.show();
    delay(500);
    
}
}
    
void mood_Purple() {
    allpixelsoff();
	delay(100);
    for (n=0; n<flashes; n++) {
    
        for (i=0; i<strip.numPixels(); i++ ){
        strip.setPixelColor(i, strip.Color(250,0,250));
        };
    strip.show();
    delay(500);

    }
}

//   allpixelsoff();
//   lampon(); 





void myHandler(const char *event, const char *data)
{


  if (strcmp(data,"doorbell")==0) {
    doorbell();
  }
  
  else if (strcmp(data,"phone")==0) {
    phone();
  }
}  

@tim, welcome to the forum! To help you, a little more information would be great. Which DeviceOS is on the Photon? Which “one” function is no longer responding?

@peekay123 Hi -

My Photon is running 0.6.2. The issue I have is that if I call a function (any of them), leave the ‘smartlamp’ alone for a while, and come back, I try to call another function. Nothing happens when I try this. The neopixels either remain ‘blue’ or ‘red’ etc. or only the bottom pixels change - I normally call the functions through tasker, or IFTTT via a webhook.

Thanks

@tim, first, you may want to update your DeviceOS to the latest v1.0.1. Second, make sure you are using the latest neopixel library. This is not done automatically for you. Third, I would strongly suggest keeping your actual effects code out of the Particle.function() call and instead set a “command” which a simple FSM in loop() waits on. Once a command is set, the FSM performs the actual lighting effect and then goes back to waiting for the next command. This ensures you are not spending too much time in your function call. Finally, you may want to consider using SYSTEM_THREAD(ENABLED);.

Then, if things are still getting stuck, you can add Serial.print() statements in your code to see if it getting stuck anywhere.

1 Like

@peekay123, Thanks for your help! I’m quite new to Particle, so might you be able to explain how to keep my effects code in an FSM loop?

@tim, it’s not much of a Finite State Machine but you’ll get the idea. If you want to get clever, you would queue Particle.function() commands instead of just allowing one at a time. The following code is untested but should work:

enum commands {
	LAMP,
	ALL_OFF,
	DOORBELL,
	REDMOOD,
	GREENMOOD,
	YELLOWMOOD,
	PURPLEMOOD,
	GMAIL,
	BRIGHT,
	DIM,
	PHONE,
	NONE
};

int current_cmd;


int smartlight(String command)
{
	if (current_cmd != NONE)	// Return -1 if current command is still being process by loop()
		return -1;

	if(command == "lamp") {
		buttonstate=buttonstate+1;
		current_cmd = LAMP;
	}
	else if(command == "allpixelsoff") {
		buttonstate=buttonstate=0;
		current_cmd = ALL_OFF;
	}
	else if(command == "doorbell") {
		current_cmd = DOORBELL;
	}
	else if(command == "redmood") {
		current_cmd = REDMOOD;
	}
	else if(command == "greenmood") {
		current_cmd = GREENMOOD;
	}
	else if(command == "yellowmood") {
		current_cmd = YELLOWMOOD;
	}
	else if (command == "purplemood") {
		current_cmd = PURPLEMOOD;
	}
	else if(command == "gmail") {
		current_cmd = GMAIL;
	}
	else if(command == "bright") {
		current_cmd = BRIGHT;
	}
	else if(command == "dim") {
		current_cmd = DIM;
	}
	else if(command == "phone") {
		current_cmd = PHONE;
	}
	else {
		return -1;
	}

	return 1;
}


void loop(){
    
	if (current_cmd != NONE) {	// Check if new command is available
		switch(current_cmd) {
			case LAMP:
				lampon();
				break;
			case ALL_OFF:
				allpixelsoff();
				break;
			case DOORBELL:
				doorbell();
				break;
			case REDMOOD:
				mood_Red();
				break;
			case GREENMOOD:
				mood_Green();
				break;
			case YELLOWMOOD:
				mood_Yellow();
				break;
			case PURPLEMOOD:
				mood_Purple();
				break;
			case GMAIL:
				gmail();
				break;
			case BRIGHT:
				levelthree();
				break;
			case DIM:
				levelone();
				break;
			case PHONE:
				phone();
				break;
			default:
				break;
		}
		current_cmd = NONE;		// Reset current command to NONE once completed
	}
}

Just for nit-picking, the return value of a Particle.function() should preferably also report back what it understood, not only that it understood something.
A minor change could look like this and actually provide some useful feedback about the function call itself

int smartlight(String command)
{
  ...

  return current_cmd; // tell the caller which choice was made
}
3 Likes

@ScruffR oustounds me with his intelligence most, if not all of the time! :wink:

3 Likes

:flushed: I’d rather claim the proverbial :corn: found by the blind :chicken: :blush:

2 Likes

Thanks for the tip :slight_smile: