#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <HX711.h>
#include <PubSubClient.h>
#include <RotaryEncoder.h>
//WiFi
const char* ssid = "Wokwi-GUEST";
const char* password = "";
//MQTT
const char* mqttServer = "qbik-dinamometro.cloud.shiftr.io";
const int mqttPort = 1883;
const char* mqttUser = "qbik-dinamometro";
const char* mqttPassword = "Tk2jnXSWJ7rJAq3D";
const char* mqttTopic = "datos/celda_de_carga";
//HX711
const int DOUT_PIN = 2; // Pin DOUT del HX711
const int SCK_PIN = 4; // Pin SCK del HX711
//RotaryEncoder
const int ENC_A = 25; // Pin A del encoder
const int ENC_B = 26; // Pin B del encoder
const int ENC_SW = 27; // Pin del botón del encoder
HX711 scale;
LiquidCrystal_I2C lcd(0x27, 20, 4);
WiFiClient espClient;
PubSubClient client(espClient);
RotaryEncoder encoder(ENC_A, ENC_B);
int buttonState = 0;
int lastButtonState = 0;
enum State {
DISPLAY_MENU,
EXECUTE_ACTION
};
enum MenuState {
OPTION_1,
OPTION_2,
OPTION_3,
OPTION_4,
NUM_OPTIONS
};
State currentState = DISPLAY_MENU;
MenuState currentMenuState = OPTION_1;
bool option1Executing = false;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password, 6);
lcd.init();
lcd.backlight();
scale.begin(DOUT_PIN, SCK_PIN);
scale.set_scale(0.4195);
pinMode(ENC_SW, INPUT_PULLUP);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Conectando a WiFi...");
}
Serial.println("Conectado a la red WiFi");
client.setServer(mqttServer, mqttPort);
displayMenu();
}
/*
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// Lectura de la celda de carga
long weight = scale.get_units(10);
// Muestra el valor en el LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Peso: " + String(weight) + " g");
// Envía el valor a MQTT
client.publish(mqttTopic, String(weight).c_str());
delay(1000);
}
*/
void loop() {
buttonState = digitalRead(ENC_SW);
encoder.tick();
switch (currentState) {
case DISPLAY_MENU:
handleDisplayMenu();
break;
case EXECUTE_ACTION:
handleExecuteAction();
break;
}
if (buttonState != lastButtonState) {
if (buttonState == LOW) {
handleButtonPress();
}
delay(50);
}
lastButtonState = buttonState;
}
void handleDisplayMenu() {
RotaryEncoder::Direction encoderDirection = encoder.getDirection();
if (encoderDirection != RotaryEncoder::Direction::NOROTATION) {
updateMenuState(encoderDirection);
displayMenu();
}
}
void updateMenuState(RotaryEncoder::Direction direction) {
if (direction == RotaryEncoder::Direction::CLOCKWISE) {
currentMenuState = static_cast<MenuState>((currentMenuState + 1) % NUM_OPTIONS);
} else if (direction == RotaryEncoder::Direction::COUNTERCLOCKWISE) {
currentMenuState = static_cast<MenuState>((currentMenuState + NUM_OPTIONS - 1) % NUM_OPTIONS);
}
}
void displayMenu() {
lcd.clear();
// Muestra todas las opciones
for (int i = 0; i < NUM_OPTIONS; ++i) {
lcd.setCursor(0, i);
lcd.print(i == currentMenuState ? "->" : " ");
switch (i) {
case OPTION_1:
lcd.print(" Opcion 1");
break;
case OPTION_2:
lcd.print(" Opcion 2");
break;
case OPTION_3:
lcd.print(" Opcion 3");
break;
case OPTION_4:
lcd.print(" Opcion 4");
break;
}
}
}
void handleButtonPress() {
currentState = EXECUTE_ACTION;
}
void handleExecuteAction() {
// Realiza acciones según la opción actual del menú
switch (currentMenuState) {
case OPTION_1:
// Acciones para la opción 1
executeOption1();
break;
case OPTION_2:
// Acciones para la opción 2
Serial.println("Acciones para la opción 2");
break;
case OPTION_3:
// Acciones para la opción 3
Serial.println("Acciones para la opción 3");
break;
case OPTION_4:
// Acciones para la opción 4
Serial.println("Acciones para la opción 4");
break;
}
currentState = DISPLAY_MENU;
displayMenu();
}
void executeOption1() {
option1Executing = true;
while (option1Executing) {
// Lectura de la celda de carga
if (!client.connected()) {
reconnect();
}
client.loop();
long weight = scale.get_units(10);
// Muestra el valor en el LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Peso: " + String(weight) + " g");
// Envía el valor a MQTT
client.publish(mqttTopic, String(weight).c_str());
delay(1000);
// Verifica si se ha presionado el botón del encoder para salir del bucle
if (digitalRead(ENC_SW) == LOW) {
option1Executing = false;
}
}
}
void reconnect() {
while (!client.connected()) {
Serial.println("Conectando al servidor MQTT...");
if (client.connect("ESP32Client", mqttUser, mqttPassword)) {
Serial.println("Conectado al servidor MQTT");
} else {
Serial.println("Error de conexión, intentando de nuevo en 5 segundos...");
delay(5000);
}
}
}