#include <Wire.h> // Librería para comunicación I2C
#include <LiquidCrystal_I2C.h> // Librería para LCD con I2C
#include <Keypad.h> // Librería para keypad
#include <HX711.h> // Librería para celda de carga
// Definiciones de pines para el módulo HX711
#define DT_PIN 3
#define SCK_PIN 2
const int RELAY_0_PIN = A0;
const int RELAY_1_PIN = A1;
const int BUZZER_PIN = A3;
// Definiciones de pines para el LCD I2C
#define LCD_ADDRESS 0x27 // Dirección I2C del LCD
#define LCD_COLUMNS 16 // Número de columnas del LCD
#define LCD_ROWS 2 // Número de filas del LCD
// Definiciones de pines para el keypad
const byte ROWS = 4; // Número de filas del keypad
const byte COLS = 4; // Número de columnas del keypad
char keys[ROWS][COLS] = { // Definición de las teclas del keypad
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte pin_rows[ROWS] = {11, 10, 9, 8}; // Pines de las filas del keypad
byte pin_cols[COLS] = {7, 6, 5, 4}; // Pines de las columnas del keypad
const int ON_FREQ = 1000;
const int ON_DURATION = 100;
unsigned int peso[5]={180, 240, 720, 720, 1650};
int i;
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_cols, ROWS, COLS);
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
HX711 scale;
const int NUM_OPTIONS = 4; // Número de opciones del menú
const char menuOptions[NUM_OPTIONS][20] = {
"1. Proceso ",
"2. Calibrar ",
"3. Configurar ",
"4. Acerca de "
};
const int NUM_SUB_OPTIONS = 6; // Número de subopciones del menú "Proceso"
const char subMenuOptions[NUM_SUB_OPTIONS][20] = {
"Masilla gris ",
"Masilla fibrat. ",
"Pegazulejo gris ",
"Pegazulejo blan.",
"Piso sobre piso ",
"Porcelanato "
};
int currentOption = 0; // Opción actual del menú
bool isInSubMenu = false; // Variable para indicar si se está en el submenú
void setup() {
pinMode(RELAY_0_PIN, OUTPUT);
pinMode(RELAY_1_PIN, OUTPUT);
digitalWrite(RELAY_0_PIN, 1);
digitalWrite(RELAY_1_PIN, 1);
scale.begin(DT_PIN, SCK_PIN);
scale.set_scale(0.416); // factor de escala en gramos
scale.tare(); // poner el valor actual como 0
lcd.begin(LCD_COLUMNS, LCD_ROWS);
lcd.print("Bienvenido!");
delay(1000);
lcd.clear();
displayMenu();
}
void loop() {
char key = keypad.getKey();
if (key) {
switch (key) {
case 'A':
if (isInSubMenu) {
selectSubOption();
} else {
selectOption();
}
break;
case '#':
if (isInSubMenu) {
nextSubOption();
} else {
nextOption();
}
break;
case '*':
if (isInSubMenu) {
previousSubOption();
} else {
previousOption();
}
break;
case 'D':
returnToMenu();
break;
}
}
}
void displayMenu() {
if (isInSubMenu) {
lcd.setCursor(0, 0);
lcd.print(subMenuOptions[currentOption]);
lcd.setCursor(0, 1);
lcd.print("< * A=OK # >");
} else {
lcd.setCursor(0, 0);
lcd.print(menuOptions[currentOption]);
lcd.setCursor(0, 1);
lcd.print("< * A=OK # >");
}
}
void nextOption() {
currentOption++;
if (currentOption >= NUM_OPTIONS) {
currentOption = 0;
}
isInSubMenu = false;
displayMenu();
}
void previousOption() {
currentOption--;
if (currentOption < 0) {
currentOption = NUM_OPTIONS - 1;
}
isInSubMenu = false;
displayMenu();
}
void selectOption() {
if (currentOption == 0) {
isInSubMenu = true;
currentOption = 0;
lcd.clear();
displayMenu();
} else {
lcd.clear();
lcd.print("Seleccionaste:");
lcd.setCursor(0, 1);
lcd.print(menuOptions[currentOption]);
delay(1000);
// Realiza las acciones correspondientes a la opción seleccionada
switch (currentOption) {
case 1:
// Lógica para la opción "Calibrar"
calibrarHX711();
break;
case 2:
// Lógica para la opción "Configurar"
break;
case 3:
// Lógica para la opción "Apagar"
break;
}
lcd.clear();
displayMenu();
}
}
void returnToMenu() {
if (isInSubMenu) {
isInSubMenu = false;
lcd.clear();
displayMenu();
}
}
void nextSubOption() {
currentOption++;
if (currentOption >= NUM_SUB_OPTIONS) {
currentOption = 0;
}
displayMenu();
}
void previousSubOption() {
currentOption--;
if (currentOption < 0) {
currentOption = NUM_SUB_OPTIONS - 1;
}
displayMenu();
}
void selectSubOption() {
lcd.clear();
lcd.print("Seleccionaste:");
lcd.setCursor(0, 1);
lcd.print(subMenuOptions[currentOption]);
delay(1000);
// Realiza las acciones correspondientes a la subopción seleccionada
switch (currentOption) {
case 0:
// Lógica para la subopción "Masilla gris"
i=0;
break;
case 1:
// Lógica para la subopción "Masilla fibratada"
i=1;
break;
case 2:
// Lógica para la subopción "Pegazulejo gris"
i=2;
break;
case 3:
// Lógica para la subopción "Pegazulejo blanco"
i=3;
break;
case 4:
// Lógica para la subopción "Piso sobre piso"
i=4;
break;
case 5:
// Lógica para la subopción "Porcelanato"
i=5;
break;
}
int cantidad = ingresarCantidad();
proceso(peso[i],cantidad);
lcd.clear();
displayMenu();
}
int ingresarCantidad() {
lcd.clear();
lcd.print("Ingresa cantidad:");
lcd.setCursor(0, 1);
String cantidadStr = ""; // Variable para almacenar la cantidad ingresada
while (true) {
char key = keypad.getKey();
if (key) {
if (key >= '0' && key <= '9') {
// Si se presiona un dígito numérico, agregarlo a la cantidad
cantidadStr += key;
lcd.print(key);
} else if (key == 'A') {
// Si se presiona el caracter 'A', finalizar la entrada de cantidad
break;
}
}
}
int cantidad = cantidadStr.toInt(); // Convertir la cantidad a un entero
return cantidad;
}
void proceso(int i, int cant){
lcd.clear();
lcd.print("En proceso");
for(int j=0;j<cant;j++){
tone(BUZZER_PIN, ON_FREQ, ON_DURATION);
delay(ON_DURATION);
noTone(BUZZER_PIN);
lcd.setCursor(0, 1);
lcd.print(j+1);
lcd.print(" de ");
lcd.print(cant);
delay(1000);
pesar(i);
}
tone(BUZZER_PIN, ON_FREQ, ON_DURATION);
delay(ON_DURATION);
noTone(BUZZER_PIN);
}
void pesar(float i ){
lcd.clear();
lcd.print("Pesando");
scale.tare();
float weight = scale.get_units(2); // obtener valor en g
//if (scale.is_ready()) {
while(weight<i){
weight = scale.get_units(2); // obtener valor en g
lcd.setCursor(0, 1);
lcd.print(weight);
lcd.print(" g ");
//Activamos el proceso de llenado de producto
digitalWrite(RELAY_0_PIN, 0);
}
//Desactivamos el proceso de llenado
digitalWrite(RELAY_0_PIN, 1);
//Abrimos la compuerta
digitalWrite(RELAY_1_PIN, 0);
delay(2000);
//Cerramos la compuerta
digitalWrite(RELAY_1_PIN, 1);
//}
}
void calibrarHX711() {
lcd.clear();
lcd.print("Coloca un objeto");
lcd.setCursor(0, 1);
lcd.print("de peso conocido");
delay(2000);
lcd.clear();
lcd.print("Calibrando...");
// Realiza la calibración utilizando un peso conocido
float pesoConocido = 100.0; // Peso conocido en gramos
scale.set_scale();
scale.tare();
float lecturaPromedio = 0.0;
int numLecturas = 10; // Número de lecturas para promediar
for (int i = 0; i < numLecturas; i++) {
lecturaPromedio += scale.get_units();
delay(100);
}
float factorEscala = lecturaPromedio / numLecturas / pesoConocido;
scale.set_scale(factorEscala);
lcd.clear();
lcd.print("Calibracion");
lcd.setCursor(0, 1);
lcd.print("completada");
delay(2000);
}