/* Hello Wokwi! */
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//Parametros Encoder
const int EncoderPin_A = 7; //CLK
const int EncoderPin_B = 6; //DT
const int OkButton = 4; //SW
#define buzzerPin 11
#define trigPin 9
#define echoPin 10
#define buttonLEIT 8
int contador = 0;
int A_estado_actual;
int A_ultimo_estado;
int estadoLeit = 0;
int estadoCalc = 0;
int mes = 0;
int menuPasto=0;
int menuPast=0;
int Tf_ind1 = 130;
int Tf_ind2 =10;
int Jg_ind1 =125;
int Jg_ind2= 10;
int Mg_ind1=120;
int Mg_ind2 =10;
byte pasto=0;
float media;
float somatorio;
float duracao;
float distancia;
float kgMS;
float Avaca;
float cm;
float dist;
int velocidad_scroll = 300;
//::::::::::MENU::::::::::::::::::::::
String menu1[] = {"Conf. Equa", "Conf. Plate", "Leitura", "Calcule"}; //Inicializamos nuestro Array con los elementos del menu
int sizemenu1 = sizeof(menu1) / sizeof(menu1[0]); //Obtenemos el número de elementos ocupados en la matriz. en este caso 6
String menu2[] = {"T85 + Pai", "Jgs + Pai", "M.G + Pai", "Back"};
int sizemenu2 = sizeof(menu2) / sizeof(menu2[0]);
String menu3[] = {"T85 + Pai", "Jgs + Pai", "M.G + Pai", "Back"};
int sizemenu3 = sizeof(menu3) / sizeof(menu3[0]);
String menu4[] = {"Ind1","Ind2", "Back"};
int sizemenu4 = sizeof(menu4) / sizeof(menu4[0]);
String menu5[] = {"Mes", "Back"};
int sizemenu5 = sizeof(menu5) / sizeof(menu5[0]);
String linea1, linea2, linea3, linea4; //Lineas del LCD
int seleccion = 0;
int pos = 0;
int level_menu = 0; //Iniciamos la variable en el menu principal 0 --> 6
int opcion = 0;
bool btnpress = false; //Esta variable de retorno en false aegurando que el boton del Encoder aun no se ha oprimido
//Direccion EEPROM para almacenar la variable brillo_led1
byte flecha[] = {B10000, B11000, B11100, B11110, B11100, B11000, B10000, B00000}; //Creamos un array de 8 posiciones para la flecha del menu
void setup() {
Serial.begin(9600); //Habilitamos la salida serial por USB
pinMode (EncoderPin_A, INPUT);
pinMode (EncoderPin_B, INPUT);
pinMode (OkButton, INPUT_PULLUP);
pinMode(buttonLEIT, INPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin,INPUT);
pinMode(buzzerPin, OUTPUT);
// pinMode(led1, OUTPUT);
// pinMode(led2, OUTPUT);
//pinMode(led3, OUTPUT);
lcd.init();
lcd.backlight();
lcd.createChar(0, flecha); //Caracter personalizado
fn_creditos();
fn_menu(contador, menu1, sizemenu1); //Iniciamos presentando el menu principal
//brillo_led1 = EEPROM.read(dir_led1); // Obtiene el dato de EEPROM y lo envía a la variable brillo_led1
//brillo_led2 = EEPROM.read(dir_led2);
//brillo_led3 = EEPROM.read(dir_led3);
// analogWrite(led1,map(brillo_led1,0,9,0,255)); //Enviamos el dato leido de EEPROM al Led 1
//analogWrite(led2,map(brillo_led2,0,9,0,255));
// analogWrite(led3,map(brillo_led3,0,9,0,255));
pasto = EEPROM.read(0);
mes = EEPROM.read(1);
Tf_ind1 = EEPROM.read(2);
Tf_ind2 = EEPROM.read(3);
Jg_ind1 = EEPROM.read(4);
Jg_ind2 = EEPROM.read(5);
Mg_ind1 = EEPROM.read(6);
Mg_ind2 = EEPROM.read(7);
Serial.print("pasto: ");
Serial.println(pasto);
Serial.print("mes: ");
Serial.println(mes);
Serial.print("Tf_ind1: ");
Serial.println(Tf_ind1);
Serial.print("Tf_ind2: ");
Serial.println(Tf_ind2);
Serial.print("Jg_ind1: ");
Serial.println(Jg_ind1);
Serial.print("Jg_ind2: ");
Serial.println(Jg_ind2);
Serial.print("Mg_ind1: ");
Serial.println(Mg_ind1);
Serial.print("Mg_ind2: ");
Serial.println(Mg_ind2);
delay(2000);
A_ultimo_estado = digitalRead(EncoderPin_A); //Leemos el estado de la salida del Encoder usando el pin CLK
}
void loop() {
menu();
} // end loop
void selectOption() {
if (digitalRead(OkButton) == LOW) {
delay(500);
btnpress = true;
}
}
void menu() {
selectOption(); //Funcion para detectar cuando se oprime el encoder. btnpress == true
//Menu 1 {"Conf. Equa","Conf. Plate","Executar", "Calcular"}
if (level_menu == 0) { //Esta variable corresponde al nivel principal del menu. level_menu = 0.
if (fn_encoder(sizemenu1) ) { //Esta funcion muestra en el LCD el menu en el que estamos
fn_menu(contador, menu1, sizemenu1); //Esta funcion muestra la posicion dentro de ese menu segun el valor de la variable contador
}
if (btnpress) { //Verificamos si el boton del encoder fue oprimido. btnpress == true
//Configurar
if (contador == 0) {
contador = 0; //Seleccionamos la posicion donde quedara la flecha de seleccion.
fn_menu(contador, menu2, sizemenu2); //Vamos a la funcion que nos muestra las opciones
level_menu = 1; //Esta variable corresponde al nivel secundario del menu.
}
//Editar
if (contador == 1) {
contador = 0;
fn_menu(contador, menu3, sizemenu3);
level_menu = 2;
}
//Leitura
if (contador == 2) {
lcd.clear();
lcd.setCursor(2,0);
lcd.print("H");
lcd.setCursor(0,1);
lcd.print(distancia);
lcd.setCursor(5,0);
lcd.print("|");
lcd.setCursor(5,1);
lcd.print("|");
lcd.setCursor(7,0);
lcd.print("N");
lcd.setCursor(7,1);
lcd.print(0);
lcd.setCursor(9,0);
lcd.print("|");
lcd.setCursor(9,1);
lcd.print("|");
lcd.setCursor(11,0);
lcd.print("Soma");
lcd.setCursor(10,1);
lcd.print(somatorio);
estadoLeit = digitalRead(buttonLEIT);
if (estadoLeit == HIGH)
{
digitalWrite(trigPin,LOW);
delayMicroseconds(2);
digitalWrite(trigPin,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin,LOW);
duracao = pulseIn(echoPin,HIGH);
distancia = (100-(duracao/57.44));
contador = contador + 1;
somatorio = somatorio + distancia;
// ultra1();
Serial.println(distancia);
Serial.println(contador);
Serial.println(somatorio);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("H");
lcd.setCursor(0,1);
lcd.print(distancia);
lcd.setCursor(5,0);
lcd.print("|");
lcd.setCursor(5,1);
lcd.print("|");
lcd.setCursor(7,0);
lcd.print("N");
lcd.setCursor(7,1);
lcd.print(contador);
lcd.setCursor(9,0);
lcd.print("|");
lcd.setCursor(9,1);
lcd.print("|");
lcd.setCursor(11,0);
lcd.print("Soma");
lcd.setCursor(10,1);
lcd.print(somatorio);
if(estadoLeit == HIGH)
{
tone(buzzerPin,2500, 500);
delay(1000);
}
else
{
noTone(buzzerPin);}
delay(400);
}
// level_menu = 3;
}
btnpress = false;
//Calcular
if (contador == 3) {
estadoCalc = digitalRead(OkButton);
if (estadoCalc == HIGH)
{
media = somatorio/contador;
if(mes==1)
{
if(pasto==1)
kgMS=( 145 *media)+(0.96*1200);
if(pasto==2)
kgMS=( 145 *media)+(0.96*1100);
if(pasto==3)
kgMS=( 145 *media)+(0.96*1150);
//else
kgMS=(0);
}
kgMS = media*0.0220;
Avaca = 18,5/kgMS;
Serial.println(somatorio);
Serial.println(contador);
Serial.println(media);
Serial.println(kgMS);
Serial.println(Avaca);
lcd.clear();
lcd.setCursor(0,1);
lcd.print("Alt");
lcd.setCursor(0,2);
lcd.print(media);
lcd.setCursor(6,1);
lcd.print("kgMS");
lcd.setCursor(6,2);
lcd.print(kgMS);
lcd.setCursor(12,1);
lcd.print("AVac");
lcd.setCursor(12,2);
lcd.print(Avaca);
delay(400);
}
level_menu = 4;
}
btnpress = false; // Nos aseguramos que esta variable de retorno de la funcion selectOption() vuelva a su estado inicial
}
}// end select menu
//SubMenu Configurar {"T85 + Pai", "Jgs + Pai", "M.G + Pai", "Back"};
if (level_menu == 1) {
if (fn_encoder(sizemenu2)) { //Nos desplazamos con el encoder sleccionando las diferentes opciones
fn_menu(contador, menu2, sizemenu2);
}
if (btnpress) { //Verificamos si el boton del encoder fue oprimido. btnpress == true
//T85 + Pai
if (contador == 0)
{
contador = 0;
fn_submenu(contador, menu4, sizemenu4);
level_menu = 0;
}
// Jgs + Pai
if (contador == 1) {
contador = 1;
fn_submenu(contador, menu4, sizemenu4);
level_menu = 1;
}
// M.G + Pai
if (contador == 2) {
contador = 2;
fn_submenu(contador, menu4, sizemenu4);
level_menu = 2;
}
//BACK
if (contador == 3) {
contador = 0;
fn_menu(contador, menu1, sizemenu1);
level_menu = 0;
}
btnpress = false;
}
} //end submenu Configurar
//SubMenu Editar {"T85 + Pai", "Jgs + Pai", "M.G + Pai", "Back"}
if (level_menu == 2) {
if (fn_encoder(sizemenu3)) {
fn_menu(contador, menu3, sizemenu3);
}
if (btnpress) {
//T85 + Pai
if (contador == 0) {
contador = mes;
lcd.clear();
do
{
fn_contador_Mes();
mes = contador;
lcd.setCursor(1, 0);
lcd.print("P: T85 + Pai");
lcd.setCursor(1, 1);
lcd.print("Mes");
analogWrite(mes,map(mes,1,12,0,255));
lcd.setCursor(1, 2);
lcd.print(mes);
}
while(digitalRead(OkButton) == HIGH); //Instrucciones despues del do se repetirán mientras esta condición sea cierta
delay(500);
EEPROM.write(1, mes); // Se agrega a EEPROM con la dirección primero y valor de la variable después
contador = 3;
}
// Jgs + Pai
if (contador == 1) {
contador = mes;
lcd.clear();
do
{
fn_contador_Mes();
mes = contador;
lcd.setCursor(1, 0);
lcd.print("P: Jgs + Pai");
lcd.setCursor(1, 1);
lcd.print("Mes");
mes =(mes, map(mes, 1, 12, 0, 255));
analogWrite(1, mes);
lcd.setCursor(1, 2);
lcd.print(mes);
}
while(digitalRead(OkButton) == HIGH); //Instrucciones despues del do se repetirán mientras esta condición sea cierta
delay(500);
EEPROM.write(1, mes); // Se agrega a EEPROM con la dirección primero y valor de la variable después
contador = 3;
}
// M.G + Pai
if (contador == 2) {
contador = mes;
lcd.clear();
do
{
fn_contador_Mes();
mes = contador;
lcd.setCursor(1, 0);
lcd.print("P: M.G + Pai");
lcd.setCursor(1, 1);
lcd.print("Mes");
analogWrite(mes,map(mes,0,12,0,255));
lcd.setCursor(1, 2);
lcd.print(mes);
}
while(digitalRead(OkButton) == HIGH); //Instrucciones despues del do se repetirán mientras esta condición sea cierta
delay(500);
EEPROM.write(1, mes); // Se agrega a EEPROM con la dirección primero y valor de la variable después
contador = 3;
}
// Back
if (contador == 3) {
contador = 1;
fn_menu(contador, menu1, sizemenu1); // retorna ao menu principal
level_menu = 0;
}
btnpress = false;
}
} //end submenu Editar
//SubMenu Select Profile {"Preparation","StepMash","Wash","BoilStep","Wirpool","Rest","Back"}
if (level_menu == 3) {
if (fn_encoder(sizemenu4)) {
fn_menu(contador, menu4, sizemenu4);
}
if (btnpress) {
// Mes
if (contador == 0) {
}
}
if (contador == 2) {
contador = 2;
fn_menu(contador, menu1, sizemenu1); // Retorna ao menu principal
level_menu = 0;
}
btnpress = false;
}
} //end submenu Select Profile
void fn_contador_Mes() {
A_estado_actual = digitalRead(EncoderPin_A);
if (A_estado_actual != A_ultimo_estado) {
if (digitalRead(EncoderPin_B) != A_estado_actual) { //DT != CLK ``````````
contador ++;
delay(250);
}
else {
contador --;
delay(250);
}
}
if (contador >= 12) {
contador = 12;
}
if (contador <= 0) {
contador = 0;
}
}
void fn_creditos() {
lcd.setCursor(0, 0);
lcd.print(" Plate Meter ");
delay(2000);
for (int positionCounter = 0; positionCounter < 20; positionCounter++)
{
lcd.scrollDisplayRight(); //Desplaza el texto del LCD hacia la Izquierda
delay(velocidad_scroll);
}
}
void fn_menu(int pos, String menus[], byte sizemenu) {
lcd.clear();
linea1 = "";
linea2 = "";
linea3 = "";
linea4 = "";
if ((pos % 4) == 0) {
lcd.setCursor(0, 0);
lcd.write(byte(0));
linea1 = menus[pos];
if (pos + 1 != sizemenu) {
linea2 = menus[pos + 1];
linea3 =menus[pos+2];
linea4 =menus[pos+3];
}
}
else
{
if(pos ==0){
linea1 = menus[pos];
linea2 = menus[pos+1];
lcd.setCursor(0, 0);
lcd.write(byte(0));
linea3 = menus[pos+2];
lcd.setCursor(0, 0);
linea4 = menus[pos+3];
}
if(pos ==1){
linea1 = menus[pos-1];
linea2 = menus[pos];
lcd.setCursor(0, 1);
lcd.write(byte(0));
linea3 = menus[pos+1];
lcd.setCursor(0, 1);
linea4 = menus[pos+2];
}
if(pos ==2){
linea1 = menus[pos-2];
linea2 = menus[pos-1];
lcd.setCursor(0, 2);
lcd.write(byte(0));
linea3 = menus[pos];
lcd.setCursor(0, 2);
linea4 = menus[pos+1];
}
if(pos ==3){
linea1 = menus[pos-3];
linea2 = menus[pos-2];
lcd.setCursor(0,3 );
lcd.write(byte(0));
linea3 = menus[pos-1];
lcd.setCursor(0, 3);
linea4 = menus[pos];
}
if(pos ==4){
linea1 = menus[pos];
linea2 = menus[pos+1];
lcd.setCursor(0, 0);
lcd.write(byte(0));
linea3 = menus[pos+2];
lcd.setCursor(0, 1);
linea4 = menus[pos+3];
}
}
lcd.setCursor(1, 0);
lcd.print(linea1);
lcd.setCursor(1, 1);
lcd.print(linea2);
lcd.setCursor(1, 2);
lcd.print(linea3);
lcd.setCursor(1, 3);
lcd.print(linea4);
}
void fn_submenu(int pos, String menus[], byte sizemenu) {
lcd.clear();
linea1 = "";
linea2 = "";
linea3 = "";
linea4 = "";
if ((pos % 3) == 0) {
lcd.setCursor(0, 0);
lcd.write(byte(0));
linea1 = menus[pos];
if (pos + 1 != sizemenu) {
linea2 = menus[pos + 1];
linea3 =menus[pos+2];
}
}
else
{
if(pos ==0){
linea1 = menus[pos];
linea2 = menus[pos+1];
lcd.setCursor(0, 0);
lcd.write(byte(0));
linea3 = menus[pos+2];
}
if(pos ==1){
linea1 = menus[pos-1];
linea2 = menus[pos];
lcd.setCursor(0, 1);
lcd.write(byte(0));
linea3 = menus[pos+1];
}
if(pos ==2){
linea1 = menus[pos-2];
linea2 = menus[pos-1];
lcd.setCursor(0, 2);
lcd.write(byte(0));
linea3 = menus[pos];
}
if(pos ==3){
linea1 = menus[pos-3];
linea2 = menus[pos-2];
lcd.setCursor(0,3 );
lcd.write(byte(0));
linea3 = menus[pos-1];
}
}
lcd.setCursor(1, 0);
lcd.print(linea1);
lcd.setCursor(1, 1);
lcd.print(linea2);
lcd.setCursor(1, 2);
lcd.print(linea3);
}
void fn_submenu1(int pos, String menus[], byte sizemenu) {
lcd.clear();
linea1 = "";
linea2 = "";
linea3 = "";
linea4 = "";
if ((pos % 2) == 0) {
lcd.setCursor(0, 0);
lcd.write(byte(0));
linea1 = menus[pos];
if (pos + 1 != sizemenu) {
linea2 = menus[pos + 1];
}
}
else
{
if(pos ==0)
{
linea1 = menus[pos];
lcd.setCursor(0, 0);
lcd.write(byte(0));
linea2 = menus[pos+1];
}
if(pos ==1)
{
linea1 = menus[pos-1];
linea2 = menus[pos];
lcd.setCursor(0, 1);
lcd.write(byte(0));
}
}
lcd.setCursor(1, 0);
lcd.print(linea1);
lcd.setCursor(1, 1);
lcd.print(linea2);
lcd.setCursor(1, 2);
lcd.print(linea3);
}
bool fn_encoder(byte sizemenu) {
bool retorno = false;
A_estado_actual = digitalRead(EncoderPin_A);
if (A_estado_actual != A_ultimo_estado) {
if (digitalRead(EncoderPin_B) != A_estado_actual) { //DT != CLK
contador ++;
delay(250);
}
else {
contador --;
delay(250);
}
if (contador <= 0) {
contador = 0;
}
if (contador >= sizemenu - 1 ) {
contador = sizemenu - 1;
}
retorno = true;
}
return retorno;
}
void ultra1() {
digitalWrite(trigPin, LOW); // Limpa o trigger
delayMicroseconds(5);
digitalWrite(trigPin, HIGH); // Configurar o trigger para nível alto para transmissão de sinais
delayMicroseconds(10); // tempo para envio do sinal
digitalWrite(trigPin, LOW);
duracao = pulseIn(echoPin, HIGH); // Inicia contagem de tempo e lê o pino de eco
dist = duracao * 0.034 / 2; // Calcular a distância
}