Tải bản đầy đủ

Thiết kế hệ nhúng - Thiết kế ứng dụng điều khiển thiết bị và đọc cảm biến qua Internet bằng ứng dụng Android và Web (Kèm code)

TRƯỜ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


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



1. 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.
3


Rấ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

4


Hì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:
5


- 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).
❖ Nhược điểm
- Nó là một đặc tả mới của HTML5, nên nó vẫn chưa được tất cả các trình duyệt
hỗ trợ.
- Không có phạm vi yêu cầu nào. Do WebSocket là một TCP socket chứ không
phải là HTTP request, nên không dễ sử dụng các dịch vụ có phạm vi-yêu cầu, như
SessionInViewFilter của Hibernate. Hibernate là một framework kinh điển cung cấp
một bộ lọc xung quanh một HTTP request. Khi bắt đầu một request, nó sẽ thiết lập
một contest (chứa các transaction và liên kết JDBC) được ràng buộc với luồng
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.

6


Node.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
• disconnect: ngắt kết nối
Ví dụ: Khai báo cho socket nhận một sự kiện “message”
socket.on("message", function(msg){
// console.log("Received: "+ msg);
});

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);});

7


3.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 32bit. 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.
8


Arduino 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

9


Cá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)
10











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
16 GPIO pins
SPI, I²C,
I²S interfaces với DMA (dùng chung với GPIO)
UART
1 10-bit ADC

4. THIẾT KẾ SƠ ĐỒ KHỐI
ThinkSpeak

Internet
Internet
Tầng 1: Server

Server (NodeJS)

Internet
Tầng 2: Client

Internet

Internet

Internet
Web App
(Mobile and
Computer)

ESP8266

Android App
(Mobile)

UART
Tầng 3: Application

Arduino

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

11


ngườ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:
const PORT = 3484;

//Đặt địa chỉ Port được mở ra để tạo
//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/tempe
rature/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-w
ildcard bắt các sự kiện
esp8266_nsp.use(middleware); //Khi esp8266 emit bất kì lệnh gì thì server bắt

12


webapp_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
function ParseJson(jsondata){
try{
return JSON.parse(jsondata);
} catch(error){
return null;
};
};

//Cài đặt webapp các fie dữ liệu tĩnh truy cập từ xa
app.use(express.static("node_modules/mobile-angular-ui"));
// Có thể truy cập các file trong node_modules/mobile-angular-ui từ xa
app.use(express.static("node_modules/angular"));
// Có thể truy cập các file trong node_modules/angular từ xa
app.use(express.static("node_modules/angular-route"));
// Có thể truy cập các file trong node_modules/angular-route từ xa
app.use(express.static("node_modules/socket.io-client"));
// Có thể truy cập các file trong node_modules/socket.io-client từ xa
app.use(express.static("node_modules/angular-socket-io"));
// Có thể truy cập các file trong node_modules/angular-socket-io từ xa
app.use(express.static("webapp"));

// Dùng để lưu trữ webapp

/*
* Bắt tất cả các lệnh từ esp8266 gửi đến
* đồng thời Up dữ liệu nhận được lên ThingSpeak
* và Ubidots
* Khi nhiệt độ, độ ẩm quá ngưỡng thì bật thiết bị
*/
esp8266_nsp.on('connection', function(socket){
console.log('Esp8266 connected!');
socket.on('disconnect', function(){
console.log('Esp8266 disconnect!');
});

13


//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);
huỗi đến webapp
android_nsp.emit(eventname, eventjson);
n android app

//Gửi toàn bộ lệnh và c

//Gửi toàn bộ lệnh và chuỗi đế

//Up dữ liệu lên ThingSpeak và ubidots
client_thingspeak.attachChannel(channelID, { writeKey: WriteKey});
báo ID và WriteKey của ThingSpeak

//Khai

//Up dữ liệu nhiệt độ và độ ẩm
if(packet.data[0] == "SENSOR"){
client_thingspeak.updateChannel(channelID, {field1: packet.data[1].Tempera
ture,
field2: packet.data[1].Humidit
y});
console.log("Sensor updated on ThingSpeak!");

//Up dữ liệu lên ubidots
var temperature = {
url: url_temperature,
method: 'POST',
json:{
"value": packet.data[1].Temperature
}
};
var humidity = {
url: url_humidity,
method: 'POST',
json:{
"value": packet.data[1].Humidity
}
};

request(temperature, function (error, response, body) {
if (!error && response.statusCode == 200) {

14


console.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.
}
});
console.log("Sensor updated on Ubidots");
}
//Up dữ liệu trạng thái 0 hoặc 1 của mỗi decive lên ThingSpeak
if(packet.data[0] == "DECIVE"){
client_thingspeak.updateChannel(channelID, {field3: packet.data[1].deciv
e_1_Status,
field4: packet.data[1].deciv
e_2_Status,
field5: packet.data[1].deciv
e_3_Status,
field6: packet.data[1].deciv
e_4_Status,})
console.log("Decive Status updated on ThingSpeak");
}
});
});

/*
* Bắt các lệnh khi webapp kết nối tới
*/
webapp_nsp.on('connection', function(socket){
console.log('Webapp connected!');
socket.on('disconnect', function(){
console.log('Webapp disconnect!');
});
//Bắt tất cả các lệnh
socket.on('*', function(packet){
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 {}

15


esp8266_nsp.emit(eventname, eventjson);
huỗi json đến esp8266

//Gửi toàn bộ lệnh và c

});
});

/*
* Bắt các lệnh khi Android App kết nối tới
*/
android_nsp.on('connection', function(socket){
console.log('Android App connected!');
socket.on('disconnect', function(){
console.log('Android App disconnect');
});
//Bắt tất cả các lệnh
socket.on('*', function(packet){
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 {}
//console.log(packet.data[1]);
esp8266_nsp.emit(eventname, eventjson);
huỗi json đến esp8266
});
});

File package.json:
{
"name": "t-home",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"angular": "^1.6.2",
"angular-route": "^1.6.2",
"angular-socket-io": "^0.7.0",
"angular-toggle-switch": "^1.3.0",
"express": "^4.14.1",
"ip": "^1.1.4",
"mobile-angular-ui": "^1.3.4",
"socket.io": "^1.7.3",

16

//Gửi toàn bộ lệnh và c


"socket.io-client": "^1.7.3",
"socketio-wildcard": "^0.3.0"
},
"devDependencies": {},
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

5.2. Phía Client
5.2.1. WebApp
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){
$routeProvider.when('/',{
templateUrl: 'home.html',
controller: 'Home'
});
}).factory('mySocket', function(socketFactory){
var myIoSocket = io.connect('/webapp');

//Tên namespace webapp

mySocket = socketFactory({
ioSocket: myIoSocket
});
return mySocket;
}).controller('Home', function($scope, mySocket){
/*
* Cài đặt tham số dùng để đặt các giá trị mặc định
*/
$scope.Humidity = 0;

//Độ ẩm

$scope.Temperature = 0;

//Nhiệt độ

$scope.Decive_Status = [0, 0, 0, 0];

//Mảng trạng thái decive

17


/*
* Cài đặt các sự kiện khi tương tác với người dùng các sự kiện ng-click, nhấn
nút
*/
//Hàm updateSensor gửi lệnh UPDATE cho Server --> Esp8266 --> Arduino
$scope.updateSensor

= function(){

console.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
}
mySocket.emit("CONTROL", json)

//Gửi lệnh CONTROL để điều khiển decive

}

/*
* Nhận dữ liệu từ Arduino gửi lên (thông qua ESP8266 rồi Socket server truyền
xuống)
*/
//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
})

/*
* Khi Webapp kết nối tới Server thì báo Connected và gửi ngay lệnh UPDATE
* để cập nhật giá trị nhiệt độ và độ ẩm
*/
mySocket.on('connect', function(){
console.log("Connected");
mySocket.emit("UPDATE");

18


})
});

File giao diện html home.html:





bsite/smarthome_page/images/icon_ss_home.png width="50" height="50"/>

T-Home 1.1







width="30"
height="30"/>


CẢM BIẾN NHIỆT
ĐỘ - ĐỘ ẨM


(Tự động cập nhật sau 30 giây)


Nhiệt độ hiện tại: {{Tempera
ture + "°C"}}


Độ ẩm hiện tại: {{Humidity +
"%"}}













width="30"
height="30"/>


ĐIỀU KHIỂN THIẾ
T BỊ TRONG NHÀ



Thiết bị {{$index}} đang rong>{{Status_value ? "bật" : "tắt"}}
ng-false-value="0" ng-c
hange="Control()" ng-model="Decive_Status[$index]" />









T-Home là hệ thống nhà thông min
h đơn giản với chức năng chính là cho phép người dùng
điều khiển bật tắt các thiết bị
điện trong nhà, hiển thị nhiệt độ và độ ẩm thông qua mạng internet,
đồng thời cảnh báo cho chủ nhà q
ua SMS khi nhiệt độ vượt quá ngưỡng cho phép.





20





5.2.2. AndroidApp
AndroidApp được viết bằng ngôn ngữ Java được tùy biến của Google. Để kết
nối tới Server ta sẽ dùng thư viện SocketIO, thư viện này cũng giống như thư viện
Socket.IO trên NodeJS.
Khai báo trong Gradle để thêm thư viện:
compile ('io.socket:socket.io-client:0.8.3') {
exclude group: 'org.json', module: 'json'
}

Source code Android:
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private final int REQ_CODE_SPEECH_INPUT = 100;

TextView txt_nhietdo, txt_doam, test;
Switch sw1, sw2, sw3, sw4;
boolean isCheck1, isCheck2, isCheck3, isCheck4;
WebView webView, webView2;
String Url = "";
String Url2 = "";
private Socket mSocket;

{

21


try {
mSocket = IO.socket("https://bk-home.mybluemix.net/android");
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

txt_nhietdo = (TextView) findViewById(R.id.txt_nhietdo);
txt_doam = (TextView) findViewById(R.id.txt_doam);
sw1 = (Switch) findViewById(R.id.switch1);
sw2 = (Switch) findViewById(R.id.switch2);
sw3 = (Switch) findViewById(R.id.switch3);
sw4 = (Switch) findViewById(R.id.switch4);
test = (TextView) findViewById(R.id.test);

mSocket.emit("UPDATE");
mSocket.on("SENSOR", Update);
mSocket.on("DECIVE", Swith_Status);
mSocket.connect();

webView = (WebView) findViewById(R.id.Webview);
webView2 = (WebView) findViewById(R.id.Webview2);
webView.getSettings().setJavaScriptEnabled(true);
webView2.getSettings().setJavaScriptEnabled(true);
webView.loadData(Url, "text/html", null);
webView2.loadData(Url2, "text/html", null);

sw1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListe
ner() {
public void onCheckedChanged(CompoundButton buttonView, boolean is
Checked) {
isCheck1 = isChecked;
Control();
}
});

22


sw2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListe
ner() {
public void onCheckedChanged(CompoundButton buttonView, boolean is
Checked) {
isCheck2 = isChecked;
Control();
}
});

sw3.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListe
ner() {

public void onCheckedChanged(CompoundButton buttonView, boolean is
Checked) {
isCheck3 = isChecked;
Control();
}
});

sw4.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListe
ner() {
public void onCheckedChanged(CompoundButton buttonView, boolean is
Checked) {
isCheck4 = isChecked;
Control();
}
});

}

public void Control() {
JSONArray array = new JSONArray();
JSONObject data = new JSONObject();
array.put(isCheck1);
array.put(isCheck2);
array.put(isCheck3);
array.put(isCheck4);
try {
data.put("Status", array);

23


} catch (JSONException e) {
e.printStackTrace();
}
mSocket.emit("CONTROL", data);
}

private Emitter.Listener Update = new Emitter.Listener() {

@Override
public void call(final Object... args) {
runOnUiThread(new Runnable() {
@Override
public void run() {
JSONObject data = (JSONObject) args[0];
String nhiet_do = "";
String do_am = "";
try {
nhiet_do = data.getString("Temperature");
do_am = data.getString("Humidity");
} catch (JSONException e) {
return;
}
txt_nhietdo.setText(nhiet_do + "\u2103");
txt_doam.setText(do_am + "%");
}
});
}//end call()
}; //end Listener

private Emitter.Listener Swith_Status = new Emitter.Listener() {

@Override
public void call(final Object... args) {
runOnUiThread(new Runnable() {
@Override
public void run() {
JSONObject data = (JSONObject) args[0];
String status_sw1, status_sw2, status_sw3, status_sw4;
try {

24


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay

×