#include <WiFi.h>
#include <PubSubClient.h>
#include "DHTesp.h"
const int DHT_PIN = 15;
DHTesp dhtSensor;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "broker.emqx.io";
const char* mqtt_topic = "DHTSQL"; // Topic duy nhất để gửi dữ liệu
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
float temp = 0;
float hum = 0;
int value = 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) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '1') {
digitalWrite(2, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is active low on the ESP-01)
} else {
digitalWrite(2, HIGH); // Turn the LED off by making the voltage HIGH
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("Connected");
// Once connected, publish an announcement...
client.publish("/indobot/mqtt", "Indobot");
// ... and resubscribe
client.subscribe("/indobot/mqtt");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
pinMode(2, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > 5000) {
lastMsg = now;
TempAndHumidity data = dhtSensor.getTempAndHumidity();
String message = String(data.temperature, 2) + "|" + String(data.humidity, 1);
client.publish(mqtt_topic, message.c_str());
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Temperature & Humidity Chart</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <!-- Thư viện vẽ biểu đồ -->
<script src="https://cdn.jsdelivr.net/npm/mqtt/dist/mqtt.min.js"></script> <!-- Thư viện MQTT.js -->
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
}
.chart-container {
width: 80%;
max-width: 800px;
}
</style>
</head>
<body>
<div class="chart-container">
<canvas id="tempHumidityChart"></canvas>
</div>
<script>
// MQTT Setup
const mqttBroker = "wss://broker.emqx.io:8084/mqtt"; // Broker MQTT với WebSocket
const topic = "DHTSQL"; // Topic mà ESP32 sẽ gửi dữ liệu tới
const clientId = "web-client-" + Math.random().toString(16).substr(2, 8); // Tạo clientId ngẫu nhiên
const client = mqtt.connect(mqttBroker, {
clientId: clientId,
clean: true,
connectTimeout: 4000,
reconnectPeriod: 1000,
});
client.on("connect", () => {
console.log("Connected to MQTT broker!");
client.subscribe(topic, (err) => {
if (!err) {
console.log(`Subscribed to topic: ${topic}`);
}
});
});
client.on("error", (err) => {
console.log("Error: " + err);
});
client.on("message", (topic, message) => {
console.log("Message received: " + message.toString());
const data = message.toString().split("|"); // Phân tách dữ liệu (Nhiệt độ | Độ ẩm)
const temperature = parseFloat(data[0]);
const humidity = parseFloat(data[1]);
// Cập nhật biểu đồ
updateChart(temperature, humidity);
});
// Biểu đồ
const ctx = document.getElementById("tempHumidityChart").getContext("2d");
const chart = new Chart(ctx, {
type: 'line', // Loại biểu đồ (Line Chart)
data: {
labels: [], // Nhãn thời gian
datasets: [{
label: 'Temperature (°C)',
borderColor: 'red',
backgroundColor: 'rgba(255, 99, 132, 0.2)',
fill: false,
data: [], // Dữ liệu nhiệt độ
}, {
label: 'Humidity (%)',
borderColor: 'blue',
backgroundColor: 'rgba(54, 162, 235, 0.2)',
fill: false,
data: [], // Dữ liệu độ ẩm
}]
},
options: {
scales: {
y: {
beginAtZero: false
}
}
}
});
// Hàm cập nhật biểu đồ
let time = 0; // Thời gian theo đơn vị giây
function updateChart(temp, hum) {
// Thêm dữ liệu mới vào biểu đồ
chart.data.labels.push(time++);
chart.data.datasets[0].data.push(temp);
chart.data.datasets[1].data.push(hum);
// Giới hạn độ dài của dữ liệu trên biểu đồ (giới hạn 20 điểm)
if (chart.data.labels.length > 20) {
chart.data.labels.shift();
chart.data.datasets[0].data.shift();
chart.data.datasets[1].data.shift();
}
chart.update();
}
</script>
</body>
</html>
////////////////////////////////////////////////////////////////////////////////////////////////////////
import mysql.connector
import paho.mqtt.client as mqtt
# Kết nối tới cơ sở dữ liệu MySQL
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="", # Thay bằng mật khẩu của bạn
database="ptiot6"
)
def maintain_table_limit(table_name):
try:
mycursor = mydb.cursor()
mycursor.execute(f"SELECT COUNT(*) FROM {table_name}")
row_count = mycursor.fetchone()[0]
if row_count > 20:
num_rows_to_delete = row_count - 20
mycursor.execute(f"DELETE FROM {table_name} ORDER BY id LIMIT {num_rows_to_delete}")
mydb.commit()
print(f"{num_rows_to_delete} old rows deleted from {table_name}.")
except mysql.connector.Error as err:
print("Error: {}".format(err))
mydb.rollback()
# Hàm được gọi khi kết nối tới MQTT broker
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# Đăng ký MQTT topic
client.subscribe("DHTSQL") # Đăng ký topic dữ liệu cảm biến
# Hàm được gọi khi nhận được tin nhắn từ MQTT topic
def on_message(client, userdata, msg):
mess = str(msg.payload.decode("utf-8"))
print(msg.topic + " " + mess)
mycursor = mydb.cursor()
# Xử lý dữ liệu từ topic DHTSQL
if msg.topic == "DHTSQL":
try:
# Giả sử dữ liệu gửi về theo định dạng "NhietDo|DoAm"
data = mess.split("|")
nhietdo = float(data[0]) # Nhiệt độ
doam = float(data[1]) # Độ ẩm
# Chèn dữ liệu vào bảng `cambien`
sql = "INSERT INTO cambien (NhietDo, DoAm) VALUES (%s, %s)"
val = (nhietdo, doam)
maintain_table_limit("cambien") # Giữ giới hạn 20 hàng
mycursor.execute(sql, val)
mydb.commit()
print("NhietDo và DoAm đã được lưu vào bảng cambien.")
except (ValueError, IndexError) as parse_err:
print(f"Lỗi phân tích dữ liệu: {parse_err}")
except mysql.connector.Error as db_err:
print(f"Lỗi MySQL: {db_err}")
mydb.rollback()
if msg.topic == "LED/Status":
try:
# Giả sử dữ liệu gửi về theo định dạng "NhietDo|DoAm"
data = mess.split("|")
battat = float(data[0]) # Nhiệt độ
# Độ ẩm
# Chèn dữ liệu vào bảng `cambien`
sql = "INSERT INTO cambien (battat) VALUES (%s)"
val = (battat)
maintain_table_limit("cambien") # Giữ giới hạn 20 hàng
mycursor.execute(sql, val)
mydb.commit()
print("battat đã được lưu vào bảng cambien.")
except (ValueError, IndexError) as parse_err:
print(f"Lỗi phân tích dữ liệu: {parse_err}")
except mysql.connector.Error as db_err:
print(f"Lỗi MySQL: {db_err}")
mydb.rollback()
# Tạo MQTT client
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
# Kết nối tới MQTT broker
client.connect("broker.emqx.io", 1883, 60)
# Lắng nghe dữ liệu từ MQTT broker
client.loop_forever()