#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <M5Core2.h>
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define WIFI_CHANNEL 6
volatile bool pregunta = false; //variable que me dice si hay pregunta
volatile bool respuesta = false; //variable que me dice si hay respuestas
const char *MQTT_BROKER_ADRESS = "mqtt.eclipseprojects.io";
const uint16_t MQTT_PORT = 1883;
const char *MQTT_CLIENT_NAME = "PabloRomero_sub_test";
WiFiClient espClient;
PubSubClient mqttClient(espClient);
String payload;
String content = "";
String content2 = "";
void ConnectWiFi()
{
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
Serial.print("Connecting to WiFi ");
Serial.print(WIFI_SSID);
while (WiFi.status() != WL_CONNECTED)
{
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void InitMqtt()
{
mqttClient.setServer(MQTT_BROKER_ADRESS, MQTT_PORT);
SuscribeMqtt_Pregunta();
SuscribeMqtt_Respuestas();
mqttClient.setCallback(OnMqttReceived);
}
void ConnectMqtt()
{
while (!mqttClient.connected())
{
Serial.print("Starting MQTT connection...");
if (mqttClient.connect(MQTT_CLIENT_NAME))
{
Serial.println("Client connected!");
SuscribeMqtt_Pregunta();
SuscribeMqtt_Respuestas();
}
else
{
Serial.print("Failed MQTT connection, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void HandleMqtt()
{
if (!mqttClient.connected())
{
ConnectMqtt();
}
mqttClient.loop();
}
void SuscribeMqtt_Pregunta()
{
mqttClient.subscribe("Central/Pregunta"); //topic de la pregunta
}
void SuscribeMqtt_Respuestas() {
mqttClient.subscribe("Central/Respuestas"); //topic de las respuestas
}
//este es el unico que uso, que se ejecuta siempre en cualquier callback
void OnMqttReceived(char *topic, byte *payload, unsigned int length)
{
content = "";
content2 = "";
M5.Lcd.print("El dispositivo está esperando una pregunta");
if (String(topic) == "PabloRomero/Pregunta")
{
for (size_t i = 0; i < length; i++)
{
content.concat((char)payload[i]);
}
pregunta = true; //ha recibido una pregunta y vibra
if (pregunta)
{
M5.Axp.SetVibration(true);
delay(100);
M5.Axp.SetVibration(false);
delay(500);
}
}
else if (String(topic) == "PabloRomero/Respuestas")
{
for (size_t i = 0; i < length; i++)
{
content2.concat((char)payload[i]);
}
respuesta = true; //ha recibido una respuesta
}
else if (pregunta == true && respuesta == true) {
M5.Lcd.print(content);
M5.Lcd.print(content2);
}
}
void PublishMqtt_Resultado(String data)
{
payload = "";
payload = String(data);
mqttClient.publish("Central/Resultados", (char *)payload.c_str());
}
void setup(void)
{
Serial.begin(115200);
M5.begin();
M5.Lcd.setTextColor(YELLOW, BLACK); // Poner el color de texto en amaruillo
M5.Lcd.setTextSize(2); // Poner el tamaño de las letras en 2
M5.Lcd.setCursor(0, 0); // Mover el cursor a la posición (x, y) = (0, 0)
ConnectWiFi();
InitMqtt();
SuscribeMqtt_Pregunta();
SuscribeMqtt_Respuestas();
}
void loop()
{
String resultado = "";
M5.update(); // Actualiza estado de los botones
HandleMqtt();
if (M5.BtnA.wasReleased()) {
PublishMqtt_Resultado("Respuesta de Pablo Romero : A");
pregunta = false;
respuesta = false;
}
else if (M5.BtnB.wasReleased()) {
PublishMqtt_Resultado("Respuesta de Pablo Romero : B");
pregunta = false;
respuesta = false;
}
else if (M5.BtnC.wasReleased()) {
PublishMqtt_Resultado("Respuesta de Pablo Romero : C");
pregunta = false;
respuesta = false;
}
delay(10);
}
Se pretende diseñar un sistema de votación remota basado en el uso del dispositivo M5Core2 utilizando el protocolo MQTT para realizar encuestas.
Se pide programar uno de estos dispositivos para que haga lo siguiente:
Vibrar1 para indicar al usuario que ha recibido una pregunta. [0.25 puntos]
Se subscribirá a un topic para saber el contenido de la pregunta, y a otro para las opciones de respuesta. El dispositivo deberá saber en qué topic se ha recibido un mensaje. [1 punto]
Sólo si se ha recibido un mensaje en ambos topics, el dispositivo deberá mostrar por pantalla el mensaje de la pregunta, así como las posibles opciones de respuesta. [0.25 puntos]
(Ejemplo: Pregunta: "¿Te gusta la asignatura de Informática Industrial?" Opciones: "A. Mucho, B. Muchísimo, C. Es la mejor asignatura que he cursado.")
Sólo si se han recibido la pregunta y las opciones de respuesta, se esperará a que el usuario pulse alguno de los botones. Cuando lo haga, se publicará la respuesta en un topic2. [0.75 puntos]
Mientras no se reciba ninguna pregunta, muestra por pantalla un mensaje que indica al usuario que el dispositivo está esperando una pregunta. Una vez el usuario haya contestado a la pregunta, el dispositivo deberá volver a mostrar el mensaje de espera. En el que permanecerá hasta que se reciba una nueva pregunta. [0.25 puntos]
NOTAS:
1 La vibración no se tiene que mantener hasta que el usuario responda. Debe vibrar durante un momento para avisar al usuario y luego parar.
2 Las preguntas son publicadas por un ordenador central para todos los dispositivos disponibles en la encuesta. Sin embargo, cada dispositivo publicará una respuesta única. Por lo tanto, se deberá utilizar algún mecanismo que permita al ordenador central identificar qué dispositivo ha publicado dicha respuesta.
(Ejemplo: Publicar en un topic /respuesta el mensaje "A", "B" o "C" NO sería suficiente para identificar qué dispositivo ha emitido dicha respuesta).