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); 
 }}}
asked Feb 16, 2018 at 15:46
7
  • you may want to fix your identation, that will help clarify the logic flow of each function Commented Feb 16, 2018 at 15:52
  • I present you the "?:" operator: lumtxt = digitalRead(relay) ? "On" : "Off"; Commented Feb 16, 2018 at 15:58
  • 3
    At a quick guess I'd say your heap is swiss cheese. Ditch String. Commented Feb 16, 2018 at 16:09
  • i will rework that to made it more digest xD sry, let me few min :) Commented Feb 16, 2018 at 16:10
  • 1
    your code is horribly formatted ... it is a mess ... it is very difficult to determine how all the parts interact Commented Feb 16, 2018 at 20:39

2 Answers 2

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/

answered Feb 16, 2018 at 16:22
7
  • Are you saying that Arduino doesn't merge back contiguous RAM blocks? Commented Feb 16, 2018 at 16:24
  • No, but often some other action takes place that puts another block on the heap. Commented Feb 16, 2018 at 16:33
  • That s seem s realy logical ! i will dig this and apply the change :) Commented Feb 16, 2018 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 ; Commented Feb 16, 2018 at 19:58
  • 1
    You can't use + to concat c-style strings. Use strncat(). Commented Feb 16, 2018 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

answered Feb 28, 2018 at 12:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.