Arduino gets hung after adding serial.available

Hi everyone,

I currently have an arduino mega that controls my fish tank, it prints data to a raspberry pi that creates a log and gives me wifi access to the system…

I recently setup a function where the raspberry pi sends data to the arduino in order to do basic functions like turning on/off the LCD backlight and running the lights for a couple of minutess… Everything works fine but after some time (hours) the arduino gets hung, I have to remove the power completley and it will work fine for some time… The watchdog timer doesnt really work since I have a capacitor in the Reset pin so that the arduino didnt reset everytime the raspberry pi opened the serial port.

Here is the function:

void backlight() //checks the LM35 temp and average_leds to smooth the value
{

  if (Serial.available()) {
    inByte = Serial.read() - '0';  
    
    if (inByte == 0){
      lcd.noBacklight();
      Serial.flush();
    }
    else if (inByte ==1){
      lcd.backlight();
      Serial.flush();
    }
    
    else if (inByte ==2){
      
      lcd.backlight();
      digitalWrite(relay_1, LOW);
      digitalWrite(relay_2, LOW);
      digitalWrite(relay_3, LOW);
      delay(500);
      
      analogWrite(blue, 215);
      analogWrite(white, 255);
      analogWrite(var, varmin);
      
      int countdown = 60;
        while (countdown>0)
        {
          onesecond(); // updates clock once per second
          //temperature();
          countdown--;
          relay1();
        }
       
      lcd.noBacklight(); 
      inByte = 0;
      Serial.flush();
  
    }
  }
}

If I remove this funcitons it works fine, I recenlty added the flush to see if it helped (it didint)… Now im thinking maybe the arduino is receiving noise or something and doesnt know what to do with it??

Anything I’m missing?
Thanks!

The Serial.flush won't do you any good. From the reference pages :

Waits for the transmission of outgoing serial data to complete.

void backlight() //checks the LM35 temp and average_leds to smooth the value

I do love it when comments help me understand the purpose of a function that has a name that could confuse me.

As to your problem it is difficult to offer advice without seeing all of your code. How/when/how often is the function called for instance ?

Why not a Serial.print (inbyte); and see what you're getting? Same for the if( )s, see which one it is going into.

Hehe I know, I noticed the comment after I posted… I was too lazy and copied another function and then edited…

The backlight functions get called very often, more like always… So when I serial.write from the raspberry the change is done “instantly”… The function works properly, it goes in to the “if” it needs to, maybe printing out the inByte will give a heads up! Thanks

Here is the code, without all the functions, since its a bit long:

/* ******************************************************************************************************************** */
/* *                                                                                                                  * */
/* *                                 L O O P                                                                          * */
/* *                                                                                                                  * */
/* ******************************************************************************************************************** */




void loop()
{
  onesecond();
  backlight();
  relay1();
  lcd.setCursor(0, 1);
  lcd.print("Blue:");
  lcd.setCursor(8, 1);
  lcd.print("White:");
  //discoverOneWireDevices();

/* ******************************************************************************************************************** */
/* *                                                                                                                  * */
/* *                                 L O O P - D I M   F U N C T I O N                                                * */
/* *                                                                                                                  * */
/* ******************************************************************************************************************** */

  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  int daybyminute = ((hour * 60) + minute); //converts time of day to a single value in minutes
      

  int bluerampup;
     if (daybyminute >= (ontime*60)) 
       bluerampup = (((ontime*60) + blueramptime) - daybyminute);
     else
       bluerampup = blueramptime;
       
  int whiterampup;
    if (daybyminute >= (ontime*60 + blueramptime)) 
       whiterampup = (((ontime*60) + blueramptime + whiteramptime) - daybyminute);
     else
       whiterampup = whiteramptime;

  int whiterampdown;
    if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
      whiterampdown = (((ontime*60) + photoperiod + blueramptime + 2*whiteramptime) - daybyminute);
    else
      whiterampdown = whiteramptime;
      
  int bluerampdown;
    if (((ontime * 60) + photoperiod + blueramptime + 2*whiteramptime) <= daybyminute)
      bluerampdown = (((ontime*60) + photoperiod + 2*blueramptime + 2*whiteramptime) - daybyminute);
    else
      bluerampdown = blueramptime;



/* ******************************************************************************************************************** */
/* *                                                                                                                  * */
/* *                                 L O O P - F A D E  I N                                                           * */
/* *                                                                                                                  * */
/* ******************************************************************************************************************** */
if ((tempC_led < mt_led) && (tempC_led != 85.00)){
 if (daybyminute >= (ontime*60))
  { 
    if (daybyminute <= ((ontime*60) + blueramptime + (whiteramptime - 1))) //if time is in range of fade in, start fading in + (whiteramptime/10*9)
    {
      
      digitalWrite(relay_1, LOW);
      digitalWrite(relay_2, LOW);
      digitalWrite(relay_3, LOW);
      
      // fade blue LEDs in from min to max.
      lcd.setCursor(14,0);
      lcd.print(" ");  
      lcd.print("RISE");
      for (int i = 1; i <= 10; i++) // setting ib value for 10% increment. Start with 0% 
      { 
          analogWrite(blue, bluepercent[i]);
          analogWrite(var, varpercent[i]); 
          lcd.setCursor(5, 1);
          lcd.print(i);
          lcd.print(" "); 
          lcd.setCursor(14, 1);
          lcd.print("0");
          
          blueglobal = bluepercent[i];
          whiteglobal = whitepercent[0];
          
          /*Serial.print("Blue_: ");
          Serial.println(bluepercent[i]);
          Serial.print("White: ");
          Serial.println(whitepercent[0]);
          */
          
          int countdown = ((bluerampup*60)/10); // calculates seconds to next step
          while (countdown>0)
          {
          onesecond(); // updates clock once per second
          backlight();
          countdown--;
          relay1();
        }
      }      

      // fade white LEDs in from min to max.
      for (int i = 1; i <= 10; i++) // setting i value for 10% increment. Start with 0%
      { 
          analogWrite(white, whitepercent[i]); 
          lcd.setCursor(14, 1);
          lcd.print(i);
          lcd.print(" "); 
          lcd.setCursor(5, 1);
          lcd.print("10");
          
          blueglobal = bluepercent[10];
          whiteglobal = whitepercent[i];
          
          /*
          Serial.print("Blue_: ");
          Serial.println(bluepercent[10]);
          Serial.print("White: ");
          Serial.println(whitepercent[i]);
          */
          
          int countdown = ((whiterampup*60)/10); // calculates seconds to next step
          while (countdown>0)
          {
            onesecond(); // updates clock once per second
            backlight();
            countdown--;
            relay1();
        }
      } 
    }
  }
}

  
/* ******************************************************************************************************************** */
/* *                                                                                                                  * */
/* *                                 L O O P - M A X  V A L U E                                                       * */
/* *                                                                                                                  * */
/* ******************************************************************************************************************** */

if ((tempC_led < mt_led) && (tempC_led != 85.00)){
 if (daybyminute >= ((ontime * 60) + blueramptime + whiteramptime)) 
  { 
    if ( daybyminute <= ((ontime * 60) + blueramptime + whiteramptime + photoperiod)) // if time is in range of photoperiod, turn lights on to maximum fade value
    {

        digitalWrite(relay_1, LOW);
        digitalWrite(relay_2, LOW);
        digitalWrite(relay_3, LOW);
    
        lcd.setCursor(14,0);
        lcd.print(" "); 
        lcd.print(" "); 
        lcd.print("MAX");
        
        analogWrite(blue, bluepercent[10]);
        analogWrite(var, varpercent[10]);
        lcd.setCursor(5, 1);
        lcd.print(10);
        lcd.print(" ");
        analogWrite(white, whitepercent[10]); 
        lcd.setCursor(14, 1);
        lcd.print(10);
        lcd.print(" "); 
        
        blueglobal = bluepercent[10];
        whiteglobal = whitepercent[10];
        
        /*
        Serial.print("Blue_: ");
        Serial.println(bluepercent[10]);
        Serial.print("White: ");
        Serial.println(whitepercent[10]);
        */
        
        backlight();
      
    } 
  }
}

I notice the problem, mostly at night since the lights wont turn off…

You need to post all of your code - we don't know that you've called Serial.begin(), for instance, and can't tell from a snippet.

remaining code of main loop:

/* ******************************************************************************************************************** */
/* *                                                                                                                  * */
/* *                                 L O O P - F A D E  O U T                                                         * */
/* *                                                                                                                  * */
/* ******************************************************************************************************************** */

if ((tempC_led < mt_led) && (tempC_led != 85.00)){
  if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
  { 
    if (((ontime * 60) + photoperiod + whiteramptime + 2*blueramptime + (blueramptime/10*9)) >= daybyminute)
    {
     
      
      digitalWrite(relay_1, LOW);
      digitalWrite(relay_2, LOW);
      digitalWrite(relay_3, LOW);
   
      lcd.setCursor(14,0);
      lcd.print(" "); 
      lcd.print(" "); 
      lcd.print("SET");
      
      // fade white LEDs out from max to min in increments of 1 point:
      for (int i = 10; i >= 0; i--) // setting i value for 10% increment. Start with 10%
      { 
        analogWrite(blue, bluepercent[10]);
        analogWrite(var, varpercent[10]);
        lcd.setCursor(5, 1);
        lcd.print(10);
        lcd.print(" "); 
        
        analogWrite(white, whitepercent[i]); 
        lcd.setCursor(14, 1);
        lcd.print(i);
        lcd.print(" ");  
        
        blueglobal = bluepercent[10];
        whiteglobal = whitepercent[i];
        
        /*
        Serial.print("Blue_: ");
        Serial.println(bluepercent[10]);
        Serial.print("White: ");
        Serial.println(whitepercent[i]);
        */

        int countdown = ((whiterampdown*60)/10); // calculates seconds to next step
        while (countdown>0)
        {
          onesecond(); // updates clock once per second
          backlight();
          countdown--;
          relay1();
        }

      } 

      // fade blue LEDs out from max to min in increments of 1 point:
      for (int i = 10; i >= 0; i--) // setting i value for 10% increment. Start with 10%
      { 
        analogWrite(blue, bluepercent[i]);
        analogWrite(var, varpercent[i]);
        lcd.setCursor(5, 1);
        lcd.print(i);
        lcd.print(" ");
        lcd.setCursor(14, 1);
        lcd.print("0");
        lcd.print(" "); 
        
        blueglobal = bluepercent[i];
        whiteglobal = whitepercent[0];
        
        /*
        Serial.print("Blue_: ");
        Serial.println(bluepercent[i]);
        Serial.print("White: ");
        Serial.println(whitepercent[0]);
        */

        int countdown = ((bluerampdown*60)/10); // calculates seconds to next step
        while (countdown>0)
        {
          onesecond(); // updates clock once per second
          backlight();
          countdown--;
          relay1();
        }
      }
    } 
  }
}

another

/* ******************************************************************************************************************** */
/* *                                                                                                                  * */
/* *                                           N I G H T                                                              * */
/* *                                                                                                                  * */
/* ******************************************************************************************************************** */

   if((daybyminute >= ((night * 60) + 15)) || (((ontime*60) - 2) >= daybyminute)) {          

          digitalWrite(relay_1, HIGH);
          digitalWrite(relay_2, HIGH);
          digitalWrite(relay_3, HIGH);
          analogWrite(blue, 255);
          analogWrite(white, 255);
          analogWrite(var, varmin);
          
          blueglobal = bluepercent[0];
          whiteglobal = whitepercent[0];
          
          /*
          Serial.print("Blue_: ");
          Serial.println(bluepercent[0]);
          Serial.print("White: ");
          Serial.println(whitepercent[0]);
          */
          
          lcd.setCursor(14,0);
          lcd.print("NIGHT"); 

          lcd.setCursor(5, 1);
          lcd.print("N");
          lcd.print(" ");
          lcd.setCursor(14, 1);
          lcd.print("N");
          lcd.print(" "); 
          onesecond(); // updates clock once per second
          relay1(); 
          backlight();
          //temperature();
          //moonPhase(year, month, dayOfMonth);

  
    }
    
    if((tempC_led >= mt_led) && (tempC_led != 85.00)) {   //shutdown lights and leave relay_1 ON, in order to reduce temp
      
          digitalWrite(relay_1, LOW); //Fans
          digitalWrite(relay_2, HIGH); //Driver1
          digitalWrite(relay_3, HIGH); //Driver2
          analogWrite(blue, 255);
          analogWrite(white, 255);
          analogWrite(var, 0);
          lcd.setCursor(14,0);
          lcd.print(" "); 
          lcd.print("HOT");
          lcd.setCursor(5, 1);
          lcd.print("H");
          lcd.setCursor(14, 1);
          lcd.print("H");
          temperature();                //keep checking the temp
          relay1();
          onesecond();
          backlight();
          Serial.println("MAX TEMP");
          Serial.println("WARNING");
         
    }
    
  }  // END LOOP

Here is the setup, I missed the post asking about the serial.begin

/* ******************************************************************************************************************** */
/* *                                                                                                                  * */
/* *                                 S E T U P                                                                        * */
/* *                                                                                                                  * */
/* ******************************************************************************************************************** */

void setup() {
  
  pinMode(relay_4, OUTPUT);     // set the digital pin as output:
  pinMode(relay_1, OUTPUT); 
  pinMode(relay_2, OUTPUT);    
  pinMode(relay_3, OUTPUT); 
  pinMode(relay_5, OUTPUT);
  pinMode(relay_6, OUTPUT);
  pinMode(relay_7, OUTPUT);
  pinMode(relay_8, OUTPUT);
  pinMode(relay_vss, OUTPUT);
  pinMode(temp_vcc, OUTPUT); 
  
  pinMode(blue, OUTPUT);
  pinMode(white, OUTPUT); 
  pinMode(var, OUTPUT); 
  
  sensors.begin();
  sensors.setResolution(tankThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(lightThermometer, TEMPERATURE_PRECISION);
  
  wdt_enable(WDTO_2S); //watchdog timer value is set for 2 seconds, if the main loop doesnt complete in 2 seconds the arduino will reset
  delay(100);
  Serial.begin(9600);  //init serial for python interface
  
/* ******************************************************************************************************************** */
/* *                                                                                                                  * */
/* *                                 S E T U P - D I S P L A Y                                                        * */
/* *                                                                                                                  * */
/* ******************************************************************************************************************** */

  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  second = 0;
  minute = 29;
  hour = 11;
  dayOfWeek = 2;                        // Sunday is 0
  dayOfMonth = 02;
  month = 07;
  year = 13;


/* ********************************************************************************* */
/* *                                                                               * */
/* *     this is where you set your time...                                        * */
/* *     1) change the second, minute, hour, etc above                             * */
/* *     2) remove // below                                                        * */
/* *     3) and load this sketch to your arduino                                   * */
/* *     4) after loading the sketch, put the // back again                        * */
/* *     5) and load this sketch again to your arduino, and save                   * */
/* *                                                                               * */
/* ********************************************************************************* */
//setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);


  analogWrite(blue, bluemin);
  analogWrite(white, whitemin);
  analogWrite(var, varmin);
  
  lcd.begin(20, 4); // set up the LCD's number of rows and columns: 
  lcd.backlight();
  
  lcd.setCursor(0, 1);
  lcd.print("Blue:S");
  lcd.print(0);
  lcd.setCursor(8, 1);
  lcd.print("White:S");
  lcd.print(0); 
  lcd.setCursor(4,4);


  digitalWrite(relay_1, HIGH); //inverted logic HIGH=OFF, turn off all relays
  digitalWrite(relay_2, HIGH);
  digitalWrite(relay_3, HIGH);
  digitalWrite(relay_4, HIGH);
  digitalWrite(relay_5, HIGH);
  digitalWrite(relay_6, HIGH);
  digitalWrite(relay_7, HIGH);
  digitalWrite(relay_8, HIGH);
  digitalWrite(temp_vcc, HIGH);
  
  digitalWrite(relay_vss, LOW); //ground for relay board.
  
delay(500);

  
}

Anyone?

Posting code in snippets makes it hard to piece the whole sketch together. It's better to post the whole thing, either inline or as an attachment.