Ligar/desligar display LCD em intervalo de tempo ou por botão

Bom dia pessoal, preciso de ajuda no seguinte:
Tenho um arduino mega controlando meu aquário e exibindo as informações num lcd, porém durante a noite a iluminação do lcd está me atrapalhando.
Gostaria de implementar algum código que desligasse o lcd das 00:00 horas às 08:00h da manhã. Ou é mais facil colocando um botão de on/off?
Segue o código anexo pq não coube aqui.

Outra coisa que não tem haver com o lcd mas sim com o horário exibido.
Hj ele apresenta a hora com 1 hora a mais, se eu tirar esses +3600 deve funcionar né?

if(requestSent && ether.ntpProcessAnswer(&timeStamp, srcPort)) {
      setActualTime(timeStamp + 3600 * TIME_ZONE);
      requestSent = false;

codigo.txt (43.1 KB)

Eu tenho isso feito. Estamos a falar do backlight de um LCD 16x2 (ou equivalente), certo? Em primeiro lugar é necessário prestar atenção ao hardware. Está a utilizar algum shield para o Arduino ou comprou o LCD e fez as ligações?

Sim, desligar o backlight ou ele por completo.
Uso um 20x4 (azul)
Blue Serial IIC/I2C/TWI 2004 204 20X4 Character LCD Module Display For Arduino

http://www.ebay.com/itm/Blue-Serial-IIC-I2C-TWI-2004-204-20X4-Character-LCD-Module-Display-For-Arduino-/201125617027?pt=LH_DefaultDomain_0&hash=item2ed4055d83

É muito mais simples de perceber o problema assim. Para o caso deste hardware tem a função lcd.noBacklight(); que lhe permite desligar a luz de fundo.
Vi nesta página:
http://arduino-info.wikispaces.com/LCD-Blue-I2C

pode me ajudar a introduzir no meu código?

Se tiveres botoes para as funcoes do aquario e quiseres aumentar o tempo de vida do LCD e projecto (o LCD consome imenso comparado ao resto do Arduino), diria que o backlight do LCD devia estar sempre desligado ou com um PWM muito baixo e quando alguem carregasse num botao de funcao do sistema e que o LCD "acordava" e aumentava a luminosidade.

Vc diz que com o tempo o lcd vai parar de funcionar?
No meu projeto não tem nenhum botão para acionamento de nada.

Vc diz que com o tempo o lcd vai parar de funcionar?

Sim vai.Afinal tudo acaba por morrer até nós :grin:, os equipamentos electrónicos todos têm um tempo de vida útil definido pelo fabricante, o chamado "Mean Time to Failure".Todos os semicondutores, condensadores .... tem isto, e portanto o teu lcd que tem uma backlight não é excepção.No entanto este tempo é elevado, não te sei dizer quando terás de consultar o datasheet dele, mas se colocares o componente a funcionar numa zona mais "leve" (com uma luminosidade reduzida) irás certamente aumentar a vida útil dele.

Ok, eu entendo que isso possa acontecer, obrigado Hugo.
Pode me ajudar a implementar o código para desligar no período de tempo?

Talvez algo assim:

#include <Wire.h>  // Comes with Arduino IDE

#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address





long now = 0;
long previousMillis = 0;


void setup()
{
 lcd.begin(16,2);
 lcd.backlight();//activas a backlight

}
void loop()
{
  now = millis();
  clearLCDBacklightAfter(5);//Passado 5 segundos a backlight deve apagar

}
void clearLCDBacklightAfter(long seconds)
{
  seconds *= 1000;
  if(now - previousMillis > seconds) 
    {
     previousMillis = now;  
     lcd.noBacklight();
    }
}

Nota que nao testei mas deve ser algo deste genero.Podes depois melhorar a coisa com a dica que o Bubulindo te disse ou seja se nao detectares movimento nos botoes executas a funçao clearLCDBacklightAfter() com um if

Obrigado Hugo,

Eu não tenho nenhum botão, então não da pra usar essa função, teria que ser algo como timer, tipo desliga às 00:00 e liga o backlight às 8:00 da manhã.

Nesse seu código quando ele liga novamente?

Desculpe as perguntas mas é que não entendo nada da programação, quem fez tudo pra mim foi um amigo.

Eu não tenho nenhum botão, então não da pra usar essa função, teria que ser algo como timer, tipo desliga às 00:00 e liga o backlight às 8:00 da manhã.

Podes usar a função se a adaptares para tal.
O que queres é possível mas como vais obter a hora no arduino?Tens algo RTC?
Pela tua resposta claramente não estas à vontade em programação portanto tens de fazer o teu trabalho de casa e estudar um pouco de C.Nota que nós não estamos aqui para fazer o código por ti apenas para te dar umas dicas e ajudar.

Olá!

Para desligar na hora que quer, pode usar este método:

if(NumMins(hora, minuto) <  480) // (8 * 60) + 0 = 480
{
  lcd.noBacklight();
}

int NumMins(uint8_t ScheduleHour, uint8_t ScheduleMinute)
{
  return (ScheduleHour*60) + ScheduleMinute;
}

Sendo hora e minuto as variáveis te tempo do teu programa.

Abraço
Fernando Garcia

Se é para desligar a meia noite, então 0 horas.
Ficaria assim?

if(NumMins(hora, minuto) <  480) // (8 * 60) + 0 = 480
{
  lcd.noBacklight();
}

int NumMins(uint8_t ScheduleHour, uint8_t ScheduleMinute)
{
  return (ScheduleHour*60) + ScheduleMinute;
}

Olá!

Sim, se você quiser por exemplo 23:30 vai ser:

if((NumMins(hora, minuto) >  1410)  ||  (NumMins(hora, minuto) <  480))  // (8 * 60) + 0 = 480
{
  lcd.noBacklight();
}

Abraço.

E eu implemento isso em qualquer lugar do código?

Eu volto a perguntar:
Como é que vais obter a hora e os minutos, tens algum RTC?
Vais ligar isso a uma bola de cristal que te vai dar a hora e os minutos do dia? :grin:

A hora vem de um servidor NTP

static byte ntpServer[] = {200,160,7,186};
static byte srcPort = 0;
void loop() {

  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

  if(timeStatus()== timeNotSet){

    if(requestSent && ether.ntpProcessAnswer(&timeStamp, srcPort)) {
      setActualTime(timeStamp + 3600 * TIME_ZONE);
      requestSent = false;
    }

    unsigned long time = millis();
    if(time - lastTime > INTERVAL) {
      lastTime = time;
      ether.ntpRequest(ntpServer, srcPort);
      requestSent = true;
    }

  }

Ok peço desculpa nao tinha visto que tinhas isso no codigo :grin:
Assim sendo deves conseguir com a funçao que o colega te passou

Eu faria uma coisa deste género:

void loop() {
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  if (timeStatus() == timeNotSet) {
    if (requestSent && ether.ntpProcessAnswer(&timeStamp, srcPort)) {
      setActualTime(timeStamp + 3600 * TIME_ZONE);
      requestSent = false;
    }

    unsigned long time = millis();
    if (time - lastTime > INTERVAL) {
      lastTime = time;
      ether.ntpRequest(ntpServer, srcPort);
      requestSent = true;
    }
  }

  if (timeStatus() == timeSet) {
    getTemp();
    controlFans();
    controlHeater();
    controlLights();
    timer();

    unsigned long Lcdtime = millis();
    if (Lcdtime - LcdlastTime > LcdInterval) {
      LcdlastTime = Lcdtime;
      refreshLcd();
      checkBkLgt();   //ADICIONAR ESTA LINHA
    }

    unsigned long postTime = millis();
    if (postTime - postLastTime > postInterval) {
      postLastTime = postTime;
      sendTemperature();
    }

    checkResponse();
    if (pos) { // check if valid tcp data is received
      char* webReturn = (char *)Ethernet::buffer + pos;
      callPages(webReturn);
    }
  }
}

Estou a aproveitar a altura em que é feito o refresh do LCD para ver se é necessário desligar a luz de fundo ou não. Para fazer esta verificação (e pegando no código que já tinha sido postado), eu faria uma coisa como a seguinte:

void checkBkLgt() {
   int horaActual = hour()*60+minute();

   if(horaActual >  480)  // (8 * 60) + 0 = 480
   {
     lcd.backlight();
   }  
   else if(horaActual >=  0 && horaActual <=  480)  // (8 * 60) + 0 = 480
   {
     lcd.noBacklight();
   }  
}

É calculado o tempo actual (penso que não é necessária nenhuma função para isto, porque apenas será chamada uma vez), depois, se a hora actual foi maior que as 8h00m, então é ligada a luz de fundo, se não, verifica se a hora está entre as 0h00m e as 8h00m (esta verificação não era necessária, por razões óbvias) e caso seja assim, desliga a luz de fundo do LCD.

Em relação à questão de:

Outra coisa que não tem haver com o lcd mas sim com o horário exibido.
Hj ele apresenta a hora com 1 hora a mais, se eu tirar esses +3600 deve funcionar né?

Deveria mudar de TIME_ZONE. Apenas é necessário na linha onde é definido:

//Define Clock
#define SECONDS_IN_DAY          86400
#define START_YEAR              1900
#define TIME_ZONE               -2
static int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

alterar esse valor para outro.