collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: Controlador automático para o aquário.  (Lida 19179 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #15 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!

Offline PDI

  • Mini Robot
  • *
  • Mensagens: 677
Re: Controlador automático para o aquário.
« Responder #16 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.
Alfredo Garcia

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #17 em: 21 de Maio de 2010, 22:33 »
Obrigado,

para o switch usei este site: 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!

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #18 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.

Offline TigPT

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 5.372
    • Tiago Rodrigues
Re: Controlador automático para o aquário.
« Responder #19 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

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #20 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.

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #21 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);
}
}

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #22 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

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...

Offline zordlyon

  • Mini Robot
  • *
  • Mensagens: 1.768
Re: Controlador automático para o aquário.
« Responder #23 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..
Cumprimentos,
André Carvalho.

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #24 em: 18 de Junho de 2010, 14:40 »
Algumas imagens do projecto ainda na Breadboard.



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.


Ligações do LCD, falta colocar cola quente para proteger as soldas.


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.

Offline LoneWolf

  • Mini Robot
  • *
  • Mensagens: 763
  • ..Ser ou não ser não tem questão nenhuma...
    • A Visão do Lobo
Re: Controlador automático para o aquário.
« Responder #25 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
« Última modificação: 18 de Julho de 2010, 15:30 por TigPT »
Blog: A Visão do Lobo

Nick antigo: kilobyte

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #26 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:
               

Offline GnobarEl

  • Mini Robot
  • *
  • Mensagens: 92
Re: Controlador automático para o aquário.
« Responder #27 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;
}