#include <Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define ONE_WIRE_BUS 7
#define dir 2
#define step 3
#define ValEntrada 12
#define ValSaida 11
#define resistencia 13
#define nivelAlto A0
#define bt_esq A1
#define bt_dir A2
#define bt_bai A3
#define bt_cim 6
#define bt_conf 8
int motorDelay = 5;
int pos = 0;
int etapa = 20;
int menu = 0;
int linha = 0;
int TemperaturaRampas[4] = {60,70,100,100};
int HistTemp = 2;
int TempoRampas[4] = {15,20,25,10};
int IngredienteRampas[4] = {1,0,2,3};
int temp_conta;
int aux_x;
unsigned long ultimo_bot = 0;
unsigned long tempo_debounce = 200;
char nomes_menu [6][17] =
{"Iniciar processo",
"Config. Etapa 1",
"Config. Etapa 2",
"Config. Etapa 3",
"Config. Etapa 4",
"Config. Histerese"};
char nomes_etapas [7][13] =
{"Enchendo...",
"1",
"2",
"3",
"4",
"Aquecendo...",
"Esvaziando..."};
byte arrowDown[8] = {B00100,B00100,B00100,B00100,B00100,B11111,B01110,B00100};
byte arrowRight[8] = {B00000,B00100,B00110,B11111,B00110,B00100,B00000,B00000};
byte setaCima[8] = {B00100,B01110,B11111,B00100,B00100,B00100,B00100,B00100};
unsigned long ultimoClick = 0; // última vez que o botão foi pressionado
unsigned long debounceDelay = 150; // O intervalo, igual ao delay do código anterior
unsigned long temp;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
Servo myservo;
int teclado_mais_menos(int mais_menos, int min, int max, bool sentido){
if((millis() - ultimo_bot) > tempo_debounce){
//Serial.println(String(mais_menos) + " " + String(max));
if(digitalRead(bt_cim) == 1){
if(!sentido)
mais_menos = mais_menos >= max ? min : mais_menos + 1; //se mais_menos é maior que max, então mais_menos recebe max, caso contrário mais_menos incrementa 1
else
mais_menos = mais_menos <= min ? max : mais_menos - 1;
ultimo_bot = millis();
lcd.clear();
}
if(digitalRead(bt_bai) == 1){
if(!sentido)
mais_menos = mais_menos <= min ? max : mais_menos - 1;
else
mais_menos = mais_menos >= max ? min : mais_menos + 1;
ultimo_bot = millis();
lcd.clear();
}
}
return mais_menos;
}
int teclado_dir_esq(int dir_esq, int min, int max){
if((millis() - ultimo_bot) > tempo_debounce){
if(digitalRead(bt_dir) == 1){
dir_esq = dir_esq >= max ? max : dir_esq + 1;
lcd.clear();
ultimo_bot = millis();
}
if(digitalRead(bt_esq) == 1){
dir_esq = dir_esq <= min ? min : dir_esq - 1;
lcd.clear();
ultimo_bot = millis();
}
}
return dir_esq;
}
int enter(){
if((millis() - ultimo_bot) > tempo_debounce){
if(digitalRead(bt_conf) == 1) {
return 1;
ultimo_bot = millis();
}
else return 0;
}
}
void tela_config(){
lcd.setCursor(2,0);
lcd.print(nomes_menu[menu]);
lcd.setCursor(1,1);
lcd.print("Temperatura: " + String(TemperaturaRampas[menu-1]) + (char)223 + "C");
lcd.setCursor(1,2);
lcd.print("Tempo: " + String(TempoRampas[menu-1]) + " s");
lcd.setCursor(1,3);
lcd.print("Ingred.: ");
if(IngredienteRampas[menu-1] > 0){
lcd.print("Sim - I" + String(IngredienteRampas[menu-1]));
}
else lcd.print("Nao");
linha = teclado_mais_menos(linha,1,3,1); //(int dir_esq, int min, int max, bool sentido)
lcd.setCursor(0, linha);
lcd.write(byte(1));
if(enter()){
linha = menu;
menu = 10;
lcd.clear();
}
switch(linha){
case 1:
TemperaturaRampas[menu-1] = teclado_dir_esq(TemperaturaRampas[menu-1], 50, 125); //(int dir_esq, int min, int max)
break;
case 2:
TempoRampas[menu-1] = teclado_dir_esq(TempoRampas[menu-1], 1, 100); //(int dir_esq, int min, int max)
break;
case 3:
IngredienteRampas[menu-1] = teclado_dir_esq(IngredienteRampas[menu-1], 0, 3); //(int dir_esq, int min, int max)
break;
}
}
void tela_processo(int A, int status, int ramp, int resta){
lcd.setCursor(1,0);
lcd.print("Status do Processo");
lcd.setCursor(0,1);
lcd.print("Etapa:");
lcd.print(nomes_etapas[status]);
int temperatura = sensors.getTempCByIndex(0);
lcd.setCursor(0,2);
lcd.print("TP: " + String(temperatura) + (char)223 + "C SP: ");
if(A>0) lcd.print(TemperaturaRampas[ramp] + (char)223 + "C");
else lcd.print("--");
lcd.setCursor(0,3);
lcd.print("TC: ");
if(A>1) lcd.print(TempoRampas[ramp] + "s ");
else lcd.print("-- ");
lcd.print("Restam ");
if(A>1) lcd.print(String(resta) + "s ");
else lcd.print("--");
}
void setup() {
lcd.init();
lcd.backlight();
lcd.createChar(0, arrowDown);
lcd.createChar(1, arrowRight);
lcd.createChar(2, setaCima);
pinMode(dir,OUTPUT);
pinMode(step,OUTPUT);
pinMode(ValEntrada,OUTPUT);
pinMode(ValSaida,OUTPUT);
pinMode(resistencia,OUTPUT);
pinMode(nivelAlto, INPUT);
pinMode(bt_esq, INPUT);
pinMode(bt_dir, INPUT);
pinMode(bt_bai, INPUT);
pinMode(bt_cim, INPUT);
pinMode(bt_conf, INPUT);
myservo.attach(5);
myservo.write(pos);
delay(200);
sensors.begin(); // Inicia a biblioteca
Serial.begin(115200);
Serial.println(">>> Automação de cozimento <<<");
Serial.println("Pressione o botão para iniciar\n");
}
void loop() {
sensors.requestTemperatures();
//Serial.println(String(menu) + " " + String(etapa) +" " + String(linha));
switch (menu){
case 10:
linha = teclado_mais_menos(linha,0,5,1); //(int dir_esq, int min, int max, bool sentido)
if(linha<4){
lcd.setCursor(0, linha);
lcd.write(byte(1));
lcd.setCursor(19, 3);
lcd.write(byte(0));
aux_x=0;
}else {
aux_x = linha - 3;
lcd.setCursor(0, 3);
lcd.write(byte(1));
lcd.setCursor(19, 0);
lcd.write(byte(2));
lcd.setCursor(19, 3);
lcd.write(byte(0));
}
for(int x=0;x<4;x++){
lcd.setCursor(1,x);
lcd.print(nomes_menu[x+aux_x]);
}
if(enter()){
menu = linha;
linha = 1;
lcd.clear();
}
break;
case 0:
etapa = 1;
menu = 11;
break;
case 11:
break;
case 5:
lcd.setCursor(1,0);
lcd.print(nomes_menu[menu]);
lcd.setCursor(0,2);
lcd.print("Histerese da Temp.:");
lcd.setCursor(8,3);
lcd.print(String(HistTemp) + (char)223 + "C");
HistTemp = teclado_dir_esq(HistTemp, 0, 10); //(int dir_esq, int min, int max)
if(enter()){
linha = menu;
menu = 10;
lcd.clear();
}
break;
default:
tela_config();
break;
}
switch(etapa){
/*case 0:
tela_processo(0,0,0);//(bool A, int ramp, int resta)
etapa = 1;
Serial.println("Processo iniciado!");
Serial.println("Enchendo recipiente...");
break;*/
case 1: //entrada de água
tela_processo(0,0,0,0);//(int A, int status, int ramp, int resta) (A = 0 não tem temp e nem tempo)
if(digitalRead(nivelAlto)){ // A = 1 tem temperatura e não tem tempo
digitalWrite(ValEntrada,0); // A = 2 tem ambos
etapa = 2;
lcd.clear();
Serial.println("Aquecendo até temperatura de " + String(TemperaturaRampas[0])
+ " °C da rampa 1.");
} else digitalWrite(ValEntrada,1);
break;
case 2: //aquecimento até temp.1 e adição do ingred. 1
aquecendo_ate_rampa(0, 1, 250); //(int rampa, int ingred, int pos_ingred)
break;
case 3: //tempo na rampa 1
controleRampa(0,1); //(int rampa, bool prox)
break;
case 4: //aquecendo até a rampa 2
aquecendo_ate_rampa(1, 0, 0); //(int rampa, int ingred, int pos_ingred)
break;
case 5: //tempo na rampa 2
controleRampa(1,1); //(int rampa, bool prox)
break;
case 6: //aquecimento até rampa 3 e adição do ingred. 2
aquecendo_ate_rampa(2, 2, 500); //(int rampa, int ingred, int pos_ingred)
break;
case 7: //tempo na rampa 3
controleRampa(2,0); //(int rampa, bool prox)
break;
case 8: //ingrediente 3 e última rampa
Serial.println("Adicionando ingrediente 3 -> posição 750");
inserirIngredientes(750);
temp = millis();
temp_conta = TempoRampas[3];
Serial.println("Rampa 4: restam " + String(temp_conta) + "segundos");
etapa = 9;
break;
case 9: //tempo na rampa 4
controleRampa(3,0);
break;
case 10: //fim
digitalWrite(resistencia,0);
digitalWrite(ValSaida,1);
if(temp_conta > 0){
if((millis() - temp) > 1000){
temp = millis();
temp_conta--;
Serial.println("Cozimento concluído! Transferindo líquido: restam "
+ String(temp_conta) + "segundos");
}
}
else{
digitalWrite(ValSaida,0);
Serial.println("Processo concluído!\n");
Serial.println(">>> Automação de cozimento <<<");
Serial.println("Pressione o botão para iniciar\n");
etapa = 0;
}
break;
}
}
void inserirIngredientes (int passo){
gira_motor (0,passo,1); //(int inicio, int fim, int dire)
garra(0, 180,1); //(int ini, int termino, int direc)
gira_motor (passo,1000,1);
garra(180, 0,-1);
gira_motor (0,1000,0);
}
void controleRampa (int rampa, bool prox){
tela_processo(2,rampa,rampa,temp_conta);//(int A, int status, int ramp, int resta)
if(temp_conta > 0){
if(sensors.getTempCByIndex(0) < (TemperaturaRampas[rampa] - HistTemp))
digitalWrite(resistencia,1);
else if(sensors.getTempCByIndex(0) >= TemperaturaRampas[rampa])
digitalWrite(resistencia,0);
if((millis() - temp) > 1000){
temp = millis();
temp_conta--;
Serial.println("Rampa " + String(rampa + 1) + ": restam " + String(temp_conta)
+ "segundos");
}
} else {
etapa++;
lcd.clear();
//Serial.println("Início do controle de temperatura e tempo da rampa " + String(rampa + 1));
if(prox){
digitalWrite(resistencia,1);
Serial.println("Aquecendo até temperatura de " + String(TemperaturaRampas[rampa + 1])
+ " °C da rampa " + String(rampa + 2));
}
else{
temp = millis();
temp_conta = 5;
}
}
}
void aquecendo_ate_rampa(int rampa, int ingred, int pos_ingred){
tela_processo(1,5,rampa,0);//(int A, int status, int ramp, int resta)
if(sensors.getTempCByIndex(0) < TemperaturaRampas[rampa])
digitalWrite(resistencia,1);
else {
digitalWrite(resistencia,0);
etapa++;
lcd.clear();
if(ingred > 0){
Serial.println("Adicionando ingrediente " + String(ingred) + " -> posição: " + String(pos_ingred));
inserirIngredientes(pos_ingred);
}
Serial.println("Início do controle de temperatura e tempo da rampa " + String(rampa + 1));
temp = millis();
temp_conta = TempoRampas[rampa];
Serial.println("Rampa " + String(rampa + 1) + ": restam " + String(temp_conta)
+ "segundos");
}
}
void gira_motor (int inicio, int fim, int dire) {
digitalWrite(dir,dire);
for(int i=inicio;i<fim;i++){
digitalWrite(step,1);
delay(motorDelay);
digitalWrite(step,0);
}
}
void garra(int ini, int termino, int direc){
for (pos = ini; pos >= termino; pos =+ direc) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 15ms for the servo to reach the position
}
delay(200);
}