Go Down

Topic: criar menu lcd shield (Read 6142 times) previous topic - next topic

tucandroid

ola amigos,

depois de conseguir colocar a mostrar as temps e acionar o alarme quando apenas a do aquario se encontra abaixo ou acima dos parametros por mim especificados.
podem ver aqui:
http://arduino.cc/forum/index.php/topic,156020.0.html

consegui tambem utilizar um sensor ultrasom que vai servir para medir a distancia da agua(para reposiçao), e o RTC


pensei no seguinte:
fazer um menu simples para alguns, muito dificil para mim :)

se possivel da seguinte forma:
Menu Inicial
Linha 1 -> Hora (RTC)
Linha 2 -> Data (RTC)
Menu 1
Linha 1 -> Temp Aquario
Linha 2 -> xx.xxºC
Menu 2
Linha 1 -> Temp Exterior
Linha 2 -> xx.xxºC
Menu 3
Linha 1 -> Distancia
Linha 2 -> xxxCm
Menu 4
Linha 1 -> Parametros (servia para alterar a temp minima e maxima)
Linha 2 -> Min xx.xxºC
e         -> Max xx.xxºC

ora pelo que andei a ver, e visto a minha shield ter os botoes incluidos ligados no pino A0
a "identificaçao" dos botoes é a seguinte:
Code: [Select]
if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50)   return btnRIGHT; 
if (adc_key_in < 195)  return btnUP;
if (adc_key_in < 380)  return btnDOWN;
if (adc_key_in < 555)  return btnLEFT;
if (adc_key_in < 790)  return btnSELECT;


ora a minha grande duvida é como fazer o menu, ja tive a pesquisar alguns, e nao consigo perceber a "logica" da coisa. :(

alguem da uma ajudinha pf?

cumprimentos

bubulindo

Tens de criar uma função que trata unicamente do LCD e é chamada de X em X tempo dentro da loop.

Code: [Select]


//para tornar o código mais bonito...
#define HOME      0
#define MENU_1   1
#define MENU_2   2
#define MENU_3   3
#define MENU_4   4

void trataLCD() {

static unsigned char menu = 0; //isto faz com que o menu correcto seja mostrado sempre que a função é chamada.

unsigned int button = analogRead(A0);
//criar funcao que passa o analog read para uma variavel tipo butUP...

//máquina de estados.
switch(menu) {
  case HOME: {
    if (button == butUP) {
      menu = MENU_1;
    }
    if (button == butDOWN) {
      menu = MENU_4;
    }
    lcd.clear();
    lcd.print(hora...);
    lcd.setCursor(0,1);
    lcd.print(data...);
    button = butNONE;
    break;
  };
  case MENU_1: {
    if (button == butUP) {
      menu++;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print(temp aquario);
    button = butNONE;
    break;
  };
  case MENU_2: {
    if (button == butUP) {
      menu++;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print(temp exterior);
    button = butNONE;   
    break;
  };
  case MENU_3: {
        if (button == butUP) {
      menu++;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print(distancia);
    button = butNONE;
    break;
  };
  case MENU_4: {
    if (button == butUP) {
      menu = HOME;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print(temperatura...);
    button = butNONE;

    break;
  };
}

Depois tens de criar uma função que passa do valor do AD relativo ao botão para um valor fixo. Por exemplo:

Code: [Select]


#define butUP           0
#define butDOWN      1
...

Outra coisa a ter em conta é garantir que o botão apenas é considerado uma vez. Ou seja, garantir que se eu manter o dedo no botão os dados não andam sempre a circular... para tal podes chamar a função apenas quando alguém mexeu num dos botões, por exemplo e apenas chamar outra vez se o valor mudou (ou seja, o utilizador levantou o dedo.
This... is a hobby.

tucandroid

dai eu dizer que nao entendo a logica. :)

na primeira parte:
Code: [Select]
case MENU_1: {
    if (button == butUP) {
      menu++;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print(temp aquario);
    button = butNONE;
    break;


nao tem de levar tambem:
Code: [Select]
case MENU_1: {
    if (button == butUP) {
      menu++;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print(temp aquario);
    lcd.setCursor(0,1);
    lcd.print(sensor temp); //este sensor temp, tem de ser alterado pelo codigo certo é claro. :)
    button = butNONE;
    break;



na segunda parte, referes-te a algo assim:
Code: [Select]
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0);      // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
if (adc_key_in < 50)   return btnRIGHT; 
if (adc_key_in < 195)  return btnUP;
if (adc_key_in < 380)  return btnDOWN;
if (adc_key_in < 555)  return btnLEFT;
if (adc_key_in < 790)  return btnSELECT;   
return btnNONE;  // when all others fail, return this...
}


obrigado pela ajuda desde ja :)

tucandroid

ja andei a fazer testes e nao consigo chegar la de maneira nenhuma mesmo. :(

da sempre erros no IDE

é possivel deitares a mao directamente no codigo :)

Code: [Select]
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int tempAlarmPin = 22;    //Buzzer ligado no PIN 22
#define ONE_WIRE_BUS 28 //Sensores ligados no PIN 28
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//Endereços sensores
DeviceAddress insideThermometer = { 0x28, 0x0C, 0x0D, 0xB0, 0x04, 0x00, 0x00, 0x80 };
DeviceAddress outsideThermometer = { 0x28, 0x49, 0x04, 0xB1, 0x04, 0x00, 0x00, 0x62 };

void setup(void)
{
// Start up the library
sensors.begin();
// set the resolution to 10 bit (good enough?)
sensors.setResolution(insideThermometer, 10);
sensors.setResolution(outsideThermometer, 10);

pinMode(tempAlarmPin, OUTPUT);    //Buzzer

lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
}

void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
lcd.print("Error");
} else {
lcd.print(tempC);
lcd.print("C");
}
}

void alarm(DeviceAddress deviceAddress){
float tempA = sensors.getTempC(deviceAddress);
if ( (tempA) >= 25) //Temp superior a 23 Graus
    {
    digitalWrite(tempAlarmPin, HIGH);
    delay(500);
    digitalWrite(tempAlarmPin, LOW);
    }
    else if ( (tempA) <= 20) //Temp inferior a 20 graus
    {
    digitalWrite(tempAlarmPin, HIGH);
    delay(500);
    digitalWrite(tempAlarmPin, LOW);

    }
}

void loop(void)
{
delay(2000);
sensors.requestTemperatures();
lcd.setCursor(0,0);
lcd.print("AGUA: ");
printTemperature(insideThermometer);
alarm(insideThermometer);
lcd.setCursor(0,1);
lcd.print("FORA: ");
printTemperature(outsideThermometer);
}



bubulindo

onde eu coloquei o lcd.print é para tu colocares os dados que pretendes.

a lógica do menu está ai, apenas tens de formatar os dados.

não estou no computador.
This... is a hobby.

tucandroid

hey amigo,

acreditas que tou mesmo a nora com isto? :(

nao consigo mesmo atinar com isto.

é assim tao complicado ou estou a ser burro como uma porta? :)

cumprimentos

tucandroid

#6
Apr 06, 2013, 03:41 pm Last Edit: Apr 06, 2013, 03:43 pm by tucandroid Reason: 1
fiz umas alteraçoes para testar o animal, so começa a dar erros na IDE no loop.

podes ver pf?

alterei todos os print.lcd para mostrar o texto, depois coloco ao certo, mas assim a ver se entro na coisa. :)
o codigo é este:
Code: [Select]
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int tempAlarmPin = 22;    //Buzzer ligado no PIN 22
#define ONE_WIRE_BUS 28 //Sensores ligados no PIN 28
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//Endereços sensores
DeviceAddress insideThermometer = { 0x28, 0x0C, 0x0D, 0xB0, 0x04, 0x00, 0x00, 0x80 };
DeviceAddress outsideThermometer = { 0x28, 0x49, 0x04, 0xB1, 0x04, 0x00, 0x00, 0x62 };
// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define butRIGHT  0
#define butUP     1
#define butDOWN   2
#define butLEFT   3
#define butSELECT 4
#define butNONE   5
#define HOME      0
#define MENU_1   1
#define MENU_2   2
#define MENU_3   3
#define MENU_4   4

// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0);      // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return butNONE; // We make this the 1st option for speed reasons since it will be the most likely result
if (adc_key_in < 50)   return butRIGHT;  
if (adc_key_in < 195)  return butUP;
if (adc_key_in < 380)  return butDOWN;
if (adc_key_in < 555)  return butLEFT;
if (adc_key_in < 790)  return butSELECT;  
return butNONE;  // when all others fail, return this...
}
void setup(void)
{
// Start up the library
sensors.begin();
// set the resolution to 10 bit (good enough?)
sensors.setResolution(insideThermometer, 10);
sensors.setResolution(outsideThermometer, 10);

pinMode(tempAlarmPin, OUTPUT);    //Buzzer

lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
}

void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
lcd.print("Error");
} else {
lcd.print(tempC);
lcd.print("C");
}
}

void alarm(DeviceAddress deviceAddress){
float tempA = sensors.getTempC(deviceAddress);
if ( (tempA) >= 25) //Temp superior a 23 Graus
   {
   digitalWrite(tempAlarmPin, HIGH);
   delay(500);
   digitalWrite(tempAlarmPin, LOW);
   }
   else if ( (tempA) <= 20) //Temp inferior a 20 graus
   {
   digitalWrite(tempAlarmPin, HIGH);
   delay(500);
   digitalWrite(tempAlarmPin, LOW);

   }
}

void trataLCD() {

static unsigned char menu = 0; //isto faz com que o menu correcto seja mostrado sempre que a função é chamada.

unsigned int button = analogRead(A0);
//criar funcao que passa o analog read para uma variavel tipo butUP...

//máquina de estados.
switch(menu) {
 case HOME: {
   if (button == butUP) {
     menu = MENU_1;
   }
   if (button == butDOWN) {
     menu = MENU_4;
   }
   lcd.clear();
   lcd.print("hora...");
   lcd.setCursor(0,1);
   lcd.print("data...");
   button = butNONE;
   break;
 };
 case MENU_1: {
   if (button == butUP) {
     menu++;
   }
   if (button == butDOWN) {
     menu--;
   }
   lcd.clear();
   lcd.print("temp aquario");
   button = butNONE;
   break;
 };
 case MENU_2: {
   if (button == butUP) {
     menu++;
   }
   if (button == butDOWN) {
     menu--;
   }
   lcd.clear();
   lcd.print("temp exterior");
   button = butNONE;    
   break;
 };
 case MENU_3: {
       if (button == butUP) {
     menu++;
   }
   if (button == butDOWN) {
     menu--;
   }
   lcd.clear();
   lcd.print("distancia");
   button = butNONE;
   break;
 };
 case MENU_4: {
   if (button == butUP) {
     menu = HOME;
   }
   if (button == butDOWN) {
     menu--;
   }
   lcd.clear();
   lcd.print("temperatura...");
   button = butNONE;

   break;
 }
}

void loop(void)
{
}


na parte do loop nao sei como fazer. :(

bubulindo

#7
Apr 06, 2013, 04:21 pm Last Edit: Apr 06, 2013, 04:28 pm by bubulindo Reason: 1
Que erro dá?

Code: [Select]

void trataLCD() {

static unsigned char menu = 0; //isto faz com que o menu correcto seja mostrado sempre que a função é chamada.

unsigned int button = read_LCD_buttons();

//máquina de estados.
switch(menu) {
  case HOME: {
    if (button == butUP) {
      menu = MENU_1;
    }
    if (button == butDOWN) {
      menu = MENU_4;
    }
    lcd.clear();
    lcd.print("hora...");
    lcd.setCursor(0,1);
    lcd.print("data...");
    button = butNONE;
    break;
  };
  case MENU_1: {
    if (button == butUP) {
      menu++;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print("temp aquario");
    button = butNONE;
    break;
  };
  case MENU_2: {
    if (button == butUP) {
      menu++;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print("temp exterior");
    button = butNONE;   
    break;
  };
  case MENU_3: {
        if (button == butUP) {
      menu++;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print("distancia");
    button = butNONE;
    break;
  };
  case MENU_4: {
    if (button == butUP) {
      menu = HOME;
    }
    if (button == butDOWN) {
      menu--;
    }
    lcd.clear();
    lcd.print("temperatura...");
    button = butNONE;

    break;
  }
}
This... is a hobby.

tucandroid

pelo que me parece estou a falhar na parte do loop. ;(

Code: [Select]
160: error: a function-definition is not allowed here before '{' token
161: error: expected `}' at end of input

bubulindo

Acho que precisas de tirar uma pausa...

Code: [Select]

 case MENU_4: {
   if (button == butUP) {
     menu = HOME;
   }
   if (button == butDOWN) {
     menu--;
   }
   lcd.clear();
   lcd.print("temperatura...");
   button = butNONE;

   break;
 }//end case
} //end switch...

}//<- Falta isto... end função.

void loop(void)
{
}


This... is a hobby.

tucandroid

ah e tal, burro que nem uma porta....

ja passou na IDE, vamos ver no bicho agora :)

tucandroid

agora nao mostra nada no lcd. :(

esta complicado isto. :)


bubulindo

É preciso chamares a função para ela fazer alguma coisa... com a loop vazia o sistema não faz nada.
This... is a hobby.

tucandroid

a porta ali esta farta de olhar pra mim. :)

meti
trataLCD é isso certo?

mas agora apenas mostra

Hora
Data

com um efeito tipo onda, vai diminuindo a intensidade dos "pixels" de cima para baixo. da um efeito fixe, mas acho que nao é bom isto. :)

se carregar nos botoes, nada muda. :(

vou mesmo fazer uma pausa nisto.

tucandroid

faltava o delay :)

mas mesmo assim, nao muda de menu :(

Go Up