Amigos,
estou trabalhando em um projeto no qual uso um LCD 16 x 2, um arduino uno, um RTC 1307, e alguns relés para controlar um sistema de irrigação.
Já publiquei a parte física da montagem no vídeo abaixo.
Agora meu problema é um menu que seja eficiente e eu consiga agregar as funções que quero.
Montei o código abaixo que funciona mas encontrei o seguinte problema. O horário mostrado na primeira ela fica congelado no momento que dispara o timer até o fim da programação.
Não sei se tenho que mudar o código de lugar.
Gostaria de criticas e aprimoramentos para colocar para funcionar. Quem quiser discutir estou aberto. O codigo foi feito aproveitando ideias da internet e por isso pode ter alguma inconsistencia. Mas agente aprende sempre.
Este sistema já está em teste de desempenho e espero que tenha ele pronto até o fim da semana.
Desde já agradeço a ajuda.
Quem quiser ver a parte física montada olha o video a seguir:
https://www.youtube.com/watch?v=iWk_hh_ZA60
int t1[7]= { //Timer do motor de 3cv
0,0,0,0,0,0,0};
int dd=1000; // used for delay in show timer data
#include <LiquidCrystal.h>
#include <Wire.h>
#include <EEPROM.h>
#include "RTClib.h"
RTC_DS1307 RTC;
// Definição dos pinos dos botões
#define bMenu A2 // Os pinos analógicos podem ser
#define bChange A3 // usados como digitais, bastando
#define bUp A0 // referenciá-los por A0, A1..
#define bDown A1
#define benter 8
#define bMenu0 90 // Valor de referência que a
#define bChange0 91 // função CheckButton() passa
#define bUp0 92 // indicando que um botão foi
#define bDown0 93 // solto
#define benter0 94
boolean aMenu, aChange, aUp, aDown, aenter; // Grava o ultimo valor lidos nos botões.
// Utilizado pela função Checkbutton p/ identificar quando há uma alteração no estado do pino dos botões
int horini=EEPROM.read(0); // variavel a ser alterada pelo menu
int minini=EEPROM.read(1);
int horfim=EEPROM.read(2);
int minfim=EEPROM.read(3);
char state=1; // variável que guarda posição atual do menu
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Declaração do objeto tipo lcd
String ArrumaZero(int i)
{
String ret;
if (i < 10) ret += "0";
ret += i;
return ret;
}
//============================================== SETUP
void setup()
{
Wire.begin();
lcd.begin(16, 2); // Iniciando a biblioteca do LCD
RTC.begin();
pinMode(bMenu, INPUT); // Botões
pinMode(bChange,INPUT);
pinMode(bUp, INPUT);
pinMode(bDown, INPUT);
pinMode(benter, INPUT);
pinMode(6, OUTPUT); // USADO PARA VALVULA 2
pinMode(7, OUTPUT); // USADO PARA VALVULA 1
pinMode(9, OUTPUT); // USADO PARA CONTROLAR A BOMBA
digitalWrite(bMenu, HIGH); // Aciona o pull-up interno
digitalWrite(bChange,HIGH); // dos botões
digitalWrite(bUp, HIGH);
digitalWrite(bDown, HIGH);
digitalWrite(benter, HIGH);
if (!RTC.isrunning())
{
RTC.adjust(DateTime(__DATE__, __TIME__));
}
t1[0]= EEPROM.read(0);
t1[1]= EEPROM.read(1);
t1[2]= EEPROM.read(2);
t1[3]= EEPROM.read(3);
t1[4]= 8;
t1[5]= 1;
}
//==============================================
//============================================== LOOP
void loop()
{
switch (state) { // Define checa qual tela atual
case 1: // executado quando na TELA 1
switch (CheckButton()) {
case bUp:
lcd.clear(); Set_state(7); // antes de mudar de tela, é necessário limpar o
break; // display com a função lcd.clear()
case bDown:
lcd.clear(); Set_state(2);
break;
default: // Caso nenhum botão tenha sido apertado, ela executa a set_state
Set_state(1); // mesmo assim para atualizar o display.
}
break;
case 2: // executado quando na TELA 2
switch (CheckButton()) {
case bMenu:
lcd.clear(); horini--;
break;
case bChange:
lcd.clear(); horini++;
break;
case bUp:
lcd.clear(); Set_state(1);
break;
case bDown:
lcd.clear(); Set_state(3);
break;
case benter:
EEPROM.write(0, horini);
default:
Set_state(2);
}
break;
case 3: // executado quando na TELA 3
switch (CheckButton()) {
case bMenu:
lcd.clear(); minini--;
break;
case bChange:
lcd.clear(); minini++;
break;
case bUp:
lcd.clear(); Set_state(2);
break;
case bDown:
lcd.clear(); Set_state(4);
break;
case benter:
EEPROM.write(1, minini);
default:
Set_state(3);
}
break;
case 4: // executado quando na TELA 4
switch (CheckButton()) {
case bMenu:
lcd.clear(); horfim--;
break;
case bChange:
lcd.clear(); horfim++;
break;
case bUp:
lcd.clear(); Set_state(3);
break;
case bDown:
lcd.clear(); Set_state(5);
break;
case benter:
EEPROM.write(2, horfim);
default:
Set_state(4);
}
break;
case 5: // executado quando na TELA 5
switch (CheckButton()) {
case bMenu:
lcd.clear(); minfim--;
break;
case bChange:
lcd.clear(); minfim++;
break;
case bUp:
lcd.clear(); Set_state(4);
break;
case bDown:
lcd.clear(); Set_state(6);
break;
case benter:
EEPROM.write(3, minfim);
default:
Set_state(5);
}
break;
case 6: // executado quando na TELA 6
switch (CheckButton()) {
case bUp:
lcd.clear(); Set_state(5);
break;
case bDown:
lcd.clear(); Set_state(7);
break;
default:
Set_state(6);
}
break;
case 7: // executado quando na TELA 7
switch (CheckButton()) {
case bUp:
lcd.clear(); Set_state(6);
break;
case bDown:
lcd.clear(); Set_state(1);
break;
default:
Set_state(7);
}
break;
default: ;
}
checktimer1();
delay(200); // to stop screen flicker
}
//============================================== FIM da função LOOP
void checktimer1()
// checa o horário para saber se irá ligar o motor
{
DateTime agora = RTC.now();
int hora = agora.hour();
int minuto = agora.minute();
int segundo = agora.second();
if (t1[4]==8);
{
if (hora==t1[0] && minuto==t1[1])
{
digitalWrite(7, HIGH);
delay(5000);
digitalWrite(9,HIGH);
delay(3600000);
digitalWrite(6,HIGH);
delay(5000);
digitalWrite(7,LOW);
delay(3600000);
digitalWrite(9,LOW);
digitalWrite(6,LOW);
t1[6]=1;
}
if (hora==t1[2] && minuto==t1[3])
{
digitalWrite(9, LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
t1[6]=0;
}
}
}
//============================================== CheckButton
char CheckButton() {
if (aMenu!=digitalRead(bMenu)) {
aMenu=!aMenu;
if (aMenu) return bMenu0; else return bMenu;
} else
if (aChange!=digitalRead(bChange)) {
aChange=!aChange;
if (aChange) return bChange0; else return bChange;
} else
if (aUp!=digitalRead(bUp)) {
aUp=!aUp;
if (aUp) return bUp0; else return bUp;
} else
if (aDown!=digitalRead(bDown)) {
aDown=!aDown;
if (aDown) return bDown0; else return bDown;
} else
if (aenter!=digitalRead(benter)) {
aenter=!aenter;
if (aenter) return benter0; else return benter;
} else
return 0;
}
//========================================================
//============================================== Set_state
void Set_state(char index) {
state = index; // Atualiza a variável state para a nova tela
DateTime agora = RTC.now();
String relogio_data = "DT: ";
String relogio_hora = "HR: ";
int dia = agora.day();
int mes = agora.month();
int ano = agora.year();
relogio_data += ArrumaZero(dia);
relogio_data += "/";
relogio_data += ArrumaZero(mes);
relogio_data += "/";
relogio_data += ano;
int hora = agora.hour();
int minuto = agora.minute();
int segundo = agora.second();
relogio_hora += ArrumaZero(hora);
relogio_hora += ":";
relogio_hora += ArrumaZero(minuto);
relogio_hora += ":";
relogio_hora += ArrumaZero(segundo);
switch (state) { // verifica qual a tela atual e exibe o conteúdo correspondente
case 1: //==================== state 1
lcd.setCursor(0, 0);
lcd.print(relogio_data);
lcd.setCursor(0, 1);
lcd.print(relogio_hora);
break;
case 2: //==================== state 2
lcd.setCursor(0,0);
lcd.print("Hor. Inicio");
lcd.setCursor(0,1);
lcd.print(horini);
break;
case 3: //==================== state 3
lcd.setCursor(0,0);
lcd.print("Min. Inicio");
lcd.setCursor(0,1);
lcd.print(minini);
break;
case 4: //==================== state 4
lcd.setCursor(0,0);
lcd.print("Hor. Fim");
lcd.setCursor(0,1);
lcd.print(horfim);
break;
case 5: //==================== state 5
lcd.setCursor(0,0);
lcd.print("Min. Fim");
lcd.setCursor(0,1);
lcd.print(minfim);
break;
case 6: //==================== state 6
lcd.setCursor(0,0);
lcd.print("Alarme:");
break;
case 7: //==================== state 7
lcd.setCursor(0,0);
lcd.print("Segundos:");
lcd.setCursor(0,1);
lcd.print( millis()/1000 , DEC); // mostra os segundos na tela
lcd.print(" s");
lcd.print(" ");
lcd.print(millis()/86400000, DEC); // mostra os dias na tela
lcd.print(" dias");
break;
default: ;
}
}
Tags:
pelo que sei os break; serve para para o case e não o switch, penso que não é necessário esse break aí fora.
O que entende por congelamento do LCD?
É ele desligar por inatividade?
Rui,
o problema é o seguinte. Como coloquei um timer para fazer funções e neste coloquei delay quando ele chega nesse ponto ele para tudo do arduino para esperar o delay, inclusive a atualização do lcd. Vc pode apertar qualquer botão que o lcd não muda até o delay acabar.
Qual é o delay que dizes que congela o lcd?
é o delay no meio do código. Ele liga a porta para ligar o motor e ficar ligado até irrigar o setor. Hoje estou por conta disso. Estou de folga. A irrigação começa amanhã então tenho que sair com isso hoje senão vai do jeito que está.
Para que serve esse delay?
Voce no loop só tem o switch case que trava no caso pretendido.
Se não tiver esse delay o que acontece?
Boas eu estou a fazer uma coisa bem mais simples mas não a estou a conseguir executar tenho um lcd 20x4 a mostrar valores instantaneos de 3 sensores de corrente e através de um botão switch quero mudar de tela para valores hora.
Como se faz a programação disso pode-me dizer??
Cumprimentos
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por