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;
    }```



  • Mod

    @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...


  • Mod


Log in to reply
 

Suggested Topics

  • 2
  • 35
  • 14
  • 2
  • 7
  • 14
  • 30
  • 2

142
Online

9.4k
Users

10.0k
Topics

104.3k
Posts