// INPUT
// DHT22
#include <WiFi.h>
#include <ThingsBoard.h>
#include <Arduino_MQTT_Client.h>
#include <DHT.h>
#define DHT22_PIN 5
DHT dht22(DHT22_PIN, DHT22);
float Temp;
float Humidity;
#define CURRENT_FIRMWARE_TITLE "TEST"
#define CURRENT_FIRMWARE_VERSION "1.0.0"
#define TB_SERVER "thingsboard.cloud"
#define TOKEN "wO5kC5hzn91VFgclDqbQ"
char auth[] = TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
constexpr uint16_t MAX_MESSAGE_SIZE = 128U;
WiFiClient espClient;
Arduino_MQTT_Client mqttClient(espClient);
ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE);
void connectToWiFi() {
Serial.println("Connecting to WiFi...");
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
WiFi.begin(ssid, pass);
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("\nFailed to connect to WiFi.");
} else {
Serial.println("\nConnected to WiFi");
}
}
void connectToThingsBoard() {
if (!tb.connected()) {
Serial.println("Connecting to ThingsBoard server");
if (!tb.connect(TB_SERVER, TOKEN)) {
Serial.println("Failed to connect to ThingsBoard");
} else {
Serial.println("Connected to ThingsBoard");
}
}
}
void sendDataToThingsBoard(float Temp, float Humidity, int lightValue, bool LED_Button, bool DCMotor_Button) {
String jsonData = "{\"temperature\":" + String(Temp) + ", \"humidity\":" + String(Humidity) + ", \"luxValue\":" + String(lightValue) + ", \"led_button\":" + String(LED_Button) + ", \"DCmotor_button\":" + String(DCMotor_Button) + "}";
tb.sendTelemetryJson(jsonData.c_str());
Serial.println("Data sent");
}
// LDR
#define Light_intensity_A0 35
float lightValue;
// MPU6050
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
Adafruit_MPU6050 mpu;
// Potentiometer
#define potentiometer 34
int currentPWM;
int LED_pwm = 0;
int DC_Motor_pwm = 0;
int deviceState = 1;
// Knob
#define Knob_CLK 2
#define Knob_DT 4
#define Knob_SW 0
int newClk = 0;
int lastClk = 0;
int sensor_page = 7;
String Sensor;
float Reading;
// Button_LED
#define LED_Button 18
bool ledButtonState = false; // Track LED button state
unsigned long lastDebounceTime_LED = 0;
unsigned long debounceDelay = 50; // Debounce delay
bool manualLEDTurnOff = false; // To track manual turn off state
// Button_Motor
#define DCMotor_Button 19
bool motorButtonState = false; // Track Motor button state
unsigned long lastDebounceTime_Motor = 0;
bool manualMotorTurnOff = false; // To track manual turn off state
// OUTPUT
// LED
#define LED 16
// Motor
#define DCMotor 17
// Fan switch
int FanState = 0;
// LED switch
int LightState = 0;
// Display OLED
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// create SSD1306 display object connected to I2C
String displayString;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
connectToWiFi();
connectToThingsBoard();
// INPUT
// DHT22
dht22.begin();
// LDR
pinMode(Light_intensity_A0, INPUT);
// MPU6050
mpu.begin();
// Potentiometer
pinMode(potentiometer, INPUT);
// Knob
pinMode(Knob_CLK, INPUT);
pinMode(Knob_DT, INPUT);
// Button_LED
pinMode(LED_Button, INPUT_PULLUP);
// Button_Motor
pinMode(DCMotor_Button, INPUT_PULLUP);
// OUTPUT
// LED
pinMode(LED, OUTPUT);
// Motor
pinMode(DCMotor, OUTPUT);
// Display OLED
// initialize OLED display with address 0x3C for 128x64
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
delay(200); // wait for initializing
oled.clearDisplay();
// clear display
oled.setTextSize(2);
// text size
oled.setTextColor(WHITE);
// text color
oled.setCursor(0, 10);
// position to display
displayString.reserve(10);
// to avoid fragmenting memory when using String
}
void loop() {
if (!tb.connected()) {
connectToThingsBoard();
}
// INPUT
// DHT22
Humidity = dht22.readHumidity(); // read humidity
Temp = dht22.readTemperature(); // read temperature
// LDR
lightValue = analogRead(Light_intensity_A0);
// MPU6050
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
int accel[] = {a.acceleration.x, a.acceleration.y, a.acceleration.z};
int gyro[] = {g.gyro.x, g.gyro.y, g.gyro.z};
int mpu_temp = temp.temperature;
// MPU6050 gyro Y as PWM
currentPWM = gyro[1];
currentPWM = map(currentPWM, -4, 4, 0, 255);
// Knob
newClk = digitalRead(Knob_CLK);
if (newClk != lastClk) {
// There was a change on the CLK pin
lastClk = newClk;
int dtValue = digitalRead(Knob_DT);
if (newClk == LOW && dtValue == HIGH) {
if (sensor_page < 11) {
sensor_page += 1;
}
}
if (newClk == LOW && dtValue == LOW) {
if (sensor_page > 1) {
sensor_page -= 1;
}
}
}
// DHT22 Temperature control. High temp fan on.
FanState = (Temp > 30) ? 1 : 0;
// Light control. High light level turns off light.
LightState = (lightValue > 150) ? 1 : 0;
// Handle LED button with debounce
if (digitalRead(LED_Button) == LOW) {
if ((millis() - lastDebounceTime_LED) > debounceDelay) {
lastDebounceTime_LED = millis();
ledButtonState = !ledButtonState;
if (ledButtonState) {
manualLEDTurnOff = !manualLEDTurnOff; // Toggle manual turn off state
}
}
}
// Handle Motor button with debounce
if (digitalRead(DCMotor_Button) == LOW) {
if ((millis() - lastDebounceTime_Motor) > debounceDelay) {
lastDebounceTime_Motor = millis();
motorButtonState = !motorButtonState;
if (motorButtonState) {
manualMotorTurnOff = !manualMotorTurnOff; // Toggle manual turn off state
}
}
}
// LED control
if (manualLEDTurnOff) {
// Manual turn off overrides light intensity
LED_pwm = 0;
} else {
// Automatic control based on light intensity
if (LightState == 1) {
LED_pwm = 0;
} else {
LED_pwm = currentPWM;
}
}
// Motor control
if (manualMotorTurnOff) {
// Manual turn off overrides temperature
DC_Motor_pwm = 0;
} else {
// Automatic control based on temperature
if (FanState == 1) {
DC_Motor_pwm = currentPWM;
} else {
DC_Motor_pwm = 0;
}
}
// OUTPUT
// LED
analogWrite(LED, LED_pwm);
// Motor
analogWrite(DCMotor, DC_Motor_pwm);
// Display OLED
switch (sensor_page) {
case 1:
Sensor = "Temperature";
Reading = Temp;
break;
case 2:
Sensor = "Humidity";
Reading = Humidity;
break;
case 3:
Sensor = "Light";
Reading = lightValue;
break;
case 4:
Sensor = "AccelerometerX";
Reading = accel[0];
break;
case 5:
Sensor = "AccelerometerY";
Reading = accel[1];
break;
case 6:
Sensor = "AccelerometerZ";
Reading = accel[2];
break;
case 7:
Sensor = "GyroX";
Reading = gyro[0];
break;
case 8:
Sensor = "GyroY";
Reading = gyro[1];
break;
case 9:
Sensor = "GyroZ";
Reading = gyro[2];
break;
case 10:
Sensor = "Mpu_Temp";
Reading = mpu_temp;
break;
}
String displayString = "";
displayString += Sensor;
displayString += ": ";
displayString += Reading;
displayString += " ";
oledDisplayCenter(displayString); // display on OLED
// Debugging feature:
Serial.println("");
Serial.println("Temp : humi : Light : ax : ay: az: gx : gy : gz : mTemp : PWM : state");
Serial.println("");
Serial.print(Temp);
Serial.print(" : ");
Serial.print(Humidity);
Serial.print(" : ");
Serial.print(lightValue);
Serial.print(" : ");
Serial.print(accel[0]);
Serial.print(" : ");
Serial.print(accel[1]);
Serial.print(" : ");
Serial.print(accel[2]);
Serial.print(" : ");
Serial.print(gyro[0]);
Serial.print(" : ");
Serial.print(gyro[1]);
Serial.print(" : ");
Serial.print(gyro[2]);
Serial.print(" : ");
Serial.print(mpu_temp);
Serial.print(" : ");
Serial.print(currentPWM);
Serial.print(" : ");
Serial.print(deviceState);
Serial.print(" : ");
Serial.print(digitalRead(LED_Button));
Serial.print(" : ");
Serial.print(digitalRead(DCMotor_Button));
Serial.println("");
sendDataToThingsBoard(Temp, Humidity, lightValue, digitalRead(LED_Button), digitalRead(DCMotor_Button));
delay(100);
}
void oledDisplayCenter(String text) {
int16_t x1;
int16_t y1;
uint16_t width;
uint16_t height;
oled.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);
// display on horizontal and vertical center
oled.clearDisplay(); // clear display
oled.setCursor((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2);
oled.println(text); // text to display
oled.display();
}