#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <math.h>
#include <IRremote.h>
#include <Stepper.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
// Define pins and constants
#define THERMISTOR_ANALOG 34 // Thermistor analog pin
#define RED_LED 2 // Red LED pin for over-temperature warning
#define GREEN_LED1 25 // Green LED1 pin for speed indication
#define GREEN_LED2 33 // Green LED2 pin for speed indication
#define GREEN_LED3 32 // Green LED3 pin for speed indication
#define IR_RECV 16 // IR Receiver pin
#define SDA 21 // OLED SDA pin
#define SCL_1 22 // OLED SCL pin
/* Stepper Motor Pins */
#define A1_MINUS 23
#define A1_PLUS 15
#define B1_PLUS 19
#define B1_MINUS 18
#define A2_MINUS 5
#define A2_PLUS 17
#define B2_PLUS 4
#define B2_MINUS 0
// Wi-Fi and MQTT configurations
const char* ssid = "Wokwi-GUEST"; // Wi-Fi SSID
const char* password = ""; // Wi-Fi password
const char* mqttServer = "63ebe1109270478689d928ac67292687.s1.eu.hivemq.cloud"; // MQTT broker
const int mqttPort = 8883; // MQTT port
const char* mqttUser = "atakan"; // MQTT username
const char* mqttPassword = "12345aTa"; // MQTT password
const int stepsPerRevolution = 200; // Steps per revolution for steppers
WiFiClientSecure espClient; // Secure Wi-Fi client for TLS/SSL
PubSubClient client(espClient);
IRrecv receiver(IR_RECV);
U8G2_SH1107_128X128_1_HW_I2C u8g2(U8G2_R0);
Stepper frontStepper(stepsPerRevolution, B2_MINUS, B2_PLUS, A2_PLUS, A2_MINUS);
Stepper backStepper(stepsPerRevolution, B1_MINUS, B1_PLUS, A1_PLUS, A1_MINUS);
bool ventPower = 0; // Ventilator power state (0: off, 1: on)
int speedLevel = 2; // Initial ventilator speed level
int ventTemp = 18; // Initial ventilator air temperature
const int lowSpeed = 1000;
const int mediumSpeed = 2000;
const int highSpeed = 3000;
// Callback function for handling incoming MQTT messages
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String message = "";
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Message received on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
Serial.println(message);
// Handle control topic
if (String(topic) == "ventilator/control") {
if (message == "ON") {
ventPower = true;
Serial.println("Ventilator turned ON via MQTT.");
} else if (message == "OFF") {
ventPower = false;
Serial.println("Ventilator turned OFF via MQTT.");
}
}
}
void connectToWiFi() {
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println(" Connected!");
}
void connectToMQTT() {
client.setCallback(mqttCallback); // Set the MQTT callback function
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("ESP32_Client", mqttUser, mqttPassword)) {
Serial.println(" Connected to MQTT!");
// Subscribe to control topic
client.subscribe("ventilator/control");
} else {
Serial.print("Failed, rc=");
Serial.println(client.state());
delay(2000);
}
}
}
float calculateTemperature(int sensorValue) {
int resistorValue = 10000;
float resistance = resistorValue / ((4095.0 / sensorValue) - 1.0);
float steinhart = resistance / 10000.0;
steinhart = log(steinhart);
steinhart /= 3950.0;
steinhart += 1.0 / (25.0 + 273.15);
steinhart = 1.0 / steinhart;
return steinhart - 273.15; // Convert to Celsius
}
void setup() {
Serial.begin(115200);
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED1, OUTPUT);
pinMode(GREEN_LED2, OUTPUT);
pinMode(GREEN_LED3, OUTPUT);
frontStepper.setSpeed(mediumSpeed);
backStepper.setSpeed(mediumSpeed);
u8g2.begin();
u8g2.setContrast(255);
receiver.enableIRIn();
connectToWiFi();
espClient.setInsecure(); // Disable certificate verification for simplicity
client.setServer(mqttServer, mqttPort);
}
void loop() {
if (!client.connected()) {
connectToMQTT();
}
client.loop();
int sensorValue = analogRead(THERMISTOR_ANALOG);
float tempC = calculateTemperature(sensorValue);
char stateMessage[50];
snprintf(stateMessage, 50, "Power: %s", ventPower ? "ON" : "OFF");
char intTempMessage[50];
snprintf(intTempMessage, 50, "Internal Temperature: %.2f°C", tempC);
char airTempMessage[50];
if (ventPower) snprintf(airTempMessage, 50, "Air Temperature: %d°C", ventTemp);
else snprintf(airTempMessage, 50, "Air Temperature: -");
char speedLevelMessage[50];
if (ventPower) snprintf(speedLevelMessage, 50, "Speed Level: %d", speedLevel);
else snprintf(speedLevelMessage, 50, "Speed Level: -");
client.publish("ventilator/power", stateMessage);
client.publish("ventilator/inttemp", intTempMessage);
client.publish("ventilator/airtemp", airTempMessage);
client.publish("ventilator/speedlevel", speedLevelMessage);
if (ventPower && tempC > 40.0) {
digitalWrite(RED_LED, HIGH);
client.publish("ventilator/heatwarning", "WARNING: DEVICE HOT");
}
else
digitalWrite(RED_LED, LOW);
if (receiver.decode()) {
setTempAndSpeed();
receiver.resume();
}
if (ventPower) {
frontStepper.step(-stepsPerRevolution);
backStepper.step(stepsPerRevolution);
}
updateLEDs();
}
void updateLEDs() {
if (!ventPower) {
digitalWrite(GREEN_LED1, LOW);
digitalWrite(GREEN_LED2, LOW);
digitalWrite(GREEN_LED3, LOW);
} else if (speedLevel == 1) {
digitalWrite(GREEN_LED1, HIGH);
digitalWrite(GREEN_LED2, LOW);
digitalWrite(GREEN_LED3, LOW);
} else if (speedLevel == 3) {
digitalWrite(GREEN_LED1, HIGH);
digitalWrite(GREEN_LED2, HIGH);
digitalWrite(GREEN_LED3, HIGH);
} else {
digitalWrite(GREEN_LED1, HIGH);
digitalWrite(GREEN_LED2, HIGH);
digitalWrite(GREEN_LED3, LOW);
}
}
void printTextOLED(float tempC) {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_fub49_tn);
u8g2.setCursor(25, 96);
if (ventPower)
u8g2.print(ventTemp);
u8g2.setCursor(0, 20);
u8g2.print("Temp:");
u8g2.print(tempC);
} while (u8g2.nextPage());
}
void setTempAndSpeed() {
if (!ventPower && receiver.decodedIRData.command != 162)
return;
switch (receiver.decodedIRData.command) {
case 162:
ventPower = !ventPower;
break;
case 48:
frontStepper.setSpeed(lowSpeed);
backStepper.setSpeed(lowSpeed);
speedLevel = 1;
break;
case 24:
frontStepper.setSpeed(mediumSpeed);
backStepper.setSpeed(mediumSpeed);
speedLevel = 2;
break;
case 122:
frontStepper.setSpeed(highSpeed);
backStepper.setSpeed(highSpeed);
speedLevel = 3;
break;
case 2:
if (ventTemp < 30) ventTemp++;
break;
case 152:
if (ventTemp > 18) ventTemp--;
break;
}
}
Loading
grove-oled-sh1107
grove-oled-sh1107