#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <PubSubClient.h>
// Configuración de WiFi
const char* ssid = "Wokwi-GUEST"; // Nombre de la red WiFi
const char* password = ""; // Sin contraseña (Wokwi)
// Configuración de Adafruit IO MQTT
const char* mqtt_broker = "io.adafruit.com";
const int mqtt_port = 1883;
const char* mqtt_user = "ralf2025"; // Tu usuario de Adafruit IO
const char* mqtt_pass = "aio_xdPv11OCbC0xAIzgJUdJeCCA55QP"; // Tu clave de Adafruit IO
const char* feed = "ralf2025/feeds/paradas"; // Feed único
// Configuración de LCD1602 (dirección I2C)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Configuración de MQTT
WiFiClient espClient;
PubSubClient client(espClient);
// Variables para manejar los datos
String received_message;
const String stop_id_target = "1"; // Configura el ID de la parada específica
String scroll_lines[3] = {"", "", ""}; // Array para almacenar líneas y tiempos
int scroll_index = 0; // Índice para el scrolling
// Función para conectar a WiFi
void connectToWiFi() {
Serial.print("Conectando a WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n¡Conexión WiFi exitosa!");
Serial.print("Dirección IP: ");
Serial.println(WiFi.localIP());
}
// Función de callback: se ejecuta cuando se recibe un mensaje MQTT
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Mensaje recibido en el feed: ");
Serial.println(topic);
// Convertir el payload a String
received_message = "";
for (int i = 0; i < length; i++) {
received_message += (char)payload[i];
}
Serial.println("JSON recibido:");
Serial.println(received_message);
// Procesar los datos recibidos
procesarDatosPorParada(received_message);
}
// Función para conectar al servidor MQTT
void connectToMQTT() {
while (!client.connected()) {
Serial.print("Conectando a MQTT...");
if (client.connect("ESP32_Client", mqtt_user, mqtt_pass)) {
Serial.println(" ¡Conexión exitosa!");
client.subscribe(feed); // Suscribirse al feed único
Serial.println("Suscrito al feed: " + String(feed));
} else {
Serial.print(" Error, rc=");
Serial.print(client.state());
Serial.println(" Reintentando en 5 segundos...");
delay(5000);
}
}
}
// Procesar los datos y almacenar las líneas y tiempos más próximos
void procesarDatosPorParada(String json) {
int stop_index = json.indexOf("\"" + stop_id_target + "\"");
if (stop_index > -1) {
// Inicializar variables
scroll_lines[0] = "";
scroll_lines[1] = "";
scroll_lines[2] = "";
int lines_index = json.indexOf("\"lines\":", stop_index) + 9;
int lines_end = json.indexOf("}", lines_index);
String lines_data = json.substring(lines_index, lines_end);
lines_data.replace("{", "");
lines_data.replace("\"", "");
// Procesar hasta 3 líneas
int line_count = 0;
while (line_count < 3) {
int colon_pos = lines_data.indexOf(":");
if (colon_pos == -1) break; // No hay más líneas
String line = lines_data.substring(0, colon_pos);
String time = lines_data.substring(colon_pos + 1, lines_data.indexOf(",", colon_pos));
time.trim();
scroll_lines[line_count] = line + ": " + time;
lines_data = lines_data.substring(lines_data.indexOf(",") + 1);
line_count++;
}
Serial.println("Líneas procesadas:");
for (int i = 0; i < 3; i++) {
Serial.println(scroll_lines[i]);
}
} else {
Serial.println("No se encontraron datos para esta parada.");
}
}
// Función para mostrar datos de forma rotativa en la LCD
void mostrarDatosRotativos() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Parada " + stop_id_target);
lcd.setCursor(0, 1);
lcd.print(scroll_lines[scroll_index]);
scroll_index = (scroll_index + 1) % 3; // Avanzar al siguiente dato
delay(3000); // Retraso de 3 segundos entre rotaciones
}
void setup() {
Serial.begin(115200);
// Inicializar LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Iniciando...");
// Conectar a WiFi
connectToWiFi();
// Configurar MQTT
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
// Conectar a MQTT
connectToMQTT();
lcd.clear();
lcd.print("Esperando datos...");
}
void loop() {
// Mantener la conexión MQTT
if (!client.connected()) {
connectToMQTT();
}
client.loop(); // Procesar mensajes MQTT
// Mostrar datos rotativos si hay datos disponibles
if (scroll_lines[0] != "") {
mostrarDatosRotativos();
}
}
El brillo de la pantalla puede modularse
con el potenciómetro de la parte trasera.