Báo cáo bài tập lớn môn học Thiết kế hệ nhúng của Viện điện tử viễn thông, trường Đại học Bách Khoa Hà Nội. Đề tài: Thiết kế ứng ứng điều khiển thiết bị điện trong nhà và đọc các dữ liệu cảm biến thông qua môi trường Internet. Các thành phần phần cứng được sử dụng trong đề tài bao gồm: Bo mạch Arduino, ESP8266, Module replay, cảm biến nhiệt độ và độ ẩm DHT11. Thành phần phần mềm bao gồm Server, ứng dụng Android, ứng dụng Web.
Trang 1TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN ĐIỆN TỬ - TRUYỀN THÔNG
BÁO CÁO BTL THIẾT KẾ HỆ NHÚNG
ĐỀ TÀI: THIẾT KẾ ỨNG DỤNG ĐIỀU KHIỂN THIẾT BỊ VÀ
ĐỌC CẢM BIẾN QUA INTERNET
Hà Nội, 05/2017
Trang 2
MỤC LỤC
MỤC LỤC 2
1 GIỚI THIỆU VỀ IOT 3
2 GIỚI THIỆU ỨNG DỤNG 4
3 MÔI TRƯỜNG THỰC HIỆN 5
3.1 WebSocket 5
3.2 NodeJS 6
3.3 Socket.IO 7
3.4 Arduino 8
3.5 ESP8266 9
4 THIẾT KẾ SƠ ĐỒ KHỐI 11
5 TRIỂN KHAI ĐỀ TÀI 12
5.1 Phía Server 12
5.2 Phía Client 17
5.2.1 WebApp 17
5.2.2 AndroidApp 21
5.2.3 ESP8266 32
5.2.4 Arduino 34
6 TÀI LIỆU THAM KHẢO 39
Trang 41 GIỚI THIỆU VỀ IOT
Internet of Thing (IoT) là một khái niệm được đặt ra bởi Kevin Ashton, 1 kỹ sư người anh đi đầu trong lĩnh vực radio-frequency identification (RFID), người đã đặt nền móng về một hệ thống mà các cảm biến điện tử ở khắp nơi được kết nốt với thế giới thông qua Internet Ba thành phần chủ chốt của IoT là “things”, “Internet” và “sự kết nối” giữa chúng
Khi mà vạn vật đều có chung một mạng kết nối thì việc liên lạc và làm việc trở nên rất dễ dàng Con người có thể hiện thực hóa mục đích của mình trong tương lai Chúng ta hoàn toàn có thể kiểm soát mọi thứ Giả sử một hệ thống tưới nước tự động cây cối trong gia đình bạn được tích hợp công nghệ IOT Giúp bạn điều khiển qui trình chăm sóc cây, tưới nước cây, thậm chí là bắt sâu bọ,…khi bạn có chuyến đi công tác xa vài ngày hay vài tháng mà không thể thực hiện được các chức năng đó Điều đó
sẽ trở nên rất đơn giải khi giả sử mà hệ thống tưới cây tự động và điện thoại hoặc laptop, PC, của bạn được kết nối và mạng lưới Internet và qua đó có thể trao đổi thông tin cũng như thực thi các câu lệnh mà bạn mong muốn
“Sự kết nối” mà được đề cập ở trên và là một thành phần quan trọng trong mạng lưới IoT chính là các cảm biến (sensors) Các thiết bị cần kết nối phải được tích hợp một chip cảm biến để có thể chuyển đổi, phát hiện các hiện tượng trong môi trường tự nhiên và biến nó thành dữ liệu trong môi trường Internet để xử lý dữ liệu và tiến hành thực thi các điều hướng trong mạng Internet đó theo cách mà người dùng mong muốn Lấy ví dụ hệ thống tưới nước cây tự động như ở trên thì hệ thống sinh thái của chúng ta phải được gắn 1 bộ cảm biến dùng để nhận biết các yếu tố như: nhiệt độ, lượng nước, độ ẩm, thời tiết,… Sau đó được chuyển thành dữ liệu và các dữ liệu này được sử dụng và được thiết lập các thiết lập các chế độ theo mục đích sử dụng Và qui trình này sẽ kết nối và hoạt động trong môi trường Internet để thông báo và tạo giao diện đến người dùng
Ứng dụng của IoT:
Thực ra khái niệm Internet Of Things được đưa ra vào năm 1999 Khi mà công nghệ Internet đang từng bước phát triển
Và cho đến ngày nay, Internet Of Things không còn là 1 vấn đề quá viễn vông,
cụ thể là rất nhiều các phát mình, ứng dụng được trình làng Khái niệm thiết bị thông minh, tủ lạnh thông minh, tivi thông minh, … được sử dụng rỗng rãi trong thể giới công nghệ ngày nay
Các bạn có thể điều khiển 1 chiếc tivi bằng điều hướng bàn tay, giọng
nói,…bằng công nghệ smart tivi của hãng Samsung, máy lạnh tự động điều chỉnh nhiệt độ theo thời tiết,…Hay như xe ô tô tích hợp chức năng chống sốc tự dộng, tự động báo cho người sử dụng khi lốp xe bị xẹp hay gặp trúng vật cản phía trước
khoảng bao nhiêu mét chẳng hạn Thậm chí là ngôi nhà – nơi chúng ta đang sống cũng
có định nghĩa là ngôi nhà thông minh với rất nhiều ứng dụng công nghệ hiện đại
Trang 5Rất và rất nhiều những ứng dụng trong Internet Of Things đã được các công ty
công nghệ khai thác vấn đề này
2 GIỚI THIỆU ỨNG DỤNG
Ứng dụng điều khiển thiết bị và đọc cảm biến thông qua mạng internet là ứng
dụng giúp người dùng có thể điều khiển bật hoặc tắt các thiết bị điện trong nhà, đọc
giá trị cảm biến nhiệt độ, độ ẩm bằng máy tính hoặc điện thoại ở bất cứ nơi nào có kết
nối internet
Hình 1: Giao diện web của ứng dụng
Trang 6Hình 2: Giao diện trên điện thoại
3 MÔI TRƯỜNG THỰC HIỆN
3.1 WebSocket
WebSoket là công nghệ hỗ trợ giao tiếp hai chiều giữa client và server bằng cách
sử dụng một TCP socket để tạo một kết nối hiệu quả và ít tốn kém Mặc dù được thiết
kế để chuyên sử dụng cho các ứng dụng web, lập trình viên vẫn có thể đưa chúng vào bất kì loại ứng dụng nào
WebSockets mới xuất hiện trong HTML5, là một kỹ thuật Reverse Ajax
WebSockets cho phép các kênh giao tiếp song song hai chiều và hiện đã được hỗ trợ trong nhiều trình duyệt (Firefox, Google Chrome và Safari) Kết nối được mở thông qua một HTTP request (yêu cầu HTTP), được gọi là liên kết WebSockets với những header đặc biệt Kết nối được duy trì để bạn có thể viết và nhận dữ liệu bằng
JavaScript như khi bạn đang sử dụng một TCP socket đơn thuần
Dữ liệu truyền tải thông qua giao thức HTTP (thường dùng với kĩ thuật Ajax) chứa nhiều dữ liệu không cần thiết trong phần header Một header request/response của HTTP có kích thước khoảng 871 byte, trong khi với WebSocket, kích thước này chỉ là 2 byte (sau khi đã kết nối)
Vậy giả sử bạn làm một ứng dụng game có thể tới 10,000 người chơi đăng nhập cùng lúc, và mỗi giây họ sẽ gửi/nhận dữ liệu từ server Hãy so sánh lượng dữ liệu header mà giao thức HTTP và WebSocket trong mỗi giây:
Trang 7- HTTP: 871 x 10,000 = 8,710,000 bytes = 69,680,000 bits per second (66Mbps)
- WebSocket: 2 x 10,000 = 20,000 bytes = 160,000 bits per second (0.153 Kbps)
❖ Ưu điểm
WebSockets cung cấp khả năng giao tiếp hai chiều mạnh mẽ, có độ trễ thấp và
dễ xử lý lỗi Không cần phải có nhiều kết nối như phương pháp Comet long-polling và cũng không có những nhược điểm như Comet streaming API cũng rất dễ sử dụng trực tiếp mà không cần bất kỳ các tầng bổ sung nào, so với Comet, thường đòi hỏi một thư viện tốt để xử lý kết nối lại, thời gian chờ timeout, các Ajax request (yêu cầu Ajax), các tin báo nhận và các dạng truyền tải tùy chọn khác nhau (Ajax long-polling và jsonp polling)
request Khi request đó kết thúc, bộ lọc hủy bỏ contest này
3.2 NodeJS
Node.js là một hệ thống được thiết kế để viết các ứng dụng internet có khả năng
mở rộng, đặc biệt là máy chủ web Chương trình được viết bằng JavaScript, sử dụng
kỹ thật điều khiển theo sự kiện, nhập/xuất không đồng bộ để tối thiểu tổng chi phí và tối đại khả năng mở rộng Node.js bao gồm có V8 JavaScript engine của Google, libUV, và vài thư viện khác
Node.js được tạo bởi Ryan Dahl từ năm 2009, và phát triển dưới sự bảo trợ của Joyent
Mục tiêu ban đầu của Dahl là làm cho trang web có khả năng push như trong một số ứng dụng web như Gmail Sau khi thử với vài ngôn ngữ Dahl chọn Javascript
vì một API Nhập/Xuất không đầy đủ Điều này cho phép anh có thể định nghĩa một quy ước Nhập/Xuất điểu khiển theo sự kiện, non-blocking
Vài môi trường tương tự được viết trong các ngôn ngữ khác bao gồm Twisted cho Python, Perl Object Environment cho Perl, libevent cho C và EventMachine cho Ruby Khác với hầu hết các chương trình Javascript, Nodejs không chạy trên một trình duyệt mà chạy trên Server Node.js sử dụng nhiều chi tiết kỹ thuật của CommonJs Nó cung cấp một môi trường REPL cho kiểm thử tương tác
Trang 8Node.js là một ngôn ngữ mới, xây dựng thuần túy bằng javascript Đây là một điểm lợi thế của Node.js để lập trình web-socket:
Thứ nhất: javascript là ngôn ngữ lập trình hướng sự kiện, mà trong lập trình
thời gian thực, cách tiếp cận bằng lập trình sự kiện là cách tiếp cận khôn ngoan nhất
Thứ hai: Node.js chạy non-blocking việc hệ thống không phải tạm ngừng để xử
lý xong một request sẽ giúp cho server trả lời client gần như ngay tức thì
Thứ ba: lập trình socket yêu cầu bạn phải xây dựng được mô hình lắng nghe –
trả lời từ cả 2 bên Nói khác đi, vai trò của client và server phải tương đương nhau, mà client thì chạy bằng javascript, nên nếu server cũng chạy bằng javascript nữa, thì việc lập trình sẽ dễ dàng và thân thiện hơn
3.3 Socket.IO
Socket.IO là một thư viện javascript có mục đích tạo ra các ứng dụng realtime trên trình duyệt cũng như thiết bị di động Việc sử dụng thư viện này cũng rất đơn giản và giống nhau ở cả server lẫn client
Server: tạo một đối tượng socket bằng phương thức listen(port) Phương thức
này chờ đợi một yêu cầu kết nối từ client
- Client: Kết nối đến server bằng phương thức connect(url,{port: server_port})
- Socket.IO cung cấp 3 event chính là connect, message và disconnect Chúng
được kích hoạt khi client/server:
• connect: tạo kết nối
• message: nhận được thông điệp
Socket.IO có thể gửi và nhận các event tự tạo với phương thức emit() Hai phía
gửi và nhận phải biết được tên của event đó để thực hiện giao tiếp:
Ví dụ:
// client gửi một dòng message "welcome" lên event "hello"
socket.emit("hello", {msg: "welcome"});
// Server nhận sự kiện event đưa lên
socket.on("hello", function (data) {
console.log(data);});
Trang 93.4 Arduino
Arduino là một board mạch vi xử lý, nhằm xây dựng các ứng dụng tương tác với nhau hoặc với môi trường được thuận lợi hơn Phần cứng bao gồm một board mạch nguồn mở được thiết kế trên nền tảng vi xử lý AVR Atmel 8bit, hoặc ARM Atmel 32- bit Những Model hiện tại được trang bị gồm 1 cổng giao tiếp USB, 6 chân đầu vào analog, 14 chân I/O kỹ thuật số tương thích với nhiều board mở rộng khác nhau Nhắc tới dòng mạch Arduino dùng để lập trình, cái đầu tiên mà người ta thường nói tới chính là dòng Arduino UNO Hiện dòng mạch này đã phát triển tới thế hệ thứ 3 (R3)
Hình 3: Arduino UNO R3
Các cổng vào/ra của UNO R3:
Arduino UNO có 14 chân digital dùng để đọc hoặc xuất tín hiệu Chúng chỉ có 2 mức điện áp là 0V và 5V với dòng vào/ra tối đa trên mỗi chân là 40mA Ở mỗi chân đều có các điện trở pull-up từ được cài đặt ngay trong vi điều khiển ATmega328 (mặc định thì các điện trở này không được kết nối)
• 2 chân Serial: 0 (RX) và 1 (TX): dùng để gửi (transmit – TX) và nhận
(receive – RX) dữ liệu TTL Serial Arduino Uno có thể giao tiếp với thiết bị khác thông qua 2 chân này
• Chân PWM (~): 3, 5, 6, 9, 10, và 11: cho phép bạn xuất ra xung PWM với
độ phân giải 8bit (giá trị từ 0 → 28-1 tương ứng với 0V → 5V) bằng hàm analogWrite()
• Chân giao tiếp SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK) Ngoài các
chức năng thông thường, 4 chân này còn dùng để truyền phát dữ liệu bằng giao thức SPI với các thiết bị khác
• LED 13: trên Arduino UNO có 1 đèn led màu cam (kí hiệu chữ L) Khi bấm
nút Reset, bạn sẽ thấy đèn này nhấp nháy để báo hiệu Nó được nối với chân
số 13 Khi chân này được người dùng sử dụng, LED sẽ sáng
Trang 10Arduino UNO có 6 chân analog (A0 → A5) cung cấp độ phân giải tín hiệu 10bit (0 → 210-1) để đọc giá trị điện áp trong khoảng 0V → 5V
3.5 ESP8266
ESP8266 là một mạch vi điều khiển có thể giúp chúng ta điều khiển các thiết bị điện tử Điều đặc biệt của nó, đó là sự kết hợp của module Wifi tích hợp sẵn bên trong con vi điều khiển chính Hiện nay, ESP8266 rất được giới nghiên cứu tự động hóa Việt Nam ưa chuộng vì giá thành cực kỳ rẻ (chỉ bằng một con Arduino Nano), nhưng lại được tích hợp sẵn Wifi, bộ nhớ flash 8Mb
ESP8266 có nhiều phiên bản và được đóng gói theo nhiều cách khác nhau, tuy nhiên nó lại khá giống nhau về chức năng và khả năng lập trình Trên thị trường phổ biến nhất hiện nay là ESP8266v1, ESP8266v7 và ESP8266v12 Các mạch này được đóng gói theo nhiều cách khác nhau dưới các tên gọi như hình ảnh dưới đây:
Hình 4: Các phiên bản của ESP8266
Trang 11Các phiên bản ESP8266 phổ biến:
Hình 5: ESP8266 v1
Hình 6: Kit Node MCU dùng ESP12
ESP8266 là dòng chip Low-power và là một wifi SOC nên cần rất ít linh kiện ngoài (tầm 7 thành phần) hoạt động trong dãi nhiệt -40°C to +125°C Đây là cấu hình của ESP8266 v12:
• 32-bit RISC CPU: Tensilica Xtensa LX106 hoạt động với 80 MHz*
• 64 KiB instruction RAM, 96 KiB data RAM
• QSPI flash ngoài – 512 KiB – 4 MiB* (có thể lên tới 16 MiB)
Trang 12• IEEE 802.11b/g/n Wi-Fi
• Tích hợpTR switch, balun, LNA, power amplifier và matching network
• WEP hoặc WPA/WPA2 authentication, open networks
Arduino
ThinkSpeak
Android App (Mobile)Tầng 2: Client
Hình 7: Sơ đồ khối của ứng dụng
Tầng 1: Server trung tâm để các client gửi dữ liệu lên, đồng thời server cũng sẽ
trả dữ liệu cho các client khác khi có yêu cầu Server kết nối với các client bằng kết
nối internet, giao tiếp bằng các chuỗi JSON Các dữ liệu về cảm biến sẽ được Server
gửi lên một dịch vụ phân tích dữ liệu khác là ThinkSpeak, dịch vụ này sẽ phân tích
dữ liệu gửi lên và vẽ biểu đồ cho người dùng
Tầng 2: Client gồm ESP8266, WebApp, Android App
• ESP8266: Có chức năng là cầu nối giữa tầng 3 là Arduino với Server
ESP8266 nhận lệnh từ Server và gửi xuống cho Arduino thực hiện, đồng thời gửi dữ liệu từ Arduino lên Server
• WebApp và Android App: giao diện người dùng đầu cuối, có chức năng kết
nối tới Server để lấy dữ liệu mà ESP8266 gửi lên, đồng thời sẽ gửi lệnh của
Trang 13người dùng lên Server WebApp và AndroidApp cũng sẽ kết nối tới dịch vụ ThinkSpeak để lấy dữ liệu đã được phân tích
Tầng 3: Arduino là nơi thực thi các lệnh từ Server gửi xuống bao gồm các lệnh
đọc cảm biến và điều khiển thiêt bị, đồng thời sẽ gửi dữ liệu lên Server thông qua ESP8266
5 TRIỂN KHAI ĐỀ TÀI
5.1 Phía Server
Server được triển khai bằng Nodejs và được viết bằng ngôn ngữ JavaScript Sau đây là source code phía server:
//ra chương trình mạng Socket Server var http = require('http'); //Include thư viện http
var express = require('express'); //Include thư viện express
var socketio = require('socket.io');//Include thư viện socketio
var ip = require('ip'); //Include thư viện ip
var app = express();
var server = http.Server(app); //Khởi tạo một server
var io = socketio(server); //Khởi tạo io sau khi tạo server
//Khai báo dữ liệu up lên ThingSpeak
var ThingSpeakClient = require('thingspeakclient');
var client_thingspeak = new ThingSpeakClient();
var WriteKey = '0UYASRTTTM6XVAE6'; //WriteKey project trên ThingSpeak var channelID = 253548; //ID tài khoản ThingSpeak
//Khai báo dữ liệu up lên ubidots
var request = require('request'); //Include thư viện request
var url_temperature = "http://things.ubidots.com/api/v1.6/devices/t-home/temperature/values?token=WYtBoP2cLzfK8l29cSwYQnXopBR8wA"
var url_humidity = "http://things.ubidots.com/api/v1.6/devices/t-home/humidity/values?token=WYtBoP2cLzfK8l29cSwYQnXopBR8wA"
//Khai báo Namespace cho client
var webapp_nsp = io.of('/webapp'); //Namespace của webapp
var esp8266_nsp = io.of('/esp8266'); //Namespace của esp8266
var android_nsp = io.of('/android'); //Namespace của App android var middleware = require('socketio-wildcard')(); //Include thư viện socketio-wildcard bắt các sự kiện
esp8266_nsp.use(middleware); //Khi esp8266 emit bất kì lệnh gì thì server bắt
Trang 14webapp_nsp.use(middleware); //Khi webapp emit bất kì lệnh gì thì server bắt android_nsp.use(middleware);//Khi android app emit bất kì lệnh gì thì server b
ắt
server.listen(process.env.PORT || PORT);//Cho socket server lắng nghe ở PORT console.log("Server running at address: " + ip.address() + ":" + PORT); //Log ra địa chỉ ip của server
//Giải nén chuỗi JSON thành các Object
Trang 15//Bắt tất cả các lệnh từ esp8266
socket.on('*', function(packet){
console.log('Esp8266 send to Server', packet.data);
var eventname = packet.data[0]; //Tên lệnh, ở đây là "SENSOR" ho
ặc "DECIVE"
var eventjson = packet.data[1] || {}; //Chuỗi Json, nếu gửi cả js
on thì lấy json từ lệnh gửi, không thì gửi chuỗi json rỗng {}
webapp_nsp.emit(eventname, eventjson); //Gửi toàn bộ lệnh và chuỗi đến webapp
android_nsp.emit(eventname, eventjson); //Gửi toàn bộ lệnh và chuỗi đế
n android app
//Up dữ liệu lên ThingSpeak và ubidots
client_thingspeak.attachChannel(channelID, { writeKey: WriteKey}); //Khai báo ID và WriteKey của ThingSpeak
//Up dữ liệu nhiệt độ và độ ẩm
if(packet.data[0] == "SENSOR"){
client_thingspeak.updateChannel(channelID, {field1: packet.data[1].Temperature,
field2: packet.data[1].Humidity});
console.log("Sensor updated on ThingSpeak!");
//Up dữ liệu lên ubidots
request(temperature, function (error, response, body) {
if (!error && response.statusCode == 200) {
Trang 16console.log(body.id) // Print the shortened url
}
});
request(humidity, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body.id) // Print the shortened url
field5: packet.data[1].decive_3_Status,
field6: packet.data[1].decive_4_Status,})
console.log("Decive Status updated on ThingSpeak");
console.log('Webapp send to Server', packet.data);
var eventname = packet.data[0];
var eventjson = packet.data[1] || {}; //Nếu gửi thêm json thì lấy json từ lệnh gửi, không thì gửi chuỗi json rỗng {}
Trang 17esp8266_nsp.emit(eventname, eventjson); //Gửi toàn bộ lệnh và chuỗi json đến esp8266
console.log('Android App send to Server', packet.data);
var eventname = packet.data[0]; //Tên lệnh
var eventjson = packet.data[1] || {}; //Nếu gửi thêm json thì lấy json từ lệnh gửi, không thì gửi chuỗi json rỗng {}
Trang 18"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
WebApp được viết bằng JavaScript và AngularJS
File thực thi WebApp.js:
angular.module('myApp',[
'ngRoute',
'mobile-angular-ui',
'btford.socket-io', ]).config(function($routeProvider){
Trang 19console.log("Send UPDATE command")
mySocket.emit("UPDATE") //Gửi lệnh UPDATE để update sensor }
//Hàm Control gửi lệnh CONTROL cho Server > Esp8266 > Arduino
$scope.Control = function(){
console.log("Send CONTROL command")
var json = { //Chuỗi json chứa trạng thái các decive "Status": $scope.Decive_Status
//Lắng nghe các lệnh từ Server gửi đến
mySocket.on('SENSOR', function(json){ //Lắng nghe lệnh SENSOR
$scope.Humidity = json.Humidity; //Đọc độ ẩm từ chuỗi gửi đến
$scope.Temperature = json.Temperature; //Đọc nhiệt độ từ chuỗi gửi đến })
mySocket.on('DECIVE', function(json){ //Lắng nghe lệnh DECIVE
console.log("Decive Status", json)
$scope.Decive_Status = json.data })
Trang 20<iframe width="450" height="260" style="border: 1px solid #cccccc;"
src="https://thingspeak.com/channels/253548/charts/2?bgcolor=%23ffffff&color=%23d62020&dynamic=true&results=60&title=B