Caracteres estranhos no lcd

Boas,

Estou a tentar fazer um projeto igual ou parecido a muitos que andam por ai para controlar umas calhas de led de um aquário. Neste momento o projeto é composto por um arduino uno, um lcd 20x4, um rtc, e um DS18B20. Tenho andado aos poucos a tentar programar através de vários exemplos que te visto. Neste momento o meu problema, é que após programado o arduino, fica tudo a funcionar mas após uns minutos por vezes horas o lcd fica cheio de caracteres estranhos, faço um reset e volta ao mesmo, já experimentei vários exemplos e dá sempre o mesmo. Outra coisa que acontece que tenho um relógio que é apresentado no lcd, com horas, minutos e segundos, mas o segundos passam de 3 em 3, ou seja começa no 0,3,6,9,12,15 e por ai fora, mas o relógio está certo. Se alguém me conseguir dar umas dicas de como resolver o problema ficava muito agradecido.

Cumprimentos

Neste momento o meu problema, é que após programado o arduino, fica tudo a funcionar mas após uns minutos por vezes horas o lcd fica cheio de caracteres estranhos, faço um reset e volta ao mesmo, já experimentei vários exemplos e dá sempre o mesmo.

Este problema é comum.Tens reles a serem acionados pelo teu Arduino?

Outra coisa que acontece que tenho um relógio que é apresentado no lcd, com horas, minutos e segundos, mas o segundos passam de 3 em 3, ou seja começa no 0,3,6,9,12,15 e por ai fora, mas o relógio está certo. Se alguém me conseguir dar umas dicas de como resolver o problema ficava muito agradecido.

Mostra o código, o problema deve estar lá

Boas, obrigado desde já pela resposta eu neste momento não tenho relés ligados, mas o código tem relés.
Achas que se eliminar os relés, fico com o problema resolvido?
Fica aqui o código em questão, vai divido em duas partes pois não consigo colocar aqui inteiro.
Mais uma vez o meu obrigado.

#include <LiquidCrystal.h>
#include “Wire.h”
#define DS1307_I2C_ADDRESS 0x68 //set rtc
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 8 //Define the pin of the DS18B20

/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| T E M P P I N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#include “Wire.h”
#define DS1307_I2C_ADDRESS 0x68 //set rtc
#include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins
#include <OneWire.h>
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| T E M P P I N ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
OneWire ds(8);
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| T E M P P I N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/

const int floatswitch = A3;
int floatstate = 0;
const int topoffpump = A1;

// TEMP CONTROL
int fan = 4;
int heat = 2;
int toocold = 24;
int toohot = 26;
int idealtemp = 25;
int tempswing = 2;

// FAN CONTROL
int ledState1 = LOW;
int ledState2 = LOW;
long previousMillis1 = 0;
long previousMillis2 = 0;

/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| L E D D I M M I N G P A R T |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| F A D E S I N A N D O U T |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
int blueramptime = 10 ; // time for blue LEDs to dim on and off in minutes ***THIS is multiplied to be longer (somehow?) by temperature(); and topoff();
int whiteramptime = 10 ; // time for white LEDs to dim on and off in minutes
int bluemin = 0 ; // minimmum dimming value of blue LEDs, range of 0-255
int bluemax = 255 ; // maximum dimming value of blue LEDs, range of 0-255
int whitemin = 0 ; // minimum dimming value of white LEDs, range of 0-255
int whitemax = 255 ; // maximum dimming value of white LEDs, range of 0-255
int photoperiod = 570 ; // amount of time array is on at full power in minutes
int ontime = 10 ; // time of day (hour, 24h clock) to begin photoperiod fade in
int blue = 3; // blue LEDs connected to digital pin 3 (pwm)
int white = 5; // white LEDs connected to digital pin 5 (pwm)
int ledfan = 111; //this fan is for cooling the LEDs ***RETIRED

int bluepercent[11] = {
0, 50, 75, 100, 125 ,150, 175, 200, 225, 250, 255 }; // this line is needed if you are using meanwell ELN60-48P
int whitepercent[11] = {
0, 50, 75, 100, 125 ,150, 175, 200, 225, 250, 255 }; // these are the values in ~10% increments does not responde to <28

/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| C L O U D S |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
//defines led random intensity range
int randNumber = random(20, 200);

//defines time delay ranges
int randTime1 = random(1000,7000); //time the cloud lasts
int randTime2 = random(20000,45000); //time between clouds

/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
LiquidCrystal lcd(13, 12, 7, 6, 5, 4);

// Set up the custom fish icon
byte newChar[8] = {
B00000,
B00000,
B10001,
B11011,
B11111,
B11111,
B11001,
B10000
};

byte newChar1[8] = {
B00001,
B00010,
B11101,
B11010,
B11111,
B11110,
B11100,
B00000
};
byte newChar2[8] = {
B00000,
B00000,
B10001,
B11011,
B11111,
B11111,
B10011,
B00001
};
byte newChar3[8] = {
B10000,
B01000,
B10111,
B01011,
B11111,
B01111,
B00111,
B00000
};
byte newChar4[8] = {
B00111,
B01110,
B11100,
B11000,
B11000,
B11100,
B01110,
B00111
};
byte newChar5[8] = {
B01010,
B10000,
B00010,
B01001,
B00100,
B10000,
B00100,
B10001
};
byte newChar6[8] = {
B01010,
B00100,
B00001,
B11011,
B00011,
B00001,
B01000,
B10010
};
byte newChar7[8] = {
B10010,
B00100,
B10000,
B11011,
B11000,
B10000,
B00010,
B01001
};
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| R T C C L O C K D S 1 3 0 7 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
byte decToBcd(byte val)
{
return ( (val/1016) + (val%10) );
}
byte bcdToDec(byte val)
{
return ( (val/16
10) + (val%16) );
}
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you’re passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour));
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}

Aqui fica a segunda parte do codigo, que não é de minha autoria, e tem algumas coisas que são para remover.

/||||||||||||||| D E F I N E : O N E S E C O N D ||||||||||||||||||/
void onesecond() //function that runs once per second while program is running
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

lcd.setCursor(0, 1);
lcd.print(hour, DEC);
lcd.print(":");
if (minute < 10) {
lcd.print(“0”);
}
lcd.print(minute, DEC);
lcd.print(":");
if (second < 10) {
lcd.print(“0”);
}
lcd.print(second, DEC);
lcd.print(" ");

delay(1000);
}

/|||||||||||||||| D E F I N E : F A N S O N ||||||||||||||||/
void fanon()
{
digitalWrite(fan, HIGH);
lcd.setCursor(9, 3);
lcd.print("Fan On ");
}
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| D E F I N E : F A N S O F F |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
void fanoff()
{
digitalWrite(fan, LOW);
lcd.setCursor(9, 3);
lcd.print(“Fan Off”);
}
/|||||||||||| D E F I N E : H E A T O N |||||||||||||||||/
void heaton()
{
digitalWrite(heat, HIGH);
lcd.setCursor(0, 3);
lcd.print("Heat On ");
}
/||||||||||||| D E F I N E : H E A T OFF ||||||||||||||||||||||||||/
void heatoff()
{
digitalWrite(heat, LOW);
lcd.setCursor(0, 3);
lcd.print(“Heat Off”);
}
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| S E T U P |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
void setup() {
pinMode(heat, OUTPUT);
pinMode(fan, OUTPUT);
digitalWrite(heat, HIGH); //if mechanical relays start LOW when the arduino boots the devices will all turn on
digitalWrite(fan, HIGH); // Set analog pin 1 as a output
pinMode(floatswitch, INPUT);
pinMode(topoffpump, OUTPUT);
digitalWrite(topoffpump, HIGH);
/||||||||||||||||| S E T U P - D I S P L A Y |||||||||||||||||||/
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();

// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.

second = 3;
minute = 18;
hour = 20;
dayOfWeek = 4; // Sunday is 0
dayOfMonth = 21;
month = 2;
year = 11;
//setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
//##################### UNCOMMENT THE ABOVE TO SET THE DATE & TIME #######
//################################

analogWrite(blue, bluemin);
analogWrite(white, whitemin);
lcd.begin(20, 4); // set up the LCD’s number of rows and columns:
lcd.setCursor(0, 0);
lcd.write(0);
lcd.write(1);
lcd.setCursor(2, 0);// set the cursor to column 0, line 0
lcd.print(“Reff Controller”);
lcd.setCursor(18, 0);
lcd.write(3);
lcd.write(2);
lcd.setCursor(0, 2);
lcd.print(“blue:”);
lcd.print(33bluemin/85);
lcd.setCursor(8, 2);
lcd.print(“white:”);
lcd.print(33
whitemin/85);
}

/||||||||||||||||||||||||||||||||||||||||||| D E F I N E : T E M P C O N T R O L ||||||||||||||||||||||||||||||||||||||||||||||/
void temperature()
{
sensors.requestTemperatures(); // Send the command to get temperatures
delay(1000);
float temp2=0;
lcd.setCursor(9, 1);
temp2= sensors.getTempCByIndex(0);
lcd.print(sensors.getTempCByIndex(0));
lcd.print((char)223);

if(temp2>toohot) return fanon(),heatoff(); //these work, but cause a constant state of either relay being ON
if(temp2<toocold) return heaton(),fanoff();

/*
//the below is for testing as of 8/5/2012…
if (temp2<(idealtemp+tempswing) && temp2>(idealtemp-tempswing)) //turn off cooler/heater
{
digitalWrite(heat, LOW);
digitalWrite(fan, LOW);
}
if (tempswing>0)
{
if (temp2 >=(idealtemp+tempswing)) //turn on fans
{
digitalWrite(fan, HIGH);
}
if (temp2<=(idealtemp-tempswing)) //turn an heater
{
digitalWrite(heat, HIGH);
}
}
*/

}

/||||||||||||||||||||||||||||||||||||||||||| D E F I N E : T O P - O F F C O N T R O L ||||||||||||||||||||||||||||||||||||||||||||||/
void topoff()
{
floatstate = digitalRead(floatswitch);
if (floatstate == HIGH){
digitalWrite(topoffpump, LOW);
}
else{
digitalWrite(topoffpump,HIGH);
}
delay (1000);
}
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| L O O P |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
void loop()
{
onesecond();
temperature();
topoff();

/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 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 >= (ontime60))
bluerampup = (((ontime
60) + blueramptime) - daybyminute);
else
bluerampup = blueramptime;
int whiterampup;
if (daybyminute >= (ontime60 + blueramptime))
whiterampup = (((ontime
60) + blueramptime + whiteramptime) - daybyminute);
else
whiterampup = whiteramptime;
int whiterampdown;
if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
whiterampdown = (((ontime60) + photoperiod + blueramptime + 2whiteramptime) - daybyminute);
else
whiterampdown = whiteramptime;
int bluerampdown;
if (((ontime * 60) + photoperiod + blueramptime + 2whiteramptime) <= daybyminute)
bluerampdown = (((ontime
60) + photoperiod + 2blueramptime + 2whiteramptime) - daybyminute);
else
bluerampdown = blueramptime;
/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| L O O P - F A D E I N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
if (daybyminute >= (ontime60))
{
if (daybyminute <= ((ontime
60) + blueramptime + (whiteramptime/109))) //if time is in range of fade in, start fading in + (whiteramptime/109)
{
// fade blue LEDs in from min to max.
for (int i = 1; i <= 10; i++) // setting ib value for 10% increment. Start with 0%
{

analogWrite(blue, bluepercent*);*

  • lcd.setCursor(5, 2);*
  • lcd.print(i);*
  • lcd.print(" ");*
    _ int countdown = ((bluerampup*60)/10); // calculates seconds to next step_
  • while (countdown>0)*
  • {*
  • onesecond(); // updates clock once per second*
  • countdown–;*
  • temperature();*
  • topoff();*
  • }*
  • } *
  • // 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*);_
    _
    lcd.setCursor(14, 2);_
    _
    lcd.print(i);_
    _
    lcd.print(" ");_
    _ int countdown = ((whiterampup60)/10); // calculates seconds to next step_

    * while (countdown>0)*
    * {*
    * onesecond(); // updates clock once per second*
    * countdown–;*
    * temperature();*
    * topoff();*
    * }*
    * }*
    * }*
    * }*
    _ /||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| L O O P - M A X V A L U E |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/_

/|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| L O O P - F A D E O U T |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/
_ if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
* {*
if (((ontime * 60) + photoperiod + whiteramptime + 2blueramptime + (blueramptime/109)) >= daybyminute)
* {*
* // 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, 255);*
* lcd.setCursor(5, 2);*
* lcd.print(10);*
* lcd.print(" ");*
analogWrite(white, whitepercent*);
lcd.setCursor(14, 2);
lcd.print(i);
lcd.print(" “);
int countdown = ((whiterampdown60)/10); // calculates seconds to next step_

* while (countdown>0)*
* {*
* onesecond(); // updates clock once per second*
* countdown–;*
* temperature();*
* topoff();*
* }*
* }*
* // 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*);
lcd.setCursor(5, 2);
lcd.print(i);
lcd.print(” ");
int countdown = ((bluerampdown60)/10); // calculates seconds to next step_

* while (countdown>0)*
* {*
* onesecond(); // updates clock once per second*
* countdown–;*
* temperature();*
* topoff();*
* }*
* }*
* }*
* }*
} // END LOOP

Por incrivel que pareca... olhando para o teu codigo diria que o teu problema de mostrar de 3 em 3 segundos (com o relogio certo) e mesmo por o teu programa demorar esse tempo a "dar a volta".

Se cortares o teu programa em metade vais ver que o relogio faz update de dois em dois ou mesmo de segundo a segundo. Outro ponto onde podes cortar o tempo de processamento e alterares o teu codigo para nao utilizar floats e no maximo int... a diferenca vai ser abismal garanto-te.

Eu aponto para o problema estar aqui:

void temperature()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
    delay(1000);
  float temp2=0;
  lcd.setCursor(9, 1);
  temp2= sensors.getTempCByIndex(0);
  lcd.print(sensors.getTempCByIndex(0));  
  lcd.print((char)223);

  if(temp2>toohot) return fanon(),heatoff(); //these work, but cause a constant state of either relay being ON
  if(temp2<toocold) return heaton(),fanoff();

  /*
   //the below is for testing as of 8/5/2012...
      if (temp2<(idealtemp+tempswing) && temp2>(idealtemp-tempswing))          //turn off cooler/heater
   {
   digitalWrite(heat, LOW);
   digitalWrite(fan, LOW);  
   }
   if (tempswing>0)
   {
   if (temp2 >=(idealtemp+tempswing))                           //turn on fans
   {
   digitalWrite(fan, HIGH);
   }
   if (temp2<=(idealtemp-tempswing))                          //turn an heater
   {
   digitalWrite(heat, HIGH);
   }
   }
   */

}

O sensor ds18B20 demora 750 ms a calcular a temperatura e a devolve-la com uma resoluçao de 10 bits.No teu codigo nao vejo onde estejas a alterar a resoluçao entao ele deve estar definido nos 10 bits.Tenta comentar este bloco do teu codigo e vê se faz diferença.

sensors.requestTemperatures(); // Send the command to get temperatures
delay(1000);

So aqui gastas 1.75 segundos ±

Obrigado pelos conselhos, vou fazer uns testes de depois deixo aqui o feedback.

Cumps