LusoRobótica - Robótica em Português

Robótica => Projectos de robótica => Projectos em desenvolvimento => Tópico iniciado por: GnobarEl em 18 de Maio de 2010, 11:04

Título: Controlador automático para o aquário.
Enviado por: GnobarEl em 18 de Maio de 2010, 11:04
Bom dia,
estou a pensar em montar um alimentador automático para o aquário.
Por agora a minha única experiência com o arduino é meramente teórica. Mas pelo que li serve perfeitamente para o que eu pretendo. Já encomendei aqui da loja os componentes necessários para desenvolver o projecto.

Este tópico serve também para dar a conhecer a evolução do trabalho e para tirar algumas duvidas que iram surgir. Tendo em conta que algumas das duvidas serão duvidas de iniciantes será também um bom tópico para outros iniciantes que por aqui apareçam.

O projecto consiste,
numa primeira fase:
ter o arduino como controlador e ter ligado a si 3 servos que iram permitir a movimentação do "braço" para despejar a comida.

Numa segunda fase:
após a conclusão da primeira, pretendo ligar as luzes do aquário ao arduinio para o arduino ligar e desligar a luz automaticamente.

Possivelmente, se aqui chegarmos, numa terceira fase:
as várias luzes vão-se ligando e desligando sequencialmente simulando assim o amanhecer e o anoitecer.

Antes de iniciar a montagem do projecto surgiu já uma duvida que ainda não consegui encontrar resposta.
Este projecto é para estar ligado 24h/dia e preciso de uma função timer()
Já estive a ler no site oficial do arduino mas ainda não entendi bem como funciona. É possível, só com o arduino criar uma função que seja executada todos os dias às 8h e às 20h?

Obrigado,
toda a ajuda é bem vinda =)



Título: Re: Controlador automático para o aquário.
Enviado por: senso em 18 de Maio de 2010, 11:38
Penso que a função millis() serve para o que queres, se todos os dias usares a propria função para fazer um reset ao miliis() a cada 24 horas não deves acumular muitos erros de tempo, mas não tenho bem a certeza sobre isso.
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 18 de Maio de 2010, 11:51
Já li algures sobre os erros que acontemcem com o tempo, mas não me faz muita diferença se for acumulando uma margem de erro. se não fizer a alimentação às 8h faz às 8:02 não faz grande diferença, a não ser que a diferença de tempo seja maior do que eu penso.
por agora o que preciso é que todos os dias aquela hora (mais minuto menos minuto) chame a função.

Tenho estado a ler isto:
http://www.arduino.cc/playground/Code/DateTime (http://www.arduino.cc/playground/Code/DateTime)
Título: Re: Controlador automático para o aquário.
Enviado por: microbyte em 18 de Maio de 2010, 11:51
Penso que já outro dia houve um utilizador que perguntou algo do género...
Não te podes reger pelo relógio do Arduino, pois passado pouco tempo, já vai desfasado do tempo real.

Como queres executar certos comandos em horas bem distintas, vais ter de usar um RTC (Real Time Clock).
Se pesquisares no fórum vais encontrar um tutorial do tr3s, se não me engano, que mostra como podes ligar um RTC ao Arduino.
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 18 de Maio de 2010, 11:58
Sim, já vi esse tutorial, mas é preciso hardware adicional, estava a tentar usar apenas o arduino sem recurrer a mais hardware. Se tiver que ser... mas até lá vou tentar usar apenas código... vamos lá ver...

Entre hoje e amanha já devo receber o arduino =)
Título: Re: Controlador automático para o aquário.
Enviado por: microbyte em 18 de Maio de 2010, 12:02
Não conhecia a biblioteca DateTime.

Depois conta a tua experiência. ;)
Título: Re: Controlador automático para o aquário.
Enviado por: senso em 18 de Maio de 2010, 12:09
O arduino tambem não pode acumular assim tanto erro, o cristal é calibrado, são 16Mhz certos, e se o timer tiver um pre-scaler que dê um overflow com um numero inteiro de ciclos de clock o erro vai ser muito reduzido mesmo
Título: Re: Controlador automático para o aquário.
Enviado por: TigPT em 18 de Maio de 2010, 12:37
http://lusorobotica.com/index.php?topic=681.0 (http://lusorobotica.com/index.php?topic=681.0)
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 18 de Maio de 2010, 13:44
Onde é que se arranja facilmente o DS1307?
Título: Re: Controlador automático para o aquário.
Enviado por: Sérgio_Sena em 18 de Maio de 2010, 13:57
Vê lá se este link funciona ::

http://shop.ebay.co.uk/?_from=R40&_trksid=m570&_nkw=DS1307&_sacat=See-All-Categories (http://shop.ebay.co.uk/?_from=R40&_trksid=m570&_nkw=DS1307&_sacat=See-All-Categories)
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 18 de Maio de 2010, 14:09
Serve, o problema é os portes, fica bem mais de portes do que o chip em si.
Vou continuar a procurar por cá.
Entretanto assim que tiver o arduino já começo a fazer algumas experiências para usar o clock apenas por software.
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 20 de Maio de 2010, 09:31
Já comecei a fazer os primeiros testes com o arduino.

E como tal também já apareceram os primeiros problemas :p
Os servos são mais pequenos e mais frágeis do que eu estava a pensar.
Não consigo que tenham um movimento constantemente suave, por vezes parece que ficam meios baralhados ou então andam aos "soluços".
outro problema, eles não fazem a rotação de 180º completa, fazem uns 150º +/-.
Estou a usar um tutorial que vi no site do arduino.

Algum ideia? Código... alguma coisa?
Título: Re: Controlador automático para o aquário.
Enviado por: TigPT em 20 de Maio de 2010, 09:57
Estas a utilizar analogWrite ou a biblioteca servo?
http://arduino.cc/en/Reference/Servo (http://arduino.cc/en/Reference/Servo)
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 20 de Maio de 2010, 10:38
Estou a utilizar a biblioteca servo.

fiz estes tuts.
se bem que o que me realmente interesse é controlar o servo apenas por código e não com o potenciómetro. Ambos os tuts funcionaram, mas com o problema acima descrito.

Servo Library

    * Knob: control the shaft of a servo motor by turning a potentiometer.
    * Sweep: sweeps the shaft of a servo motor back and forth.
Título: Re: Controlador automático para o aquário.
Enviado por: metRo_ em 20 de Maio de 2010, 22:27
http://hackaday.com/2010/05/20/automatic-fish-feeder/ (http://hackaday.com/2010/05/20/automatic-fish-feeder/)
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 21 de Maio de 2010, 00:22
Obrigado pela dica =)
este é diferente do que eu quero fazer, pretendo fazer algo parecido com um "braço" mecânico para despejar a comida. Mas tem lá algumas coisas interessantes, quem sabe numa versão futura.

Neste momento estou a estudar como se liga um switch.

Obrigado a todos pela ajuda e pelas dicas!
Título: Re: Controlador automático para o aquário.
Enviado por: PDI em 21 de Maio de 2010, 22:23
Por acaso não tens um desenho do que pretendes fazer, assim a malta pode ajudar melhor.
Já agora tens duvidas sobre os switch.
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 21 de Maio de 2010, 22:33
Obrigado,

para o switch usei este site: http://www.ladyada.net/learn/arduino/lesson5.html (http://www.ladyada.net/learn/arduino/lesson5.html)
e já estão a funcionar. Estou agora a estudar o código.

Ainda não tenho desenhos, nem sei bem como desenhar lol
mesmo mentalmente as vezes confundo-me todo.
Em principio segunda feira chegam os novos servos (obrigado Tiago por toda a disponibilidade prestada) e já poderei ter uma noção mais real de como vai ficar.

A ideia principal é colocar o "contentor" da comida (um pequeno cilindro) dos peixes escondia da parte de trás do aquário. Quando for para alimentar os peixes o servo levanta o contentor da comida e um outro servo roda ligeiramente o contentor para deixar cair um pouco de comida. Por fim faz o reverso e volta à posição inicial.

A próxima etapa, possivelmente mais demorada por falta de hardware, vai ser criar o "relógio". Enquanto isso, vou tentar usar apenas código para controlar as horas.

Obrigado!
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 02 de Junho de 2010, 11:53
Boas,

Actualização do projecto:

- Já tenho os motores servos e já estão a ser controlados pelo arduino. Como ainda não montei no sitio uso apenas valores de referência.
- Ainda não tenho o RTC mas tenho usado a função time, não tive o arduino ligado muito tempo seguido para ver o desfasamento. Mas mesmo que haja algum desfasamento pelos meus testes não deve ser assim tanto.
-O problema do switch já está resolvido, existe um switch para ligar e desligar o alimentador automático, caso esteja desligado, quando chega a hora de executar uma função não acontece nada :)
-Alguém tem algum esquema para ligar um relé? Já andei a procura no fórum mas ainda não tenho bem a certeza de como se liga. Em principio sábado já devo comprar um relé de 220V para ligar a iluminação do aquário.

Se não estou em erro, pelo que li, basta ligar quase directamente o relé ao arduino. Depois com isso posso controlar a iluminação do aquário.

Logo já coloco o código que tenho, por agora não tem nada de especial, mas podem ser fazer comentários.

Comentem à vontade. Todas as criticas são bem vindas.
Título: Re: Controlador automático para o aquário.
Enviado por: TigPT em 02 de Junho de 2010, 12:11
Muito bem! Depois tens que nos mostrar a cara de felicidade dos peixinhos ;D

-Alguém tem algum esquema para ligar um relé? Já andei a procura no fórum mas ainda não tenho bem a certeza de como se liga. Em principio sábado já devo comprar um relé de 220V para ligar a iluminação do aquário.
http://lusorobotica.com/search.php?cx=000416183904538598060%3Abqwm1z-rqvk&cof=FORID%3A10&ie=UTF-8&q=arduino+relé&sa=Pesquisar (http://lusorobotica.com/search.php?cx=000416183904538598060%3Abqwm1z-rqvk&cof=FORID%3A10&ie=UTF-8&q=arduino+relé&sa=Pesquisar)
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 07 de Junho de 2010, 09:30
Actualização do projecto.

Finalmente atingiu a versão beta 1.0 =)

- A luz liga e desliga normalmente, afinal a ligação do relé foi bem mais simples do que me pareceu inicialmente.

- O alimentador já está colocado no sitio, só falta regular a abertura por causa da comida que cai.

Mais logo deixo aqui algumas fotos.

Fica o código que tenho.
PS. o código ainda precisa de ser bem revisto, algumas coisas foram colocadas apenas de forma a trabalhar. Alguma melhoria sintam-se à vontade de dizer

Código: [Seleccione]
//feed The Fisher
// Alpha1
// 22 Maio 2010

/*
 To do:
 *feedTheFishes                 - done 80%
 *RTC                           - notDone
 *automatic feed                - notDone
 *turnOn/Off the lights         - done 100%
 *turnOn/Off lighs sequentially - notDone
 *turnOn/Off Fan                - notDone
 *nokia 3310 LCD                - notDone
 
 
 Arduino Controller
 
 Analog Pin 0 =
 Analog Pin 1 =
 Analog Pin 2 =
 Analog Pin 3 =
 Analog Pin 4 =
 Analog Pin 5 =
 
 Digital Pin 0 = RX
 Digital Pin 1 = TX
 Digital Pin 2 = switchOn/Off
 Digital Pin 3 = Alarm
 Digital Pin 4 = Servo1
 Digital Pin 5 = Servo2
 Digital Pin 6 = Servo3
 Digital Pin 7 = Luz aquário (relay)
 Digital Pin 8 =
 Digital Pin 9 =
 Digital Pin 10 =
 Digital Pin 11 =
 Digital Pin 12 = arduinoWorkingBusy
 Digital Pin 13 = fedeerOn/Off
 */


#include <pitches.h>
#include <Time.h>
#include <TimeAlarms.h>
#include <Servo.h>

//Debug switch
boolean DEBUG = true;
//boolean DEBUG = false;


//melody notes
int melody[] = {
  NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
int noteDelays[] = {
  4,8,8,4,4,4,4,4};

int dPinSatus         = 13;       //global on or off status
int dPinWorking       = 12;       //doing some action
//int dPin11          = 11;
//int dPin10          = 10;
//int dPin9           = 9;
//int dPin8           = 8;
int light             = 7;        //luzDoAquario
//int servo3            = 6;        //servo3
//int servo2            = 5;        //servo2
//int servo1            = 4;        //servo1
int dPinAlarm         = 3;        //piezoAlarm
int dPinSw            = 2;        //switchOn/Off
int dPinTx            = 1;        //Tx
int dPinRx            = 0;        //Rx

int lightMode         = 0;        // Is the light on or off?
int estadoDoArduino   = 0;        // 1- Arduino ligado || 0 - Arduino desligado

int buttonState       = 0;        // current state of the button
int lastButtonState   = 0;        // previous state of the button
int ledState          = 0;        // remember current led state

Servo myservo1;  // create servo object to control a servo
int pos = 0;    // variable to store the servo position


void setup() { 

  pinMode(dPinRx, OUTPUT);
  pinMode(dPinTx, INPUT);
  pinMode(dPinSw, INPUT);
  pinMode(dPinAlarm, OUTPUT);
//pinMode(servo1, OUTPUT);
//pinMode(servo2, OUTPUT);
//pinMode(servo3, OUTPUT);
  pinMode(light, OUTPUT);
//pinMode(dPin8, OUTPUT);
//pinMode(dPin9, OUTPUT);
//pinMode(dPin10, OUTPUT);
//pinMode(dPin11, OUTPUT);
  pinMode(dPinWorking, OUTPUT);
  pinMode(dPinSatus, OUTPUT);

myservo1.attach(4);  // attaches the servo on pin 4 to the servo object
myservo1.write(pos);

  Serial.begin(9600);

    setTime(12,0,0,5,23,10); //12:00:00 May 23, 2010
    Alarm.alarmRepeat(8,30,0, morningAlarm);
    Alarm.alarmRepeat(19,30,0, eveningAlarm);


}


void loop() {
   
  if (DEBUG){
    digitalClockDisplay();
    Alarm.delay(15);      // wait one second between clock display
  }
 
  buttonState = digitalRead(dPinSw); // read the pushbutton input pin

  // check if the button is pressed or released
  // by comparing the buttonState to its previous state

  if (buttonState != lastButtonState) {   // change the state of the led when someone pressed the button
    if (buttonState == 1) {
      if(ledState==1){
        if (DEBUG){
          Serial.println("automaticFeederOff ");
          playSongStop();
        }
        ledState=0;
      }
      else{
        if (DEBUG){
          Serial.println("automaticFeederOn ");
          playSongStart();
        }
        ledState=1;
      }         
    }
    lastButtonState = buttonState; // remember the current state of the button
  }
  digitalWrite(dPinSatus, ledState); // turns LED on if the ledState=1 or off if the ledState=0
  delay(20); // adding a small delay prevents reading the buttonState to

fast
}


void playSongStart() {
  estadoDoArduino = 1;
    if (DEBUG){
    Serial.print("estadoDoArduino: ");
  }
    if (DEBUG){
    Serial.println(estadoDoArduino);
  }
  if (DEBUG){
    Serial.println("playSoungStart ");
  }
  for(int thisNote = 0; thisNote <8; thisNote++){
    int noteDelay = 1000/noteDelays[thisNote];
    tone(3,melody[thisNote],noteDelay);

    int pauseBetweenNotes = noteDelay * 1.30;
    delay(pauseBetweenNotes);
  }
}

void playSongStop() {
 estadoDoArduino = 0;
  if (DEBUG){
    Serial.print("estadoDoArduino: ");
  }
    if (DEBUG){
    Serial.println(estadoDoArduino);
  }
 
  if (DEBUG){
    Serial.println("playSoungEnd ");
  }
  for(int thisNote = 8; thisNote >0; thisNote--){
    int noteDelay = 1000/noteDelays[thisNote];
    tone(3,melody[thisNote],noteDelay);

    int pauseBetweenNotes = noteDelay * 1.30;
    delay(pauseBetweenNotes);
  }
}

void morningAlarm() {
  if (DEBUG){
    Serial.println("morning alarm ");
  }
  if(estadoDoArduino == 1) {
    turnLightsOn();
    //waits one minute and start feeding the fishes
    feedTheFish();
  }
  else {
    Serial.println("automaticFisherOff ");
  }
}


void eveningAlarm() {
  if (DEBUG){
    Serial.println("evening alarm ");
  }
  if(estadoDoArduino == 1) {
    feedTheFish();
    delay(10000);
    //waits one minute and turnoff the light
    turnLightsOff();
  }
  else {
    Serial.println("automaticFisherOff ");
  }
}


void feedTheFish() {
  if (DEBUG){
    Serial.println("feeding the fishes ");
  }
 
    // workingLight on - start feeding
    digitalWrite(dPinWorking, HIGH);   // set the LED on


    //código para colocar os servos a funcionar

    //check this part to full control the servos movement

 for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
    delay(10);                       // waits 15ms for the servo to reach the position
  }

  for(pos = 180; pos>=0; pos-=1)     // goes from 180 degrees to 0 degrees
  {                               
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
    delay(10);                       // waits 15ms for the servo to reach the position
  }
 delay(5000);


    digitalWrite(dPinWorking, LOW);   // set the LED off

}

void turnLightsOn() {
  //turnOnTheLights
  if (DEBUG){
    Serial.println("turnOn the lights and waits 10 minutes before feed the fishes ");
  }
  digitalWrite(light, HIGH);   // Turn ON the Light
  delay(5000);
}

void turnLightsOff() {
  //turnOffTheLights
  if (DEBUG){
    Serial.println("turnOff the lights ");
  }
  digitalWrite(light, LOW);   // Turn OFF the Light
}

void digitalClockDisplay()
{
  if (DEBUG){
    Serial.print("clockDisplay ");
  }
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}

void printDigits(int digits)
{
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

Obrigado.
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 18 de Junho de 2010, 12:03
Actualização do projecto
-------------------------------

Código: [Seleccione]
/*
feed The Fisher
 Alpha1
 22 Maio 2010
 
 To do:
 
 *feedTheFishes                 - done 80%
 *RTC                           - notDone
 *automatic feed                - done 100%
 *turnOn/Off the lights         - done 100%
 *turnOn/Off lighs sequentially - notDone
 *turnOn/Off Fan                - notDone
 *nokia 3310 LCD                - done 100%
 *2 food containers             - done 100%
 *manual control                - 50%
 
 Arduino Controller
 
 Analog Pin 0 = Switch BTN
 Analog Pin 1 =
 Analog Pin 2 = Potenciometro
 Analog Pin 3 =
 Analog Pin 4 =
 Analog Pin 5 =
 
 Digital Pin 0 = RX
 Digital Pin 1 = TX
 Digital Pin 2 = switchOn/Off
 Digital Pin 3 = Alarm
 Digital Pin 4 = Servo1
 Digital Pin 5 = Servo2
 Digital Pin 6 = NOKIA LCD
 Digital Pin 7 = NOKIA LCD
 Digital Pin 8 = NOKIA LCD
 Digital Pin 9 = NOKIA LCD
 Digital Pin 10 = NOKIA LCD
 Digital Pin 11 = Luz aquário (relay)
 Digital Pin 12 = arduinoWorkingBusy (LED)
 Digital Pin 13 = fedeerOn/Off
 */

#include <nokia_3310_lcd.h>

#include "Andrew.h"
#include "pacman.h"
#include <pitches.h>
#include <Time.h>
#include <TimeAlarms.h>
#include <Servo.h>
#include "Wire.h"

//melody notes
int melody[] = {NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
int noteDelays[] = {4,8,8,4,4,4,4,4};
int alarm[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_C5, NOTE_G4, NOTE_C5};
int durations[] = {1,1,1,3,1,3};

int dPinTx = 1;                        // Tx
int dPinRx = 0;                        // Rx
int dPinAlarm = 3;                                                              // Alarm
int dPinWorking = 7;                                                    // ledOn when motors are working
int aquariumLight = 6;

//menu starting points
#define MENU_X 10                                     // 0-83
#define MENU_Y 0                                       // 0-5
#define NUM_MENU_ITEM 7

int pot=0;                                                                      // pino do potenciometro
int botao=2;                                                                    // pino do botao AnalogPin
int i=0;                                                                        // varialve de teste

int estadoDoArduino    = 1;                                            // 1- Arduino ligado || 0 - Arduino desligado
int firstStartup       = 0;                                                     // logo inicial, ocorre uma vez quando o programa inicia.
int feedContainer      = 30;                                          // Numero de vezes que o alimentador alimenta os peixes, ao fim de 30 vezes a comida acaba e soa o alarm.
int feedTimeMorning    = 1;                                     // Number of times the motor rotates to feed the fishes
int feedTimeEvening    = 1;
int feeding = 1;                                     // Number os times the motor rotates to feed.


Servo myServo1;                          // create servo object to control a servo
Servo myServo2;
int pos = 0;                            // variable to store the servo position

//Debug switch
boolean DEBUG = true;
//boolean DEBUG = false;

// menu definition
char menu_items[NUM_MENU_ITEM][40]={
"Feeder1",
"Feeder2",
"Light",
"Feed Num",
"Set Alarm"
};

void (*menu_funcs[NUM_MENU_ITEM])(void) = {
feederC1,
feederC2,
light,
feedNum,
setAlarm
};

char current_menu_item;
int blflag = 1;                                                                 // Backlight initially ON
char degree = 0x7b;                                                             // Degree symbol

Nokia_3310_lcd lcd=Nokia_3310_lcd();

void setup(){
pinMode(dPinRx, OUTPUT);
pinMode(dPinTx, INPUT);
pinMode(pot, OUTPUT);                                                       // Colocar o pino do potenciometro como entrada.
pinMode(botao, OUTPUT);                                                     // Colocar o pino do botao como entrada.
pinMode(dPinAlarm, OUTPUT);                                                 // Alarm - output
pinMode(aquariumLight, OUTPUT);
pinMode(dPinWorking, OUTPUT);
 
 
        digitalWrite(aquariumLight, HIGH);

        Serial.begin(9600);
 
setTime(23,10,45,5,23,10);                         // 12:00:00 May 23, 2010
Alarm.alarmRepeat(23,11,0, morningAlarm);
Alarm.alarmRepeat(23,30,0, eveningAlarm);

lcd.init();
lcd.clear();


init_MENU();    // menu initialization
current_menu_item = 0;
 // int blflag = 1;                                                             // Light initially ON
}


void init_MENU(void) {

byte i;
lcd.clear();
lcd.writeString(MENU_X, MENU_Y, menu_items[0], MENU_HIGHLIGHT );

for (i=1; i<5; i++) {
lcd.writeString(MENU_X, MENU_Y+i, menu_items[i], MENU_NORMAL);
}
}

// waiting for center key press
// trocar por SW2
void waitfor_OKkey() {
delay(500); // This delay is to avoid the to keep pressing the SW
int key = 0;
int temp = 0;
lcd.gotoXY( 5,3 );
while (key!= 1){
if(digitalRead(2)==1){                                              // Se o botao estiver pressionado...
key=1;
}
}
}

void loop() {
  //**************
  // colocar a funcçao getkeys da luz na funcao loop
  // conector RJ45
  // print_time();
  //************** 
if (DEBUG){
digitalClockDisplay();
Alarm.delay(10);                       // wait one second between clock display
}
 
bootProgram();
  //Nao iniciar logo com o menu, screen de apresentação
  //dataBig e ao clicar no SW aparece o menu
  //mainScreen();
 
pot=analogRead(0);                                                          // Le o valor do potenciometro na entrada 0;
i=map(pot,0,950,0,4);                                                       // Mapeia o valor lido de 0 a 1023 num valor de 0 a 5 que ? o numero de linhas. - Coloquei 950 em vez de 1023 porque quando carregava no botao havia um queda de tensao suficiente para passar o valor de 5 para 4.
 if (DEBUG){
  lcd.gotoXY( 76,5 );
  lcd.print( i ); // Menu Number
 }
switch(i){
case 0:
//lcd.writeString(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
lcd.writeString(10, 0, menu_items[0], MENU_HIGHLIGHT );
lcd.writeString(10, 1, menu_items[1], MENU_NORMAL );
lcd.writeString(10, 2, menu_items[2], MENU_NORMAL );
lcd.writeString(10, 3, menu_items[3], MENU_NORMAL );
lcd.writeString(10, 4, menu_items[4], MENU_NORMAL );
current_menu_item =0;
break;
case 1:
lcd.writeString(10, 0, menu_items[0], MENU_NORMAL );
lcd.writeString(10, 1, menu_items[1], MENU_HIGHLIGHT );
lcd.writeString(10, 2, menu_items[2], MENU_NORMAL );
lcd.writeString(10, 3, menu_items[3], MENU_NORMAL );
lcd.writeString(10, 4, menu_items[4], MENU_NORMAL );
current_menu_item =1;
break;
case 2:
lcd.writeString(10, 0, menu_items[0], MENU_NORMAL );
lcd.writeString(10, 1, menu_items[1], MENU_NORMAL );
lcd.writeString(10, 2, menu_items[2], MENU_HIGHLIGHT );
lcd.writeString(10, 3, menu_items[3], MENU_NORMAL );
lcd.writeString(10, 4, menu_items[4], MENU_NORMAL );
current_menu_item =2;
break;
case 3:
lcd.writeString(10, 0, menu_items[0], MENU_NORMAL );
lcd.writeString(10, 1, menu_items[1], MENU_NORMAL );
lcd.writeString(10, 2, menu_items[2], MENU_NORMAL );
lcd.writeString(10, 3, menu_items[3], MENU_HIGHLIGHT );
lcd.writeString(10, 4, menu_items[4], MENU_NORMAL );
current_menu_item =3;
break;
case 4:
lcd.writeString(10, 0, menu_items[0], MENU_NORMAL );
lcd.writeString(10, 1, menu_items[1], MENU_NORMAL );
lcd.writeString(10, 2, menu_items[2], MENU_NORMAL );
lcd.writeString(10, 3, menu_items[3], MENU_NORMAL );
lcd.writeString(10, 4, menu_items[4], MENU_HIGHLIGHT );
current_menu_item =4;
break;
}  
 
if(digitalRead(2)==1){                                                  // Se o botao estiver pressionado...
lcd.clear();
(*menu_funcs[current_menu_item])();
lcd.clear();
init_MENU();
current_menu_item = 0;           
}  
}
void mainScreen() {
delay(500);
lcd.writeString( 0, 1, "MainScreen", MENU_NORMAL);
lcd.writeString(24, 5, "Picture", MENU_HIGHLIGHT );
waitfor_OKkey();
lcd.clear();
}

// Display temperature in big digits, feederC2 in small digits underneath
void feederC1() {
lcd.gotoXY(6,1);
lcd.print("Feeder C1");
lcd.gotoXY(6,3);
lcd.print("Start");
waitfor_OKkey();

for(pos = 0; pos < 180; pos += 1)             // goes from 0 degrees to 180 degrees
{                                          // in steps of 1 degree
myServo1.write(pos);                      // tell servo to go to position in variable 'pos'
delay(10);                            // waits 15ms for the servo to reach the position
}

for(pos = 180; pos>=0; pos-=1)                  // goes from 180 degrees to 0 degrees
{                               
myServo1.write(pos);                      // tell servo to go to position in variable 'pos'
delay(10);                          // waits 15ms for the servo to reach the position
}
delay(500);                                         // Avoid the key is pressed for a long time and jumbs to menu.
lcd.clear();
}

void feederC2() {
lcd.gotoXY(6,1);
lcd.print("Feeder C2");
lcd.gotoXY(6,3);
lcd.print("Start");
waitfor_OKkey();
 
for(pos = 0; pos < 180; pos += 1)             // goes from 0 degrees to 180 degrees
{                                          // in steps of 1 degree
myServo1.write(pos);                      // tell servo to go to position in variable 'pos'
delay(10);                            // waits 15ms for the servo to reach the position
}

for(pos = 180; pos>=0; pos-=1)                  // goes from 180 degrees to 0 degrees
{                               
myServo1.write(pos);                      // tell servo to go to position in variable 'pos'
delay(10);                          // waits 15ms for the servo to reach the position
}
delay(500);                                         // Avoid the key is pressed for a long time and jumbs to menu.
lcd.clear();
}
 
void light() {
lcd.writeString( 0, 2, "Backlight is ", MENU_NORMAL);

if( blflag != 0 ) {
lcd.writeString( 60, 2, "Off", MENU_HIGHLIGHT);
} else{
lcd.writeString( 60, 2, "On", MENU_HIGHLIGHT);
}
if( blflag != 0 ) {
blflag=0;
digitalWrite( aquariumLight, LOW );
}else{
blflag = 1;
digitalWrite( aquariumLight, HIGH );
}
delay(1500);
lcd.clear();
}


void feedNum(){
lcd.gotoXY(2,1);
lcd.print("How many times");
lcd.gotoXY(2,2);
lcd.print("feed the fishes?");
 
int key = 0;
int temp = 0;
lcd.writeString(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
//Retirar este delay ou reduzir para 1000
//delay(5000);
  //waitfor_OKkey();
while (key!= 1){
lcd.clear();
// Teste!!! apagar
lcd.gotoXY(20,6);
lcd.print(temp);
temp++;
//*****************
pot=analogRead(0);                                                  // Le o valor do potenciometro na entrada 0;
i=map(pot,0,950,0,7);
 
lcd.gotoXY(5,3);
lcd.print("Feed ");
lcd.print(i);
lcd.print(" times");

lcd.writeString(38, 5, "OK", MENU_HIGHLIGHT );

if(digitalRead(2)==1){                                              // Se o botao estiver pressionado...
key=1;
}
}
delay(1000);
lcd.clear();

if(debug){
lcd.gotoXY(5,3);
lcd.print("Escolheu: ");
lcd.print(i);
delay(5000); // Avoid the key is pressed for a long time and jumbs to menu.
}
lcd.clear();

/*  delay(500);
  lcd.writeString( 0, 1, "Text feedNum", MENU_NORMAL);
  lcd.writeString(24, 5, "START", MENU_HIGHLIGHT );
  waitfor_OKkey();
  lcd.clear();
 
  lcd.writeStringBig( 0, 0, "123456", MENU_NORMAL );
  lcd.writeStringBig( 0, 3, "7890+-.", MENU_NORMAL );
  delay(2000);
 
  lcd.writeStringBig( 0, 0, "123456", MENU_HIGHLIGHT );
  lcd.writeStringBig( 0, 3, "7890+-.", MENU_HIGHLIGHT );
  delay(2000);

  lcd.clear();
 
  delay(500);
  lcd.writeString( 0, 1, "Graphic Demo", MENU_NORMAL);
  lcd.writeString(24, 5, "START", MENU_HIGHLIGHT );
  waitfor_OKkey();
  lcd.clear();
  // Draw some circles pulsing in and out
  for(int a=0; a< 4; a++) {
    for( int r = 1; r < 49; r+=1 ) {
      lcd.drawCircle(42, 24, r, PIXEL_ON );
      delay(10);
    }
    delay(10);
    for( int r = 48; r >0; r-=1 ) {
      delay(10);
      lcd.drawCircle(42, 24, r, PIXEL_OFF );
    }
  }

  // More circles
  for( int xc = 10; xc < 85; xc+=15 ) {
    lcd.drawCircle(xc, 24, 20, PIXEL_ON );
  }
  delay( 2000 );
   
  // Draw diagonal lines using XOR colour
  lcd.drawLine(0,0,83,47, PIXEL_XOR);
  lcd.drawLine(0,43,83,0, PIXEL_XOR);

  delay( 2000 );
 
  // Draw a rectangle
  lcd.drawRectangle(5,5,78,42, PIXEL_ON);
  delay( 2000 );

  // Draw 2 filled rectangles
  lcd.drawFilledRectangle(5,3,78,20, PIXEL_ON);
  lcd.drawFilledRectangle(5,25,78,42, PIXEL_ON);
  delay( 2000 );

  // Draw bitmap image
  lcd.drawBitmapP( 0,0, &Andrew[0],84,48);
  delay(5000);

  // Pacman animation
  lcd.clear();
  int px = 0;
  int py = 1;
  int pause=70;
  for( int p=0; p <9; p++) {
    lcd.drawBitmapP( px,py, &pacman1[0],32,32);
    delay( pause );
    lcd.clearBitmap( px++,py, 32,32);
    lcd.drawBitmapP( px,py, &pacman2[0],32,32);
    delay( pause );
    lcd.clearBitmap( px++,py, 32,32);
    lcd.drawBitmapP( px,py, &pacman3[0],32,32);
    delay( pause );
    lcd.clearBitmap( px++,py, 32,32);
    lcd.drawBitmapP( px,py, &pacman4[0],32,32);
    delay( pause );
    lcd.clearBitmap( px++,py, 32,32);
    lcd.drawBitmapP( px,py, &pacman3[0],32,32);
    delay( pause );
    lcd.clearBitmap( px++,py, 32,32);
    lcd.drawBitmapP( px,py, &pacman2[0],32,32);
    delay( pause );
    lcd.clearBitmap( px++,py, 32,32);
  }
  lcd.drawBitmapP( px,py, &pacman1[0],32,32);

  delay(500);
  lcd.clear();
  lcd.writeString( 0, 1, "Graphic Demo", MENU_NORMAL);
  lcd.writeString( 0, 3, "The End!!", MENU_NORMAL);
  lcd.writeString(38, 5, "OK", MENU_HIGHLIGHT );


  waitfor_OKkey();
  delay(1000);
  lcd.clear();
  */
}

void setAlarm(){
lcd.gotoXY( 0, 1 );
lcd.print("Alarm - test" );
lcd.gotoXY( 0, 2 );
lcd.print( "Morning / Evening" );
lcd.gotoXY( 0, 3 );
lcd.print( "==============" );
lcd.writeString(38, 5, "OK", MENU_HIGHLIGHT );
lcd.gotoXY( 0, 4 );
  //lcd.print( key );
delay(500);
waitfor_OKkey();
}

void bootProgram() {

if (firstStartup == 0 ){
//futuramente colocar uma imagem de como logo
lcd.clear();
lcd.gotoXY(20,2);
lcd.print("Aquario");
lcd.gotoXY(16,3);   
lcd.print("V1.0 Beta");
//delay (5000);
//clearram();
for(int thisNote = 0; thisNote <8; thisNote++){
int noteDelay = 1000/noteDelays[thisNote];
tone(3,melody[thisNote],noteDelay);
int pauseBetweenNotes = noteDelay * 1.30;
delay(pauseBetweenNotes);
}
firstStartup++;
lcd.clear();
}
}

void unbootProgram() {
//* rever funcionalidade do unboot
//*********************************
estadoDoArduino = 0;
if (DEBUG){
Serial.print("Arduino is now ");
if(estadoDoArduino == 1) {
Serial.println("ON");
}else{
Serial.println("OFF");
}
}

if (DEBUG){
Serial.println("Play Song OFF.");
}
 
for(int thisNote = 8; thisNote >0; thisNote--){
int noteDelay = 1000/noteDelays[thisNote];
tone(3,melody[thisNote],noteDelay);
int pauseBetweenNotes = noteDelay * 1.30;
delay(pauseBetweenNotes);
}
}
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 18 de Junho de 2010, 12:04
Código: [Seleccione]

void morningAlarm(){
if (DEBUG){
Serial.println("Good Morning.");
Serial.println("Start Feeding the fishes.");
}

lcd.clear();
lcd.gotoXY( 5,2 );
lcd.print("Good Morning");
delay(2000); 
turnLightsOn();
  // waits before feed
delay(1000);
   
//workingLight on - start feeding
    digitalWrite(dPinWorking, HIGH);                    // set the LED on

/*
   for(int x = 0; feeding >= x; feeding--)
   {
   
for(pos = 0; pos < 180; pos += 1)                 // goes from 0 degrees to 180 degrees
      {                                                  // in steps of 1 degree
        myServo1.write(pos);                              // tell servo to go to position in variable 'pos'
        delay(10);                                    // waits 15ms for the servo to reach the position
      }

      for(pos = 180; pos>=0; pos-=1)                  // goes from 180 degrees to 0 degrees
      {                               
        myServo1.write(pos);                              // tell servo to go to position in variable 'pos'
        delay(10);                                  // waits 15ms for the servo to reach the position
      }
      // alterar esta funcao do contentor de comida
      //foodContainer = foodContainer-1;
    }
    */
 
delay(1000);
if (DEBUG){
Serial.println("Stop Feeding the fishes.");
}
digitalWrite(dPinWorking, LOW);                // set the LED off
}

void eveningAlarm(){
if (DEBUG){
Serial.println("Good Evening.");
Serial.println("Start Feeding the fishes.");
}

lcd.clear();
lcd.gotoXY( 5,2 );
lcd.print("Good Evening");
delay(2000); 
turnLightsOff();
  // waits before feed
delay(1000);
   
//workingLight on - start feeding
    digitalWrite(dPinWorking, HIGH);                    // set the LED on

/*
   for(int x = 0; feeding >= x; feeding--)
   {
   
for(pos = 0; pos < 180; pos += 1)                 // goes from 0 degrees to 180 degrees
      {                                                  // in steps of 1 degree
        myServo1.write(pos);                              // tell servo to go to position in variable 'pos'
        delay(10);                                    // waits 15ms for the servo to reach the position
      }

      for(pos = 180; pos>=0; pos-=1)                  // goes from 180 degrees to 0 degrees
      {                               
        myServo1.write(pos);                              // tell servo to go to position in variable 'pos'
        delay(10);                                  // waits 15ms for the servo to reach the position
      }
      // alterar esta funcao do contentor de comida
      //foodContainer = foodContainer-1;
    }
    */
 
delay(1000);
if (DEBUG){
Serial.println("Stop Feeding the fishes.");
}
digitalWrite(dPinWorking, LOW);                // set the LED off
}

void turnLightsOn() {                 // turnOnTheLights
if (DEBUG){
Serial.println("Light is ON.");
}
blflag=1;
lcd.clear();
lcd.gotoXY(1,3);
lcd.print("Turn ON Lights");
digitalWrite(aquariumLight, HIGH);
delay(1000);
lcd.clear();
}

void turnLightsOff() {                 //turnOffTheLights
if (DEBUG){
Serial.println("Light is OFF.");
}

blflag=0;
lcd.clear();
lcd.gotoXY(1,3);
lcd.print("Turn OFF Lights");
digitalWrite(aquariumLight, LOW);
delay(1000);
lcd.clear();
}

void digitalClockDisplay() {
if (DEBUG){
Serial.print("Time: ");
}
                // digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.println();
}

void printDigits(int digits){                 // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}

/*
void print_time(){
  lcd.setCursor(0,13);
  int hour;
  int minute;
  hour = RTC.get(DS1307_HR,true);
  minute = RTC.get(DS1307_MIN,true);
  if(hour < 10 && hour > 0 || hour >= 13 && hour <= 21){
    lcd.print(" ");
  }
  if(hour >= 13 && hour != 0){
    lcd.print(hour - 12);
    amorpm = 1;
  }else if(hour == 0){
    lcd.print("12");
    amorpm = 0;
  }else if(hour == 12){
    lcd.print("12");
    amorpm = 1;
  }else{
    lcd.print(hour);
    amorpm = 0;
  }
  lcd.print(":");
  if(minute < 10){
    lcd.print("0");
  }
  lcd.print(minute);//read minutes without update (false)
  lcd.print(ampm[amorpm]);
}
*/


Como podem ver por alguns comentários ainda existem coisas para fazer, o próximo "grande" passo vai ser a construção da placa. Para ser mais simples vou usar uma placa perfurada.

Quero agradecer a toda a comunidade da lusorobotica salientando o tr3s o metRo_ e o TigPT pelo seu contributo. Parte do código utilizado foi desenvolvido e partilhado por eles.

utilizei também as librarias para a shield do 3310
http://blog.thiseldo.co.uk/?p=383 (http://blog.thiseldo.co.uk/?p=383)

Todos os comentários e sugestões são bem vindas =)

PS. os meus conhecimentos de electrónica e programação são muito básicos...
Título: Re: Controlador automático para o aquário.
Enviado por: zordlyon em 18 de Junho de 2010, 13:18
Muitos parabéns pelo projecto...

Agora o que eu queria ver era fotos  :P :P :P :P :P

Cumprimentos..
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 18 de Junho de 2010, 14:40
Algumas imagens do projecto ainda na Breadboard.

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg441.imageshack.us%2Fimg441%2F4817%2Fp1060594i.th.jpg&hash=7ce02a96589b9a116602a5a32c6daecf3b042e09) (http://img441.imageshack.us/i/p1060594i.jpg/)

Montagens inicial, o display de 7 segmentos servia para indicar o numero de "comida" que existia no recipiente. Quando o valor atingisse zero o piezo emitia um sinal sonoro.

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg63.imageshack.us%2Fimg63%2F2757%2Fp1060791c.th.jpg&hash=fd119ad7985776806b430ecdaa05c389960a0a5b) (http://img63.imageshack.us/i/p1060791c.jpg/)
Ligações do LCD, falta colocar cola quente para proteger as soldas.

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg693.imageshack.us%2Fimg693%2F699%2Fp1060799.th.jpg&hash=7d046b9c10f4667c1359df8bcb342afafeb7718a) (http://img693.imageshack.us/i/p1060799.jpg/)
Projecto na fase final. Pronto para ser montado no PCB, ainda falta o RTC, mas assim que chegar será implementado.

Assim que tiver tempo vou passar o circuito para um PCB.
Título: Re: Controlador automático para o aquário.
Enviado por: LoneWolf em 15 de Julho de 2010, 18:10
boas a todos, Sr. GnobarEl achei o seu projecto engradado e útil, mas tenho uma pergunta quanto ao alimentador, como faz para os alimentar? adaptou algum alimentador de compra? é sempre certo, deitando sempre a mesma quantidade? só pergunto porque também sou aquariofilista já a alguns anos e uso alimentadores de compra, ou alias usava e deixe porque não eram certos a dar de comida, ora dava pouca ora dava muita e o que por vezes é fatal aos peixes.

Abraços
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 21 de Outubro de 2010, 21:55
Boas a todos,
depois de um meses de ter começado  a desenvolver este projecto e depois de uma longa pausa finalmente terminei-o.

Inicialmente estava projectado montar um PCB com o arduino juntamente com o resto dos componentes necessários para o projecto e usar um LCD de um nokia 3310 tal como se pode ver pelas fotos anteriores.

Acontece que estraguei o LCD, não sei como, mas deixou de funcionar, além do mais, não é muito practico as ligações todas do LCD.
Como tive que comprar outro optei por uma shield e já que ia comprar a shield do LCD comprei também uma ProtoShield. Assim todo o conjunto ficava com melhor aspecto. Parei com o projecto que já tinha, retirei os componentes todos do PCB e adaptei à shield.

O código foi desenvolvido aos pouco e deixo em anexo para quem esteja interessado. De salientar que não sou programador! Fiz o melhor que pude com tudo o que fui aprendendo, o código está minimamente organizado, no entanto ainda à muitos pedaços de código que precisam de uma limpeza.

Funções:
. Liga / Desliga a luz automaticamente:
. RTC -  mesmo que falhe a luz o relógio continua a funcionar.
. 3310LCD - LCD com o menu para um fácil manuseamento.
. Possibilidade de controlo automático e manual.
. Neste momento só tem um contentor com comida, mas facilmente se adapta outro e pode-se variar de comida. Ex. um tipo de comida de manha e outro à noite.
. Gráfico com a quantidade de comida no(s) contentor(es).
. Alertas sonoros para falta de comida.
. etc...

Tenho mais algumas ideias que posso vir a implementar no futuro tal como alerta para a troca de água. Reorganizar o menu e colocar imagens em vez de texto. Possibilidade de definir os horários para ligar/desligar e alimentação.

Espero que tenham gostado e que possa servir a alguém de inspiração para os seus projectos.

Código:
Código: [Seleccione]
/*
feed The Fisher
Alpha1
Inicio
22 Maio 2010

To do:

 *Full Project                   - done 90%
-------------------------------------------
 *RTC                           - Done 100%
 *automatic feed                - Done 100%
 *turnOn/Off the lights         - Done 100%
 *nokia 3310 LCD                - Done 100%
 *2 food containers             - Done 90%
 *manual control                - done 100%
 *OPCCAO MANUAL, INDICADOR DE MUDA DE AGUA, A CADA 15 DIAS ALERTA PARA FAZER UMA TPA

Arduino Controller
------------------

Analog Pin 0 = Switch BTN
Analog Pin 1 =
Analog Pin 2 = Potenciometro
Analog Pin 3 =
Analog Pin 4 =
Analog Pin 5 =

Digital Pin 0 = RX
Digital Pin 1 = TX
Digital Pin 2 = switchOn/Off
Digital Pin 3 = Alarm
Digital Pin 4 = Servo1
Digital Pin 5 = Servo2
Digital Pin 6 = NOKIA LCD
Digital Pin 7 = NOKIA LCD
Digital Pin 8 = NOKIA LCD
Digital Pin 9 = NOKIA LCD
Digital Pin 10 = NOKIA LCD
Digital Pin 11 = Luz aquário (relay)
Digital Pin 12 = arduinoWorkingBusy (LED)
Digital Pin 13 = fedeerOn/Off

 */

/*

14 Agosto 2010

Deixou de ser usada a placa controladora (home made) do arduino, passando a ser utilizada uma breadboard shield e um LCD shield.
Algumas das portas IO irao ser alteradas para serem adaptadas ao novo hardware.

 */


/*
1 setembro 2010

adiccao de graficos com o representacao da quantidade de comida por contentor.
possibilidade de seleccionar o manualmente o contentor da comida.

 */


/*

07 outubro 2010

adiccao de elementos sonoros
trocar beeper por um novo

9 outubro 2010
RTC

 */

/*
20 outubro 2010
versao final 1.5

 */

#include <nokia_3310_lcd.h>
#include "Andrew.h"
#include "pacman.h"
#include "pictures.h"
#include <Servo.h>
#include <Wire.h>
#include "pitches.h"                       //Include the Tone Library


//melody notes
int melody[]=
{
  NOTE_C4,NOTE_G3,NOTE_G3,NOTE_A3,NOTE_G3,0,NOTE_B3,NOTE_C4
};
int noteDelays[]=
{
  4,8,8,4,4,4,4,4
};
int alarm[]=
{
  NOTE_C4,NOTE_C4,NOTE_G4,NOTE_C5,NOTE_G4,NOTE_C5
};
int durations[]=
{
  1,1,1,3,1,3
};

// Pass Tones:
const int melody_pass[]=
{
  NOTE_C4,NOTE_G3,NOTE_G3,NOTE_A3,NOTE_G3,0,NOTE_B3,NOTE_C4
};
const int noteDurations_pass[]=
{
  4,8,8,4,4,4,4,4
};
//Fail Tones:
const int melody_fail[]=
{
  NOTE_D4,NOTE_D3,NOTE_D2,NOTE_D1
};
const int noteDurations_fail[]=
{
  4,4,4,1
};

int dPinTx=1; // Tx
int dPinRx=0; // Rx
int dPinAlarm=3; // Alarm
int dPinWorking=7; // ledOn when motors are working
int aquariumLight=6;
int numberC1=0;
int numberC2=0;

//menu starting points
#define MENU_X 0                                     // 0-83
#define MENU_Y 0                                       // 0-5
#define NUM_MENU_ITEM 7

// Pin used by Backlight, so we can turn it on and off. Pin setup in LCD init function
#define BL_PIN 7

int pot=0; // pino do potenciometro
int botao=2; // pino do botao AnalogPin
int i=0; // varialve de teste

int estadoDoArduino=1; // 1- Arduino ligado || 0 - Arduino desligado
int firstStartup=0; // logo inicial, ocorre uma vez quando o programa inicia.
int feedContainer=30;
// Numero de vezes que o alimentador alimenta os peixes, ao fim de 30 vezes a comida acaba e soa o alarm.
int feedTimeMorning=1; // Number of times the motor rotates to feed the fishes
int feedTimeEvening=1;
int feeding=1; // Number os times the motor rotates to feed.
int oldPot=0; //contador para verificar se o arduino está a ser utilizado
int newPot=0;
int potCont=0;
int percentagemComidaC1=0;


Servo myServo1; // create servo object to control a servo
Servo myServo2;
int pos=0; // variable to store the servo position

//Debug switch
boolean DEBUG=true;
//boolean DEBUG = false;

// menu definition
char menu_items[NUM_MENU_ITEM][40]=
{
  "Manual Feed","Aquarium Light","LCD Light","Settings","Status"
};

void(*menu_funcs[NUM_MENU_ITEM])(void)=
{
  manual,setLight,setBackLight,settings,status_
};

char current_menu_item;
int blflag=1; // Backlight initially ON
int backLight=1;
char degree=0x7b; // Degree symbol

#define DS1307_I2C_ADDRESS 0x68
Nokia_3310_lcd lcd=Nokia_3310_lcd();


byte hour,minute,second,date,month,year,dayofweek;
char timep1[]="    30";
char timep2[]="12-30";
char mon[]="JAN";
char dates[]="12 JUN 2010";
char dow[]="Saturday";
char percentagemComidaC2[]=" ";

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ((val/10 * 16)+(val%10));
}

// Convert binary coded decimal to normal decimal numbers
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)); // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateDs1307)
  Wire.send(decToBcd(dayOfWeek));
  Wire.send(decToBcd(dayOfMonth));
  Wire.send(decToBcd(month));
  Wire.send(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,byte *minute,byte *hour,byte *dayOfWeek,byte
  *dayOfMonth,byte *month,byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS,7);

  // A few of these need masks because certain bits are control bits
  *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());
}

//-------------------------------------------------------------------------

void readTime()
{
  getDateDs1307(&second,&minute,&hour,&dayofweek,&date,&month,&year);
}

//-------------------------------------------------------------------------

void setTime()
{
  setDateDs1307(second,minute,hour,dayofweek,date,month,year);
}

//-------------------------------------------------------------------------


void setup()
{
  Serial.begin(9600);
  Wire.begin(); // start connection

  //set time run only if its the first time youre setting the time.
  /*
  hour = 23;
  minute = 00;
  second = 48;
  month = 10;
  dayofweek = 1;
  date = 19;
  year = 10;
  setTime();
   */

  pinMode(dPinRx,OUTPUT);
  pinMode(dPinTx,INPUT);
  pinMode(pot,OUTPUT); // Colocar o pino do potenciometro como entrada.
  pinMode(botao,OUTPUT); // Colocar o pino do botao como entrada.
  pinMode(dPinAlarm,OUTPUT); // Alarm - output
  pinMode(aquariumLight,OUTPUT);
  pinMode(dPinWorking,OUTPUT);

  myServo1.attach(5); // attaches the servo on pin 4 to the servo object
  myServo2.attach(4);
  myServo1.write(pos);
  myServo2.write(pos);

  digitalWrite(aquariumLight,HIGH);

  lcd.init();
  lcd.clear();

  init_MENU(); // menu initialization/
  current_menu_item=0;
  int blflag=1; // Light initially ON
  int backLigth=1;
}

//-------------------------------------------------------------------------

void init_MENU(void)
{
  byte i;
  lcd.clear();
  lcd.writeString(MENU_X,MENU_Y,menu_items[0],MENU_HIGHLIGHT);

  for(i=1;i<5;i++)
  {
    lcd.writeString(MENU_X,MENU_Y+i,menu_items[i],MENU_NORMAL);
  }
}

// waiting for center key press
// trocar por SW2
void waitfor_OKkey()
{
  delay(500); // This delay is to avoid the to keep pressing the SW
  int key=0;
  int temp=0;
  // lcd.gotoXY( 5,3 );  // ?????????????????
  while(key!=1)
  {
    if(digitalRead(2)==1)
    {
      // Se o botao estiver pressionado...
      key=1;
    }
  }
}

//-------------------------------------------------------------------------

void loop()
{


  readTime();

  if(hour>=12)
  {
    lcd.writeString(75,5,"PM",MENU_NORMAL);
  }
  else
  {
    lcd.writeString(75,5,"AM",MENU_NORMAL);
  }


  if(hour==15)
  {
    if(minute==00)
    {
      if(second==00)
      {
        digitalWrite(aquariumLight,HIGH);
      }
    }
  }

  if(hour==15)
  {
    if(minute==10)
    {
      if(second==00)
      {
        feederC1();

      }
    }
  }

  if(hour==22)
  {
    if(minute==30)
    {
      if(second==00)
      {
        feederC1();

      }
    }
  }

  if(hour==23)
  {
    if(minute==00)
    {
      if(second==00)
      {
        digitalWrite(aquariumLight,LOW);
      }
    }
  }

  sprintf(timep1,"%02d",second);
  sprintf(timep2,"%2d:%02d:",hour,minute);

  lcd.writeString(30,5,timep2,MENU_NORMAL);
  lcd.writeString(65,5,timep1,MENU_NORMAL);

  bootProgram();
  pot=analogRead(1); // Le o valor do potenciometro na entrada 0;
  i=map(pot,0,950,0,4);
  // Mapeia o valor lido de 0 a 1023 num valor de 0 a 5 que e o numero de linhas. - Coloquei 950 em vez de 1023 porque quando carregava no botao havia um queda de tensao suficiente para passar o valor de 5 para 4.

  //////////////////////////////////////////////////////////
  // Funcao para verificar se arduino está a ser utilizado
  // SIM - LCD BACKLIGH ON
  // NAO - LCD BACKLIGH OFF

  newPot=i;

  if(newPot==oldPot)
  {
    potCont=potCont++;

    if(potCont<=1000)
    {
      digitalWrite(BL_PIN,HIGH);
    }
    else
    {
      if(potCont>=1001)
      {
        digitalWrite(BL_PIN,LOW);
      }
    }
  }
  else
  {
    oldPot=newPot;
    potCont=0;
  }

  if(DEBUG){}
  switch(i)
  {
    case 0:
      //lcd.writeString(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
      lcd.writeString(MENU_X,0,menu_items[0],MENU_HIGHLIGHT);
      lcd.writeString(MENU_X,1,menu_items[1],MENU_NORMAL);
      lcd.writeString(MENU_X,2,menu_items[2],MENU_NORMAL);
      lcd.writeString(MENU_X,3,menu_items[3],MENU_NORMAL);
      lcd.writeString(MENU_X,4,menu_items[4],MENU_NORMAL);
      current_menu_item=0;
      break;
    case 1:
      lcd.writeString(MENU_X,0,menu_items[0],MENU_NORMAL);
      lcd.writeString(MENU_X,1,menu_items[1],MENU_HIGHLIGHT);
      lcd.writeString(MENU_X,2,menu_items[2],MENU_NORMAL);
      lcd.writeString(MENU_X,3,menu_items[3],MENU_NORMAL);
      lcd.writeString(MENU_X,4,menu_items[4],MENU_NORMAL);
      current_menu_item=1;
      break;
    case 2:
      lcd.writeString(MENU_X,0,menu_items[0],MENU_NORMAL);
      lcd.writeString(MENU_X,1,menu_items[1],MENU_NORMAL);
      lcd.writeString(MENU_X,2,menu_items[2],MENU_HIGHLIGHT);
      lcd.writeString(MENU_X,3,menu_items[3],MENU_NORMAL);
      lcd.writeString(MENU_X,4,menu_items[4],MENU_NORMAL);
      current_menu_item=2;
      break;
    case 3:
      lcd.writeString(MENU_X,0,menu_items[0],MENU_NORMAL);
      lcd.writeString(MENU_X,1,menu_items[1],MENU_NORMAL);
      lcd.writeString(MENU_X,2,menu_items[2],MENU_NORMAL);
      lcd.writeString(MENU_X,3,menu_items[3],MENU_HIGHLIGHT);
      lcd.writeString(MENU_X,4,menu_items[4],MENU_NORMAL);
      current_menu_item=3;
      break;
    case 4:
      lcd.writeString(MENU_X,0,menu_items[0],MENU_NORMAL);
      lcd.writeString(MENU_X,1,menu_items[1],MENU_NORMAL);
      lcd.writeString(MENU_X,2,menu_items[2],MENU_NORMAL);
      lcd.writeString(MENU_X,3,menu_items[3],MENU_NORMAL);
      lcd.writeString(MENU_X,4,menu_items[4],MENU_HIGHLIGHT);
      current_menu_item=4;
      break;
  }
  if(digitalRead(2)==1)
  {
    // Se o botao estiver pressionado...
    lcd.clear();
    (*menu_funcs[current_menu_item])();
    lcd.clear();
    init_MENU();
    current_menu_item=0;
  }
}

/*
desenhar os contentores C1 e C2 representando graficamente a quantidade de comida de cada um deles
 */

void feederC1()
{

  ////////////////////////////////////////////////////////
  // COLOCAR UMA VERIFICAÇÃO DE QUE LADO ESTA O CONTENTOR PARA RODAR NO SENTIDO INVERSO
  //////////////////////////////////////////////////////////

  int pos;
  lcd.clear();
  lcd.gotoXY(6,1);
  lcd.print("Feeding...");
  //waitfor_OKkey();

  for(pos=0;pos<180;pos+=1)
  // goes from 0 degrees to 180 degrees
  {
    // in steps of 1 degree
    myServo1.write(pos); // tell servo to go to position in variable 'pos'
    delay(10); // waits 15ms for the servo to reach the position
  }

  for(pos=180;pos>=0;pos-=1)
  // goes from 180 degrees to 0 degrees
  {
    myServo1.write(pos); // tell servo to go to position in variable 'pos'
    delay(10); // waits 15ms for the servo to reach the position
  }

  lcd.clear();
  lcd.gotoXY(6,3);
  lcd.print("Done");
  lcd.gotoXY(6,4);
  lcd.print(numberC1);
  delay(500); // Avoid the key is pressed for a long time and jumbs to menu.
  lcd.clear();
  numberC1=numberC1++;
}

//-------------------------------------------------------------------------

void feederC2()
{

  lcd.clear();
  lcd.gotoXY(6,1);
  lcd.print("Feeding...");

  for(pos=0;pos<180;pos+=1)
  // goes from 0 degrees to 180 degrees
  {
    // in steps of 1 degree
    myServo1.write(pos); // tell servo to go to position in variable 'pos'
    delay(10); // waits 15ms for the servo to reach the position
  }

  for(pos=180;pos>=0;pos-=1)
  // goes from 180 degrees to 0 degrees
  {
    myServo1.write(pos); // tell servo to go to position in variable 'pos'
    delay(10); // waits 15ms for the servo to reach the position
  }

  lcd.clear();
  lcd.gotoXY(6,3);
  lcd.print("Done");
  delay(500); // Avoid the key is pressed for a long time and jumbs to menu.
  lcd.clear();
  numberC2=numberC2++;
}


Imagens:
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg264.imageshack.us%2Fimg264%2F3523%2Fp1080098.th.jpg&hash=710c619f2ac4f168a2ca40b256487d49931eb139) (http://img264.imageshack.us/i/p1080098.jpg/)    (https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg830.imageshack.us%2Fimg830%2F1640%2Fp1080089.th.jpg&hash=b63491c48ee7909c24ccce08cf8c6e02d3f97cde) (http://img830.imageshack.us/i/p1080089.jpg/)    (https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg69.imageshack.us%2Fimg69%2F7383%2Fp1080099k.th.jpg&hash=2e9ee3295b68542d80ed4fed14ef280c08f67b06) (http://img69.imageshack.us/i/p1080099k.jpg/)    (https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg16.imageshack.us%2Fimg16%2F9350%2Fp1080084k.th.jpg&hash=c395772964f8301517ae19df905a30e6995d292e) (http://img16.imageshack.us/i/p1080084k.jpg/)   (https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg294.imageshack.us%2Fimg294%2F2935%2Fp1080086e.th.jpg&hash=bfff535eab052adcf21be25af2295ebc21e3b39c) (http://img294.imageshack.us/i/p1080086e.jpg/)
Título: Re: Controlador automático para o aquário.
Enviado por: GnobarEl em 21 de Outubro de 2010, 21:58
Continuação do código:

Código: [Seleccione]
//-------------------------------------------------------------------------

void setLight()
{
  lcd.clear();
  lcd.writeString(5,2,"Light is now: ",MENU_NORMAL);

  if(blflag!=0)
  {
    lcd.writeString(34,3,"Off ",MENU_NORMAL);
    blflag=0;
    digitalWrite(aquariumLight,LOW);
  }
  else
  {
    lcd.writeString(40,3,"On ",MENU_NORMAL);
    blflag=1;
    digitalWrite(aquariumLight,HIGH);
  }

  delay(1500);
  lcd.clear();
}

//-------------------------------------------------------------------------

void feedNum()
{
 
  lcd.gotoXY(2,1);
  lcd.print("How many times");
  lcd.gotoXY(2,2);
  lcd.print("feed the fishes?");

  int key=0;
  int temp=0;
  lcd.writeString(38,5,"OK",MENU_HIGHLIGHT);
  waitfor_OKkey();
  delay(500);
  //waitfor_OKkey();
  while(key!=1)
  {
    lcd.clear();
    pot=analogRead(0); // Le o valor do potenciometro na entrada 0;
    i=map(pot,0,950,0,7);
    lcd.gotoXY(5,3);
    lcd.print("Feed ");
    lcd.print(i);
    lcd.print(" times");
    lcd.writeString(38,5,"OK",MENU_HIGHLIGHT);
    if(digitalRead(2)==1)
    {
      // Se o botao estiver pressionado...
      key=1;
    }
  }
  delay(500);
  lcd.clear();

  if(DEBUG)
  {
    lcd.gotoXY(5,3);
    lcd.print("Escolheu: ");
    lcd.print(i);
    delay(5000);
    // Avoid the key is pressed for a long time and jumbs to menu.
  }
  lcd.clear();
}

/*
VERIFICAR ESTA FUNCAO setAlarm()
 */


void setAlarm()
{
  lcd.gotoXY(0,1);
  lcd.print("Alarm - test");
  lcd.gotoXY(0,2);
  lcd.print("Morning / Evening");
  lcd.gotoXY(0,3);
  lcd.print("==============");
  lcd.writeString(38,5,"OK",MENU_HIGHLIGHT);
  lcd.gotoXY(0,4);
  //lcd.print( key );
  delay(500);
  waitfor_OKkey();
}

//-------------------------------------------------------------------------

void setBackLight()
{
  lcd.writeString(0,2,"BackLight is ",MENU_NORMAL);
  if(blflag!=0)
  {
    lcd.writeString(60,2,"Off",MENU_HIGHLIGHT);
  }
  else
  {
    lcd.writeString(60,2,"On",MENU_HIGHLIGHT);
  }
  if(blflag!=0)
  {
    blflag=0;
    digitalWrite(BL_PIN,LOW);
  }
  else
  {
    blflag=1;
    digitalWrite(BL_PIN,HIGH);
  }
  delay(1500);
  lcd.clear();
}

//-------------------------------------------------------------------------

void status_()
{

  lcd.clear();


  int percentagemC1;
  int percentagemC2;

  int percentagem2C1;
  int percentagem2C2;

  int BC1;
  int BC2;
  int barraC1;
  int barraC2;

  percentagemC1=(numberC1 *100)/30;
  percentagemC2=(numberC2 *100)/30;

  percentagem2C1=100-percentagemC1;
  percentagem2C2=100-percentagemC2;

  lcd.gotoXY(12,2);
  lcd.print("C1 -> ");
  lcd.print(percentagem2C1);
  lcd.print(" %");

  lcd.gotoXY(12,5);
  lcd.print("C2 -> ");
  lcd.print(percentagem2C2);
  lcd.print(" %");

  barraC1=(percentagem2C1 *80)/100;
  barraC2=(percentagem2C2 *80)/100;

  lcd.drawRectangle(0,0,80,10,PIXEL_ON);
  lcd.drawFilledRectangle(0,0,barraC1,10,PIXEL_ON);
  lcd.drawRectangle(0,25,80,35,PIXEL_ON);
  lcd.drawFilledRectangle(0,25,barraC2,35,PIXEL_ON);


  delay(5000);

}

//-------------------------------------------------------------------------


void manual()
{
  //REVER
  digitalWrite(BL_PIN,HIGH);
  delay(200);
  lcd.clear();
  int key=0;
  int p=1;
  while(key!=1)
  {
    pot=analogRead(1); // Le o valor do potenciometro na entrada 0;
    i=map(pot,0,950,0,1);
    lcd.gotoXY(5,3);
    lcd.print(i);
    if(i==0)
    {
      lcd.writeString(10,2,"C1",MENU_HIGHLIGHT);
      lcd.writeString(60,2,"C2",MENU_NORMAL);
    }
    if(i==1)
    {
      lcd.writeString(10,2,"C1",MENU_NORMAL);
      lcd.writeString(60,2,"C2",MENU_HIGHLIGHT);
    }

    lcd.writeString(40,5,"OK",MENU_HIGHLIGHT);

    //WAITS FOR OK KEY PRESS
    if(digitalRead(2)==1)
    {
      // Se o botao estiver pressionado...
      key=1;
      lcd.clear();
    }

  }

  key=0;
  //waitfor_OKkey();
  while(key!=1)
  {
    pot=analogRead(1); // Le o valor do potenciometro na entrada 0;
    i=map(pot,0,950,0,1);
    lcd.gotoXY(5,3);
    lcd.print(i);
    // condicao para verificar em que lado esta o potenciometro
    // lado esquerdo ou lado direito
    if(i==0)
    {
      feederC1();
      key=1; //sai do loop
    }

    if(i==1)
    {
      feederC2();
      key=1; // sai do loop
    }
  } // Avoid the key is pressed for a long time and jumbs to menu.
  lcd.clear();
}

//-------------------------------------------------------------------------

void settings()
{
  lcd.clear();
  digitalWrite(BL_PIN,HIGH);
  demo();
  delay(5000);
}

//-------------------------------------------------------------------------


void bootProgram()
{
  // verificar se é possivel colocar esta funcao dentro da funcao setup() visto que esta so e executada uma vez.
  if(firstStartup==0)
  {
    //Draw bitmap image
    lcd.drawBitmapP(0,0,&introPIC[0],84,48);
    delay(500);
    lcd.gotoXY(20,4);
    lcd.print("Aquario");
    lcd.gotoXY(16,5);
    lcd.print("V1.5 Beta");
    for(int thisNote=0;thisNote<8;thisNote++)
    {
      int noteDelay=1000/noteDelays[thisNote];
      tone(3,melody[thisNote],noteDelay);
      int pauseBetweenNotes=noteDelay * 1.30;
      delay(pauseBetweenNotes);
    }
    firstStartup++;
    lcd.clear();
  }
}

//-------------------------------------------------------------------------

void morningAlarm()
{
  if(DEBUG)
  {
    Serial.println("Good Morning.");
    Serial.println("Start Feeding the fishes.");
  }

  lcd.clear();
  lcd.gotoXY(5,2);
  lcd.print("Good Morning");
  lcd.gotoXY(5,3);
  lcd.print("turn ON the lights");
  delay(2000);
  turnLightsOn();

  //workingLight on - start feeding
  digitalWrite(dPinWorking,HIGH); // set the LED on

  // fix the food counter

  /*
  for(int x = 0; feeding >= x; feeding--)
  {

  for(pos = 0; pos < 180; pos += 1)                 // goes from 0 degrees to 180 degrees
  {                                                  // in steps of 1 degree
  myServo1.write(pos);                              // tell servo to go to position in variable 'pos'
  delay(10);                                    // waits 15ms for the servo to reach the position
  }

  for(pos = 180; pos>=0; pos-=1)                  // goes from 180 degrees to 0 degrees
  {
  myServo1.write(pos);                              // tell servo to go to position in variable 'pos'
  delay(10);                                  // waits 15ms for the servo to reach the position
  }
  // alterar esta funcao do contentor de comida
  //foodContainer = foodContainer-1;
  }
   */
  if(DEBUG)
  {
    Serial.println("Stop Feeding the fishes.");
  }

  digitalWrite(dPinWorking,LOW); // set the LED off
}

//-------------------------------------------------------------------------

void eveningAlarm()
{
  if(DEBUG)
  {
    Serial.println("Good Evening.");
    Serial.println("Start Feeding the fishes.");
  }

  lcd.clear();
  lcd.gotoXY(5,2);
  lcd.print("Good Evening");
  lcd.gotoXY(5,3);
  lcd.print("turn OFF lights");
  delay(2000);


  //workingLight on - start feeding
  digitalWrite(dPinWorking,HIGH); // set the LED on

  // fix the food counter

  /*
  for(int x = 0; feeding >= x; feeding--)
  {

  for(pos = 0; pos < 180; pos += 1)                 // goes from 0 degrees to 180 degrees
  {                                                  // in steps of 1 degree
  myServo1.write(pos);                              // tell servo to go to position in variable 'pos'
  delay(10);                                    // waits 15ms for the servo to reach the position
  }

  for(pos = 180; pos>=0; pos-=1)                  // goes from 180 degrees to 0 degrees
  {
  myServo1.write(pos);                              // tell servo to go to position in variable 'pos'
  delay(10);                                  // waits 15ms for the servo to reach the position
  }
  // alterar esta funcao do contentor de comida
  //foodContainer = foodContainer-1;
  }
   */

  delay(1000);
  if(DEBUG)
  {
    Serial.println("Stop Feeding the fishes.");
  }
  digitalWrite(dPinWorking,LOW); // set the LED off
  turnLightsOff();

}

//-------------------------------------------------------------------------

void turnLightsOn()
{
  // turnOnTheLights
  if(DEBUG)
  {
    Serial.println("Light is ON.");
  }
  blflag=1;
  lcd.clear();
  digitalWrite(aquariumLight,HIGH);
  // Futuramente delay de 10 minutos antes de alimentar os peixes
  delay(1000);
}

//-------------------------------------------------------------------------

void turnLightsOff()
{
  //turnOffTheLights
  if(DEBUG)
  {
    Serial.println("Light is OFF.");
  }
  blflag=0;
  lcd.clear();
  digitalWrite(aquariumLight,LOW);
}

// Display the simple graphics demo
void demo()
{
  readTime();

  if(hour>=12)
  {
    lcd.writeString(68,0,"PM",MENU_NORMAL);
  }
  else
  {
    lcd.writeString(68,0,"AM",MENU_NORMAL);
  }
  if(hour==0)
  {
    hour=12;
  }
  if(hour>12)
  {
    hour=hour-12;
  }

  sprintf(timep1,"%02d",second);
  sprintf(timep2,"%2d:%02d",hour,minute);
  sprintf(dates,"%2d %s 20%2d",date,getmonth(month),year);

  lcd.writeStringBig(4,0,timep2,MENU_NORMAL);
  lcd.writeString(68,2,timep1,MENU_NORMAL);
  lcd.writeString(0,3,"==============",MENU_NORMAL);
  lcd.writeString(20,4,getday(dayofweek),MENU_NORMAL);
  lcd.writeString(10,5,dates,MENU_NORMAL);

  delay(1000);
}

//-------------------------------------------------------------------------

char *getday(int d)
{
  switch(d)
  {
    case 7:
      strcpy(dow,"Sunday");
      break;
    case 1:
      strcpy(dow,"Monday");
      break;
    case 2:
      strcpy(dow,"Tuesday");
      break;
    case 3:
      strcpy(dow,"Wednesday");
      break;
    case 4:
      strcpy(dow,"Thursday");
      break;
    case 5:
      strcpy(dow,"Friday");
      break;
    case 6:
      strcpy(dow,"Saturday");
      break;
  }
  return dow;
}

//-------------------------------------------------------------------------

char *getmonth(int d)
{
  switch(d)
  {
    case 1:
      strcpy(mon,"JAN");
      break;
    case 2:
      strcpy(mon,"FEB");
      break;
    case 3:
      strcpy(mon,"MAR");
      break;
    case 4:
      strcpy(mon,"APR");
      break;
    case 5:
      strcpy(mon,"MAY");
      break;
    case 6:
      strcpy(mon,"JUN");
      break;
    case 7:
      strcpy(mon,"JUL");
      break;
    case 8:
      strcpy(mon,"AUG");
      break;
    case 9:
      strcpy(mon,"SEP");
      break;
    case 10:
      strcpy(mon,"OCT");
      break;
    case 11:
      strcpy(mon,"NOV");
      break;
    case 12:
      strcpy(mon,"DEC");
      break;
  }
  return mon;
}