#include <WiFi.h> // WiFi control for ESP32
//#include <ThingsBoard.h> // ThingsBoard SDK
#include "ThingsBoard.h"
// Count Of formula for GPIO Relay Control
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
//Wowki WIFI Setup for Emulation and Testing
#define WIFI_AP_NAME "Wokwi-GUEST"
#define WIFI_PASSWORD ""
//Thingsboard Server Configuration
#define THINGSBOARD_MQTT_SERVER "server2.compuservenam.com"
#define THINGSBOARD_MQTT_ACESSTOKEN "1OMXU0ZxjM7GxaTMPhyx"
#define THINGSBOARD_MQTT_PORT 1883
#define SERIAL_DEBUG_BAUD 115200
WiFiClient espClient;
ThingsBoard tb(espClient);
int status = WL_IDLE_STATUS;
// Array with LEDs that should be controlled from ThingsBoard, one by one
uint8_t relays_control[] = { 26, 33, 25, 32 };
//Input State
#define INPUT_STATE1 23 // GIOP23 pin connected to button
#define INPUT_STATE2 22 // GIOP22 pin connected to button
// Temp Sensor Float
const float BETA = 3950; // should match the Beta Coefficient of the thermistor Temp Sensor
// Voltate Offset
int voltage_offset = 20;
// Main application loop delay
int quant = 20;
// Period/Delay of sending data on Voltage, INPUT and GPIO State data.
int send_delay = 1000;
// Time passed after temperature/humidity data was sent, milliseconds.
int send_passed = 0;
// Set to true if application is subscribed for the RPC messages.
bool subscribed = false;
// LED number that is currenlty ON.
int current_led = 0;
RPC_Response processSetGpioState(const RPC_Data &data)
{
Serial.println("Received the set GPIO RPC method");
int pin = data["pin"];
bool enabled = data["enabled"];
Serial.print("Setting LED ");
Serial.print(pin);
Serial.print(" to state ");
Serial.println(enabled);
// Red: 26, Green: 33, Blue: 25
digitalWrite(pin, enabled);
return String("{\"" + String(pin) + "\": " + String(enabled?"true":"false") + "}");
}
RPC_Response processGetGpioState(const RPC_Data &data)
{
Serial.println("Received the get GPIO RPC method");
String respStr = "{";
for (size_t i = 0; i < COUNT_OF(relays_control); ++i) {
int pin = relays_control[i];
Serial.print("Getting Relay ");
Serial.print(pin);
Serial.print(" state ");
bool ledState = digitalRead(pin);
Serial.println(ledState);
respStr += String("\"" + String(pin) + "\": " + String(ledState?"true":"false") + ", ");
}
respStr = respStr.substring(0, respStr.length() - 2);
respStr += "}";
return respStr;
}
// RPC handlers
RPC_Callback callbacks[] = {
{ "setGpioStatus", processSetGpioState },
{ "getGpioStatus", processGetGpioState },
};
void setup() {
Serial.begin(SERIAL_DEBUG_BAUD);
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
InitWiFi();
for (size_t i = 0; i < COUNT_OF(relays_control); ++i) {
pinMode(relays_control[i], OUTPUT);
}
// initialize the pushbutton pin as an pull-up input
// the pull-up input pin will be LOW when the switch is open and HIGH when the switch is closed.
pinMode(INPUT_STATE1, INPUT_PULLDOWN);
pinMode(INPUT_STATE2, INPUT_PULLDOWN);
//Temp Sensor Setup
pinMode(35,INPUT);
}
void loop()
{
delay(quant);
send_passed += quant;
// Reconnect to WiFi, if needed
if (WiFi.status() != WL_CONNECTED) {
reconnect();
return;
}
// Reconnect to ThingsBoard, if needed
if (!tb.connected()) {
subscribed = false;
// Connect to the ThingsBoard
Serial.print("Connecting MQTT to: ");
Serial.print(THINGSBOARD_MQTT_SERVER);
Serial.print(" at port no. ");
Serial.println(THINGSBOARD_MQTT_PORT);
Serial.print(" with access token ");
Serial.println(THINGSBOARD_MQTT_ACESSTOKEN);
if (!tb.connect(THINGSBOARD_MQTT_SERVER, THINGSBOARD_MQTT_ACESSTOKEN, THINGSBOARD_MQTT_PORT)) {
Serial.println("Failed to connect");
return;
}
}
// Subscribe for RPC, if needed
if (!subscribed) {
Serial.println("Subscribing for RPC... ");
// Perform a subscription. All consequent data processing will happen in
// callbacks as denoted by callbacks[] array.
if (!tb.RPC_Subscribe(callbacks, COUNT_OF(callbacks))) {
Serial.println("Failed to subscribe for RPC");
return;
}
Serial.println("Subscribe done");
subscribed = true;
}
// Check if it is a time to send Telementry Data (Loop for sending data on Volts, Inputstate and Temp)
if (send_passed > send_delay) {
Serial.println();
Serial.print("Sending data... ");
//voltage
analogReadResolution(12);
int volt = analogRead(34);// read the input
double voltage = map(volt,0, 4096, 0, 3600) + voltage_offset;// map 0-1023 to 0-3300 and add correction offset
voltage /=100;// divide by 100 to get the decimal values
Serial.print(" Voltage: ");
Serial.print(voltage);//print the voltge
Serial.println("V");
tb.sendTelemetryFloat("Voltage", voltage);
// Read Input State 1
int inputstate1 = digitalRead(INPUT_STATE1);
// print out the Input State1
Serial.print(" Input State 1: ");
Serial.println(inputstate1);
tb.sendTelemetryBool("Inputstate1", inputstate1);
// Read Input State 2
int inputstate2 = digitalRead(INPUT_STATE2);
// print out the Input State2
Serial.print(" Input State 2: ");
Serial.println(inputstate2);
tb.sendTelemetryBool("Inputstate2", inputstate2);
// read Temp Sensor
analogReadResolution(10);
int temp = analogRead(35);
float celsius = 1 / (log(1 / (1023. / temp - 1)) / BETA + 1.0 / 298.15) - 273.15;
Serial.print("Temperature: ");
Serial.print(celsius);
Serial.println(" ℃");
tb.sendTelemetryFloat("Temp", celsius);
send_passed = 0;
}
tb.loop();
}
void InitWiFi()
{
Serial.println("Connecting to AP ...");
// attempt to connect to WiFi network
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(WiFi.localIP());
Serial.println("Connected to AP");
}
void reconnect() {
// Loop until we're reconnected
status = WiFi.status();
if ( status != WL_CONNECTED) {
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(WiFi.localIP());
Serial.println("Connected to AP");
}
}