#include <WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ArduinoJson.h>
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "broker.hivemq.com";
String macAddressString;
// Set MQTT topics using the MAC address as a string
char stopic[30];
char ptopic[30];
char datatopic[30];
char lwt_topic[30];
bool cn_check = false;
const int ONE_WIRE_PIN = 4; // dùng pin GPIO4
const int BATTERY_PIN = 16;
const int control_BAT = 14;
const float minValue = 1.05; // Minimum analog value
const float maxValue = 1.26; // Maximum analog value
int count=0;
int alarmt=0;
String type_data1 = "temp";
String type_data2 = "batt";
String type_data3 = "gas";
// Create a OneWire object
OneWire oneWire(ONE_WIRE_PIN);
// Create a DallasTemperature object
DallasTemperature sensors(&oneWire);
// Define a variable to store the temperature reading
float temperature;
float prv_value;
float volt;
int percentage;
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(19, HIGH);
delay(200);
digitalWrite(19, LOW);
delay(200);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Obtain the MAC address as a string
uint8_t mac[6];
WiFi.macAddress(mac);
char macAddress[18];
sprintf(macAddress, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// Convert macAddress to a string
for (int i = 0; i < 6; i++) {
char hexChar[8];
sprintf(hexChar, "%02X", mac[i]);
macAddressString += hexChar;
}
Serial.print("MAC Address: ");
Serial.println(macAddress);
sprintf(stopic, "cmd_%s", macAddress);
Serial.println(stopic);
sprintf(lwt_topic, "lwt_topic_%s", macAddress);
Serial.println(lwt_topic);
sprintf(datatopic, "data_topic_%s", macAddress);
Serial.println(datatopic);
sprintf(ptopic, "stt_topic_%s", macAddress);
Serial.println(ptopic);
}
void ReceivedMessage(char* topic, byte* payload, unsigned int length) {
// Output the first character of the message to serial (debug)
StaticJsonDocument<100> doc;
deserializeJson(doc, payload, length);
// Extract values from the JSON data
String mac = doc["mac"];
String id = doc["id"];
String cmd = doc["cmd"];
Serial.print(id);
Serial.print(":");
Serial.println(cmd);
if(id=="1"&& cmd=="1"){digitalWrite(3, LOW); Serial.println("LOW");}
if(id=="1"&& cmd=="0") {digitalWrite(3, HIGH); Serial.println("HIGH");}
if(id=="2"&& cmd=="1"){digitalWrite(4, LOW); Serial.println("LOW");}
if(id=="2"&& cmd=="0") {digitalWrite(4, HIGH); Serial.println("HIGH");}
if(id=="3"&& cmd=="1"){digitalWrite(5, LOW); Serial.println("LOW");}
if(id=="3"&& cmd=="0") {digitalWrite(5, HIGH); Serial.println("HIGH");}
if(id=="0"&&cmd=="alarm") {alarmt=1;}
if(id=="0"&&cmd=="stt"){
// Read the current states of the pins
int state12 = digitalRead(3);
int state13 = digitalRead(4);
int state14 = digitalRead(5);
// Create a JSON object
StaticJsonDocument<100> doc;
//doc["stt"] = "resp";
doc["1"] = state12;
doc["2"] = state13;
doc["3"] = state14;
// Serialize the JSON object to a string
String jsonStr;
serializeJson(doc, jsonStr);
const char* payload1 = jsonStr.c_str();
Serial.print("Publishing:stt");
client.publish(ptopic, payload1);
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(19, HIGH);
delay(200);
digitalWrite(19, LOW);
delay(200);
Serial.print(".");
}
// Create a random client ID
String clientId = "ESP32Client-"+macAddressString;
Serial.println(clientId);
//clientId += String(random(0xffff), HEX);
// Attempt to connect
StaticJsonDocument<50> lwtJson;
lwtJson["stt"] = 0; // Customize the JSON data as needed
// Convert the JSON object to a JSON string
char lwtMessage[200];
serializeJson(lwtJson, lwtMessage);
if (client.connect(clientId.c_str(),lwt_topic, 2, true, lwtMessage)) {
Serial.println("connected");
cn_check =true;
DynamicJsonDocument RtJson(50);
RtJson["stt"] = 1; // Customize the JSON data as needed
// Convert the JSON object to a JSON string
String RtMessage;
serializeJson(RtJson, RtMessage);
// Once connected, publish an announcement...
const char* pl_RtMessage = RtMessage.c_str();
client.publish(lwt_topic, pl_RtMessage, true);
// ... and resubscribe
client.subscribe(stopic);
} else {
cn_check =false;
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void publish_data(String type_data, float value)
{ //Serial.print(type_data);
if (type_data=="temp") prv_value=value;
//volt = read_voltage();
//dtostrf(temperature, 6, 2, result_temp); // Leave room for too large numbers!
//dtostrf(data_temp.humidity, 6, 2, result_hum); // Leave room for too large numbers!
DynamicJsonDocument json(100);
json["stt"] =3;
json["type_data"] = type_data;
json["value"] = String(value);
String jsonString;
serializeJson(json, jsonString);
const char* payload = jsonString.c_str();
Serial.print("Publishing: ");
Serial.println(payload);
client.publish(datatopic, payload);
Serial.print("Done!");
}
void buzzer_funct(){
digitalWrite(15, HIGH);
delay(70);
digitalWrite(15, LOW);
delay(70);
}
int read_voltage(){
digitalWrite(control_BAT, LOW);
delay(100);
float value= analogRead(BATTERY_PIN);
if(value==0){
percentage=0;
}else {
volt = value / 4095.0 * 3.3;
Serial.println(volt);
float normalizedValue = (volt - minValue) / (maxValue - minValue) + 0.005; // Normalize the value between 0 and 1
percentage = normalizedValue * 100; // Convert the normalized value to a percentage
percentage = (percentage/10)*10;
Serial.println(normalizedValue);
Serial.println(percentage);
}
//delay(100);
digitalWrite(control_BAT, HIGH);
return percentage;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
//Serial.println(lwtMessage);
// Set ADC attenuation to 11dB
//analogSetAttenuation(ADC_11db); //esp32 only
//pinMode(3, OUTPUT); // Initialize the BUILTIN_LED pin as an output
pinMode(19, OUTPUT);
pinMode(15, OUTPUT);
pinMode(control_BAT, OUTPUT);
pinMode(18, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
digitalWrite(19, LOW);
digitalWrite(15, LOW);
digitalWrite(control_BAT, HIGH);
setup_wifi();
sensors.begin();
client.setServer(mqtt_server, 1883);
client.setCallback(ReceivedMessage);
}
void loop() {
if (!client.connected()) {
cn_check =false;
reconnect();
}
client.loop();
sensors.requestTemperatures();
digitalWrite(control_BAT, HIGH);
//int statetest = digitalRead(control_BAT);
//float test = analogRead(33);
//Serial.println(test);
//Serial.println(statetest);
delay(100);
// Get the temperature reading from the first sensor publish_temp(float temperature, String type_data)
temperature = sensors.getTempCByIndex(0);
delay(100);
//Serial.println("Hello, ESP32!");
int stateGas = digitalRead(12);
if (alarmt==1) buzzer_funct();
if (stateGas==0) {buzzer_funct();}
if (cn_check ==true) digitalWrite(19, LOW);
read_voltage();
delay(500);
publish_data(type_data2, percentage);
if (cn_check ==true && temperature!= prv_value) {publish_data(type_data1, temperature);}
}