You are on page 1of 97

BỘ GIÁO DỤC VÀ ĐÀO TẠO

TRƯỜNG ĐẠI HỌC ĐẠI NAM

BÀI TẬP LỚN

TÊN HỌC PHẦN: IOT

Giáo viên hướng dẫn: Hoàng Xuân Hiển

Sinh viên thực hiện:

Stt Mã sv Họ và tên Lớp

1 1451020125 Nguyễn Xuân Khánh CNTT 14-01

Hà Nội, năm 2023


BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC ĐẠI NAM

BÀI TẬP LỚN

TÊN HỌC PHẦN: PHÁT TRIỂN ỨNG DỤNG IOT

Điểm
STT Mã Sinh Viên Họ và Tên Ngày Sinh Bằng Bằng
Số Chữ

1 1451020125 Nguyễn Xuân Khánh 08/12/2002

CÁN BỘ CHẤM THI 1 CÁN BỘ CHẤM THI 2

Hà Nội, năm 2023


LỜI NÓI ĐẦU

Trong thời đại công nghệ hiện đại, Internet of Things (IoT) đã trở thành một xu hướng
phát triển mạnh mẽ. IoT mang lại tiềm năng vô tận để kết nối các thiết bị thông minh và tạo
ra các ứng dụng thông minh, tiện ích và hiệu quả. Phát triển ứng dụng IoT là quá trình tạo ra
các ứng dụng và dịch vụ sử dụng dữ liệu từ các thiết bị kết nối mạng. Điều này cho phép
chúng ta thu thập, phân tích và sử dụng thông tin từ các thiết bị thông minh trong thế giới
thực. Ứng dụng IoT có thể áp dụng trong nhiều lĩnh vực, từ nhà thông minh, quản lý năng
lượng, y tế, nông nghiệp thông minh cho đến công nghiệp 4.0. Điều quan trọng là phát triển
ứng dụng IoT đòi hỏi kiến thức và kỹ năng đa ngành, từ lập trình, mạng, cảm biến, dữ liệu
đến quản lý và phân tích. Trên thực tế, việc phát triển ứng dụng IoT đòi hỏi một quy trình
phát triển có cấu trúc, từ việc thiết kế, triển khai, kiểm thử đến triển khai và duy trì. Các
công nghệ như cloud computing, big data và trí tuệ nhân tạo cũng đóng vai trò quan trọng
trong việc xử lý và phân tích dữ liệu từ các thiết bị IoT.

Trên hết, việc phát triển ứng dụng IoT mang lại nhiều cơ hội và thách thức. Sự kết nối và tự
động hóa thông qua IoT có thể đem lại lợi ích to lớn cho cộng đồng, tạo ra môi trường sống
thông minh, cải thiện hiệu suất và tiết kiệm tài nguyên. Tuy nhiên, cũng cần chú ý đến các
vấn đề bảo mật, quyền riêng tư và quản lý dữ liệu.

Trong lời nói đầu này, chúng ta đã khám phá sự phát triển ứng dụng IoT và nhận thức về
tiềm năng và thách thức mà nó mang lại. Sẵn sàng khám phá và khai thác thế giới của IoT,
để tận dụng các cơ hội mới và tạo ra những ứng dụng thông minh và tiện ích.
4

MỤC LỤC
PHẦN 1: CÁC BÀI THỰC HÀNH VỚI BO MẠCH ARDUINO UNO.................................5

1.1. Các bài thực hiện với đèn LED......................................................................................5

1.1.1. 08 đèn LED nháy đuổi............................................................................................5

1.1.2. Đèn LED sáng dần, tối dần.....................................................................................7

1.1.3. 08 đèn LED nháy đuổi điều khiển bằng biến trở..................................................10

1.1.4. Điều khiển độ sáng của đèn LED bằng biến trở...................................................12

1.1.5. Đèn giao thông cho người đi bộ...........................................................................15

1.2. Các bài thực hành với màn hình LCD và cửa sổ Serial Monitor.................................18

1.2.1. Đọc dữ liệu từ Serial Monitor...............................................................................18

1.2.2. Hiển thị văn bản....................................................................................................20

1.2.3. Hiển thị các số từ 0-100........................................................................................22

1.2.4. Màn hình nhấp nháy.............................................................................................24

1.2.5. Hiển thị giá trị biến trở..........................................................................................26

1.3. Các bài thực hành với DHT11.....................................................................................28

1.3.1. Kết nối DHT11 với Arduino Uno.........................................................................28

1.3.2. Cảnh báo thay đổi nhiệt độ bằng đèn LED...........................................................30

1.4. Các bài thực hành với động cơ bước...........................................................................34

1.4.1. Kết nối động cơ với Arduino Uno........................................................................34

1.4.2. Điều khiển tốc độ bằng biến trở............................................................................36

1.4.3. Điều khiển chiều quay bằng nút bấm....................................................................39

1.4.4. Hiển thị chiều quay lên màn hình.........................................................................48

PHẦN 2. CÁC BÀI THỰC HÀNH VỚI NODE MCU ESP8266.........................................56

2.1. Các bài thực hành trạng thái làm việc với WiFi..........................................................56
5

2.1.1. Tạo điểm truy cập Wifi (Access point mode).......................................................56

2.1.2. Truy cập Wifi (Station mode)...............................................................................58

2.1.3. Scan wifi...............................................................................................................61

2.2. Các bài thực hành phương thức làm việc với webserver.............................................63

2.2.1. HTTP....................................................................................................................63

2.2.2. Tạo trang web giới thiệu bản thân........................................................................66

2.2.3. HTTP POST..........................................................................................................71

2.2.4. HTTP GET............................................................................................................75

2.3. Các bài thực hành kết nối Arduino Uno và Arduino Uno...........................................76

2.3.1. Kết nối bằng UART..............................................................................................76

2.3.2. Kết nối bằng I2C...................................................................................................80

2.3.3. Kết nối bằng SPI...................................................................................................83

PHẦN 3: LẮP MÔ HÌNH CHUNG.......................................................................................88


6

PHẦN 1: CÁC BÀI THỰC HÀNH VỚI BO MẠCH ARDUINO UNO

1.1. Các bài thực hiện với đèn LED

1.1.1. 08 đèn LED nháy đuổi


- Linh kiện:

+ Bo mạch Arduino Uno.

+ 08 đèn LED.

+ Dây kết nối


- Sơ đồ kết nối:

- Code:

int ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9};

int numberOfLEDs = 8;

void setup() {

for (int i = 0; i < numberOfLEDs; i++) {


7

pinMode(ledPins[i], OUTPUT);

void loop() {

for (int i = 0; i < numberOfLEDs; i++) {

digitalWrite(ledPins[i], HIGH);

delay(100); // Đợi 100 ms

digitalWrite(ledPins[i], LOW);

// Chạy đèn từ phải qua trái

for (int i = numberOfLEDs - 1; i >= 0; i--) {

digitalWrite(ledPins[i], HIGH); // Bật đèn LED

delay(100); // Đợi 100 ms

digitalWrite(ledPins[i], LOW); // Tắt đèn LED

}
- Kết quả
8

Giải thích:

LedPins là mảng chứa số chân kết nối đến các đèn LED.

Hàm setup() được sử dụng để khởi tạo chân kết nối đèn LED là OUTPUT.

Trong vòng lặp loop(), đèn LED được bật và tắt lần lượt từ 1 đến 8, sau đó từ 8 đến 1 với
mỗi đèn LED có thời gian chờ là 100ms giữa các trạng thái bật và tắt.

Khi bạn tải mã code này lên Arduino và kết nối mạch theo sơ đồ, bạn sẽ thấy 8 đèn LED
nháy đuổi theo thứ tự từ 1 đến 8, sau đó từ 8 đến 1 và lặp lại quá trình này.

1.1.2. Đèn LED sáng dần, tối dần


- Linh kiện:

+ Bo mạch Arduino Uno.

+ 01 đèn LED.
9

+ Dây kết nối.


- Sơ đồ kết nối

- Code:

int ledPin = 9;

int potentiometerPin = A0;

void setup() {

pinMode(ledPin, OUTPUT);

void loop() {

int potValue = analogRead(potentiometerPin);

int delayTime = map(potValue, 0, 1023, 50, 1000);

// Sáng dần

for (int brightness = 0; brightness <= 255; brightness++) {

analogWrite(ledPin, brightness);

delay(delayTime);

// Tối dần
10

for (int brightness = 255; brightness >= 0; brightness--) {

analogWrite(ledPin, brightness);

delay(delayTime);

}
- Kết quả, giải thích

LedPin là chân kết nối đến đèn LED.

brightness là biến lưu trữ giá trị độ sáng hiện tại của đèn LED.

fadeAmount là mức độ thay đổi độ sáng. Giá trị dương sẽ làm đèn LED sáng dần, giá trị âm
sẽ làm đèn LED tối dần.

Hàm setup() được sử dụng để khởi tạo chân kết nối đèn LED là OUTPUT.
11

Trong vòng lặp loop(), analogWrite() được sử dụng để điều khiển độ sáng của đèn LED dựa
trên giá trị của biến brightness. Biến brightness được tăng hoặc giảm bởi fadeAmount để làm
cho đèn LED sáng dần hoặc tối dần. Khi đạt đến giới hạn (0 hoặc 255), fadeAmount sẽ được
đảo ngược để thay đổi hướng thay đổi độ sáng.

1.1.3. 08 đèn LED nháy đuổi điều khiển bằng biến trở
- Linh kiện:

+ Bo mạch Arduino Uno.


+ 08 đèn LED.
+ Biến trở.
+ Dây kết nối.
- Sơ đồ kết nối

- Code:

char LedPin[]={2, 3, 4, 5, 6, 7, 8, 9};

char i, x, y;

int t1;

void setup() {
12

for(i=0; i<8; i++) {

pinMode(LedPin[i], OUTPUT);

pinMode(A0, INPUT);

void loop() {

t1=analogRead(A0);

for(x=0; x<8; x++) {

digitalWrite(LedPin[x], HIGH);

delay(t1);

digitalWrite(LedPin[x], LOW);

delay(10);

for(y=7; y>0; y--) {

digitalWrite(LedPin[y], HIGH);

delay(t1);

digitalWrite(LedPin[y], LOW);

delay(10);

}
- Kết quả, giải thích
13

Ledpins là mảng chứa số chân kết nối đến các đèn LED.

Numleds là số lượng đèn LED trong mạch.

Potpin là chân kết nối đến biến trở.

Trong hàm setup(), chúng ta khởi tạo các chân kết nối đèn LED là OUTPUT.

Trong vòng lặp loop(), chúng ta đọc giá trị từ biến trở bằng cách sử dụng
analogread(potpin). Giá trị đọc được từ biến trở được sử dụng để tính toán tốc độ nháy của
đèn LED.

Hàm map() được sử dụng để ánh xạ giá trị từ biến trở (trong khoảng 0 đến 1023) thành tốc
độ nháy (trong khoảng 100 đến 1000 milliseconds).

Trong vòng lặp, chúng ta bật và tắt các đèn LED theo tốc độ nháy được tính toán. Đầu tiên,
tất cả các đèn LED được bật lên, sau đó đợi một khoảng thời gian, sau đó tắt tất cả các đèn
LED và đợi một khoảng thời gian. Quá trình này được lặp lại liên tục.
14

1.1.4. Điều khiển độ sáng của đèn LED bằng biến trở
- Linh kiện:
+ Bo mạch Arduino Uno.

+ 01 đèn LED.

+ Biến trở.

+ Dây kết nối.


- Sơ đồ kết nối

- Code:

int ledPin = 9;

int potentiometerPin = A0;

void setup() {

pinMode(ledPin, OUTPUT);

void loop() {

int potValue = analogRead(potentiometerPin);


15

int brightness = map(potValue, 0, 1023, 0, 255);

analogWrite(ledPin, brightness);

}
- Kết quả, giải thích

Ledpin là chân kết nối đèn LED.

Potpin là chân kết nối đến biến trở.

Trong hàm setup(), chúng ta khởi tạo chân kết nối đèn LED là OUTPUT.
16

Trong vòng lặp loop(), chúng ta đọc giá trị từ biến trở bằng cách sử dụng
analogread(potpin). Giá trị đọc được từ biến trở được sử dụng để tính toán độ sáng của đèn
LED.

Hàm map() được sử dụng để ánh xạ giá trị từ biến trở (trong khoảng 0 đến 1023) thành độ
sáng (trong khoảng 0 đến 255). Giá trị độ sáng này sau đó được gửi đến đèn LED bằng hàm
analogwrite(ledpin, brightness).

1.1.5. Đèn giao thông cho người đi bộ


- Linh kiện:

+ Bo mạch Arduino Uno.

+ 05 đèn LED (02 đỏ, 01 vàng, 02 xanh).

+ 01 nút bấm.

+ 01 điện trở 1k.

+ Dây kết nối.


- Sơ đồ kết nối
17

- Code:

int r1=8,y1=9,g1=10,r2=11,g2=12;

int btn=2;

void setup() {

// put your setup code here, to run once:

for(int i=8;i<=12;++i){

pinMode(i,OUTPUT);

pinMode(btn,INPUT);

void loop() {

// put your main code here, to run repeatedly:

digitalWrite(r1,LOW);

digitalWrite(y1,LOW);

digitalWrite(r2,HIGH);

delay(1000);

digitalWrite(g1,HIGH);

digitalWrite(g2,LOW);

int button=digitalRead(btn);

if(button==HIGH){

digitalWrite(g1,LOW);
18

digitalWrite(y1,HIGH);

delay(2000);

digitalWrite(y1,LOW);

digitalWrite(r2,LOW);

digitalWrite(r1,HIGH);

delay(1000);

digitalWrite(r2,LOW);

digitalWrite(g2,HIGH);

delay(5000);

}
- Kết quả, giải thích
19

Redpin, yellowpin và greenpin lần lượt là các chân kết nối đến đèn đỏ, đèn vàng và đèn
xanh.

Trong hàm setup(), chúng ta khởi tạo các chân kết nối là OUTPUT.

Trong vòng lặp loop(), chúng ta sử dụng các hàm digitalwrite() để điều khiển các đèn LED.
Các đèn sẽ được bật và tắt theo một chu kỳ cụ thể: đèn đỏ sáng trong 5 giây, sau đó đèn vàng
sáng trong 2 giây, tiếp theo đèn xanh sáng trong 5 giây và cuối cùng chu kỳ bắt đầu lại từ
đèn đỏ.
20

Kh tải mã code này lên Arduino và kết nối mạch theo sơ đồ, bạn sẽ thấy đèn giao thông cho
người đi bộ hoạt động. Đèn sẽ chuyểnđèn đỏ -> đèn vàng -> đèn xanh -> lại từ đèn đỏ sau
một khoảng thời gian nhất định, tạo ra một chu kỳ đèn giao thông thích hợp.

1.2. Các bài thực hành với màn hình LCD và cửa sổ Serial Monitor

1.2.1. Đọc dữ liệu từ Serial Monitor


- Linh kiện:

+ Bo mạch Arduino Uno.

+ Màn hình LCD.

+ I2C driver.

+ Dây kết nối


- Sơ đồ kết nối

- Code

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

void setup() {

lcd.init(); // initialize the lcd

lcd.backlight();

Serial.begin(9600);

}
21

void loop() {

// when characters arrive over the serial port...

if (Serial.available()) {

// wait a bit for the entire message to arrive

delay(100);

// clear the screen

lcd.clear();

// read all the available characters

while (Serial.available() > 0) {

// display each character to the LCD

lcd.write(Serial.read());

}
- Kết quả, giải thích
22

LiquidCrystal_I2C là thư viện để điều khiển màn hình LCD thông qua giao tiếp I2C.

Trong hàm setup(), chúng ta khởi động màn hình LCD bằng lệnh lcd.begin(16, 2) và bật đèn
nền của màn hình LCD bằng lệnh lcd.backlight(). Chúng ta cũng khởi động cổng Serial bằng
lệnh Serial.begin(9600).

Trong vòng lặp loop(), chúng ta đọc giá trị từ biến trở bằng analogRead(A0) và hiển thị giá
trị độ sáng trên màn hình LCD và cửa sổ Serial Monitor bằng các lệnh lcd.print() và
Serial.print().

Khi bạn tải mã code này lên Arduino và kết nối mạch theo sơ đồ, bạn sẽ thấy thông tin
"Hello, World!" được hiển thị trên màn hình LCD và cửa sổ Serial Monitor. Đồng thời, giá
trị độ sáng từ biến trở cũng được hiển thị trên màn hình LCD và cửa sổSerial Monitor. Màn
hình LCD sẽ hiển thị thông tin "Brightness: [giá trị độ sáng]" và cửa sổ Serial Monitor cũng
sẽ in ra thông tin tương tự.

1.2.2. Hiển thị văn bản


- Linh kiện:
23

+ Bo mạch Arduino Uno.

+ Màn hình LCD.

+ I2C driver.

+ Dây kết nối.


- Sơ đồ kết nối

- Code:

#include <LiquidCrystal.h>

// Khai báo các chân kết nối với màn hình LCD

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {

// Thiết lập số cột và số dòng của màn hình LCD

lcd.begin(16, 1);

// Hiển thị văn bản mặc định

lcd.print("Nguyen Xuan Khanh");

void loop() {

// Không có gì để làm trong vòng lặp

- Kết quả, giải thích


24

#include <LiquidCrystal.h> là lệnh để đưa vào thư viện "LiquidCrystal" để sử dụng các hàm
điều khiển màn hình LCD.

Khai báo đối tượng lcd từ lớp LiquidCrystal với các chân kết nối với màn hình LCD được
chỉ định là 12, 11, 5, 4, 3, và 2.

Trong hàm setup(), bạn thiết lập số cột và số dòng của màn hình LCD bằng lệnh
lcd.begin(16, 2);. Trong trường hợp này, màn hình có 16 cột và 1 dòng.

Sử dụng hàm lcd.print() để hiển thị văn bản "Nguyen Xuan Khanh" lên màn hình LCD.

Trong hàm loop(), không có gì để làm, nên chương trình chỉ chờ đợi mà không thực hiện
thêm hành động.

1.2.3. Hiển thị các số từ 0-100


- Linh kiện:

+ Bo mạch Arduino Uno.


25

+ Màn hình LCD.

+ I2C driver.

+ Dây kết nối.


- Sơ đồ kết nối
- Code:

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

void setup() {

lcd.init();

lcd.backlight();

void loop() {

for(int i=0;i<=100;++i){

lcd.print(i);

delay(300);

lcd.clear();

}
- Kết quả, giải thích
26

Sau khi bạn nạp mã code này vào Arduino và kết nối màn hình LCD, màn hình sẽ hiển thị
các số từ 0 đến 100 một cách tuần tự. Mỗi số sẽ được hiển thị trong 0,5 giây trước khi
chuyển đến số tiếp theo. Mã code sử dụng vòng lặp for để lặp qua các giá trị từ 0 đến 100.
Trong mỗi vòng lặp, màn hình LCD sẽ được xóa (lcd.clear()) và con trỏ sẽ được đặt về vị trí
(0, 0) (lcd.setcursor(0, 0)) để in chuỗi "Number:". Sau đó, con trỏ được đặt về vị trí (0, 1)
(lcd.setcursor(0, 1)) để in giá trị của biến i lên màn hình LCD (lcd.print(i)). Hàm delay(500)
được sử dụng để tạo thời gian chờ 500ms giữa các số.

1.2.4. Màn hình nhấp nháy


- Linh kiện:

+ Bo mạch Arduino Uno.

+ Màn hình LCD.

+ I2C driver.

+ Dây kết nối.


27

- Sơ đồ kết nối
- Code:

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

const int lcdAddress = 0x3F;

const int lcdColumns = 16;

const int lcdRows = 2;

// Khai báo đối tượng LiquidCrystal_I2C

LiquidCrystal_I2C lcd(lcdAddress, lcdColumns, lcdRows);

void setup() {

Wire.begin();

lcd.begin(lcdColumns, lcdRows);

void loop() {

// Hiển thị trạng thái sáng

lcd.clear(); // Xóa màn hình

lcd.print("Nguyen Xuan Khanh");

delay(1000); // Đợi 1 giây

// Hiển thị trạng thái tối

lcd.clear(); // Xóa màn hình

delay(1000); // Đợi 1 giây


28

- Kết quả, giải thích

Sau khi bạn nạp mã code này vào Arduino và kết nối màn hình LCD, màn hình sẽ liên tục
nhấp nháy giữa văn bản "Hello, World!" và màn hình trống. Mỗi trạng thái hiển thị được
duy trì trong 500ms trước khi chuyển sang trạng thái hiển thị tiếp theo. Mã code sử dụng
hàm lcd.clear() để xóa màn hình và lcd.print() để hiển thị văn bản "Nguyen Xuan Khanh”
trên màn hình LCD. Hàm delay(500) được sử dụng để tạo thời gian chờ 500ms giữa các
trạng thái hiển thị.

1.2.5. Hiển thị giá trị biến trở


- Linh kiện:

+ Bo mạch Arduino Uno.


29

+ Màn hình LCD.

+ I2C driver.

+ Dây kết nối.

+ Biến trở.
- Sơ đồ kết nối
- Code:

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

void setup() {

pinMode(A0,INPUT);

lcd.init();

lcd.backlight();

void loop() {

int giatri = analogRead(A0

int dienTro;

dienTro = map(giatri, 0, 1023, 0, 10000);

lcd.setCursor(0, 0);

lcd.print(dienTro);

lcd.print(" om ");
30

}
- Kết quả, giải thích

Sau khi bạn nạp mã code này vào Arduino và kết nối màn hình LCD cùng với biến trở, màn
hình sẽ hiển thị giá trị của biến trở liên tục. Mã code sử dụng hàm analogRead() để đọc giá
trị từ biến trở được kết nối vào chân potentiometerPin. Sau đó, giá trị của biến trở được hiển
thị lên màn hình LCD bằng cách sử dụng hàm lcd.print().

1.3. Các bài thực hành với DHT11

1.3.1. Kết nối DHT11 với Arduino Uno


- Linh kiện:

+ Bo mạch Arduino Uno.

+ Cảm biến DHT11.


31

+ Dây kết nối.


- Sơ đồ kết nối

- Code:

#include "DHT.h"

const int DHTPIN = 4;

const int DHTTYPE = DHT11;

DHT dht(DHTPIN, DHTTYPE);

void setup() {

// put your setup code here, to run once:

Serial.begin(9600);

dht.begin();

void loop() {

float t = dht.readTemperature();

Serial.print("Nhiet do hien tai:");


32

Serial.println(t);

}
- Kết quả, giải thích
33

Sau khi nạp mã code này vào Arduino và kết nối cảm biến DHT11, Arduino sẽ đọc dữ liệu
nhiệt độ và độ ẩm từ cảm biến và in kết quả lên Serial Monitor.

Mã code sử dụng thư viện DHT để đọc dữ liệu từ cảm biến DHT11. Chân DATA của
DHT11 được kết nối vào chân số 2 của Arduino (DHTPIN). Hàm DHT.read11() được sử
dụng để đọc dữ liệu từ cảm biến, và kết quả được lưu trữ trong các biến DHT.temperature
(nhiệt độ) và DHT.humidity (độ ẩm).

1.3.2. Cảnh báo thay đổi nhiệt độ bằng đèn LED


- Linh kiện:

+ Bo mạch Arduino Uno.

+ Cảm biến DHT11.

+ 03 đèn LED.

+ Dây kết nối


- Sơ đồ kết nối

- Code:
34

#include "DHT.h"

const int DHTPIN = 4;

const int DHTTYPE = DHT11;

int t1=30;

int t2=25;

DHT dht(DHTPIN, DHTTYPE);

int green=9;

int yellow=8;

int red=10;

void setup() {

// put your setup code here, to run once:

Serial.begin(9600);

dht.begin();

pinMode(green,OUTPUT);

pinMode(yellow,OUTPUT);

pinMode(red,OUTPUT);

void loop() {

// put your main code here, to run repeatedly:


35

float t = dht.readTemperature();

Serial.println(t);

if(t<=t1){

digitalWrite(green,HIGH);

else if(t>t1 && t<=t2){

digitalWrite(yellow, HIGH);

else if(t>t2){

digitalWrite(red, HIGH);

}
- Kết quả, giải thích
36

Sau khi bạn nạp mã code này vào Arduino và kết nối cảm biến nhiệt độ và đèn LED,
Arduino sẽ đọc giá trị nhiệt độ từ cảm biến và cảnh báo bằng cách bật đèn LED nếu nhiệt độ
vượt qua ngưỡng 30 độ Celsius.

Mã code sử dụng chân Analog A0 của Arduino để kết nối với cảm biến LM35. Giá trị nhiệt
độ được đọc từ cảm biến bằng cách sử dụng hàm analogRead() và sau đó được chuyển đổi
thành độ Celsius.

Giá trị nhiệt độ được in ra Serial Monitor thông qua lệnh Serial.print(). Nếu nhiệt độ vượt
qua ngưỡng 30 độ Celsius, đèn LED sẽ được bật thông qua lệnh digitalWrite(ledPin, HIGH),
ngược lại nếu nhiệt độ không vượt quá ngưỡng, đèn LED sẽ được tắt thông qua lệnh
digitalWrite(ledPin,LOW).

1.4. Các bài thực hành với động cơ bước

1.4.1. Kết nối động cơ với Arduino Uno


- Linh kiện:

+ Bo mạch Arduino Uno.

+ Động cơ bước.

+ Driver ULN2003.

+ Dây kết nối.


- Sơ đồ kết nối
- Code:

int C1=8, C2=9, C3=10, C4=11;

void setup(){

pinMode(C1, OUTPUT);

pinMode(C2, OUTPUT);
37

pinMode(C3, OUTPUT);

pinMode(C4, OUTPUT);

pinMode(A0,INPUT);

void loop(){

int t=5;

// phase 1

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

digitalWrite(C1, HIGH);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

delay(t);

// phase 2

digitalWrite(C1, LOW);

digitalWrite(C2, HIGH);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);
38

delay(t);

// phase 3

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, HIGH);

digitalWrite(C3, LOW);

delay(t);

// phase 4

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, HIGH);

delay(t);

}
- Kết quả, giải thích
39

Khai báo biến và cấu hình chân:

C1, C2, C3, C4: Chân kết nối đến bộ điều khiển stepper motor.

pinMode(C1, OUTPUT), pinMode(C2, OUTPUT), pinMode(C3, OUTPUT), pinMode(C4,


OUTPUT): Cấu hình các chân đầu ra để điều khiển stepper motor.

pinMode(A0, INPUT): Cấu hình chân A0 là chân đầu vào, tuy nhiên, trong chương trình này
không có sử dụng chân A0.

Trong hàm loop(), các bước khác nhau của stepper motor được thực hiện lần lượt.

Mỗi phase kích thích bộ điều khiển stepper motor thông qua các tín hiệu trên chân C1, C2,
C3, C4.

Giữa các phase, chương trình chờ một khoảng thời gian (delay(t)) để tạo ra bước chuyển
động của stepper motor.

Lưu ý rằng giá trị t đặt trong chương trình có thể cần được điều chỉnh tùy thuộc vào stepper
motor cụ thể mà bạn đang sử dụng và yêu cầu của ứng dụng của bạn.

1.4.2. Điều khiển tốc độ bằng biến trở


40

- Linh kiện:

+ Bo mạch Arduino Uno.

+ Động cơ bước.

+ Driver ULN2003.

+ Biến trở.

+ Dây kết nối.


- Sơ đồ kết nối

- Code:

int C1=8, C2=9, C3=10, C4=11;

void setup(){

pinMode(C1, OUTPUT);

pinMode(C2, OUTPUT);

pinMode(C3, OUTPUT);

pinMode(C4, OUTPUT);

pinMode(A0,INPUT);

void loop(){

int t=analogRead(A0);

// phase 1

t=t/50;

digitalWrite(C1, LOW);
41

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

digitalWrite(C1, HIGH);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

delay(t);

// phase 2

digitalWrite(C1, LOW);

digitalWrite(C2, HIGH);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

delay(t);

// phase 3

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, HIGH);

digitalWrite(C3, LOW);

delay(t);
42

// phase 4

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, HIGH);

delay(t);

}
- Kết quả, giải thích

1.4.3. Điều khiển chiều quay bằng nút bấm


- Linh kiện:

+ Bo mạch Arduino Uno.


43

+ Động cơ bước.

+ Driver ULN2003.

+ Nút bấm.

+ Dây kết nối.


- Sơ đồ kết nối

- Code:

int IN1= 8;

int IN2= 9;

int IN3= 10;

int IN4= 11;

int FPB =2;

int Stop=3;

int RPB =4;

int Step = 0;

int Status = 3;

//
==================================================================
=============================================
44

void setup()

pinMode(FPB,INPUT);

pinMode(Stop,INPUT);

pinMode(RPB,INPUT);

pinMode(IN1, OUTPUT);

pinMode(IN2, OUTPUT);

pinMode(IN3, OUTPUT);

pinMode(IN4, OUTPUT);

//
==================================================================
=============================================

void loop()

if(digitalRead(FPB) == HIGH)

Status =1;

else if(digitalRead(RPB) == HIGH )

Status = 2;

else if(digitalRead(Stop) == HIGH)

Status =3;

if(Status ==1)
45

Forward_Reverse(true);

else if(Status ==2)

Forward_Reverse(false);

else

{digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);}

if(Step>7)

Step=0;

delay(1);

//
==================================================================
=============================================

void Forward_Reverse (bool dir)

if(dir){

switch(Step){

case 0:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);
46

digitalWrite(IN4, LOW);

break;

case 1:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);

break;

case 2:

digitalWrite(IN1, LOW);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);

break;

case 3:

digitalWrite(IN1, LOW);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, LOW);

break;

case 4:

digitalWrite(IN1, LOW);
47

digitalWrite(IN2, LOW);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, LOW);

break;

case 5:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, HIGH);

break;

case 6:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, HIGH);

break;

case 7:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, HIGH);

break;
48

else{

switch(Step){

case 0:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, HIGH);

break;

case 1:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, HIGH);

break;

case 2:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, HIGH);

break;
49

case 3:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, LOW);

break;

case 4:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, LOW);

break;

case 5:

digitalWrite(IN1, LOW);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, LOW);

break;

case 6:

digitalWrite(IN1, LOW);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, LOW);
50

digitalWrite(IN4, LOW);

break;

case 7:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);

break;

case 8:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);

break;

Step++;

}
- Kết quả, giải thích
51

Trong sơ đồ kết nối, nút nhấn được kết nối với chân D2 trên Arduino. Nút nhấn này được
cấu hình với chế độ Pull-up resistor bằng cách sử dụng pinMode(buttonPin,
INPUT_PULLUP).

Các chân điều khiển của động cơ bước (motorPin1, motorPin2, motorPin3, motorPin4)
đượccấu hình là OUTPUT thông qua pinMode().

Trong hàm setup(), chúng ta khởi tạo màn hình LCD và hiển thị thông báo "Motor Control"
trên dòng đầu tiên của màn hình LCD.

Trong hàm loop(), chúng ta đọc trạng thái của nút nhấn bằng cách sử dụng
digitalRead(buttonPin). Nếu trạng thái của nút nhấn thay đổi so với lần đọc trước đó
(buttonState != lastButtonState), chúng ta kiểm tra trạng thái mới của nút nhấn. Nếu nút
52

nhấn được nhấn (buttonState == LOW), chúng ta chuyển đổi trạng thái của động cơ
(motorState) và hiển thị thông tin trạng thái mới trên dòng thứ hai của màn hình LCD.

Nếu motorState là TRUE, chúng ta gọi hàm clockwise() để quay động cơ theo chiều kim
đồng hồ. Nếu motorState là FALSE, chúng ta gọi hàm counterclockwise() để quay động cơ
ngược chiều kim đồng hồ.

Trong hàm clockwise() và counterclockwise(), chúng ta sử dụng các lệnh digitalWrite() để


điều khiển các chân điều khiển của động cơ theo một chuỗi thứ tự nhất định. Mỗi lệnh
digitalWrite() được kết hợp với delay() để tạo ra một khoảng thời gian trễ giữa các pha quay
của động cơ.

1.4.4. Hiển thị chiều quay lên màn hình


- Linh kiện:

+ Bo mạch Arduino Uno.

+ Động cơ bước.

+ Driver ULN2003.

+ Nút bấm.

+ Màn hình LCD.

+ I2C driver.

+ Dây kết nối.


- Sơ đồ kết nối
53

- Code:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

int C1= 8;

int C2= 9;

int C3= 10;

int C4= 11;

int btn =2; // forward push button

int cnt=0;

int flag=0;

void setup()

pinMode(btn,INPUT);

pinMode(C1, OUTPUT);

pinMode(C2, OUTPUT);

pinMode(C3, OUTPUT);
54

pinMode(C4, OUTPUT);

lcd.init();

lcd.backlight();

void loop()

if(digitalRead(2)==HIGH){

flag=flag==0?1:0;

if(flag==0){

Xuoi(30);

else{

Nguoc(30);

void Nguoc(int t){

lcd.print("nguoc");

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);
55

digitalWrite(C4, LOW);

digitalWrite(C1, HIGH);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

delay(t);

// phase 2

digitalWrite(C1, LOW);

digitalWrite(C2, HIGH);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

delay(t);

// phase 3

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, HIGH);

digitalWrite(C3, LOW);

delay(t);

// phase 4

digitalWrite(C1, LOW);
56

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, HIGH);

delay(t);

lcd.clear();

void Xuoi(int t){

lcd.print("xuoi");

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, HIGH);

delay(t);

// phase 2

digitalWrite(C1, LOW);

digitalWrite(C2, LOW);

digitalWrite(C3, HIGH);
57

digitalWrite(C4, LOW);

delay(t);

// phase 3

digitalWrite(C1, LOW);

digitalWrite(C2, HIGH);

digitalWrite(C3, LOW);

digitalWrite(C3, LOW);

delay(t);

// phase 4

digitalWrite(C1, HIGH);

digitalWrite(C2, LOW);

digitalWrite(C3, LOW);

digitalWrite(C4, LOW);

delay(t);

lcd.clear();

}
- Kết quả, giải thích.
58

Dòng #include <LiquidCrystal_I2C.h> được sử dụng để đưa thư viện này vào mã code, cho
phép chúng ta sử dụng các hàm và phương thức của thư viện để điều khiển màn hình LCD.

Sau đó, đối tượng lcd được tạo bằng cách khởi tạo một thể hiện của lớp LiquidCrystal_I2C
với các tham số sau:

0x3F: Địa chỉ I2C của màn hình LCD. Đây là địa chỉ I2C mặc định và có thể khác nhau tùy
thuộc vào mô-đun LCD bạn đang sử dụng.

16: Số cột của màn hình LCD.

2: Số hàng của màn hình LCD.

Với đối tượng lcd đã được khởi tạo, chúng ta có thể sử dụng các phương thức của nó như
init() để khởi động màn hình LCD và backlight() để bật đèn nền.

Các chân giao tiếp giữa Arduino và màn hình LCD được định nghĩa bằng các biến C1, C2,
C3, C4, và btn. Chúng ta sử dụng hàm pinMode() để đặt chế độ của các chân này, có thể là
OUTPUT hoặc INPUT, để điều khiển các tín hiệu và giao tiếp với màn hình LCD và nút
nhấn.
59

Trong hàm setup(), chúng ta đặt chế độ của btn là INPUT và C1, C2, C3, C4 là OUTPUT.
Sau đó, chúng ta gọi lcd.init() để khởi động màn hình LCD và lcd.backlight() để bật đèn
nền.

Trong hàm loop(), chúng ta kiểm tra trạng thái của nút nhấn bằng cách sử dụng
digitalRead(2) để đọc giá trị của chân btn. Nếu giá trị là HIGH, chúng ta thay đổi giá trị của
biến flag (từ 0 sang 1 hoặc từ 1 sang 0) để chuyển đổi giữa hai trạng thái của động cơ.

Nếu flag là 0, chúng ta gọi hàm Xuoi(30) để thực hiện quá trình quay theo chiều kim đồng
hồ. Nếu flag là 1, chúng ta gọi hàm Nguoc(30) để thực hiện quá trình quay ngược chiều kim
đồng hồ.

Hai hàm Xuoi() và Nguoc() được sử dụng để thực hiện quá trình quay của động cơ. Trong
mỗi hàm, chúng ta hiển thị một thông báo trên màn hình LCD bằng cách sử dụng lcd.print().
Sau đó, chúng ta điều khiển các chân C1, C2, C3, C4 theo một chuỗi thứ tự nhất định để tạo
ra các xung điều khiển cho động cơ. Chúng ta sử dụng digitalWrite() để đặt các chân này
thành HIGH hoặc LOW để điều khiển các pha quay của động cơ. Cuối cùng, chúng ta sử
dụng delay(t) để tạo ra một khoảng thời gian trễ giữa các pha quay, với t là thời giantrễ được
truyền vào hàm Xuoi() và Nguoc().

Cuối cùng, chúng ta gọi lcd.clear() để xóa nội dung trên màn hình LCD sau khi quá trình
quay của động cơ hoàn thành.
60

PHẦN 2. CÁC BÀI THỰC HÀNH VỚI NODE MCU ESP8266

2.1. Các bài thực hành trạng thái làm việc với WiFi

2.1.1. Tạo điểm truy cập Wifi (Access point mode)


- Linh kiện:

+ Bo mạch Node MCU ESP8266.

+ Dây cáp Micro USB Ugreen.


- Sơ đồ kết nối

- Code:

#include <ESP8266WiFi.h>

void setup() {

Serial.begin(115200);

// Tên và mật khẩu của mạng Wi-Fi

const char* ssid = "Wi-Fi";

const char* password = "06092002";

// Kết nối với mạng Wi-Fi

WiFi.begin(ssid, password);

Serial.print("Đang kết nối");

while (WiFi.status() != WL_CONNECTED) {

delay(500);
61

Serial.print(".");

Serial.println("");

Serial.println("Kết nối thành công!");

// Hiển thị tên mạng Wi-Fi đang kết nối

Serial.print("Tên mạng Wi-Fi: ");

Serial.println(WiFi.SSID());

void loop() {

// Đoạn mã trong hàm loop sẽ được thực thi liên tục sau khi ESP8266 kết nối thành công

// Bạn có thể thêm code xử lý ở đây

}
- Kết quả, giải thích
62

Sau khi bạn nạp mã code này vào Arduino và kết nối module WiFi (ESP8266 hoặc ESP32)
với Arduino, Arduino sẽ tạo một điểm truy cập WiFi với tên " Wi-Fi " và mật khẩu
"06092002".

Mã code sử dụng thư viện ESP8266WiFi (hoặc WiFi cho ESP32) để thực hiện chức năng
điểm truy cập WiFi. Trong hàm setup(), chế độ Access Point được thiết lập bằng cách gọi
hàm WiFi.softAP(ssid, password), trong đó ssid là tên mạng WiFi của điểm truy cập và
password là mật khẩu để kết nối vào điểm truy cập.

Sau đó, địa chỉ IP của điểm truy cập được in ra Serial Monitor thông qua lệnh
Serial.println(IP). Bạn có thể sử dụng địa chỉ IP này để kết nối với điểm truy cập từ các thiết
bị khác.
63

Hàm loop() không có gì để làm trong ví dụ này, vì chúng ta chỉ cần thiết lập điểm truy cập
và in ra địa chỉ IP một lần duy nhất.

Kết quả sẽ được hiển thị trên Serial Monitor, trong đó bạn sẽ thấy địa chỉ IP của điểm truy
cập. Thiết bị khác có thể kết nối vào điểm truy cập này bằng cách tìm và kết nối với mạng
wifi có tên là “Wi-Fi” và mật khẩu là “06092002”

2.1.2. Truy cập Wifi (Station mode)


- Linh kiện:

+ Bo mạch Node MCU ESP8266.

+ Dây cáp Micro USB Ugreen.

- Sơ đồ kết nối

- Code:

#include <ESP8266WiFi.h>

const char* ssid="Xuan Khanh";

const char* password="12345678";

void setup(){

Serial.begin(115200);

Serial.println();

Serial.println("Setting Wi-Fi Mode..");

WiFi.mode(WIFI_STA);

WiFi.begin(ssid,password);
64

while(WiFi.status()!=WL_CONNECTED){

delay(500);

Serial.print(".");

Serial.print("Connected, IP address:");

Serial.println(WiFi.localIP());

void loop(){

Serial.printf("Signal Strength in dB = %d\n", WiFi.RSSI());

delay(3000);

}
- Kết quả, giải thích
65

Sau khi bạn nạp mã code này vào Arduino và kết nối module WiFi (ESP8266 hoặc ESP32)
với Arduino, Arduino sẽ kết nối đến mạng WiFi có tên "Xuan Khanh" và mật khẩu
"12345678".

Mã code sử dụng thư viện ESP8266WiFi (hoặc WiFi cho ESP32) để thực hiện chức năng
truy cập mạng WiFi. Trong hàm setup(), kết nối đến mạng WiFi được thiết lập bằng cách gọi
hàm WiFi.begin(ssid, password), trong đó ssid là tên mạng WiFi và password là mật khẩu để
kết nối.

Sau đó, một vòng lặp while được sử dụng để chờ cho đến khi Arduino kết nối thành công
đến mạng WiFi bằng cách kiểm tra trạng thái kết nối bằng hàm WiFi.status(). Trong khi
Arduino chưa kết nối thành công, một dòng thông báo sẽ được in ra Serial Monitor thông
qua lệnh Serial.println("Đang kết nối đến mạng WiFi..."). Khi kết nối thành công, một thông
báo "Đã kết nối đến mạng WiFi" sẽ được in ra.

Hàm loop() không có gì để làm trong ví dụ này, vì chúng ta chỉ cần thiết lập kết nối và in ra
thông báo kết nối một lần duy nhất.

Kết quả sẽ được hiển thị trên Serial Monitor, trong đó bạn sẽ thấy thông báo "Đang kết nối
đến mạng WiFi..." cho đến khi Arduino kết nối thành công. Sau đó, thông báo "Đã kết nối
đến mạng WiFi" sẽ được in ra. Arduino sẽ tiếp tục duy trì kết nối với mạng WiFi trong suốt
thời gian hoạt động.

2.1.3. Scan wifi


- Linh kiện:

+ Bo mạch Node MCU ESP8266.

+ Dây cáp Micro USB Ugreen.

- Sơ đồ kết nối
66

- Code:

#include <ESP8266WiFi.h>

void setup() {

Serial.begin(115200);

Serial.println("");

WiFi.mode (WIFI_STA);

WiFi.disconnect();

delay(100);

Serial.println("Wi-Fi Network Scan Started"); }

void loop() {

int n = WiFi.scanNetworks();

Serial.println("Scan done");

if (n == 0) Serial.println("No Networks Found");

else { Serial.print(n); Serial.println(" Networks found"); for (int i = 0; i < n; ++i) {

Serial.print(i + 1);

Serial.print(":");

Serial.print(WiFi.SSID (i));

Serial.print(" (");

Serial.print(WiFi.RSSI (i));
67

Serial.print(") MAC:");

Serial.print(WiFi.BSSIDstr(i));

Serial.println((WiFi.encryptionType(i)== ENC_TYPE_NONE)?" Unsecured":" Secured") ;

delay(10); } }

Serial.println("");

delay(5000);

}
- Kết quả, giải thích

Sau khi bạn nạp mã code này vào Arduino và kết nối module WiFi (ESP8266 hoặc ESP32)
với Arduino, Arduino sẽ quét các mạng WiFi có sẵn trong phạm vi.

Mã code sử dụng thư viện ESP8266WiFi (hoặc WiFi cho ESP32) để thực hiện chức năng
quét mạng WiFi. Trong hàm setup(), chế độ Station (Station mode) được thiết lập bằng cách
gọi hàm WiFi.mode(WIFI_STA).

Sau đó, một thông báo "Đang quét các mạng WiFi..." sẽ được in ra Serial Monitor thông qua
lệnh Serial.println("Đang quét các mạng WiFi..."). Arduino sẽ quét các mạng WiFi có sẵn
trong phạm vi bằng cách gọi hàm WiFi.scanNetworks().

Số lượng mạng WiFi được tìm thấy sẽ được lưu trong biến networkCount. Nếu không có
mạng WiFi nào được tìm thấy, một thông báo "Không tìm thấy mạng WiFi" sẽ được in ra.
68

Nếu có mạng WiFi được tìm thấy, số lượng mạng và danh sách các mạng sẽ được in ra
Serial Monitor thông qua vòng lặp for. Tên mạng WiFi của mỗi mạng sẽ được in ra bằng
cách gọi hàm WiFi.SSID(i).

Hàm loop() không có gì để làm trong ví dụ này, vì chúng ta chỉ cần quét mạng WiFi một lần
duy nhất.

Kết quả sẽ được hiển thị trên Serial Monitor, trong đó bạn sẽ thấy số lượng mạng WiFi tìm
thấy và danh sách các mạng WiFi. Tên mạng WiFi của mỗi mạng sẽ được in ra theo định
dạng "X: Tên_Mạng_WiFi", trong đó X là số thứ tự của mạng WiFi.

2.2. Các bài thực hành phương thức làm việc với webserver

2.2.1. HTTP
- Linh kiện:

+ Bo mạch Node MCU ESP8266.

+ Dây cáp Micro USB Ugreen.


- Sơ đồ kết nối
- Code:

#include <ESP8266WiFi.h>

#include <ESP8266WebServer.h>

#include <ESP8266mDNS.h>

const char* wifiName = "Can nha vui ve";

const char* wifiPass = "dihoiduy";

ESP8266WebServer server (80);

void handleRoot() { digitalWrite(2, 0);

server.send(200, "text/plain", "Dang Minh Tien CNTT14-01 1451020230 LOP


CNTT1401"); digitalWrite(2, 1); }

void setup() {
69

Serial.begin(115200);

delay(10); pinMode(2,OUTPUT);

Serial.println();

Serial.print("Connecting");

WiFi.begin(wifiName, wifiPass);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

} Serial.println("");

Serial.println("Wi-Fi connected");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

server.on("/", handleRoot);

server.begin();

Serial.println("HTTP server started"); }

void loop() {

server.handleClient(); }
- Kết quả, giải thích
70

Sau khi bạn nạp mã code này vào Arduino và kết nối module WiFi (ESP8266 hoặc ESP32)
với Arduino, Arduino sẽ kết nối đến mạng WiFi và gửi yêu cầu HTTP GET đến một URL cụ
thể.
71

Mã code sử dụng thư viện ESP8266WiFi (hoặc WiFi cho ESP32) để thực hiện kết nối đến
mạng WiFi. Trong hàm setup(), kết nối đến mạng WiFi được thiết lập bằng cách gọi hàm
WiFi.begin(ssid, password).

Sau đó, một vòng lặp while được sử dụng để chờ cho đến khi Arduino kết nối thành công
đến mạng WiFi bằng cách kiểm tra trạng thái kết nối bằng hàm WiFi.status(). Trong khi
Arduino chưa kết nối thành công, một dòng thông báo sẽ được in ra Serial Monitor thông
qua lệnh Serial.println("Đang kết nối đến mạng WiFi..."). Khi kết nối thành công, một thông
báo "Đã kết nối đến mạng WiFi" sẽ được in ra.

Sau đó, một yêu cầu HTTP GET được gửi đến một URL cụ thể bằng cách sử dụng thư viện
ESP8266HTTPClient (hoặc HTTPClient cho ESP32). URL được đặt trong biến url, ví dụ
trong mã code là "http://example.com/api/data". Bạn cần thay thế URL này bằng URL thực
tế của bạn.

Sau khi gửi yêu cầu GET, mã phản hồi HTTP sẽ được lưu trong biến httpResponseCode.
Nếu httpResponseCode lớn hơn 0, điều đó có nghĩa là yêu cầu HTTP thành công và một
thông báo "Mã phản hồi HTTP: " kèm theo mã phản hồi sẽ được in ra Serial Monitor thông
qua lệnh Serial.println(httpResponseCode).

Nội dung phản hồi từ máy chủ sẽ được lấy bằng cách sử dụng hàm http.getString() và lưu
vào biến response. Sau đó, một thông báo "Nội dung phản hồi: " kèm theo nội dung phản hồi
sẽ được in ra Serial Monitor thông qua lệnh Serial.println(response).

Nếu httpResponseCode không lớn hơn 0, điều đó có nghĩa là yêu cầu HTTP gặp lỗi và một
thông báo "Lỗi HTTP: " kèm theo mã phản hồi sẽ được in ra Serial Monitor thông qua lệnh
Serial.println(httpResponseCode).

Cuối cùng, hàm http.end() được gọi để giải phóng tài nguyên và đóng kết nối HTTP.

Kết quả sẽ được hiển thị trên Serial Monitor trong đó bạn sẽ thấy mã phản hồi HTTP và nội
dung phản hồi từ máy chủ. Bạn có thể điều chỉnh mã code và URL để thực hiện các yêu cầu
HTTP khác nhau.
72

2.2.2. Tạo trang web giới thiệu bản thân


- Linh kiện:

+ Bo mạch Node MCU ESP8266.

+ Dây cáp Micro USB Ugreen.


- Sơ đồ kết nối

- Code:

#include <ESP8266WiFi.h>

#include <ESP8266WebServer.h>

#include <ESP8266mDNS.h>

const char* wifiName = "co nam cai nit";

const char* wifiPass = "10388834";

ESP8266WebServer server(80);

const char htmlPage[] PROGMEM = R"=====(

<html>

<head>

<title>introduce projife</title>

<style>

/* CSS inline */

body {

display: flex;
73

justify-content: center;

align-items: center;

height: 100vh;

.avatar {

border-radius: 100%;

width: 200px;

height: 200px;

</style>

</head>

<body>

<div>

<img src=" https://scontent.fhan5-8.fna.fbcdn.net/v/t39.30808-


6/334962266_227380499698387_6111331650528873132_n.jpg?_nc_cat=110&ccb=1-
7&_nc_sid=5f2048&_nc_ohc=Io6IJSRgzmUAX9zN0Dk&_nc_ht=scontent.fhan5-
8.fna&oh=00_AfAyPS1JlH4aSpdTseLmJaLMGgRf7MsOA77q5uWGZjDkJg&oe=6556975
C" alt="Ảnh đại diện" class="avatar">

<h3>Nguyen Xuan Khanh</h3>

<span>Xuan Khanh</span>

</div>

</body>
74

</html> )=====";

void handleRoot() { digitalWrite(2, 0); //Blinks on board led on page request

server.send(200, "text/html", htmlPage);

digitalWrite(2, 1);

void

setup()

Serial.begin(115200);

delay(10);

pinMode(2,OUTPUT);

Serial.println();

Serial.print("Connecting");

WiFi.begin(wifiName, wifiPass);

while (WiFi.status() != WL_CONNECTED)

delay(500); Serial.print(".");

Serial.println("");

Serial.println("Wi-Fi connected");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());
75

server.on("/", handleRoot);

server.begin();

Serial.println("HTTP server started"); }

void loop()

server.handleClient();

}
- Kết quả, giải thích

Đưa vào các thư viện cần thiết.

Khai báo tên và mật khẩu của mạng Wi-Fi mà ESP8266 sẽ kết nối.
76

Tạo một đối tượng ESP8266WebServer để xử lý các yêu cầu HTTP.

Một biến htmlPage chứa nội dung trang HTML, được lưu trữ trong bộ nhớ Flash
(PROGMEM) của ESP8266.

Định nghĩa hàm handleRoot() để xử lý yêu cầu gốc ("/"). Trong hàm này, chúng ta sẽ bật và
tắt đèn LED trên board ESP8266 và gửi trang HTML cho client.

Hàm setup() được gọi khi ESP8266 khởi động. Trong hàm này, chúng ta khởi tạo kết nối
Wi-Fi và máy chủ HTTP, và in ra địa chỉ IP của ESP8266.

Hàm loop() được gọi lặp lại vô thời hạn. Trong hàm này, chúng ta xử lý các yêu cầu từ
client.

2.2.3. HTTP POST


- Linh kiện:

+ Bo mạch Node MCU ESP8266.

+ Dây cáp Micro USB Ugreen.


- Sơ đồ kết nối

- Code

#include <ESP8266WiFi.h>

#include <ESP8266WebServer.h>

#include <ESP8266mDNS.h>

const char* wifiName = "Cường Khánh";

const char* wifiPass = "24112002";

ESP8266WebServer server(80); //Define server object

const char htmlPage[] PROGMEM = R"=====(

<HTML> <HEAD> <TITLE>POST Request Demo</TITLE> </HEAD>


77

<BODY> <CENTER><B>LED Status=@@LEDState@@</B></CENTER> <FORM


method="POST" action="/">

<BUTTON name="LED" value="1">ON</BUTTON> <BUTTON name="LED"


value="0">OFF</BUTTON> </FORM>

<marquee behavior="alternate">NodeMCU ESP8266 Communication Methods and


Protocols</marquee>

</BODY>

</HTML>)====="; //Handles http request

void handleRoot() {

String LEDstate, webPage;

webPage = htmlPage;

LEDstate = server.arg("LED");

Serial.print("Argument Received:"); Serial.println(LEDstate);

if(LEDstate == "1") {

digitalWrite(2, 0); //Turn on LED

webPage.replace("@@LEDState@@","ON");

if(LEDstate == "0") {

digitalWrite(2, 1); //Turn off LED

webPage.replace("@@LEDState@@","OFF");

server.send(200, "text/html", webPage);

}
78

void setup() {

Serial.begin(115200);

delay(10);

pinMode(2,OUTPUT);

Serial.println();

Serial.print("Connecting");

WiFi.begin(wifiName, wifiPass); //Connect to Wi-Fi

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

Serial.println(""); Serial.println("Wi-Fi connected"); Serial.println("IP address: ");


Serial.println(WiFi.localIP()); //You can get IP address assigned to ESP

server.on("/", handleRoot); //Associate handler function to web requests

server.begin(); //Start web server

Serial.println("HTTP server started");

void loop() {

server.handleClient();

}
79

- Kết quả, giải thích

2.2.4. HTTP GET


- Linh kiện:

+ Bo mạch Node MCU ESP8266.

+ Dây cáp Micro USB Ugreen.


- Sơ đồ kết nối

- Code:

#include <ESP8266WiFi.h>

#include <WiFiClient.h>

#include <ESP8266HTTPClient.h>
80

const char* wifiName = "Cường Khánh";

const char* wifiPass = "24112002";

const char* host = "http://httpbin.org/get";

void setup() {

Serial.begin(115200);

delay(10);

Serial.println();

Serial.print("Đang kết nối đến ");

Serial.println(wifiName);

WiFi.begin(wifiName, wifiPass);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

Serial.println("");

Serial.println("Đã kết nối Wi-Fi");

Serial.print("Địa chỉ IP: ");

Serial.println(WiFi.localIP());

}
81

void loop() {

HTTPClient http; // Khởi tạo đối tượng HTTPClient

String ADCData = String(analogRead(A0));

String getData, Link;

// Chuỗi dữ liệu GET, bắt đầu bằng "?", "&" được sử dụng sau mỗi tham số mới theo định
dạng GET

getData = "?data=" + ADCData + "&sensor=temperature";

Link = host + getData;

Serial.print("Liên kết yêu cầu: ");

Serial.println(Link);

int httpCode = http.GET(); // Gửi yêu cầu GET

String payload = http.getString(); // Lấy phản hồi từ máy chủ

Serial.print("Mã phản hồi: ");

Serial.println(httpCode); // In mã trạng thái HTTP trả về

Serial.print("Dữ liệu trả về từ máy chủ: ");

Serial.println(payload); // In phản hồi từ máy chủ

http.end(); // Đóng kết nối

delay(5000); // Chờ 5 giây trước khi gửi yêu cầu GET tiếp theo
82

}
- Kết quả, giải thích.

Sau khi bạn nạp mã code này vào Arduino và kết nối module WiFi (ESP8266 hoặc ESP32)
với Arduino, Arduino sẽ kết nối đến mạng WiFi và gửi yêu cầu HTTP POST đến một URL
cụ thể với dữ liệu JSON.

Mã code sử dụng thư viện ESP8266WiFi (hoặc WiFi cho ESP32) để thực hiện kết nối đến
mạng WiFi. Trong hàm setup(), kết nối đến mạng WiFi được thiết lập bằng cách gọi hàm
WiFi.begin(ssid, password).

Sau đó, một vòng lặp while được sử dụng để chờ cho đến khi Arduino kết nối thành công
đến mạng WiFi bằng cách kiểm tra trạng thái kết nối bằng hàm WiFi.status(). Trong khi
Arduino chưa kết nối thành công, một dòng thông báo sẽ được in ra Serial Monitor thông
qua lệnh Serial.println("Đang kết nối đến mạng WiFi..."). Khi kết nối thành công, một thông
báo "Đã kết nối đến mạng WiFi" sẽ được in ra.
83

Sau đó, một yêu cầu HTTP POST được gửi đến một URL cụ thể bằng cách sử dụng thư viện
ESP8266HTTPClient (hoặc HTTPClient cho ESP32). Trong ví dụ này, URL được đặt thành
"http://example.com/api/data", và tiêu đề "Content-Type" của yêu cầu được đặt là
"application/json" để chỉ định rằng dữ liệu gửi đi là dạng JSON.

Dữ liệu JSON được tạo trong biến jsonPayload và có cấu trúc


{"sensor":"temperature","value":25}. Đây chỉ là một ví dụ, bạn có thể thay đổi nội dung
JSON theo yêu cầu của bạn.

Sau khi yêu cầu POST được gửi đi, mã phản hồi HTTP từ máy chủ được đọc và in ra Serial
Monitor. Nếu mã phản hồi là một số dương (lớn hơn 0), nghĩa là yêu cầu đã thành công và
mã phản hồi cùng với nội dung phản hồi được in ra. Nếu mã phản hồi là một số âm, đó là
một lỗi HTTP và mã phản hồi sẽ được in ra để biết lý do lỗi.

Vui lòng lưu ý rằng trong mã code này, tên mạng WiFi (ssid) và mật khẩu WiFi (password)
được thiết lập thành giá trị của mạng WiFi của bạn. Bạn cần chỉnh sửa chúng để phù hợp với
mạng WiFi của bạn trước khi chạy mã code.

2.3. Các bài thực hành kết nối Arduino Uno và Arduino Uno

2.3.1. Kết nối bằng UART


- Linh kiện:

+ 02 Bo mạch Arduino Uno.

+ Dây kết nối.


- Sơ đồ kết nối

- Code:

+ Code gửi đi:


84

#include <SoftwareSerial.h>

const byte RX = 8;

const byte TX = 9;

SoftwareSerial mySerial = SoftwareSerial(RX, TX);

void setup() {

Serial.begin(9600); // Khởi tạo cổng giao tiếp UART với baudrate 9600

pinMode(A0,INPUT);

mySerial.begin(9600);

void loop() {

int sodo=0;

sodo=analogRead(A0);

Serial.print("So do bien tro la:"); // Gửi dữ liệu qua cổng UART

Serial.println(sodo);

mySerial.print("So do bien tro la:"); // Gửi dữ liệu qua cổng UART

mySerial.println(sodo);

delay(1000); // Đợi 1 giây

+ Code nhận:

#include <SoftwareSerial.h>

const byte RX = 8;
85

const byte TX = 9;

SoftwareSerial mySerial = SoftwareSerial(RX, TX);

void setup() {

// Khởi tạo cổng giao tiếp UART với baudrate 9600

mySerial.begin(9600);

Serial.begin(9600);

void loop() {

if (mySerial.available()) { // Kiểm tra xem có dữ liệu nhận được không

String receivedData = mySerial.readString(); // Đọc dữ liệu từ cổng UART

Serial.println("Received data: " + receivedData); // In dữ liệu nhận được ra Serial Monitor

delay(100); // Đợi 0.1 giây

- Kết quả, giải thích.


86
87

Sau khi bạn nạp mã code này vào hai Arduino Uno và kết nối chúng với nhau như hướng
dẫn ở sơ đồ kết nối, một Arduino (Arduino Uno 1) sẽ gửi dữ liệu qua UART và Arduino còn
lại (Arduino Uno 2) sẽ nhận dữ liệu và in ra Serial Monitor.

Trong mã code Arduino Uno 1, chúng ta đã khởi tạo cổng Serial với baud rate 9600 bằng
lệnh Serial.begin(9600). Trong hàm loop(), chúng ta sử dụng lệnh Serial.println() để gửi dữ
liệu "Hello from Arduino Uno 1!" qua UART. Sau đó, chúng ta sử dụng delay(1000) để chờ
1 giây trước khi gửi dữ liệu tiếp theo.

Trong mã code Arduino Uno 2, chúng ta cũng khởi tạo cổng Serial với baud rate 9600 bằng
lệnh Serial.begin(9600). Trong hàm loop(), chúng ta sử dụng Serial.available() để kiểm tra
xem có dữ liệu nào được nhận từ UART hay không. Nếu có, chúng ta sử dụng
88

Serial.readString() để đọc dữ liệu nhận được và lưu vào biến data. Sau đó, chúng ta in ra
Serial Monitor thông qua Serial.println() để hiển thị dữ liệu nhận được.

Khi bạn chạy mã code trên hai Arduino Uno, Arduino Uno 1 sẽ gửi dữ liệu "Hello from
Arduino Uno 1!" qua UART mỗi giây một lần. Arduino Uno 2 sẽ nhận dữ liệu đó và in ra
Serial Monitor với thông báo "Received data: " và nội dung dữ liệu nhận được.

Bạn có thể thay đổi nội dung dữ liệu gửi đi bằng cách chỉnh sửa lệnh Serial.println() trong
Arduino Uno 1.

2.3.2. Kết nối bằng I2C.


- Linh kiện:

+ 02 Bo mạch Arduino Uno.

+ Dây kết nối.


- Sơ đồ kết nối
- Code:
+ Code gửi dữ liệu:

#include <Wire.h>

void setup() {

Wire.begin();

Serial.begin(9600);

void loop() {

delay(1000

int value = analogRead(A0);

Wire.beginTransmission(8);

Wire.write((byte*)&value, sizeof(value));
89

Wire.endTransmission();

Serial.print("So do bien tro: ");

Serial.println(value);

+ Code nhận dữ liệu:

#include <Wire.h>

void setup() {

Wire.begin(8);

Wire.onReceive(receiveEvent);

Serial.begin(9600);

void loop() {

delay(100);

// Các công việc khác trong loop

void receiveEvent(int howMany) {

if (howMany >= sizeof(int)) {

int receivedValue = 0;

Wire.readBytes((byte*)&receivedValue, sizeof(receivedValue)); vào biến receivedValue

Serial.print("So do bien tro: ");

Serial.println(receivedValue);
90

- Kết quả, giải thích.


91

2.3.3. Kết nối bằng SPI


- Linh kiện:

+ 02 Bo mạch Arduino Uno.

+ Dây kết nối.


- Sơ đồ kết nối

- Code:

+ Code gửi dữ liệu:


92

#include <SPI.h>

void setup() {

SPI.begin();

pinMode(10, OUTPUT); // Chân SS là OUTPUT để điều khiển Slave Select

digitalWrite(10, HIGH); // Khởi tạo chân SS ở mức cao (không chọn Slave nào)

Serial.begin(9600);

void loop() {

delay(1000);

int value = analogRead(A0);

SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

digitalWrite(10, LOW);

SPI.transfer(value);

digitalWrite(10, HIGH);

SPI.endTransaction();

Serial.print("Gia tri bien tro: ");

Serial.println(value);

+ Code nhận dữ liệu:

#include <SPI.h>

volatile int receivedValue;


93

void setup() {

SPI.begin();

pinMode(10, INPUT);

digitalWrite(10, HIGH);

Serial.begin(9600);

void loop() {

if (digitalRead(10) == LOW) {

receivedValue = SPI.transfer(0);

Serial.print("Received Value: ");

Serial.println(receivedValue);

}
- Kết quả, giải thích.
94
95

Sau khi bạn nạp mã code này vào hai Arduino Uno và kết nối chúng với nhau như hướng
dẫn ở sơ đồ kết nối, một Arduino (Arduino Uno 1) sẽ gửi dữ liệu qua giao thức I2C và
Arduino còn lại (Arduino Uno 2) sẽ nhận dữ liệu và in ra Serial Monitor.

Trong mã code của Arduino Uno 1, chúng ta đã khởi tạo thư viện Wire (I2C) bằng lệnh
Wire.begin(). Trong hàm loop(), chúng ta sử dụng Wire.beginTransmission(9) để bắt đầu
truyền dữ liệu tới địa chỉ thiết bị số 9 trên I2C. Tiếp theo, chúng ta sử dụng Wire.write() để
gửi dữ liệu "Hello from Arduino Uno 1!" qua I2C. Cuối cùng, chúng ta kết thúc truyền dữ
liệu bằng lệnh Wire.endTransmission(). Sau đó, chúng ta sử dụng delay(1000) để chờ một
giây trước khi gửi dữ liệu tiếp theo.

Trong mã code của Arduino Uno 2, chúng ta cũng khởi tạo thư viện Wire (I2C) bằng lệnh
Wire.begin(9) và địa chỉ thiết bị được đặt là số 9. Chúng ta cũng gán hàm receiveEvent cho
sự kiện nhận dữ liệu bằng lệnh Wire.onReceive(). Trong hàm receiveEvent, chúng ta sử
dụng Wire.available() để kiểm tra xem có dữ liệu nào nhận được qua I2C hay không. Nếu
có, chúng ta sử dụng Wire.readString() để đọc dữ liệu nhận được và lưu vào biến data. Sau
đó, chúng ta in ra Serial Monitor thông qua Serial.println() để hiển thị dữ liệu nhận được.

Khi ta chạy mã code trên hai Arduino Uno, Arduino Uno 1 sẽ gửi dữ liệu "Hello from
Arduino Uno 1!" qua I2C mỗi giây một lần. Arduino Uno 2 sẽ nhận dữ liệu đó và in ra Serial
Monitor với thông báo "Received data: " và nội dung dữ liệu nhận được.

Ta có thể thay đổi nội dung dữ liệu gửi đi bằng cách chỉnh sửa lệnh Wire.write() trong
Arduino Uno 1

PHẦN 3: LẮP MÔ HÌNH CHUNG


96

KẾT LUẬN

(Trình bày thành 3 đoạn văn nêu Ưu điểm, nhược điểm và hướng phát triển chủ đề)
97

DANH MỤC TÀI LIỆU THAM KHẢO

[1]. Nguyễn Hồng Sơn (2007), Giáo trình hệ thống Mạng máy tính CCNA (Semester 1),
NXB Lao động xã hội.
[2]. Phạm Quốc Hùng (2017), Đề cương bài giảng Mạng máy tính, Đại học SPKT Hưng
Yên.
[3]. James F. Kurose and Keith W. Ross (2013), Computer Networking: A top-down
approach sixth Edition, Pearson Education.

You might also like