P10 – Điều khiển thiết bị bằng giọng nói (P2)

Tiếp tục với phần 1, trong phần này chúng ta sẽ thực hiện một hệ thống điều khiển thiết bị bằng giọng nói. Linh kiện được sử dụng rất đơn giản, chỉ có một vi điều khiển NodeMCU với chip wifi ESP8266 gắn sẵn và một bo rơ-le để điều khiển bật tắt thiết bị dùng điện 220V. Phần mềm trên điện thoại Android được viết trên nền tảng của MIT App Inventor.

Đầu tiên, ta phải cài đặt phần mềm Arduino IDE để có thể nạp chương trình cho NodeMCU. Cụ thể cách thức cài đặt có thể xem lại bài viết B31-Sử dụng NodeMCU. 

Đối với rơ-le, sử dụng mạch làm sẵn là một lựa chọn hợp lý để tiết kiệm thời gian và công việc. Trong bài này, chúng ta sẽ điều khiển 6 rơ-le nên mua một bo 8 rơ-le hoặc gắn riêng lẻ đều được.

Để đảm bảo yếu tố cách ly giữa điện áp thấp và thiết bị sử dụng điện áp cao, người ta thường sử dụng linh kiện quang (opto) để cách ly rơ-le và phần điều khiển.

Rơ-le gắn kèm opto cách ly

Khi kiểm tra sơ đồ nguyên lý của mạch rơ-le, chân Vcc và JDVcc cần được loại bỏ kết nối (jumper) để đảm bảo yếu tố cách ly nguồn điện riêng.

Bỏ jumper Vcc-JDVcc

Theo sơ đồ như trên, điện áp điều khiển mức thấp tại chân IN0 sẽ kích hoạt rơ-le. Bình thường phải đặt ở mức cao thì rơ-le không hoạt động.

Đối với NodeMCU, trên bo mạch có gắn sẵn ổn áp 3,3V nên có thể cấp nguồn vào chân VIn có giá trị tối đa lên đến 20V.

Nếu sử dụng nguồn 5V chung cho cả NodeMCU và bo rơ-le thì công suất dòng tối thiểu phải đạt 1,5A

Dùng chung nguồn 5V (1,5A)

Chú ý: Loại bỏ kết nối (jumper) giữa Vcc-JDVcc.

  • Bo rơ-le gắn nguồn tại JDVcc và GND
  • Nối từng chân điều khiển của NodeMCU đến bo rơ-le.
  • Nối chân 3,3V từ NodeMCU đến Vcc trên bo rơ-le. Một số bo rơ-le sẽ khó kích hoạt vì điện áp 3,3V không đủ cung cấp cho mạch opto.

Trong trường hợp cấp nguồn qua cáp USB cho NodeMCU, nối chân VU hoặc Vin sang Vcc của bo rơ-le.

Chương trình trên điện thoại

Tải chương trình HomeDL tại đây. Giải nén và cài đặt trên điện thoại, chuyển ngôn ngữ điện thoại về tiếng Việt là có thể sử dụng.

Chương trình cho NodeMCU

/*
Smart Home DL1
Tung Le
bandardalat.com
6 devices
16 05 04 14 12 13
D0 D1 D2 D5 D6 D7
*/
// Load Wi-Fi library
#include <ESP8266WiFi.h>
// Replace with your network credentials
// Tên mạng wifi và mật khẩu
const char* ssid = "ABC";
const char* password = "xyz";
// Set web server port number to 80
WiFiServer server(80);
// Variable to store the HTTP request
String header;
// Auxiliar variables to store the current output state
String output4State = "off";
String output5State = "off";
String output16State = "off";
String output14State = "off";
String output12State = "off";
String output13State = "off";
// Assign output variables to GPIO pins
const int output4 = 4;
const int output5 = 5;
const int output16 = 16;
const int output14 = 14;
const int output12 = 12;
const int output13 = 13;
void setup()
{
Serial.begin(115200);
// Initialize the output variables as outputs
pinMode(output4, OUTPUT);
pinMode(output5, OUTPUT);
pinMode(output16, OUTPUT);
pinMode(output14, OUTPUT);
pinMode(output13, OUTPUT);
pinMode(output12, OUTPUT);
// Set outputs to HIGH
digitalWrite(output4, HIGH);
digitalWrite(output5, HIGH);
digitalWrite(output16, HIGH);
digitalWrite(output14, HIGH);
digitalWrite(output13, HIGH);
digitalWrite(output12, HIGH);
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop()
{
WiFiClient client = server.available(); // Listen for incoming clients
if (client)
{ // If a new client connects,
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected())
{ // loop while the client's connected
if (client.available())
{
char c = client.read();
Serial.write(c);
header += c;
if (c == '\n')
{ // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0)
{
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// turns the GPIOs on and off
if (header.indexOf("GET /4/on") >= 0)
{
Serial.println("GPIO 4 on");
output4State = "on";
digitalWrite(output4, LOW); }
else if (header.indexOf("GET /4/off") >= 0)
{ Serial.println("GPIO 4 off");
output4State = "off"; digitalWrite(output4, HIGH); }
else if (header.indexOf("GET /5/on") >= 0)
{ Serial.println("GPIO 5 on");
output5State = "on"; digitalWrite(output5, LOW); }
else if (header.indexOf("GET /5/off") >= 0)
{ Serial.println("GPIO 5 off");
output5State = "off"; digitalWrite(output5, HIGH); } else if (header.indexOf("GET /12/on") >= 0)
{ Serial.println("GPIO 12 on");
output12State = "on"; digitalWrite(output12, LOW); }
else if (header.indexOf("GET /12/off") >= 0)
{ Serial.println("GPIO 12 off");
output12State = "off"; digitalWrite(output12, HIGH); }
else if (header.indexOf("GET /13/on") >= 0)
{ Serial.println("GPIO 13 on");
output13State = "on"; digitalWrite(output13, LOW); }
else if (header.indexOf("GET /13/off") >= 0)
{ Serial.println("GPIO 13 off");
output13State = "off"; digitalWrite(output13, HIGH); }
else if (header.indexOf("GET /14/on") >= 0)
{ Serial.println("GPIO 14 on");
output14State = "on"; digitalWrite(output14, LOW); }
else if (header.indexOf("GET /14/off") >= 0)
{ Serial.println("GPIO 14 off");
output14State = "off"; digitalWrite(output14, HIGH); }
else if (header.indexOf("GET /16/on") >= 0)
{ Serial.println("GPIO 16 on");
output16State = "on"; digitalWrite(output16, LOW); }
else if (header.indexOf("GET /16/off") >= 0)
{ Serial.println("GPIO 16 off");
output16State = "off"; digitalWrite(output16, HIGH); }
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// Web Page Heading
client.println("<body><h1>Smart Home DL1</h1>");
// Display current state for GPIO
client.println("<p>GPIO 4 - State " + output4State + "</p>"); client.println("<p>GPIO 5 - State " + output5State + "</p>"); client.println("<p>GPIO 12 - State " + output12State + "</p>"); client.println("<p>GPIO 13 - State " + output13State + "</p>"); client.println("<p>GPIO 14 - State " + output14State + "</p>"); client.println("<p>GPIO 16 - State " + output16State + "</p>"); client.println("<p>Please visit www.bandardalat.com for more projects.</p>");
client.println("</body></html>");
// The HTTP response ends with another blank line client.println();
// Break out of the while loop
break;
}
else
{
// if you got a newline, then clear currentLine
currentLine = ""; } }
else if (c != '\r')
{ // if you got anything else but a carriage return character, currentLine += c;
// add it to the end of the currentLine } }}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}

Cách sử dụng chương trình tham khảo video sau

Leave a Reply

Your email address will not be published. Required fields are marked *