Tạo file mới trong Arduino IDE, copy toàn bộ đoạn code dưới đây và nhớ thay đổi phần CẤU HÌNH cho phù hợp với mạng của bạn.
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <DHT.h>
#include <EEPROM.h>
#include <WebSocketsClient.h>
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* SERVER_HOST = "192.168.1.100";
const int SERVER_PORT = 5175;
const char* DEVICE_NAME = "ESP32-Smart-Home";
const char* DEVICE_SECRET = "my_secret_key_123";
#define DHT_PIN 4
#define DHT_TYPE DHT22
#define LED_PIN 2
#define SEND_INTERVAL 10000
#define PING_INTERVAL 30000
DHT dht(DHT_PIN, DHT_TYPE);
WebSocketsClient webSocket;
int deviceId = 0;
String deviceToken = "";
bool isRegistered = false;
unsigned long lastSendTime = 0;
unsigned long lastPingTime = 0;
void webSocketEvent(WStype_t type, uint8_t* payload, size_t length) {
switch (type) {
case WStype_CONNECTED:
Serial.println("✓ WebSocket connected!");
{ StaticJsonDocument<128> msg;
msg["type"] = 1;
msg["target"] = "JoinDeviceGroup";
msg["arguments"].add(deviceId);
String msgStr; serializeJson(msg, msgStr);
webSocket.sendTXT(msgStr); }
break;
case WStype_TEXT: {
StaticJsonDocument<512> doc;
if (!deserializeJson(doc, payload)) {
String method = doc["target"] | "";
JsonArray args = doc["arguments"];
if (method == "ReceiveCommand") {
JsonObject cmd = args[0];
String command = cmd["command"];
if (command == "set_pin") {
int pin = cmd["params"]["pin"];
String val = cmd["params"]["value"];
if (pin == 2) {
digitalWrite(LED_PIN, val == "1" ? HIGH : LOW);
Serial.println(val == "1" ? "> LỆNH: LED BẬT" : "> LỆNH: LED TẮT");
}
}
}
}
break; }
case WStype_DISCONNECTED:
Serial.println("✗ WebSocket disconnected!");
break;
}
}
void connectWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.print("Connecting WiFi");
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.printf("\n✓ WiFi Connected: %s\n", WiFi.localIP().toString().c_str());
}
bool registerDevice() {
HTTPClient http;
http.begin(String("http://") + SERVER_HOST + ":5175/api/auth/register-device");
http.addHeader("Content-Type", "application/json");
StaticJsonDocument<256> doc;
doc["macAddress"] = WiFi.macAddress();
doc["name"] = DEVICE_NAME;
doc["secret"] = DEVICE_SECRET;
String body; serializeJson(doc, body);
int code = http.POST(body);
if (code == 200) {
StaticJsonDocument<512> res;
deserializeJson(res, http.getString());
deviceId = res["data"]["deviceId"];
deviceToken = res["data"]["token"].as<String>();
EEPROM.begin(512);
for (int i = 0; i < deviceToken.length(); i++) EEPROM.write(i, deviceToken[i]);
EEPROM.write(deviceToken.length(), '\0');
EEPROM.write(200, (deviceId >> 24) & 0xFF);
EEPROM.write(201, (deviceId >> 16) & 0xFF);
EEPROM.write(202, (deviceId >> 8) & 0xFF);
EEPROM.write(203, deviceId & 0xFF);
EEPROM.commit();
Serial.printf("✓ Registered! ID=%d\n", deviceId);
http.end();
return true;
}
Serial.printf("✗ Register failed. Code: %d\n", code);
http.end();
return false;
}
void sendSensorData(float temp, float hum) {
HTTPClient http;
http.begin(String("http://") + SERVER_HOST + ":5175/api/datastream/" + deviceId + "/update");
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer " + deviceToken);
StaticJsonDocument<256> doc;
JsonArray pins = doc.createNestedArray("pins");
JsonObject p0 = pins.createNestedObject();
p0["pin"] = 0; p0["value"] = String(temp, 1);
JsonObject p1 = pins.createNestedObject();
p1["pin"] = 1; p1["value"] = String(hum, 1);
String body; serializeJson(doc, body);
int code = http.POST(body);
if (code == 200) Serial.printf("↑ Sent Data: Temp=%.1f°C, Hum=%.1f%%\n", temp, hum);
else Serial.printf("✗ Send Data Failed: %d\n", code);
http.end();
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
dht.begin();
connectWiFi();
EEPROM.begin(512);
char token[400]; int i = 0;
while (i < 399) { token[i] = EEPROM.read(i); if (token[i] == '\0') break; i++; }
deviceId = (EEPROM.read(200)<<24)|(EEPROM.read(201)<<16)|(EEPROM.read(202)<<8)|EEPROM.read(203);
if (strlen(token) > 10 && deviceId > 0) {
deviceToken = String(token);
isRegistered = true;
Serial.printf("✓ Token Loaded. ID=%d\n", deviceId);
}
}
void loop() {
webSocket.loop();
if (!isRegistered) {
if (registerDevice()) {
isRegistered = true;
webSocket.begin(SERVER_HOST, SERVER_PORT, "/iotHub");
webSocket.onEvent(webSocketEvent);
webSocket.setReconnectInterval(5000);
}
delay(5000);
return;
}
unsigned long now = millis();
if (now - lastSendTime >= SEND_INTERVAL) {
lastSendTime = now;
float t = dht.readTemperature();
float h = dht.readHumidity();
if (!isnan(t) && !isnan(h)) sendSensorData(t, h);
}
if (now - lastPingTime >= PING_INTERVAL) {
lastPingTime = now;
HTTPClient http;
http.begin(String("http://") + SERVER_HOST + ":5175/api/device/" + deviceId + "/ping");
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer " + deviceToken);
http.POST("{}");
http.end();
}
delay(10);
}