Arduino Mega RGBW sketch lock-ups
-
Hi everyone,
I have this current node controlling the lights and TV in my bedroom that works great, only problem is that on occasion it locks up for a period of time I cant identify, but its somewhere north of 30 minutes. If I just wait it will eventually go back to working, or I can pull the power, wait, plug it back in and it goes back to working. It doesn't happen at the same time of day, no real pattern that I can find. I can deal but it doesn't really pass the wife test as she can't reach it Anyone have any suggestions? (Also I'll take other optimizations if anyone has any, it's been running for 3 years on the current sketch)
/** Based on the MySensors Project: http://www.mysensors.org This sketch controls a (analog)RGBW strip by listening to new color values from a (OpenHab2) controller and then fading to the new color. Version 2.0 - Updated to MySensors 2 and changed fading Version 1.0 - Changed pins and gw definition Version 0.9 - Oliver Hilsky **/ #define SN "RGBW and TV" #define SV "v3.0 09112019" // library settings #define MY_RADIO_NRF24 #define MY_NODE_ID 22 #define MY_DEBUG // Enables debug messages in the serial log #define MY_RF24_CE_PIN 49 //atmega 2560 code #define MY_RF24_CS_PIN 53 //atmega 2560 code #define MY_RF24_PA_LEVEL RF24_PA_HIGH #include <SPI.h> #include <MySensors.h> #define RELAY_1 30 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) #define NUMBER_OF_RELAYS 1 // Total number of attached relays #define RELAY_ON 1 // GPIO value to write to turn on attached relay #define RELAY_OFF 0 // GPIO value to write to turn off attached relay #define SENSOR_ID 10 //RGBW Sensor ID // Arduino pin attached to driver pins #define RED_PIN 6 #define WHITE_PIN 8 #define GREEN_PIN 5 #define BLUE_PIN 7 #define NUM_CHANNELS 4 // how many channels, RGBW=4 RGB=3... // Smooth stepping between the values #define STEP 1 #define INTERVAL 10 // Stores the current color settings byte channels[4] = {RED_PIN, GREEN_PIN, BLUE_PIN, WHITE_PIN}; byte values[4] = {0, 0, 0, 255}; byte target_values[4] = {0, 0, 0, 255}; boolean isOn = true; // tracks if the strip should be on of off // time tracking for updates unsigned long lastupdate = millis(); void before() { for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { // Then set relay pins in output mode pinMode(pin, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF); } // Set all channels to output (pin number, type) for (int i = 0; i < NUM_CHANNELS; i++) { pinMode(channels[i], OUTPUT); } } void presentation() { // Present sketch (name, version) sendSketchInfo(SN, SV); for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { // Register all sensors to gw (they will be created as child devices) present(sensor, S_BINARY); } // Register sensors (id, type, description, ack back) present(SENSOR_ID, S_RGBW_LIGHT, SN, true); } void setup() { request(SENSOR_ID, V_RGBW); // get old values if this is just a restart updateLights(); // init lights Serial.println("Waiting for messages..."); } void loop() { // and set the new light colors if (millis() > lastupdate + INTERVAL) { updateLights(); lastupdate = millis(); } } // callback function for incoming messages void receive(const MyMessage &message) { Serial.print("Got a message - "); Serial.print("Messagetype is: "); Serial.println(message.type); // acknoledgment if (message.isAck()) { Serial.println("Got ack from gateway"); } // on / off message else if (message.type == V_STATUS) { if(message.sensor == SENSOR_ID) { Serial.print("Turning light "); isOn = message.getInt(); if (isOn) { Serial.println("on"); } else { Serial.println("off"); } }else { digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } } // new color value else if (message.type == V_RGBW) { const char * rgbvalues = message.getString(); inputToRGBW(rgbvalues); // a new color also means on, no seperate signal gets send (by domoticz); needed e.g. for groups isOn = true; } } // this gets called every INTERVAL milliseconds and updates the current pwm levels for all colors void updateLights() { // for each color for (int v = 0; v < NUM_CHANNELS; v++) { if (values[v] < target_values[v]) { //Serial.print("V+: "); //Serial.print(v); //Serial.print(" value/target value: "); //Serial.print(values[v]); //Serial.println(target_values[v]); values[v] += STEP; if (values[v] > target_values[v]) { values[v] = target_values[v]; } } if (values[v] > target_values[v]) { //Serial.print("V-: "); //Serial.print(v); //Serial.print(" value/target value: "); //Serial.print(values[v]); //Serial.println(target_values[v]); values[v] -= STEP; if (values[v] < target_values[v]) { values[v] = target_values[v]; } } } // set actual pin values for (int i = 0; i < NUM_CHANNELS; i++) { if (isOn) { analogWrite(channels[i], values[i]); } else { analogWrite(channels[i], 0); } } } // converts incoming color string to actual (int) values // ATTENTION this currently does nearly no checks, so the format needs to be exactly like domoticz sends the strings void inputToRGBW(const char * input) { Serial.print("Got color value of length: "); Serial.println(strlen(input)); if (strlen(input) == 6) { Serial.println("new rgb value"); target_values[0] = fromhex (& input [0]); target_values[1] = fromhex (& input [2]); target_values[2] = fromhex (& input [4]); target_values[3] = 0; } else if (strlen(input) == 8) { Serial.println("new rgbw value"); target_values[0] = fromhex (& input [0]); // ignore # as first sign target_values[1] = fromhex (& input [2]); target_values[2] = fromhex (& input [4]); target_values[3] = fromhex (& input [6]); } else { Serial.println("Wrong length of input"); } Serial.print("New color values: "); Serial.println(input); for (int i = 0; i < NUM_CHANNELS; i++) { Serial.print(target_values[i]); Serial.print(", "); } } // converts hex char to byte byte fromhex (const char * str) { char c = str [0] - '0'; if (c > 9) c -= 7; int result = c; c = str [1] - '0'; if (c > 9) c -= 7; return (result << 4) | c; }```
-
@gundark2 Maybe related to this thread?
https://forum.mysensors.org/topic/10750/mysensors-gateway-and-network-reliability/4
-
@gundark2 the sketchlooks good to me.
Best way would be if you can get the debug log for the time when it locks up.
-
@mfalkvidd I was afraid someone would say something about this avenue of debugging. I was "smart" enough to put all of the connections up high where I can't reach... I guess a next step could be to order a longer usb cable for the mega.
@skywatch Seeing your post here makes me remember when I tried to add a watchdog timer which didn't seem to work... But I thought that the problem persisting meant the watchdog wasn't working... but maybe there is something going on with this radio causing it to misbehave for a period of time...
-
@gundark2 a long usb cable, or something like https://www.aliexpress.com/item/32959138610.html or https://www.openhardware.io/view/532/The-Logger-Machine-Short-and-long-term-serial-logging