ESP32 điều khiển Relay qua Web Server – Điều khiển thiết bị AC
Trong bài viết này, mình cách sử dụng ESP32 để điều khiển Relay thông qua Web Server nhé! Qua dự án, bạn không chỉ biết cách điều khiển thiết bị relay, mà còn có thể điều khiển những thiết bị AC khác từ xa một cách đơn giản.
Giới thiệu về Relay
Relay được hiểu đơn giản là một công tắc đóng ngắt, chúng sẽ cho dòng điện chạy qua hoặc ngăn không cho dòng điện chạy qua.
Bạn có thể điều khiển Relay ở các mức điện áp thấp như 3.3V trên mạch ESP32, hoặc là điều khiển các điện áp cao hơn như 12V, 24V hoặc thậm chí là điện áp dân dụng 220V đều được.
Hiện nay, có nhiều loại Relay với số lượng các kênh khác nhau. Bạn có thể sử dụng Relay có 1 kênh, 2 kênh, 4 kênh, 8 kênh hoặc 16 kênh đều được. Số lượng kênh này đại diện cho số lượng thiết bị đầu ra (ví dụ như đèn, quạt,…) mà chúng ta cần điều khiển bật / tắt.
Các Relay có nam châm điện có thể hoạt động ở mức điện áp thấp là 5V hoặc 3.3V. Cả 2 loại này đều có thể được điều khiển bởi ESP32.
Sơ đồ chân trên Relay
Trong phần này, IoTZone sẽ giới thiệu đến bạn sơ đồ của Relay 2 kênh nhé! Relay có số lượng kênh khác cũng tương tự như vậy:
Như hình trên, ở phía bên trái bạn sẽ thấy có các ổ cắm để kết nối với điện áp cao, còn các chân ở bên phải có điện áp thấp, dùng để kết nối với chân GPIO trên ESP32.
Cổng kết nối với điện áp
Mỗi một Relay sẽ có 2 cổng kết nối, mỗi cổng trong đó thì gồm 3 chân chính là:
- COM (common): Kết nối với điện áp nguồn mà bạn cần điều khiển
- NC (Normally Closed): Bạn có thể sử dụng cấu hình này khi muốn Relay hoạt động theo chế độ mặc định. Khi đó, cổng NC và cổng COM được kết nối với nhau, cho phép dòng điện chạy qua, trừ khi bạn dùng ESP32 điều khiển Relay mở mạch và ngắt dòng điện.
- NO (Normally Open): Ở chế độ này, chân NO và COM không kết nối với nhau, mạch có thể sẽ bị hỏng trừ khi bạn dùng ESP32 gửi tín hiệu để đóng mạch.
Chân điều khiển Relay
Phía bên phải sẽ có 2 bộ chân điều khiển khác nhau, 1 bộ có 3 chân và 1 bộ có 3 chân. Mình sẽ giải thích từng bộ nhé!
Bộ đầu tiên có 4 chân, trong đó VCC và GND dùng để cấp nguồn cho module, còn IN1 (Input 1) và IN2 được dùng để điều khiển phần top và phần bottom của Relay tương ứng.
Trong trường hợp bạn dùng module Relay có 1 kênh thì bạn sẽ chỉ có 1 chân IN thôi. Tương tự, nếu bạn dùng Relay 4 kênh thì bạn sẽ có 4 kênh IN, và cứ thế mà tính nhé!
Tín hiệu chúng ta gửi đến IN sẽ đóng vai trò quyết định xem Relay có hoạt động hay không. Relay sẽ được kích hoạt khi đầu vào ở mức dưới 2V, nên chúng ta sẽ gặp các tình huống như sau:
1. Cấu hình thường đóng (NC):
- Tín hiệu HIGH: Dòng điện đang chạy
- Tín hiệu LOW: Dòng điện ngưng chạy
2. Cấu hình thường mở (NO):
- Tín hiệu HIGH – Dòng điện ngưng chạy
- Tín hiệu LOW – Dòng điện đang chạy
Theo kinh nghiệm của mình thì bạn nên dùng NC khi cần dòng điện chạy qua thường xuyên, và thỉnh thoảng bạn cần dừng nó một chút thôi.
Ngược lại, bạn nên dùng NO khi muốn dòng điện không chạy qua mạch, và lâu lâu bạn cần mở dòng điện một chút rồi tắt (ví dụ như thỉnh thoảng bật đèn lên sử dụng một chút rồi tắt).
Bộ chân thứ 2 gồm có GND, VCC và JD-VCC. 2 chân đầu tiên là GND, VCC cũng có vai trò cấp nguồn, còn JD-VCC thì có vai trò cấp nguồn cho nam châm điện của Relay. Như trong hình minh họa của mình thì JD-VCC có màu vàng, nhưng thực tế tùy vào loại mạch Relay mà màu sắc của nó có thể khác nhé!
Khi kết nối dây Jumper, VCC và JD-VCC được kết nối với nhau. Khi đó, mạch Relay được cấp nguồn trực tiếp từ mạch ESP32.
Nếu không có dây Jumper, bạn cần cấp nguồn độc lập cho Relay thông qua chân JD-VCC nhé! Đây là cách mình thường dùng để cách ly Relay với mạch ESP32 trong môi trường vật lý, tránh làm hư hỏng mạch ESP32 khi xảy ra xung đột hoặc sự cố về điện.
Trên đây mình đã giải thích sơ lược kiến thức về mạch Relay rồi. Không dài dòng nữa, chúng ta hãy đi vào phần hướng dẫn thực hiện dự án điều khiển Relay bằng ESP32 qua Web Server nhé! Let’s go!
>> Bài viết liên quan: Cách bắt đầu với ESP32 cho người mới & 10 dự án ESP32 cơ bản
Cách điều khiển Relay bằng ESP32 cơ bản
Kết nối dây
Bạn hãy nối dây như sơ đồ sau nhé! Mình lấy ví dụ bằng Relay 2 kênh, với các loại Relay khác thì bạn thực hiện tương tự là được.
Lưu ý quan trọng: Trong dự án này mình đang hướng dẫn bạn thực hiện với điện áp cao, có thể gây nguy hiểm. Do đó, nếu bạn chưa quen khi làm việc với mức điện áp này, hãy tìm ai đó hỗ trợ. Khi lập trình hoặc nạp chương trình cho ESP32, hay khi kết nối dây, vui lòng đảm bảo rằng bạn đã ngắt hệ thống các thiết bị khỏi điện áp nguồn (như rút dây điện hoặc tắt cầu dao).
Hoặc bạn có thể lựa chọn nguồn điện áp 12V để điều khiển các thiết bị nhỏ có điện áp 12V nhé!
Trong ví dụ này, mình đang điều khiển một chiếc đèn LED. Mình muốn đèn luôn tắt, chỉ thỉnh thoảng mới bật đèn thôi, nên mình sẽ sử dụng cấu hình NO thông thường.
Mình đang kết nối cổng IN1 của Relay vào chân GPIO 26 trên ESP32.
Chương trình trên Arduino
Chương trình điều khiển đèn LED này khá đơn giản, tương tự như khi điều khiển một thiết bị output nào khác thôi. Vì đang dùng NO, nên mình sẽ sử dụng tín hiệu điều khiển như sau:
- HIGH để ngắt dòng điện => LED tắt
- LOW để dòng điện chạy qua => LED bật
Chương trình mình viết sẵn dưới đây sẽ giúp LED của bạn bật trong 10 giây, sau đó tắt trong 10 giây:
const int relay = 26; void setup() { Serial.begin(115200); pinMode(relay, OUTPUT); } void loop() { // Normally Open configuration, send LOW signal to let current flow // (if you're usong Normally Closed configuration send HIGH signal) digitalWrite(relay, LOW); Serial.println("Current Flowing"); delay(5000); // Normally Open configuration, send HIGH signal stop current flow // (if you're usong Normally Closed configuration send LOW signal) digitalWrite(relay, HIGH); Serial.println("Current not Flowing"); delay(5000); } 1
Đây chỉ là một chương trình điều khiển Relay đơn giản qua ESP32, để bạn làm quen. Dưới đây mới là phần chính: Cách điều khiển Relay qua Web Server, để chúng ta có thể bật / tắt Relay từ xa qua Internet.
Cách điều khiển Relay qua Web Server bằng ESP32
Sau khi hoàn thành phần này, bạn có thể điều khiển bật tắt Relay từ xa qua 1 Website trên điện thoại hoặc máy tính dễ dàng, ví dụ như hình dưới:
Tải thư viện
Để tạo Web Server như vậy, chúng ta sẽ dùng thư viện ESPAsyncWebServer. Bạn hãy click vào đây để tải thư viện này xuống, sau đó giải nén và di chuyển thư mục vào folder thư viện cài đặt trong Arduino IDE trên máy bạn nhé!
Ngoài ra, thư viện trên sẽ cần thêm thư viện AsyncTCP để hoạt động. Bạn hãy click vào đây để tải thư viện AsyncTCP và làm tương tự như trên nhé!
Chương trình lập trình
Bạn hãy nạp đoạn code sau vào thiết bị nhé (Lưu ý: Cần đổi thông tin mạng WiFi thành mạng của bạn để code chạy được):
/********* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp32-relay-module-ac-web-server/ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *********/ // Import required libraries #include "WiFi.h" #include "ESPAsyncWebServer.h" // Set to true to define Relay as Normally Open (NO) #define RELAY_NO true // Set number of relays #define NUM_RELAYS 5 // Assign each GPIO to a relay int relayGPIOs[NUM_RELAYS] = {2, 26, 27, 25, 33}; // Replace with your network credentials const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD"; const char* PARAM_INPUT_1 = "relay"; const char* PARAM_INPUT_2 = "state"; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); const char index_html[] PROGMEM = R"rawliteral( <!DOCTYPE HTML><html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> html {font-family: Arial; display: inline-block; text-align: center;} h2 {font-size: 3.0rem;} p {font-size: 3.0rem;} body {max-width: 600px; margin:0px auto; padding-bottom: 25px;} .switch {position: relative; display: inline-block; width: 120px; height: 68px} .switch input {display: none} .slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px} .slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px} input:checked+.slider {background-color: #2196F3} input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)} </style> </head> <body> <h2>ESP Web Server</h2> %BUTTONPLACEHOLDER% <script>function toggleCheckbox(element) { var xhr = new XMLHttpRequest(); if(element.checked){ xhr.open("GET", "/update?relay="+element.id+"&state=1", true); } else { xhr.open("GET", "/update?relay="+element.id+"&state=0", true); } xhr.send(); }</script> </body> </html> )rawliteral"; // Replaces placeholder with button section in your web page String processor(const String& var){ //Serial.println(var); if(var == "BUTTONPLACEHOLDER"){ String buttons =""; for(int i=1; i<=NUM_RELAYS; i++){ String relayStateValue = relayState(i); buttons+= "<h4>Relay #" + String(i) + " - GPIO " + relayGPIOs[i-1] + "</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"" + String(i) + "\" "+ relayStateValue +"><span class=\"slider\"></span></label>"; } return buttons; } return String(); } String relayState(int numRelay){ if(RELAY_NO){ if(digitalRead(relayGPIOs[numRelay-1])){ return ""; } else { return "checked"; } } else { if(digitalRead(relayGPIOs[numRelay-1])){ return "checked"; } else { return ""; } } return ""; } void setup(){ // Serial port for debugging purposes Serial.begin(115200); // Set all relays to off when the program starts - if set to Normally Open (NO), the relay is off when you set the relay to HIGH for(int i=1; i<=NUM_RELAYS; i++){ pinMode(relayGPIOs[i-1], OUTPUT); if(RELAY_NO){ digitalWrite(relayGPIOs[i-1], HIGH); } else{ digitalWrite(relayGPIOs[i-1], LOW); } } // Connect to Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } // Print ESP32 Local IP Address Serial.println(WiFi.localIP()); // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html, processor); }); // Send a GET request to <ESP_IP>/update?relay=<inputMessage>&state=<inputMessage2> server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) { String inputMessage; String inputParam; String inputMessage2; String inputParam2; // GET input1 value on <ESP_IP>/update?relay=<inputMessage> if (request->hasParam(PARAM_INPUT_1) & request->hasParam(PARAM_INPUT_2)) { inputMessage = request->getParam(PARAM_INPUT_1)->value(); inputParam = PARAM_INPUT_1; inputMessage2 = request->getParam(PARAM_INPUT_2)->value(); inputParam2 = PARAM_INPUT_2; if(RELAY_NO){ Serial.print("NO "); digitalWrite(relayGPIOs[inputMessage.toInt()-1], !inputMessage2.toInt()); } else{ Serial.print("NC "); digitalWrite(relayGPIOs[inputMessage.toInt()-1], inputMessage2.toInt()); } } else { inputMessage = "No message sent"; inputParam = "none"; } Serial.println(inputMessage + inputMessage2); request->send(200, "text/plain", "OK"); }); // Start server server.begin(); } void loop() { } 1
Demo kết quả
Sau khi nạp đoạn code trên vào ESP32, chúng ta hãy thử điều khiển Relay nhé! Nhưng trước đó, bạn hãy mở Serial Monitor ở tốc độ 115200 và nhấn nút trên ESP32 để lấy địa chỉ IP của mạch.
Khi có địa chỉ IP, bạn hãy mở trình duyệt Web trên điện thoại / máy tính chạy bằng mạng local, nhập địa chỉ IP vào thanh tìm kiếm và truy cập vào Web Server.
Lúc này, bạn có thể tự do điều khiển Relay hoạt động bằng điện thoại rồi đấy! Hãy thử nhấn bật / tắt trên điện thoại và quan sát kết quả nhé!
Để đảm bảo an toàn, bạn nên đặt Relay và mạch ESP32 vào trong vỏ hộp bảo vệ khi sử dụng, để tránh lộ chân AC nào bên ngoài gây nguy hiểm khi dùng nhé!
Lời kết
Trên đây mình đã hướng dẫn bạn chi tiết về cách điều khiển Relay bằng ESP32 thông qua Web Server. Đây là hướng dẫn phù hợp cho người mới, để bạn bắt đầu tìm hiểu kỹ hơn về cách điều khiển các thiết bị gia dụng AC từ xa. Nhìn chung, việc điều khiển Relay cũng khá đơn giản, chỉ phụ thuộc vào tín hiệu HIGH và LOW thôi. Hãy theo dõi Blog tại IoTZone để cập nhật thêm nhiều tài liệu hướng dẫn khác nhé!