I'm not sure wether this is a LCD related problem or not.
I made a real nice garage-door-opener. (really proud on myself :)) see: http://www.instructables.com/id/The-iButton-garage-door-opener-Arduino/
It works great but after a while the screen freezes and the iButton doesn't work anymore. After I push one of the buttons, the LCD goes crazy.
Sometimes it works OK for hours and sometimes it fails in 15 minutes.
I suspect it is something with the LCD, but I don't understand why the iButton also doesn't work anymore.
Yes if I just keep it running without doing anything it goes crazy.
I hope you can see it on the pictures. The first picture gives strange text and when I push a button it start running crazy like on picture 2.
I thought of that also, but it also crashes when nobody entered and the strings are only 1 byte/piece. But I will try it anyway and let you know.
(I know the sketch is long, I wrote it ) But thank you for going through it.
I broke down the sketch to the bare minimum and it looks like it runs now. Little by little I want to introduce more and more code, until I find where it goes wrong. Until now it looks like it is working. It now just opens the door and shows the last person entering on the LCD, without date or time and without memory. I will run this for one more day and if it doesn't crash I will introduce more code.
#include <LiquidCrystal.h> //adding the LCD library
#include <OneWire.h> //adding the iButton library
LiquidCrystal lcd(11, 10, 5, 4, 3, 2); //the pins that the LCD is connected on
int knoptijd = 400; //setting all the variables for the clock part(sorry for the Dutch names)
OneWire ds(12); //setting the variables for the iButton part
byte addr[8];
int but3[6] = {0,235,75,138,9,0};
String name3 = "Peter ";
byte uit3 = 1;
int but5[6] = {0,87,171,46,13,0};
String name5 = "Jelle ";
byte uit5 = 1;
String keyStatus="";
byte welkeBut = 0;
String name = "";
int i = 0;
void setup() {
pinMode(7, OUTPUT); //opening the door
lcd.begin(20, 2); //set up the size of the LCD
}
void loop(){
delay(1000);
getKeyCode(); //getting the iButton code
testKeyCode(); //testing the iButton code
}
void getKeyCode(){ //getting the code from the iButton
byte present = 0;
byte data[12];
keyStatus="";
if ( !ds.search(addr)) {
ds.reset_search();
return;
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
keyStatus="CRC invalid";
return;
}
if ( addr[0] != 0x01) {
keyStatus="not DS1990A";
return;
}
keyStatus="ok";
ds.reset();
}
void testKeyCode(){ //check if the iButton presented is the right one
lcd.setCursor(0, 1);
if(keyStatus=="ok"){
if(addr[1] == but3[1] && addr[2] == but3[2] && addr[3] == but3[3] && addr[4] == but3[4] && uit3 == 1){welkeBut=3; name = name3;}
if(addr[1] == but5[1] && addr[2] == but5[2] && addr[3] == but5[3] && addr[4] == but5[4] && uit5 == 1){welkeBut=5; name = name5;}
if(welkeBut == 1 || welkeBut == 2 || welkeBut == 3 || welkeBut == 4 || welkeBut == 5){
lcd.print(name);
lcd.print(" ");
digitalWrite(7, HIGH);
delay(500);
digitalWrite(7, LOW);
}
if(welkeBut != 1 && welkeBut != 2 && welkeBut != 3 && welkeBut != 4 && welkeBut != 5){
digitalWrite(7, LOW);
lcd.print(" ");
lcd.setCursor(0, 1);
byte i;
for( i = 5; i >0; i--) {
lcd.print(":");
lcd.print(addr[i], DEC);
}
delay(1000);
lcd.setCursor(0, 1);
lcd.print(" ");
}
}
else {
welkeBut = 0;
if (keyStatus!="") {
lcd.setCursor(0, 1);
lcd.print(keyStatus);
delay(1000);
lcd.setCursor(0, 1);
lcd.print(" ");
}
}
}
I strongly advise against using the String class in any sketch that needs to run reliably for long periods of time. Using dynamic memory allocation (as the String class does) is a big mistake in C/C++-based embedded systems, because it so easily leads to memory fragmentation and hence exhaustion, which leads to a system crash. This is what appears to be happening to your system.
FIXED IT!!!
Yeah!!! I finally fixed it. The problem was in the code.
In the "void modeklok()" I jump back to the loop if the counter "i" is zero. I assumed that the next time the "void modeklok()" is called from the loop, it would just run the "void modeklok()" from the beginning, but it doesn't! It will enter "void modeklok()" at the point where it left the void the last time. The counting of "i" is now totally off and it goes below zero, what isn't possible and makes the sketch crash. The simple command "return;" fixed the thing and I'm very happy with it now.
Thanx to everybody who helped me finding the problem!
@dc42 I'm still figuring out C and will try to write the memory to eprom-memory if I will get any more problems with it in the future. For now it runs flawlessly.
OK I've been busy so I left without reading your code. Now that I read it, I think it's not a code problem. It's is how you use variables. If "i" is a loop iterator, it should only be defined at the loop and modified inside the loop, right? You used a global variable, not very wise to share an iterator with other code outside the loop, and with a very generic name such as "i". If you have the habit of using an "i" as variable then you WILL use it in other functions and that will mess up the i value. Use a name like i, or j only in those places of local variable and where you don't care to use it extensively inside of the loop.
It still works!!
update: after 2,5 weeks it still works perfectly. I didn't change anything in the code or hardware for 2,5 weeks. The clock, that uses only the internal crystal of the arduino to keep the time is still spot on.