Phụ lục Bài thực hành 1: Khái niệm về IOT .................................................................................... 1 1.1. Tìm hiểu thiết bị và cài đặt phần mềm lập trình .................................................... 1 1.2. Điều khiển On/Off led trên ESP và hiển thị qua serial (1) .................................... 1 1.2.1. Linh kiện ..................................................................................................... 1 1.2.2. Thực hành ................................................................................................... 1 Bài thực hành 2: Thiết lập ban đầu cho dự án IOT ............................................................. 3 2.1. Hiển thị nội dung trên LCD i2c và hiển thị qua serial ........................................... 3 2.1.1. Linh kiện ..................................................................................................... 3 2.1.2. Thực hành ................................................................................................... 3 2.2. Kết nối biến trở đo adc và hiển thị qua LCD i2c và serial (2) ............................... 4 2.2.1. Linh kiện ..................................................................................................... 4 2.2.2. Thực hành ................................................................................................... 5 2.3. Kết nối cảm biến (DHT11/DHT22) với ESP8266 và hiển thị nhiệt độ độ ẩm qua LCD i2c và serial (3) ....................................................................................................... 6 2.3.1. Linh kiện ..................................................................................................... 6 2.3.2. Thực hành ................................................................................................... 7 2.4. Điều khiển relay và hiển thị qua LCD i2c và serial ............................................... 9 2.4.1. Linh kiện ..................................................................................................... 9 2.4.2. Thực hành ................................................................................................... 9 Bài thực hành 3: Giám sát dữ liệu đám mây ..................................................................... 11 3.1. Lấy dữ liệu trực tuyến (dữ liệu bất kỳ) hiển thị qua LCD i2c ............................. 11 3.1.1. Linh kiện ................................................................................................... 11 3.1.2. Thực hành ................................................................................................. 11 3.2. Kết nối cảm biến (DHT11/DHT22) với ESP8266 và hiển thị qua LCD i2c và lưu trữ dữ liệu trên Blynk (4) ............................................................................................... 17 3.2.1. Linh kiện ................................................................................................... 17 1 3.2.2. Thực hành ................................................................................................. 17 Bài thực hành 4: Tương tác với các dịch vụ web và máy với máy ................................... 20 4.1. Giám sát dữ liệu cảm biến từ bảng điều khiển đám mây ..................................... 20 Giao diện trên Web Blynk ............................................................................................. 20 4.2. Thực hành một số công cụ xử lý số liệu. ............................................................. 21 Bài thực hành 5: Đồ án kết thúc học phần ......................................................................... 22 Tài liệu tham khảo ............................................................................................................. 27 2 Bài thực hành 1: Khái niệm về IOT 1.1. Tìm hiểu thiết bị và cài đặt phần mềm lập trình 1.2. Điều khiển On/Off led trên ESP và hiển thị qua serial (1) 1.2.1. Linh kiện Esp Dây usb 1.2.2. Thực hành Màn hình Serial Monitor: Trình bày code: void setup() { // khởi tạo chân kỹ thuật số LED_BUILTIN làm đầu ra. pinMode(LED_BUILTIN, OUTPUT); Serial.begin(9600); } // chức năng vòng lặp chạy đi chạy lại mãi mãi void loop() { digitalWrite(LED_BUILTIN, HIGH); // bật đèn LED (CAO là mức điện áp) Serial.println("LED ON"); delay(2000); // đợi 2 giây digitalWrite(LED_BUILTIN, LOW); // tắt đèn LED bằng cách đặt điện áp THẤP Serial.println("LED OFF"); delay(2000); // đợi 2 giây } 1 Kết quả: Led Off Led On 2 Bài thực hành 2: Thiết lập ban đầu cho dự án IOT 2.1. Hiển thị nội dung trên LCD i2c và hiển thị qua serial 2.1.1. Linh kiện Esp Dây usb LCD 8 dây cái cái 2.1.2. Thực hành Màn hình Serial Monitor: Trình bày code: #include <LiquidCrystal_I2C.h> //define I2C address...... LiquidCrystal_I2C lcd(0x27,16,2); void setup() { Serial.begin(9600); lcd.init(); // Khởi động LCD lcd.backlight(); // Mở đèn } void loop() { lcd.setCursor(2,0); // Từ ô thứ 2 dòng 1 lcd.print("Hello There !!!"); Serial.println("Line1: Hello There"); lcd.setCursor(2,1); // Từ ô thứ 2 dòng 1 lcd.print("LCD Display"); Serial.println("Line2: LCD Display"); delay(2000); } 3 Đi dây: Kết quả: 2.2. Kết nối biến trở đo adc và hiển thị qua LCD i2c và serial (2) 2.2.1. Linh kiện Esp Dây usb LCD Biến trở 11 dây cái cái 4 2.2.2. Thực hành Màn hình Serial Monitor: Đi dây: Trình bày code: #include <LiquidCrystal_I2C.h> //define I2C address...... LiquidCrystal_I2C lcd(0x27,16,2); const int analogInPin = A0; // ESP8266 Analog Pin ADC0 = A0 int sensorValue = 0; void setup() { Serial.begin(9600); lcd.init(); lcd.backlight(); } // Khởi động LCD // Mở đèn void loop() { lcd.setCursor(1,0); // Từ ô thứ 2 dòng 1 lcd.print("Bien tro:"); sensorValue = analogRead(analogInPin); 5 // Hiển thị kết quả trên serial Serial.print("sensor = "); Serial.println(sensorValue); lcd.setCursor(11,0); //Từ ô 11 hàng 1 lcd.print(sensorValue); delay(2000); } Kết quả: 2.3. Kết nối cảm biến (DHT11/DHT22) với ESP8266 và hiển thị nhiệt độ độ ẩm qua LCD i2c và serial (3) 2.3.1. Linh kiện Esp Dây usb LCD 7 dây cái cái DHT11 6 2.3.2. Thực hành Đi dây: Màn hình Serial Monitor: Trình bày code: #include <DHT.h> #include <DHT_U.h> #include <LiquidCrystal_I2C.h> //define I2C address...... LiquidCrystal_I2C lcd(0x27,16,2); #define DHTPIN D4 #define DHTTYPE DHT11 // Khai báo chân tín hiệu // Khai báo loại sensor #include <Arduino.h> #include <ESP8266WiFi.h> DHT dht(DHTPIN, DHTTYPE); void setup(){ pinMode(DHTPIN, INPUT); dht.begin(); Serial.begin(115200); // Khởi động DHT11 7 // Khởi động LCD lcd.init(); // Mở đèn lcd.backlight(); } void loop(){ delay(1000); lcd.setCursor(0, 0); // print message lcd.print("Temperature: "); // set cursor to first column, second row lcd.setCursor(0,1); lcd.print("Humidity: "); float DoAm = dht.readHumidity(); // Đọc độ ẩm môi trường float DoC = dht.readTemperature(); //Đọc nhiệt độ C float DoF = dht.readTemperature(true); //Đọc nhiệt độ F if (isnan(DoAm) || isnan(DoC) || isnan(DoF)) // Kiểm tra tín hiệu trả về từ cảm biến. { Serial.println("Không có giá trị trả về từ cảm biến DHT"); return; } Serial.print(F("Temp: ")); Serial.print(DoC); Serial.print(F("°C ")); Serial.print(F("Humidity: ")); Serial.print(DoAm); Serial.println(F("%")); lcd.setCursor (11,0); lcd.print(DoC); lcd.setCursor (11,1); lcd.print(DoAm); } Kết quả: 8 2.4. Điều khiển relay và hiển thị qua LCD i2c và serial 2.4.1. Linh kiện Esp Dây usb LCD Relay 5v 11 dây cái cái 2.4.2. Thực hành Đi dây: 9 Màn hình Serial Monitor: Trình bày code: #include <DHT.h> #include <DHT_U.h> #include <LiquidCrystal_I2C.h> //define I2C address...... LiquidCrystal_I2C lcd(0x27,16,2); #define RELAY_PIN D4 // Khai báo chân tín hiệu #include <Arduino.h> #include <ESP8266WiFi.h> void setup(){ pinMode(RELAY_PIN, OUTPUT); Serial.begin(9600); // Khởi động LCD lcd.init(); // Mở đèn lcd.backlight(); lcd.setCursor(0,0); lcd.print("Trang thai:"); } void loop(){ // Mở digitalWrite(RELAY_PIN, HIGH); Serial.println("ON"); lcd.setCursor(11,0); //Từ ô 11 lcd.print("ON "); delay(3000); 10 //Tắt digitalWrite(RELAY_PIN, LOW); Serial.println("OFF"); lcd.setCursor(11,0); //Từ ô 11 lcd.print("OFF"); delay(3000); } Kết quả: Bài thực hành 3: Giám sát dữ liệu đám mây 3.1. Lấy dữ liệu trực tuyến (dữ liệu bất kỳ) hiển thị qua LCD i2c 3.1.1. Linh kiện Esp Dây usb LCD 8 dây cái cái 3.1.2. Thực hành Lấy dữ liệu từ OpenWeatherMAP 11 Cú pháp: https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lo n}&appid={API key} {lat},{lon}: Toạ độ {lat},{lon}: = 16.465332062776817, 107.56136489079877 {API key } = 8429431f69436fa157da75ffc1f96999 (như ảnh trên) Thông số cần thiết Tọa độ địa lý (kinh độ, vĩ độ). Nếu bạn cần trình mã hóa địa lý để tự động chuyển đổi tên thành phố và mã zip thành tọa độ địa lý và ngược lại, vui lòng sử dụng API mã hóa địa lý của nhà OpenWeatherMap. appid cần thiết Khóa API duy nhất của bạn (bạn luôn có thể tìm thấy khóa này trên trang tài khoản của mình trong tab "Khóa API" ). mode không bắt buộc Định dạng phản hồi. Các giá trị có thể là xml và html . Nếu bạn không lat, lon sử dụng modeđịnh dạng tham số là JSON theo mặc định. 12 units không bắt buộc Đơn vị đo lường. standard , metric và imperial các đơn vị có sẵn. Nếu bạn không sử dụng units tham số, standard các đơn vị sẽ được áp dụng theo mặc định. lang không bắt buộc Bạn có thể sử dụng tham số này để nhận đầu ra bằng ngôn ngữ của mình API link: https://api.openweathermap.org/data/2.5/weather?lat=16.465332062776817&lon=10 7.56136489079877&units=metric&appid=8429431f69436fa157da75ffc1f96999 Phân tích Json Màn hình Serial Monitor: Trình bày code: #include #include #include #include <ESP8266WiFi.h> <ESP8266HTTPClient.h> <WiFiClient.h> <Arduino_JSON.h> #include <LiquidCrystal_I2C.h> 13 LiquidCrystal_I2C lcd(0x27,19,20); const char* ssid = "ThanhBinh1"; const char* password = "27627679"; // tên wifi // mật khẩu wifi // Your Domain name with URL path or IP address with path String openWeatherMapApiKey = "fee6882e46a02ff030490637056c4fa0"; // Kinh độ, vĩ độ: String lat = "16.465332062776817"; String lon = "107.56136489079877"; // THE DEFAULT TIMER IS SET TO 10 SECONDS FOR TESTING PURPOSES // For a final application, check the API call limits per hour/minute to avoid getting blocked/banned unsigned long lastTime = 0; unsigned long timerDelay = 10000; // Settime String jsonBuffer; void setup() { Serial.begin(115200); WiFiConnect(); lcd.init(); //Khởi động LCD lcd.backlight(); //Mở đèn } void loop() { // Send an HTTP GET request if ((millis() - lastTime) > timerDelay) { // Check WiFi connection status if(WiFi.status()== WL_CONNECTED){ // String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&APPID=" + openWeatherMapApiKey; String serverPath = "http://api.openweathermap.org/data/2.5/weather?lat="+lat+"&lon="+lon+"&un its=metric&appid=" + openWeatherMapApiKey; jsonBuffer = httpGETRequest(serverPath.c_str()); JSONVar myObject = JSON.parse(jsonBuffer); Serial.print("Latitude = "); Serial.println(lat); Serial.print("Longitude = "); 14 Serial.println(lon); Serial.print("City: "); String city = JSON.stringify(myObject["name"]); Serial.print(city); Serial.print(" - "); Serial.println(myObject["sys"]["country"]); lcd.setCursor(0,0); // Từ ô 1 lcd.print("City: " + city); lcd.setCursor(0,1); // Từ ô 2 lcd.print("Humi: "); lcd.print(myObject["main"]["humidity"]); lcd.print("%"); Serial.print("Temperature: "); Serial.println(myObject["main"]["temp"]); Serial.print("Humidity: "); Serial.println(myObject["main"]["humidity"]); Serial.print("Pressure: "); Serial.println(myObject["main"]["pressure"]); Serial.print("Wind Speed: "); Serial.println(myObject["wind"]["speed"]); } else { Serial.println("FAILED"); Serial.println("REASON: " + fbdo.errorReason()); } lastTime = millis(); } } void WiFiConnect(){ WiFi.begin(ssid, password); Serial.print("Connecting to SSID: "); Serial.println(ssid); while(WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to WiFi network with IP Address: "); 15 Serial.println(WiFi.localIP()); } String httpGETRequest(const char* serverName) { WiFiClient client; HTTPClient http; // Your IP address with path or Domain name with URL path http.begin(client, serverName); // Send HTTP POST request int httpResponseCode = http.GET(); String payload = "{}"; Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); payload = http.getString(); // Free resources http.end(); return payload; } Kết quả: 16 3.2. Kết nối cảm biến (DHT11/DHT22) với ESP8266 và hiển thị qua LCD i2c và lưu trữ dữ liệu trên Blynk (4) 3.2.1. Linh kiện Esp Dây usb LCD 11 dây DHT11 3.2.2. Thực hành Trình bày code: // Fill-in information from your Blynk Template here #define BLYNK_TEMPLATE_ID "TMPLxYB_ArQ2" #define BLYNK_DEVICE_NAME "DHT11" #define BLYNK_AUTH_TOKEN "nQJeGJOemR08hC-zVzzxeXMjkFHX1_dD" #define BLYNK_FIRMWARE_VERSION #define BLYNK_PRINT Serial //#define BLYNK_DEBUG "1.0.1" #define APP_DEBUG #define USE_NODE_MCU_BOARD #include "BlynkEdgent.h" #include <DHT.h> #include <DHT_U.h> #include <LiquidCrystal_I2C.h> 17 //define I2C address...... LiquidCrystal_I2C lcd(0x27,16,2); #define DHTPIN D4 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); unsigned long times=millis(); WidgetLED led(V0); BlynkTimer timer; // V0 LED Widget is blinking void blinkLedWidget(){ if (led.getValue()) { led.off(); } else { led.on(); } } void setup(){ Serial.begin(115200); lcd.init(); // turn on LCD backlight lcd.backlight(); delay(100); BlynkEdgent.begin(); //Keetss nối Blynk dht.begin(); timer.setInterval(1000L, blinkLedWidget); } // Khởi động timer void loop() { BlynkEdgent.run(); timer.run(); if(millis()-times>2000){ // Reading temperature or humidity float t = dht.readTemperature(); // Do nhiệt độ từ DHT11 float h = dht.readHumidity(); // // Do nhiệt độ từ DHT11 lcd.setCursor(0, 0); // print message lcd.print("Temp: "); // set cursor to first column, second row lcd.setCursor(0,1); lcd.print("Humi: "); 18 if (isnan(h) || isnan(t)) { Serial.println(F("Failed to read from DHT sensor!")); return; } lcd.setCursor (8,0); lcd.print(t); lcd.setCursor (8,1); // go to start of 2nd line lcd.print(h); Blynk.virtualWrite(V1,t); // Gửi lên chân ảo V1 Blynk.virtualWrite(V2,h); // Gửi lên chân ảo V1 Serial.print(F("Temperature: ")); Serial.print(t); Serial.print(F("°C ")); Serial.print(F("Humidity: ")); Serial.print(h); Serial.println(F("%")); times = millis(); } } Kết quả: 19 Bài thực hành 4: Tương tác với các dịch vụ web và máy với máy 4.1. Giám sát dữ liệu cảm biến từ bảng điều khiển đám mây Giao diện trên Web Blynk Giao diện trên App Blynk 20 4.2. Thực hành một số công cụ xử lý số liệu. Sử dụng bộ lọc KalmaFilter để lọc tín hiệu trước khi gửi dữ liệu đi. Rõ ràng khi ta sử dụng cảm biến, giá trị trả về từ chúng luôn thay đổi quanh vị trí cân bằng dù là rất nhỏ nhưng dù sao KalmaFilter cũng mang lại giải pháp cho vấn đề này Và rõ ràng phần code này sẽ được thêm trước phần gửi dữ liệu gửi đến blynk. // đọc một giá trị tham chiếu từ chân tín hiệu và ánh xạ nó từ 0 đến 100 float real_value = t/1024.0 * 100.0; // thêm nhiễu vào giá trị tham chiếu và sử dụng làm giá trị đo được float measured_value = real_value + random(-100,100)/100.0; // tính toán giá trị ước tính với Bộ lọc Kalman float t_estimated_value = simpleKalmanFilter.updateEstimate(measured_value); float real_value2 = h / 1024.0 * 100.0; // thêm nhiễu vào giá trị tham chiếu và sử dụng làm giá trị đo được float measured_value2 = real_value2 + random(-100,100)/100.0; // tính toán giá trị ước tính với Bộ lọc Kalman float h_estimated_value = simpleKalmanFilter.updateEstimate(measured_value2); Blynk.virtualWrite(V1,t_estimated_value); // Gửi lên chân ảo V1 Blynk.virtualWrite(V2,h_estimated_value); // Gửi lên chân ảo V1 } 21 Bài thực hành 5: Đồ án kết thúc học phần Sử dụng esp8266 đọc, sử dụng bộ lọc tín hiệu và hiển thị các thông số cảm biến trên màn hình LCD, gửi dử liệu cảm biến thời gian thực lên nền tảng đám mấy (lựa chọn bất kỳ), xử lý số liệu và trực quan hóa dữ liệu trên đám mây (hoặc app). Thời gian làm việc của hệ thống nhỏ nhất là 10 ngày. Tính giá trị trung bình cảm biến trong từng ngày và hiển thị giá trị đó trên màn hình màn hình LCD. Viết báo cáo đồ án và thuyết minh. 5.1 Thiết bị sử dụng: LCD – I2C DHT11 5.2 Phần thực hành. Đi dây: Phần code: // Fill-in information from your Blynk Template here #define BLYNK_TEMPLATE_ID "TMPLxYB_ArQ2" #define BLYNK_DEVICE_NAME "DHT11" #define BLYNK_AUTH_TOKEN "nQJeGJOemR08hC-zVzzxeXMjkFHX1_dD" #define BLYNK_FIRMWARE_VERSION #define BLYNK_PRINT Serial //#define BLYNK_DEBUG "1.0.1" #define APP_DEBUG #define USE_NODE_MCU_BOARD #include "BlynkEdgent.h" #include <Arduino.h> #include <DHT.h> 22 #include <DHT_U.h> #include <LiquidCrystal_I2C.h> #include <SimpleKalmanFilter.h> SimpleKalmanFilter simpleKalmanFilter(2, 2, 0.01); // Serial output refresh time const long SERIAL_REFRESH_TIME = 100; long refresh_time; //define I2C address...... LiquidCrystal_I2C lcd(0x27,16,2); #define DHTPIN D4 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); unsigned long times=millis(); WidgetLED led(V0); BlynkTimer timer; // V0 LED Widget is blinking void blinkLedWidget(){ if (led.getValue()) { led.off(); } else { led.on(); } } void setup(){ Serial.begin(115200); lcd.init(); // turn on LCD backlight lcd.backlight(); delay(100); BlynkEdgent.begin(); //Keetss nối Blynk dht.begin(); timer.setInterval(1000L, blinkLedWidget); } float count = 0; float tem = 0; float hum = 0; void loop() { BlynkEdgent.run(); // Khởi động timer 23 timer.run(); // delay(2000); if(millis()-times>5000){ // Reading temperature or humidity float t = dht.readTemperature(); // Do nhiệt độ từ DHT11 float h = dht.readHumidity(); // // Do nhiệt độ từ DHT11 lcd.setCursor(0, 0); // print message lcd.print("Tempday: "); // set cursor to first column, second row lcd.setCursor(0,1); lcd.print("Humiday: "); if (isnan(h) || isnan(t)) { Serial.println(F("Failed to read from DHT sensor!")); return; } // ý tưởng tính trung bình nhiệt độ 1 ngày: if (count < 1) { // Lần đầu sẽ gán giá trị tem, hum = vs t,h float tem = t; // Sau đó liên tục tính trung bình cộng các giá trị này float hum = h; // Kết quả trung bình cộng sẽ reset sau 1 ngày tức 86400/5 lần chạy Serial.print("temp:"); Serial.println(tem) ; } if (count = 17280) { // 1day = 86400s -> 86400/5 float count = 0; return; } float count = count + 1; Serial.println(count) ; float temp = (tem + t)/2; float humi = (hum + h)/2; lcd.setCursor (11,0); lcd.print(temp); lcd.setCursor (11,1); // go to start of 2nd line random(-100,100) lcd.print(humi); float tem = t; float hum = h; Blynk.virtualWrite(V1,t); // Gửi lên chân ảo V1 Blynk.virtualWrite(V2,h); // Gửi lên chân ảo V1 24 Serial.print(F("Temperature: ")); Serial.print(t); Serial.print(F("°C ")); Serial.print(F("Humidity: ")); Serial.print(h); Serial.println(F("%")); // } times = millis(); } Kết quả thực hiện: 25 Blynk web: Blynk app: 26 Tài liệu tham khảo 1. https://arduino.esp8266.vn/basic/led.html. 2. KamlFilter : http://arduino.vn/tutorial/1492-bo-loc-kalman-giai-phap-chong-nhieu-tuyet-voi-cho-moidu-su-dung-cam-bien 3. ESP8266 Weather Server With LCD Display. www.instructables.com. [Online] [Cited: 12 20, 2022.] https://www.instructables.com/ESP8266-Weather-Server-With-LCDDisplay/. 4. Blynk app: https://docs.blynk.io/en/blynk.console/widgets-console/modules 5. https://insys.vn/2021/02/28/thu-thap-du-lieu-cam-bien/ 6. https://community.blynk.cc/t/average-from-virtual-pins-possible/12834/7 27