ESP8266 kết nối Internet - Phần 1: Cài đặt ESP8266 làm một socket client kết nối tới socket server trong mạng LAN

 I. Giới thiệu

Hiện nay, nhu cầu nghiên cứu ESP8266 và điều khiển từ xa qua Internet ngày càng lớn. Có rất nhiều cách để kêt nối ESP8266 vào Internet, và mình sẽ chọn phương pháp giao tiếp qua Socket để hướng dẫn mọi người cách tiếp cận vào thế giới Internet Of Things. Đây là phương pháp theo mình đánh giá là dễ dàng nhất. Tất cả đều hướng theo sự kiện, nghĩa là bạn có thể bắt (catch) và xử lý nó một cách dễ dàng. Hôm nay, chúng ta hãy cùng tìm hiểu một cách kỹ lưỡng về nó.

II. ESP8266 là gì?

1. ESP8266 là gì?

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! Điều đó thật tuyệt vời phải không nào?

NodeMCU 0.9

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:

Trong dự án này, mình sẽ sử dụng mạch ESP8266v12 được đóng gói trong mạch NodeMCU 0.9. Các board khác sử dụng nhân ESP8266v12 hoặc v7 đều có thể chạy được, ví dụ như WeMos, Olimex, ESPino hay bất kỳ hãng nào sử dụng ESP8266v12 làm core chính. Mỗi hãng chỉ khác nhau cách đặt board và bố trí thứ tự chân mà thôi!

2. Làm thế nào để lập trình cho Arduino ESP8266 bằng Arduino IDE?

Để lập trình cho ESP8266 bạn nên tải bản Arduino IDE 1.6.5 trở lên, có thể tải ngay bản Arduino IDE 1.6.7 tại mục Tải về của Cộng đồng Arduino Việt Nam.

Bạn Đỗ Hữu Toàn đã nói rất rõ về vấn đề này đối với board ESP8266v1, mình xin trich dẫn một số nội dung từ bài viết Lập trình ESP8266 bằng Arduino IDE để các bạn nhanh chóng nắm bắt được vấn đề. Vì board ESP8266v12 hay v7 của bất kỳ hãng nào cũng có cách làm tương tự đó mà. 

Vào File→ Preferences, vào textbox Additional Board Manager URLs thêm đường link sau vào 

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Click OK để chấp nhận. 

Tiếp theo vào ToolBoardBoards Manager

đợi một lát để chương trình tìm kiếm. Ta kéo xuống và click vào ESP8266 by ESP8266 Community, click vào Install. Chờ phần mềm tự động download và cài đặt.

Chọn Board để lập trình cho ESP8266:

Vào ToolBoardNode MCU 0.9 chọn cổng COM tương ứng với module NodeMCU tương ứng. Đối với các mạch khác như WeMos mini thì ta chọn WeMos D1 R2 & mini. 

Ok, đến bước này là chúng ta đã có thể lập trình ESP8266 của bất cứ hãng nào.

III. Hiểu về Socket Server và Socket Client

1. Vì sao mình lại chọn mô hình Socket để sử dụng cho dự án này?

Vì sao mình lại chọn WebSocket để giao tiếp giữa người dùng từ trình duyệt với Arduino? Mình có thể sử dụng các yêu cầu HTTP truyền thống mà! Và lý do là:

  • Một lệnh HTTP truyền thống cần phải có thời gian thiết lập kết nối, điều đó là bắt buộc. Sau đó, tuần tự các phép chuyển dữ liệu mới diễn ra. Trong khi đó, websocket chỉ cần thiết đặt một lần duy nhất và khi kết nối còn giữ thì mọi việc diễn ra rất nhanh, dữ liệu được gửi đi ngay tức khắc với độ trễ chỉ khoảng 1-2 mili giây.
  • Việc trao đổi diễn ra hai chiều: Nghĩa là server có thể tạo ra một sự kiện ở client.

Vậy chỉ cần chuẩn bị một Socket Server ở ngoài Internet và cài đặt ESP8266 trở thành một Socket Client ở tại một địa điểm trong nhà và chúng ta đã có một hệ thống Internet of Things phù hợp trong việc nghiên cứu và giải trí. Với mô hình này, bạn không thể làm thương mại được! Vì sự bảo mật của nó và khả năng chịu lỗi trong môi trường phức tạp không cao! Tuy nhiên, nếu dừng ở mức demo và làm các ứng dụng DIY vui vui thì đây là giải pháp tối ưu. Vì nó đơn giản, không cần quan tâm đến các chuẩn công nghiệp và dễ dàng tùy chỉnh. Ngoài việc sử dụng Socket, chúng ta có thể sử dụng phương thức MQTT để truyền tín hiệu. Bản chất MQTT vẫn sử dụng Socket và có thêm các tính năng phù hợp trong công nghiệp như khả năng phân quyền, dễ dàng mở rộng và độ chịu lỗi lớn. Tuy nhiên, chúng ta sẽ không bàn đến MQTT trong dự án này, và sẽ dành việc đó cho bạn để sáng tạo thêm.

2. Mô hình Socket Server và Socket Client trong dự án này

Chúng ta sẽ sử dụng NodeJS để lập trình cho một server được cài NodeJS nằm ngoài Internet. Máy chủ này sẽ tiếp nhận mọi yêu cầu từ Socket Client và sẽ là môi giới liên lạc giữa các Socket Client. Các Socket Client có thể là mạch ESP8266 hay là người dùng sử dụng trình duyệt web (trên điện thoại thông minh hoặc trên máy tính điện tử).

Theo như mô hình trên:

  • Socket Server nằm ở tầng cao nhất gọi là tầng Server.
  • ESP8266 và Trình duyệt Web nằm ở tầng thứ 2 gọi là tầng Client
  • Arduino ở tầng thử 3 gọi là Application.
  • Mỗi tầng chỉ có thể liên lạc với tầng kế tiếp hoặc bên dưới nó.

Như vậy, chỉ cần xây dựng các phần mô hình giao tiếp ổn định giữa các tầng là chúng ta đã có ngay mô hình. Cụ thể, chúng ta sẽ xây dựng 2 phương thức giao tiếp giữa các tầng.

  • Để giao tiếp giữa tầng 1 và tầng 2, chúng ta sử dụng kết nối Internet thông qua các gói dữ liệu được đóng gói theo chuẩn JSON.
    • JSON là gì mà lại chọn nó? JSON là một kiểu dữ liệu đặc biệt, nó sẽ giúp ta đóng gói tập hợp các dữ liệu thành một chuỗi đơn giản theo quy chuẩn nhất định. Chuỗi này sẽ dễ dàng được vận chuyển thông qua môi trường Internet. 
    • Ví dụ về một chuỗi JSON:
      • {"khanh_dep_trai": "khanh dep trai","ESP8266": 12,"soPi": 3.14}
      • Chuỗi này là một chuỗi JSON chứa 3 tham số khanh_dep_trai, ESP8266 và soPi. Trong đó khanh_dep_trai là một biến kiểu chuỗi, ESP8266 là một biến kiểu số nguyên, soPi là một kiểu số thực.
      • Chúng ta không cần lo lắng đến cách làm thế nào để truyền các tham số vào một chuỗi JSON vì đã có thư viện ArduinoJSON chúng ta làm việc đó (ở ESP8266) và thư viện JSON (ở Socket Server là trình duyệt Web).
      • JSON là kiểu dữ liệu chuẩn, dễ encode (nén) và decode (giải mã) nhất, hầu hết các thiết bị và nền tảng lập trình đều hỗ trợ kiểu dữ liệu này/
  • Để giao tiếp giữa tầng 2 và tầng 3, chúng ta sử dụng cổng Serial truyền thống mà các bạn đã có thể làm quen thông qua việc làm xe điều khiển từ xa thông qua bluetooth.
    • Nói chung Serial cũng đã là một giao tiếp chuẩn và tất cả các mạch ESP8266 và Arduino đều hỗ trợ ít nhất một cổng Serial trong hệ thống IO của mình. Trong dự án này, mình sẽ sử dụng Serial để việc giao tiếp giữa Arduino và ESP8266 trở nên dễ dàng.

Trong suốt dự án, mình sẽ cùng các bạn xây dựng giao tiếp giữa các tầng qua các phần trong dự án. Mỗi phần mình sẽ hướng dẫn chi tiết để các bạn hiểu và làm lại được. 

IV. Truyền tin giữa tầng 1 và tầng 2

Để đơn giản bài viết, mình sẽ hướng dẫn các bạn làm toàn bộ mô hình trên trong một mạng LAN (Wifi). Để hoạt động được trong môi trường Internet, chỉ cần có một server đặt tại Internet hoặc NAT port để bạn tự xây dựng một Socket Server tại nhà.

1. Cài đặt NodeJS

Để cài đặt NodeJS, bạn hãy đọc bài Cài đặt NodeJS trên Windows - mô hình môi trường IOT chuyên nghiệp nếu bạn muốn sử dụng máy tính Windows của bạn làm Socket Server. Nếu bạn cài đặt một mạch Raspberry Pi hay Orange Pi làm server thì hãy theo bài viết này Lập trình nhúng trên Raspberry Pi bằng ngôn ngữ Javascript trong môi trường NodeJS - chìa khóa thành công của Raspi.

2. Tạo project NodeJS Socket Server đầu tiên

Bạn mở hộp thoại tìm kiếm của Windows và tìm chương trình Run như hình. Mục tiêu của bước này để vào Run để gõ các lệnh ở Command Line.

Sau đó gõ lệnh cmd để bật chương trình Command line. 

Sau đó chương trình Command Line sẽ hiện ra, các bước trên chỉ với một mục đích duy nhất là giúp bạn mở được command line. Vì khi làm việc với NodeJS chúng ta không có IDE như với Arduino. Vì vậy, chúng ta dùng Command Line để khởi tạo các chương trình viết bằng Javascript trong môi trường NodeJS.

Bạn sẽ tạo một thư mục tên là workspace và lưu các code liên quan đến NodeJS ở trong này. Các phiên bản tiếp theo mình cứ theo như trong này và làm việc.

Bạn sẽ clone project socketServer1 của mình về ở git https://github.com/ngohuynhngockhanh/socketServer1

cd workscape

git clone https://github.com/ngohuynhngockhanh/socketServer1

Nếu bạn chưa cài git, bạn có thể tải về tại https://git-scm.com/downloads

Sau đó, bạn hãy chuyển vào thư mục project và chạy các lệnh sau để cài project và chạy project.

npm install

node index.js

npm install #cài đặt project socketServer1

node index.js #Chạy chương trình index.js

Chú ý

Nếu chương trình của bạn chạy ra địa chỉ IP 169.254.x.x thì trên máy tính của bạn đang có những card mạng khác và bạn không thể sử dụng địa chỉ IP này cho các ví dụ phía sau. Nói chung, bạn hãy theo các bước sau để xem địa chỉ IP của card wifi trên máy tính để cho kết quả chính xác.

Như vậy, kết quả địa chỉ IP trong mạng LAN (Wifi) của chúng ta đó là 192.168.200.46

Nói tóm lại, chúng ta đã tạo một dịch vụ mạng được mở ở port 3434 ở địa chỉ ip 192.168.200.46 (địa chỉ ip này sẽ khác trên máy tính của bạn, hãy thay đổi nó phù hợp trong trường hợp của bạn).

Như vậy, bạn đã chạy thành công socket Server đầu tiên trên máy tính của mình.

3. Hiểu về Socket Server

Trong project Nodejs chúng ta vừa tạo, có một file cài đặt chương trình Javascript có đuôi là .js với tên là index.js. Hãy cùng mở thử và xem nội dung bên trong của chúng ta là gì?

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 - Tìm thêm về từ khóa http nodejs trên google nếu bạn muốn tìm hiểu thêm. Nhưng theo kinh nghiệm của mình, Javascript trong môi trường NodeJS cực kỳ rộng lớn, khi bạn bí thì nên tìm hiểu không nên ngồi đọc và cố gắng học thuộc hết cái reference (Tài liêu tham khảo) của nodejs làm gì. Vỡ não đó!
var socketio = require('socket.io')				//#include thư viện socketio

var ip = require('ip');
var app = http.createServer();					//#Khởi tạo một chương trình mạng (app)
var io = socketio(app);								//#Phải khởi tạo io sau khi tạo app!
app.listen(PORT);										// Cho socket server (chương trình mạng) lắng nghe ở port 3484
console.log("Server nodejs chay tai dia chi: " + ip.address() + ":" + PORT)

//giải nén chuỗi JSON thành các OBJECT
function ParseJson(jsondata) {
    try {
        return JSON.parse(jsondata);
    } catch (error) {
        return null;
    }
}

//Gửi dữ liệu thông qua 
function sendTime() {
	
	//Đây là một chuỗi JSON
	var json = {
		khanh_dep_trai: "khanh dep trai", 	//kiểu chuỗi
        ESP8266: 12,									//số nguyên
		soPi: 3.14,										//số thực
		time: new Date()							//Đối tượng Thời gian
    }
    io.sockets.emit('atime', json);
}

//Khi có mệt kết nối được tạo giữa Socket Client và Socket Server
io.on('connection', function(socket) {	//'connection' (1) này khác gì với 'connection' (2)
	//hàm console.log giống như hàm Serial.println trên Arduino
    console.log("Connected"); //In ra màn hình console là đã có một Socket Client kết nối thành công.
	
	//Gửi đi lệnh 'welcome' với một tham số là một biến JSON. Trong biến JSON này có một tham số và tham số đó tên là message. Kiểu dữ liệu của tham số là một chuối.
    socket.emit('welcome', {
        message: 'Connected !!!!'
    });
	
	//Khi lắng nghe được lệnh "connection" với một tham số, và chúng ta đặt tên tham số là message. Mình thích gì thì mình đặt thôi.
	//'connection' (2)
    socket.on('connection', function(message) {
        console.log(message);
    });
	
	//khi lắng nghe được lệnh "atime" với một tham số, và chúng ta đặt tên tham số đó là data. Mình thích thì mình đặt thôi
    socket.on('atime', function(data) {
        sendTime();
        console.log(data);
    });
	
	socket.on('arduino', function (data) {
	  io.sockets.emit('arduino', { message: 'R0' });
      console.log(data);
    });
});

Nhận xét

Hãy để ý các dòng sau:

var app = http.createServer();					//#Khởi tạo một chương trình mạng (app)
var io = socketio(app);								//#Phải khởi tạo io sau khi tạo app!
app.listen(PORT);										// Cho socket server (chương trình mạng) lắng nghe ở port 3484
console.log("Server nodejs chay tai dia chi: " + ip.address() + ":" + PORT)

Chúng ta đã tạo một dịch vụ mạng (trong trường hợp này là socket server), dịch vụ này lắng nghe các kết nối tại địa chỉ 3484. Tất cả các chương trình mạng khác (socket client,...) muốn kết nối đến socket server thì phải biết được địa chỉ IP hoặc tên miền (trong trường hợp ra Internet) và địa chỉ port (cổng kết nối) của dịch vụ socket server. Như vậy, nếu trong một địa chỉ IP mạng LAN nếu máy tính của chúng ta bị thay đổi IP (router hoặc modem wifi cấp DHCP lại một địa chỉ IP mới sau khi bị mất điện) thì các chương trình Socket Client tin tưởng vào địa chỉ IP trong mạng Local kia sẽ không hoạt động được vì không tìm thấy dịch vụ mạng socket server tại địa chỉ ip và port nói trên. Bạn có thể sét ip tĩnh cho máy server của bạn, tuy nhiên, đó chỉ là giải pháp tạm thời và không mang tính chuyên nghiệp. Ở phần cuối mình sẽ hướng dẫn bạn đưa dịch vụ socket server ra internet hoặc tạo một socket server ở một server ngoài Internet.

Tiếp theo để ý đến dòng

io.on('connection', function(socket) {
    ...
}

Ở đây là một API của thư viện socket.io (xem các dòng khai báo thư viện), sự kiện này sẽ xảy ra khi một dịch vụ socket client kết nối vào socket server! Ở đây, khi một socket client kết nối đến server, thì thư viện socket.io thông qua đại diện là biến io sẽ tạo ra một sự kiện tên là 'connection' với một biến là tên là socket. Biến socket này sẽ giúp chúng ta giao tiếp với các socket client từ chương trình socket server.

	//hàm console.log giống như hàm Serial.println trên Arduino
    console.log("Connected"); //In ra màn hình console là đã có một Socket Client kết nối thành công.
	
	//Gửi đi lệnh 'welcome' với một tham số là một biến JSON. Trong biến JSON này có một tham số và tham số đó tên là message. Kiểu dữ liệu của tham số là một chuối.
    socket.emit('welcome', {
        message: 'Connected !!!!'
    });
	
	//Khi lắng nghe được lệnh "connection" với một tham số, và chúng ta đặt tên tham số là message. Mình thích gì thì mình đặt thôi.
	//'connection' (2)
    socket.on('connection', function(message) {
        console.log(message);
    });
	
	//khi lắng nghe được lệnh "atime" với một tham số, và chúng ta đặt tên tham số đó là data. Mình thích thì mình đặt thôi
    socket.on('atime', function(data) {
        sendTime();
        console.log(data);
    });

Ở các dòng bên trong sự kiện connection trên, chúng ta để ý rằng, socket có 2 hàm chính đó là "on" và "emit" . Trong đó, hàm on là hàm bắt sự kiện và hàm emit là hàm các sự kiện. Tham số của các hàm lần lượt là:

.on(<tên sự kiện>, function(<danh sách tham số>) {
    <nội dung hàm xử lý>
})
.emit(<tên sự kiện>, <danh sách tham số>)

Dựa vào trong đoạn code trên, chúng ta sẽ thấy rằng. 

Khi có kết nối được gửi tên từ client thì chương trình sẽ in ra dòng "Connected" trên console (command line). Sau đó gửi đi sự kiện welcome với nội dung như trong code mình đã liệt kê. Sau đó, chương trình socket server sẽ đăng ký lắng nghe 2 sự kiện tên là 'connection' và 'atime'. Và khi từ client mà có 'emit' lên 2 sự kiện này thì các hàm được đăng ký kèm theo tên sự kiện đã được đăng ký ở trên. Xem code thêm để biết thêm chi tiết.

Nếu tinh ý, bạn sẽ để ý thấy có 2 lần on('connection'). Câu hỏi đặt ra là 2 dòng này có giống nhau không? Câu tra lời là Không. Vì nó được đăng ký trên 2 đối tượng khác nhau. Một là trên đối tượng io, còn lại là trên đối tượng socket. Và 2 đối tượng này là khác nhau: io thì quản lý toàn bộ các socket client đã kết nối, còn socket thì lại chỉ dùng để xử lý một socket client mà nó trỏ đến. Bạn xem ảnh bên dưới để hiểu rõ hơn.

  1. Socket Client sẽ yêu cầu kết nối tới Socket Server
  2. Socket Server sẽ cho phép kết nối, đồng thời sinh ra sự kiện 'connection'.
  3. Chúng ta bắt sự kiện 'connection' và lấy socket từ đó để thêm các sự kiện bắt dữ liệu (connection và atime).
  4. Socket đó thực chất là một trong những socket mà IO quản lý. Khi socket đó được tạo ra thì nó gửi sự kiện tên là welcome với các tham số đến cho socket client.
  5. Và khi socket client gửi sự kiện 'connection' và 'atime' đến tới socket server thì các lệnh đăng ký sẽ được thực thi. Nếu sự kiện đó chưa được đăng ký khi cài đặt chương trình mạng thì sẽ không có việc gì xảy ra cả.
    • Khi đã thực hiện 4 bước trên xong thì bước thứ 5 chính là bước loop, giống void loop trong Arduino vậy!
    • Nghĩa là nó sẽ lặp vô tận!
    • Bạn sẽ cài đặt các sự kiện ở bước 5 mà thôi.

Tóm lại, mọi thứ kết nối đều được quy về việc bạn 'emit' sự kiện nào và đăng ký bắt (on) sự kiện gì. Chỉ cần dựa vào hai lệnh 'emit' và 'on'. Chúng ta đã có thể làm được hết mọi việc một cách hoàn hảo ở tầng 1 và tầng 2!

V. Xây dựng Socket Client ở ESP8266

Như vậy chúng ta đã hiểu được cách thức hoạt động của tầng 1 và tầng 2. Đồng thời chúng ta đã xây dựng được chương trình Socket Server của tầng 1. Nhiệm vụ của chúng ta bây giờ là xây dựng một Socket Client trên con ESP8266 để nó có thể liên lạc với Socket Server. Và thật may mắn, chúng ta đã có thư viện Socket.io-v1.x-Library của washo4evr. Tuy nhiên, mình không ưng ý lắm về các biến toàn cục xử lý của anh này. Vì vậy, mình đã chỉnh sửa lại một xíu, bao gồm:

  • Thêm #define DEBUG (mặc định là false), để các lệnh DEBUG (Serial.println) trong thư viện không xuất hiện ra ngoài màn hình Serial Monitor.
  • Thêm biến toàn cục Rfull chứa toàn bộ nội dung chuỗi JSON để xử lý sau, thay vì cắt ra luôn thành 3 biến toàn cục như các ví dụ trước đây của anh ta.

Và bây giờ mình sẽ hướng dẫn các bạn xây dựng một Socket Client trên con ESP8266 nhỏ nhắn này. Nhiệm vụ của nó rất đơn giản:

  • Kết nối tới Socket Server.
  • Nếu nó bị ngắt kết nối thì tự động kết nối lại.
  • Cứ sau mỗi 2 giây sẽ gửi lệnh atime lên Socket Server để phá.
  • Nếu nhận bất cứ lệnh gì từ socket server thì in ra console để xem chơi cho vui.

Và đây là đoạn code chương trình và lưu đồ thuật toán. Để chương trình có thể chạy được, bạn hãy tải về thư viện Socket.io-v1.x-Library của mình tại đây (mirror).

#include <ESP8266WiFi.h>
#include <SocketIOClient.h>

SocketIOClient client;
const char* ssid = "MACHTUDONG";          //Tên mạng Wifi mà Socket server của bạn đang kết nối
const char* password = "smarthome12345";  //Pass mạng wifi ahihi, anh em rãnh thì share pass cho mình với.

char host[] = "192.168.200.145";  //Địa chỉ IP dịch vụ, hãy thay đổi nó theo địa chỉ IP Socket server của bạn.
int port = 3484;                  //Cổng dịch vụ socket server do chúng ta tạo!

//từ khóa extern: dùng để #include các biến toàn cục ở một số thư viện khác. Trong thư viện SocketIOClient có hai biến toàn cục
// mà chúng ta cần quan tâm đó là
// RID: Tên hàm (tên sự kiện
// Rfull: Danh sách biến (được đóng gói lại là chuối JSON)
extern String RID;
extern String Rfull;


//Một số biến dùng cho việc tạo một task
unsigned long previousMillis = 0;
long interval = 2000;

void setup()
{
    //Bật baudrate ở mức 115200 để giao tiếp với máy tính qua Serial
    Serial.begin(115200);
    delay(10);

    //Việc đầu tiên cần làm là kết nối vào mạng Wifi
    Serial.print("Ket noi vao mang ");
    Serial.println(ssid);

    //Kết nối vào mạng Wifi
    WiFi.begin(ssid, password);

    //Chờ đến khi đã được kết nối
    while (WiFi.status() != WL_CONNECTED) { //Thoát ra khỏi vòng 
        delay(500);
        Serial.print('.');
    }

    Serial.println();
    Serial.println(F("Da ket noi WiFi"));
    Serial.println(F("Di chi IP cua ESP8266 (Socket Client ESP8266): "));
    Serial.println(WiFi.localIP());

    if (!client.connect(host, port)) {
        Serial.println(F("Ket noi den socket server that bai!"));
        return;
    }

    //Khi đã kết nối thành công
    if (client.connected()) {
        //Thì gửi sự kiện ("connection") đến Socket server ahihi.
        client.send("connection", "message", "Connected !!!!");
    }
}

void loop()
{
    //tạo một task cứ sau "interval" giây thì chạy lệnh:
    if (millis() - previousMillis > interval) {
        //lệnh:
        previousMillis = millis();

        //gửi sự kiện "atime" là một JSON chứa tham số message có nội dung là Time please?
        client.send("atime", "message", "Time please?");
    }

    //Khi bắt được bất kỳ sự kiện nào thì chúng ta có hai tham số:
    //  +RID: Tên sự kiện
    //  +RFull: Danh sách tham số được nén thành chuỗi JSON!
    if (client.monitor()) {
        Serial.println(RID);
        Serial.println(Rfull);
    }

    //Kết nối lại!
    if (!client.connected()) {
      client.reconnect(host, port);
    }
}

Và đây la thành quả

VI. Còn nữa...

Bài đã dài, chúng ta cũng đã là mệt mỏi, nhưng chí ít là đã hiểu được quy trình và những thứ cần xây dựng. Đặc biệt, chúng ta đã xây dựng được cơ sở căn bản tầng 1 và tầng 2, hoàn chỉnh quy trình giao tiếp giữa tầng 1 (Socket Server) và tầng 2 (Socket Client). Ở bài sau, chúng ta sẽ hoàn chỉnh bộ quy tắc ứng xử giữa tầng 2 và tầng 3 (Arduino). Từ đó, viết bổ sổ sung chương trình cho tầng 1 với khả năng điều khiển tầng 3. Hẹn các bạn ở bài sau.

lên
36 thành viên đã đánh giá bài viết này hữu ích.
Chuyên mục: 
Các dự án được truyền cảm hứng

Bộ điều khiển PID - ứng dụng phần 2 - xe dò line dùng thuật toán PID

Tiép nối bài viết về xe dò line cảm ơn Đỗ Hữu Toàn đã viết hộ mình phần 4. hôm nay mình sẽ làm cho chiếc xe dò line đi mượt và có hồn hơn 

lên
34 thành viên đã đánh giá bài viết này hữu ích.
Các bài viết cùng tác giả

Chứng chỉ Arduino - Phân loại trình độ Arduino để cùng làm dự án lớn

Giấy chứng nhận Arduino (gọi tắt là chứng nhận) là một sáng kiến của Ban quản trị Cộng đồng Arduino Việt Nam để chính thức chứng nhận người dùng ở các cấp độ khác nhau và xác nhận chuyên môn của họ trong các lĩnh vực quan trọng. Chứng chỉ được cung cấp tại 04 mức độ, gồm: ...

lên
53 thành viên đã đánh giá bài viết này hữu ích.

Bảng mã ASCII

Bảng mã ASCII (American Standard Code for Information Interchange) được ra đời vào thập kỉ 60 của thế kỷ trước. Đây là tiêu chuẩn trong việc mã hóa chuỗi thành một số và ngược lại.

Lưu ý: 32 ký tự đầu tiên của bảng mã này (0-31) không thể xuất hiện trên đây được. Các ký tự này được gọi là ký tự điều khiển (ví dụ: khi nhấn vào nút Ctrl, bạn có thầy cái gì xuất hiện không ?)

lên
6 thành viên đã đánh giá bài viết này hữu ích.