// ledb-pb-mqtt.ino
// Written by Wong SS - 1 Nov 2023
// this is similar to https://wokwi.com/projects/379930552025347073
// Except BLINK_T is used to do LED manipulation
// IMPORTANT: Make a copy of this project in your own wokwi free account.
// In prj.h, change the MQTT_ROOT_TOPIC name
// so that it will not clash with others running the same program
// IMPORTANT: In prj.h, MUST set these values correctly:
// MQTT_IN = 1 if WiFi and MQTT used, 0 if all local
// WOKWI = 1 to use WiFi simulator in WOKWI, 0 to use really ESP32 hw
// Files:
// test-dly-io-mqtt.ino - setup() and loop() ...
// prj.h - hardware connections
// dly-in-out.h - C++ classes SDELAYMS_T, SINPUT_T and SOUTPUT_T definition
// dly-in-out.cpp - C++ classes implementations
// blink.h and blink.cpp - BLINK_T class defined and implemented
// wifi-mqtt.cpp - wifi and mqtt functions
// ===========================================================================================
// What this program does:
// Red LED toggles at .3s intervals
// Green LED toggles at 0.5s intervals
// Both Red and Green LEDs blinking can be disable/enabled by PB1 & PB2
// or sending 'r' or 'g' to serial monitor
// Yellow LED always on for 200ms and off for 1800ms as system heartbeat
// This program is non-blocking even if WiFi & MQTT used and their connections fail.
// The WiFi connection, disconnections handling (reconnection) are all event driven, thus non-blocking
// However, an attempt to connect to MQTT server may take a little bit of time
// If MQTT_IN==1:
// Can also control the Red LED blinking enable/disable
// Use e.g. mqtt explorer (https://mqtt-explorer.com/) or mobile app to
// connect to "broker.emqx.io"
// PUBLISH (replace xxxx with the root name you use in prj.h)
// "xxxx/ledblink" with values "toggleR" or "toggleG"
// to enable/disable Red & GReen LED blinking. IMPORTANT: NOT double quotes!
// SUBSCRIBE topics that has values of "1" or "0" (sent by the system every 2s)
// "xxxx/ledy" - toggle "1" and "0" at 2s intervals indicating system alive
// "xxxx/ledr" - "1" means Red blinking is enabled, "0" disabled
// "xxxx/ledg" - "1" means Green blinking is enabled, "0" disabled
#include "prj.h" // defines MQTT_IN, WOKWI and MQTT_ROOT_TOPIC
#include "blink.h"
#include "dly-in-out.h" // C++ classes: SDELAYMS_T, SINPUT_T, SOUTPUT_T
// ===========================================================================================
BLINK_T blink_R(ledPinR,ledOnVal,300,300); // default initally enabled and on
BLINK_T blink_Y(ledPinY,ledOnVal,200,1800);
BLINK_T blink_G(ledPinG,ledOnVal,500,500);
#if (MQTT_IN) // defined in prj.h
// Functions in mqtt.cpp
void wifiMQTTInit();
void chkMQTT();
bool mqttPublish(char topic[], char value[]);
bool MQTT_ok();
char MQTT_ledVal_on[] = "1";
char MQTT_ledVal_off[] = "0";
char ledStatusY[] = MQTT_ROOT_TOPIC "/ledy"; // toggle 2 sec intervals indicating system alive
char ledStatusR[] = MQTT_ROOT_TOPIC "/ledr"; // blinking on or off
char ledStatusG[] = MQTT_ROOT_TOPIC "/ledg";
void ledMqttBlinkReport() {
if (blink_R.isEnabled()) {
// if (LEDR_blink_enabled_flg) {
mqttPublish(ledStatusR,MQTT_ledVal_on);
}
else {
mqttPublish(ledStatusR,MQTT_ledVal_off);
}
if (blink_G.isEnabled()) {
// if (LEDG_blink_enabled_flg) {
mqttPublish(ledStatusG,MQTT_ledVal_on);
}
else {
mqttPublish(ledStatusG,MQTT_ledVal_off);
}
}
#endif
void ledInit() {
Serial.print("\nInitialize LEDs");
blink_R.blinkEnable();
blink_Y.blinkEnable();
blink_G.blinkEnable();
#if (MQTT_IN) // defined in prj.h
Serial.printf(
"\nSubscribe topics to show LED blinking status. Value \"1\"=on, \"0\"=off"
"\n%s\n%s",ledStatusR,ledStatusG);
Serial.printf(
"\nIf system alive, this topic toggle between 1 and 0 at 2s intervals"
"\n%s",ledStatusY);
Serial.print("\nThese topic status are sent when Yellow LED turned on, i.e. every 2s");
#endif
}
// ===========================================================================================
SINPUT_T pb1(PB1,INPUT,200,LOW); // pin, inputType, bounceDuration, PressedIsLOW
SINPUT_T pb2(PB2,INPUT,200,LOW);
// ------------------------------------
void chkPBs() {
if (pb1.justPressed()) {
blink_R.toggleEnable();
Serial.print("\nPB1 enable/disable Red LED blinking");
}
if (pb2.justPressed()) {
blink_G.toggleEnable();
Serial.print("\nPB2 enable/disable Green LED blinking");
}
}
// ------------------------------------
void setup() {
Serial.begin(115200);
delay(100);
Serial.print("\nDemo:"
"\nRed & Green LEDs blink enable/disable controlled by PB1 & PB2, or Serial 'r' or 'g' cmds"
"\nYellow LED always pulse at 0.2s on and 1.8s off as system heartbeat");
#if (MQTT_IN)
Serial.print("\n\nMQTT ...."
"\nIMPORTANT: Make a copy of this project in your own wokwi free account."
"\nIn prj.h, change the MQTT_ROOT_TOPIC name to be unique to you"
"\nso that it will not clash with others running the same program");
wifiMQTTInit();
#endif
ledInit();
Serial.print("\nEnd of setup()\n");
}
// ------------------------------------
void chkSerial() {
if (Serial.available()) {
switch (Serial.read()) {
case 'r': case 'R':
blink_R.toggleEnable();
Serial.print("\nSerial 'r' or 'R' enable/disable Red LED blinking");
break;
case 'g': case 'G':
blink_G.toggleEnable();
Serial.print("\nSerial 'g' or 'G' enable/disable Green LED blinking");
break;
}
}
}
// ------------------------------------
#if (MQTT_IN) // defined in prj.h
// Send MQTT msgs on LED status
void mqtt_ledPub() {
static SDELAYMS_T pd(1000);
if (!pd.dlyExpiredRestart() || !MQTT_ok()) return; // every second report
static bool toggle = false;
char *valptr;
Serial.print("S");
toggle = !toggle;
valptr = toggle? MQTT_ledVal_on: MQTT_ledVal_off;
mqttPublish(ledStatusY,valptr); // publish Yellow
if (blink_R.isEnabled()) {
mqttPublish(ledStatusR,MQTT_ledVal_on);
}
else {
mqttPublish(ledStatusR,MQTT_ledVal_off);
}
if (blink_G.isEnabled()) {
mqttPublish(ledStatusG,MQTT_ledVal_on);
}
else {
mqttPublish(ledStatusG,MQTT_ledVal_off);
}
}
#endif
// ------------------------------------
void loop() {
blink_R.doBlink();
blink_Y.doBlink();
blink_G.doBlink();
chkPBs();
chkSerial();
#if (MQTT_IN)
chkMQTT(); // Must be called very regularly to service MQTT msgs
mqtt_ledPub();
#endif
}
// ------------------------------------
Follow NP SoE IoT Kit
PB-LED pins
LOW to on
Pressed LOW
RLED
pin23
YLED
pin19
GLED
pin18
PB1 pin27
PB2 pin25