SOLVED -- Why Arduino freezes around in 24 hours

Hi, I've a code for automatic irrigation system. It uses RTC module for time, ESP8266 module for remote control and communication, flowmeter to measure the amount of water used, DHT module for temp/humidity preview, 16*2 LCD, several buttons etc.

So when system is powered Arduino starts with menu=1, so it loops in function displayDateAndTime() until any alarm starts or any button is pressed. During this it displays date and time on the screen and checks serial input for any command. If it gets any command, it process it. The serial is connected to ESP8266 which is connected to Blynk.

I generally do not do anything after I start up the arduino, just let it work itself.

There are 8 different alarm times to activate pump. 1 timer for screen light out, 1 timer for alarm duration, 1 extra alarm for RTC/Arduino time synchronization. When one of 8 alarms is activated it pulls pin 6 high which runs a pump and creates an timer for 1:45minutes. Pin 6 should be pulled down when timer expires.

In 20%-30% of the times it works ok without any problems. But 70%-80% of the times, I see problems. How it happens is, first alarm is working correctly, pump runs, time is counting on lcd correctly, after 20 to 80seconds, I see that time on LCD is frozen and alarm is not deactivated if time is up.

As a precaution, I've added a watchdog timer. In all my menus/loops, I've watchdog reset. If arduino freezes and does not loop within 8 seconds, watchdog is not resetted so it triggers arduino reset. So at least it does not cause pump run for hours, but I need to find out the reason.

I was suspected that code causes constant increase in RAM usage which causes it to freeze after some time. For this purpose, I send available RAM amount from serial to Blynk every time alarm started. I see that Arduino has around 1050bytes of RAM available. I can trigger arduino to print RAM amount manually, and in any part of the code I see that RAM is between 1040-1070bytes. So it shouldnt be RAM problem.

I was suspected that loose jumper cables might cause this, however when everything works ok, I moved cables a lot manually and it does not create any problems.

One more thing, this hardware is working correctly when I'm using an older code. So it should be a coding issue.

Please find Arduino code, ESP8266 code, circuit drawing and circuit photo attached. Note that cables are put on pump driver on purpose to show from where to where they go, normally they are hanged from sides.


Edit: Thanks for everybody who helped me to find out the cause of this problem, specially to cattledog who was the one pointing out the main reason.

It happened to be that the main reason of this problem was the code below:
transferVolume = flowPulses * 1,5;

I should have used full stop instead of comma. After this fix system works fine without any freezing for last 48 hours.

Additionally I've learned that IDE is hiding warnings during compile process, shows only errors. When you enable all warnings you see any problem in your code. After enabling all warnings I've seen that this problem was also pointed out by IDE as well. Just open IDE, go to File-Preferences, and enable ALL warnings and thats it.

Irrigation_Flowmeter_Blynk.ino (20.3 KB)

Huzzah_Print_Irrigation_Volume.ino (1.05 KB)

How have you hooked the whole thing up ?

ESP8266 is not an Arduino.

jremington:
ESP8266 is not an Arduino.

Yes, of course I know ESP8266 is not an Arduino. I dont know why did you think that but if you think it is the one that freezes, it is not. ESP8266 works normally while Arduino freezes itself.

Deva_Rishi:
How have you hooked the whole thing up ?

Is there anything special that you are suspected? I dont have a connection scheme that I can share yet but if there is any special part you are suspected I can list the connection of that part only.

Main I/O connections are connected correctly as written in the sketch below and they all work fine under normal conditions.

#define flowMeter 3               //Assign Pin 3 for Flow Meter
#define nextMenu 4              //Assign Pin 4 to Next Menu Button
#define change 5                  //Assign Pin 5 for Change Button
#define alarmOut 6               //Assign Pin 6 for Alarm Output
#define plus 7                       //Assign Pin 7 for + Button
#define minus 8                    //Assign Pin 8 for - Button
#define temp 9                     //Assign Pin 2 to Temperature/Humidity Sensor
  • All I2C modules are connected through A4 and A5 pins.
  • ESP8266 is connected to Arduino via TX/RX(Crossed).
  • ESP8266 is powered from a separate usb power but its ground is connected to Arduino's GND.
  • All modules are(LCD, RTC, DHT,..) are powered from a separate 5V source but Arduino's 5V output is also connected to the same rail.
  • There is a logic level converter in between ESP8266/Arduino, it is powered from Arduino's 3.3V output.

What code is running on the Arduino, and which Arduino is it?

You waste an incredible amount of RAM by not putting constants in program memory.

What does the ESP8266 have to do with anything?

Is there anything special that you are suspected? I dont have a connection scheme that I can share yet but if there is any special part you are suspected I can list the connection of that part only.

Nothing in particular. just the same as the others it wasn't clear to me what the ESP has to with it all and what the connections really are would clarify that. Anyway, since it all works initially let's not worry to much about it, but the more info we have the better. Since there is no code for the ESP (and we don't know which one you are using) the possibility exists that it is flooding the Arduino (eh which one it is ? an UNO ? ) with data, since you could disconnect it without any issue as far as i can tell and do the Serial communication via USB directly, the way to eliminate that as the issue is obvious.

  • All modules are(LCD, RTC, DHT,..) are powered from a separate 5V source but Arduino's 5V output is also connected to the same rail.

so the Arduino is also powered through that 5v. Ok.
For the rest i don't see anything obvious, even if any of the buffers overflow, so what ? The LCD takes up quite a lot of time to be written to, which does disable the other devices on the I2C, but if that is really an issue it would probably show up a lot quicker. Which in the end leaves the alarms. So is there a way of eliminating that as a possible cause ?

jremington:
What code is running on the Arduino, and which Arduino is it?

You waste an incredible amount of RAM by not putting constants in program memory.

What does the ESP8266 have to do with anything?

It is Arduino Uno R3. The code is attached to my first post. It is long hence I didnt copy paste it directly.

ESP is listening Serial Port and send it to Blynk. Additionally I'm using ESP to send serial commands from Blynk, for example I send code x to manually activate output remotely.

What do you mean by putting constants in program memory? How would I do that? Can you give an example?

I just realised that after around 70 seconds I've repowered arduino, the LCD starts struggling. Instead of organised date, time and DHT info, I start to see different numbers/characters. Arduino still works when this happens, alarms work correctly, serial communication is ok, but LCD is showing strange characters. I believe this might be the main problem which causes arduino to freeze after some time.

1 Like

gunaygurer:
I just realised that after around 70 seconds I've repowered arduino, the LCD starts struggling. Instead of organised date, time and DHT info, I start to see different numbers/characters. Arduino still works when this happens, alarms work correctly, serial communication is ok, but LCD is showing strange characters. I believe this might be the main problem which causes arduino to freeze after some time.

can you remove the LCD from the I2C ? and address the pins directly ?

Deva_Rishi:
can you remove the LCD from the I2C ? and address the pins directly ?

LCD is presoldered with I2C module so I cannot do it easily.

By the way I'm trying to put as much data as I can into flash memory. Using PROGMEM in the below part of the code only reduced RAM usage from 52% to 46%.

const char PROGMEM daysOfTheWeek[8][12] = {" ", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 

const byte PROGMEM alarmIcon[8] =       {B00000,B00100,B01110,B01110,B01110,B11111,B00100,B00000};
const byte PROGMEM temperatureIcon[8] = {B00100,B01010,B01010,B01110,B01110,B11111,B11111,B01110};  
const byte PROGMEM humidityIcon[8] =    {B00100,B00100,B01010,B01010,B10001,B10001,B10001,B01110};

Additionally as I'm doing lcd.print once a second, I believe it would also make sense to use lcd.print(F("something")); My question here is will it consume extra space from flash every time this code run so I consume flash memory more and more every second?

Ok I've made several changes and now it looks ok. At least Arduino does not start showing random characters after around 70 seconds. But of course I dont know if it is fixed permanently or if it will show up within a couple of hours or days.

Anyway, here is what I did.

I've removed usage of weekday as it is a big array. Tried to use PROGMEM to save weekdays to flash and recall it. It is easy to save but not easy to recall for me because of my lack of experience. As it is not so important to see day on screen, I just removed it until when I learn how to recall it from PROGMEM.

I used lcd.print(F("...")); and Serial.print(F("...")); instead without F to save some RAM.

Before I was showing temperature and humidity on the main screen, now I've moved it to another screen, so I wont constantly measuring it and print on screen which uses some ram as well. Just click menu button to preview temperature screen when I need.

Additionally I was constantly calculate transferVolume multiple times a second and print it. Now I dont make any calculation and reprint it when screen backlight is off because I cannot see anything anyway.

gunaygurer:
I just removed it until when I learn how to recall it from PROGMEM.

For future reference: avr-libc: <avr/pgmspace.h>: Program Space Utilities

char daysOfTheWeek[8][12] = {" ", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  //Create daysOfTheWeek array to assign day names

You are wasting a lot of space with the daysOfTheWeek array, there is no need to allocate 12 bytes when you only use 4 (3 characters plus the terminating null). There is also no need to have daysOfTheWeek[0] = " " to shift the array index to match weekday(), just subtract 1 from weekday() to get the correct index.

char daysOfTheWeek[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  //Create daysOfTheWeek array to assign day names

//adjust weekday() from 1-7 to 0-6
lcd.print(daysOfTheWeek[weekday() - 1]);

It can be done in PROGMEM, but finding the correct syntax to read it back easily in the lcd.print statement can take a bit of searching.

const char daysOfTheWeek[7][4] PROGMEM = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  //Create daysOfTheWeek array to assign day names

lcd.print((__FlashStringHelper*)daysOfTheWeek[weekday()-1]);

One major problem I see in the code is that the variable used in the interrupt service routine, flowPulses, is declared as an int, which is two bytes of storage. Whenever you access that variable in the main code, you need to temporarily disable interrupts to avoid an interrupt occurring between the access of the 1st and 2nd byte.

Dear Dougp, thanks for sharing the link. I'll certainly read it.

Dear david_2018, I had no idea about the reason of assigning number 12 for day names. I was guessing it was to match the day names correctly within different weeks of 12 months :)) Now I understand that it was just to state the length of day names.

I definitely want to try PROGMEM for lcd.print of weekdays but as you said it is a bit of a hassle for me for now, I need to do some search, understand the basics so I can use it.

I'm not sure of the reason for using 12 as the size for the days of the week either, probably a left-over from when someone was using the full name for each day, and possibly in a foreign language because some characters that are not part of the standard ascii set take more than a single byte to store.

I wouldn't think you would be having problems caused by lack of ram, you are not using any String variables, which can be a major source of memory problems, and I don't see anything that would be allocating large memory buffers. How do you have everything connected? If you are using a breadboard for wiring everything together there may be some intermittent connections causing problems. Something else that will cause a program to freeze up or act erratically is to exceed the bounds of an array.

Unfortunately the problem continues after all the improvements.

Here is how it happens.

First I start to see extra characters on lcd. I also can see that LCD prints the right content on the wrong place for a short period of time. For example, date is printed on the first line of lcd, time is printed on the second line. When Arduino just starts to fail, I can see that there are extra characters/symbols in the first line and date is printed on the second line(for a second maybe). Then everything starts to be more corrupted and unreadable.

When I see extra characters on the screen, I might still have Arduino communicating with ESP8266 through serial correctly. When I send commands it is processed and replied correctly. But after some time Arduino becomes completely irresponsive.

Sometimes I see that there is nothing printed on lcd. As it takes some time to happen, lcd backlight is already off(because of screentimeout timer) and I dont know if lcd is completely gone or if nothing is printed.

About the connections, I'm still using breadboard, I'll be able to solder them in 2 weeks when I've prototype board on hand. Just to make sure it is not a loose connection problem, I restarted Arduino, moved all the cables and it didnt cause any problems.

I'm more interested in your arrays theory. Can you please check the arrays in my code if there is any problem on them? I'm adding the recent version of the code as an attachment.

Irrigation_Flowmeter_Blynk.ino (17.3 KB)

Unfortunately the problem continues after all the improvements.

You forgot to post the code.

I attached it to my last post, cannot put it here as it exceeds maximum character limit.

How are you powering everything? I really don't see anything that sticks out in the code, and since I already had an uno with an RTC and LCD hooked up here, have had your earlier code running displaying the time/temp/humidity for several hours with no problems.