1

i have an arduino, an RTC (time), a DHT (humidity and temp sensor), oled screen (128x32 ; microoled 1306) and 4 relais ;

all seems to work perfectly for hours, but sometime (1 or 2 per day..) everything stop working ;

  • screen i frozen on last info displayed
  • relais stay stuck in a random position (somtimes turning everythings ON (on=LOW with thoses relay.))

i obviously made a mistake, but don t know what... what can cause a loop to stay stuck randomly ??? plz save me :)

EDIT => A REWORK OF THAT TERRIBLE CODE AVAILABLE IN ANSWER, THE PROBLEM IS STILL THERE

// GND GND
// A4 SCL
// A5 SDA
// VCC  5V

// for DHT11, 
//      VCC: 5V or 3V
//      GND: GND
//      DATA: A7+

// YL-39 + YL-69 humidity sensor
const byte humidity_sensor_pin = A1;
const byte humidity_sensor_vcc = 6;


// ecran SDA / SDL
// RELAIS Pin D8
// RELAIS2 Pin D9
// RELAIS3 Pin D10
// RELAIS4 Pin D11

// Relais reboot D5 ?

#include <SimpleDHT.h>
#include <Wire.h>
#include "U8glib.h"
#include "RTClib.h"

const int pinDHT11 = 7;
 SimpleDHT11 dht11;

RTC_DS1307 RTC;
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);


const int relay = 8; // Light
const int relay2 = 9; // Wind
const int relay3 = 10; // Heat
const int relay4 = 11; // Humidity

// Time Variable
DateTime InitTime ;
int InitHour;

const int startHour = 20;
const int startMin = 01;
const int startTime = startHour *100 + startMin;
const int endHour = 8;
const int endMin = 01;
const int endTime= endHour *100 + endMin;
const int maxWind = 5;
const int startWind = 05;
int lastWind ;

const int dayMinTemp = 18;
const int dayMaxTemp = 20;
const int nightMinTemp = 16;
const int nightMaxTemp = 19;

const int minhum = 50;

void drawInit(DateTime InitD){
String text = String(InitD.day());
  text += " ";
text += String(InitD.month());

String text2 = String(InitD.hour());
  text2 += ":";
text2 += String(InitD.minute());
text2 += ":";
text2 += String(InitD.second());

 u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(0,16);
  u8g.print(text); 
  u8g.setPrintPos(0,32);
  u8g.print(text2); 

}
void drawTemp(float temp, int hum, int nowT){
String text = "Temp: ";
  text += temp;
    text += "*C";
String text2 = "Hum: ";
  text2 += hum;
    text2 += "% :";
    text2 += nowT;

 u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(0,16);
  u8g.print(text); 
  u8g.setPrintPos(0,32);
  u8g.print(text2); 
}

void draw(String staT, String endT, String nowT){
String iotxt;
if (digitalRead(relay) == LOW){iotxt="On";}else{iotxt="Off";}

String text = "S: ";
  text += staT;
  text += " E: ";
  text += endT;
String text2 = "H: ";
  text2 += nowT;
//  text2 += " L: ";
//  text2 += iotxt;

  u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(0,16);
  u8g.print(text); 
  u8g.setPrintPos(0,32);
  u8g.print(text2); 
}

void drawerror(String error){ 
  String text = "err mod: ";
  text += error;

  u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(0,16);
  u8g.print(text); 

}

void draw2(int nowTime){ 
  String iotxt;
  String hottxt;
  String lumtxt;
    String humtxt;

if (digitalRead(relay) == LOW){lumtxt="On";}else{lumtxt="Off";}
if (digitalRead(relay2) == LOW){iotxt="On";}else{iotxt="Off";}
if (digitalRead(relay3) == LOW){hottxt="On";}else{hottxt="Off";}
if (digitalRead(relay4) == LOW){humtxt="On";}else{humtxt="Off";}



String text = "Hot: ";
  text += hottxt;
  text += " Lum: ";
  text += lumtxt;


String text2 = "Hum: ";
  text2 += humtxt;
  text2 += " Win: ";
  text2 += iotxt;

  u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(0,16);
  u8g.print(text); 
  u8g.setPrintPos(0,32);
  u8g.print(text2); 
}

void setup () {



 pinMode(relay, OUTPUT);
 pinMode(relay2, OUTPUT);
 pinMode(relay3, OUTPUT);
 pinMode(relay4, OUTPUT);
 digitalWrite(relay, HIGH);
 digitalWrite(relay2,HIGH);
 digitalWrite(relay3,HIGH);
 digitalWrite(relay4,HIGH);


    Serial.begin(9600);
    Wire.begin();

    if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  RTC.begin();

   DateTime now = RTC.now(); 
 InitTime = now ;
InitHour =  now.hour()*100 + now.minute();
}

void loop () {

 byte temperature = 0;
  byte humidity = 0;

int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(pinDHT11, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
//    Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);

    u8g.firstPage();
  do {  
    drawerror("DHT");
  } while( u8g.nextPage() );
delay(3000); 

    return;
  }else{

  // Serial.print("Sample OK: ");
 // Serial.print((int)temperature); Serial.print(" *, "); 
 // Serial.print((int)humidity); Serial.println(" H");

// Relay Chaleur
if (digitalRead(relay)==LOW){
if((int)temperature < dayMinTemp){
   digitalWrite(relay3,LOW);
   //  Serial.print("HEAT : On"); 

  }else{digitalWrite(relay3,HIGH);
     //  Serial.print("HEAT : Off"); 
}  
  }else{
    if((int)temperature < nightMinTemp){
   digitalWrite(relay3,LOW);
     //   Serial.print("HEAT : On"); 

}else{
      digitalWrite(relay3,HIGH);
   //  Serial.print("HEAT : Off"); 

      }
    }
// fin relay chaleur

  if (! RTC.isrunning()) {
    drawerror("RTC");}else{

   DateTime now = RTC.now(); 

int nowTime= now.hour()*100 + now.minute();

// § WIND
if(now.minute() >= startWind && now.minute() <= startWind+maxWind ){
      digitalWrite(relay2,LOW);
     // Serial.println("Wind ON");
      lastWind = nowTime;

  }else if(now.minute()>startWind+5 || now.minute()<startWind){
          digitalWrite(relay2,HIGH);
    //  Serial.println("Wind OFF");
      }

// § END WIND

// START humidity
if(int(humidity)<minhum){
      digitalWrite(relay4,LOW);

  }else{    digitalWrite(relay4,HIGH);
  }
//
// § LIGHT START

if(startTime<endTime){
  if(startTime <= nowTime && endTime >= nowTime){
      digitalWrite(relay,LOW);
    //  Serial.println("Light ON");
  }else{
      digitalWrite(relay,HIGH);
//      Serial.println("Light OFF");
}}else{
  if(endTime <= nowTime && startTime >= nowTime){

      digitalWrite(relay,HIGH);
  //    Serial.println("Light OFF");
  }else{
          digitalWrite(relay,LOW);
    //  Serial.println("Light ON");
    }}

//  if(nowTime >= startTime && nowTime <= 2359){ 
//            digitalWrite(relay, LOW);  
//            Serial.println("Light ON");
//            }
//       else if(nowTime  < endTime ){
//            digitalWrite(relay, LOW);
//            Serial.println("LIGHT ON");}
//       else if(nowTime  >= endTime && nowTime  < startTime){
//            digitalWrite(relay, HIGH);        
//            Serial.println("Light OFF");}     
//      }
      // § LIGHT END

u8g.firstPage();
  do {  
    draw(String(startTime),String(endTime),String(nowTime));
  } while( u8g.nextPage() );
delay(3000); 

u8g.firstPage();
  do {  
    drawInit(InitTime);    
  } while( u8g.nextPage() ); 
 delay(3000); 

u8g.firstPage();
  do {  
    draw2(nowTime);    
  } while( u8g.nextPage() ); 
 delay(3000); 
u8g.firstPage();
  do {  
    drawTemp(float(temperature), int(humidity),int(NowT));    
  } while( u8g.nextPage() ); 
 delay(3000); 
    }}}
7
  • you may want to fix your identation, that will help clarify the logic flow of each function – ratchet freak Feb 16 '18 at 15:52
  • I present you the "?:" operator: lumtxt = digitalRead(relay) ? "On" : "Off"; – user31481 Feb 16 '18 at 15:58
  • 3
    At a quick guess I'd say your heap is swiss cheese. Ditch String. – Majenko Feb 16 '18 at 16:09
  • i will rework that to made it more digest xD sry, let me few min :) – Evans Padnom Feb 16 '18 at 16:10
  • 1
    your code is horribly formatted ... it is a mess ... it is very difficult to determine how all the parts interact – jsotola Feb 16 '18 at 20:39
3

While it makes logical sense to use the String type to hold strings of text, it's really a very poor choice for a low-RAM device like an Arduino.

You are using the string concatenation operator (+) a lot. The String type handles this by grabbing a new block of RAM that is equal to the sum of the 2 strings you are concatenating, puts the new string in that RAM, and marks the previous block of RAM that held one of the strings as empty and available for re-use.

The problem is that when you keep concatenating bits to the same string variable, it has to keep finding longer and longer continuous blocks of RAM into which to put the new string. All the previous blocks that are "available" for use, are also too short, as they are all the length of previous strings prior to your new, longer string requirement.

As @Majenko noted, this means your RAM is "swiss cheese" -- full of holes that can't be used by the program for more strings.

One solution is to avoid the String variable type and instead use what are called C-Style Strings - arrays of char type. It's a whole new, old world of doing things, and can be more challenging than the String type, but it has a distinct advantage of not shredding the device's RAM.

The C-style string world is ruled by monsters like strnlen() and strncpy(), and making sure you have remembered to allocate enough RAM at the start of your program, and making sure you null-terminate your array.

Of the myriad tutorials and descriptions on using C-style strings, one is at https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/

7
  • Are you saying that Arduino doesn't merge back contiguous RAM blocks? – user31481 Feb 16 '18 at 16:24
  • No, but often some other action takes place that puts another block on the heap. – jose can u c Feb 16 '18 at 16:33
  • That s seem s realy logical ! i will dig this and apply the change :) – Evans Padnom Feb 16 '18 at 16:50
  • arf, till a small problem, i don t achieve to concat in any way my char[] and my INT :/ char screen[16] ; char text[3] = "abc" ; int i = 12 ; screen[16] = text + i ; – Evans Padnom Feb 16 '18 at 19:58
  • 1
    You can't use + to concat c-style strings. Use strncat(). – jose can u c Feb 16 '18 at 19:59
0

after rewrite all code, rewire all relay, bypass the relay card (using another relay), the problem is still there, but i finally found other people with the same problem, and the solution seem to be adding a "snubber" on each relay, i m waiting for it and will give u a return if it work : link to arduino forum for a common problem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.