1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Các dự án ứng dụng lập trình IOT với ESP8266 trong Arduino

75 1,2K 12

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 75
Dung lượng 3,62 MB

Nội dung

Chuẩn bị: Cài đặt ESP8266 để lập trình trong Arduino.Dự án 1: Lập trình đồng hồ LED 7 đoạn dùng ESP8266 và DS1307Dự án 2: Điều khiển ESP8266 bằng giọng nói với Google AssistantDự án 3 Giải mã dữ liệu thời tiết qua cấu trúc JSON trong ArduinoDự án 4 WiFiManager cho ESP8266 – tự động kết nối, cấu hình, quản lý SSID và Password

Trang 1

Bốn dự án ứng dụng lập trình IOT với

ESP8266 trong Arduino

Trang 2

Mục lục

Giới thiệu 3

Chuẩn bị: Cài đặt ESP8266 để lập trình trong Arduino 3

Dự án 1: Lập trình đồng hồ LED 7 đoạn dùng ESP8266 và DS1307 10

Dự án 2: Điều khiển ESP8266 bằng giọng nói với Google Assistant 31

Dự án 3 - Giải mã dữ liệu thời tiết qua cấu trúc JSON trong Arduino 38

Dự án 4 - WiFiManager cho ESP8266 – tự động kết nối, cấu hình, quản lý SSID và Password 53

Trang 3

Giới thiệu

ESP8266 tương đối phổ thông ở Việt Nam và chi phí cũng không quá cao Trong tài liệu này, tôi giới thiệu các dự án tôi đã lập trình với ESP8266 cho các bạn tham khảo Công cụ dùng để lập trình là Arduino IDE

Chuẩn bị: Cài đặt ESP8266 để lập trình trong Arduino

NodeMCU là bo mạch khai thác khả năng của chip esp8266 Nó kết hợp các chức năng của WIFI, vi xử lý

và ngôn ngữ LUA ESP8266 NodeMCU cung cấp

 Giống các chân IO phần cứng Arduino

 API điền khiển sự kiện cho các ứng dụng mạng

 10 chân GPIO từ D0 – D10, có chức năng PWM, IIC, giao tiếp SPI, 1-Wire và ADC trên chân A0

 Kết nối mạng wifi (có thể là sử dụng như điểm truy cập và/hoặc trạm máy chủ lưu trữ một, máy chủ web), kết nối internet để lấy hoặc tải lên dữ liệu

 Chi phí phù hợp cho các dự án Internet of Things (IoT)

PHẦN CỨNG

Module ESP8266

Trang 4

1) Cài Arduino dành cho chip ESP8266 WiFi trong Arduino IDE và xem các bài code mẫu trong đó 2) Chạy và chỉnh sửa các bài code mẫu để kiểm tra các chân D0 , GPIO-16 cũng như các chân cấu hình

Ghi chú – để sử dụng bo mạch NodeMCU V1 hoặc V2 hoặc V3 trong Arduino IDE, bạn không cần chép firmware với công cụ using nodemcu flasher Nó chỉ yêu cầu khi sử dụng ngôn ngữ LUA

Bạn có thể theo dõi video hướng dẫn chép firware sau:

Bước 1: Lập sơ đồ chân của NodeMCU ESP-12E

* Chip ESP8266 sử dụng điện áp 3.3V , bạn có thể lấy mức điện áp từ trên bo Arduino

* NodeMCU ESP-12E có thể nối với nguồn 5V sử dụng cáp micro USB hoặc chân Vin có sẵn trên bo

* Các chân ESP8266 chỉ sử dụng điện áp 3.3V , không sử dụng điện áp 5V tại các chân ngõ vào Khi sử dụng với các chân I/O 5V, bạn cần sử dụng mạch chuyển đổi từ 5V sang 3.3V

Tải : source of images

Trang 5

Bước 2: cài đặt chương trình lõi Arduino cho NodeMCU ESP-12E dùng chương trình quản lý bo

Arduino

Chép đường link sau từ trang Github

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

Trang 6

Dán link vào Arduino IDE trong File -> Preferences-

Đóng và khởi động lại Arduino IDE

Bước 3 : Tools – Boards Manager

Vào Tools – Boards manager và tìm ESP8266 và cài đặt thư viện có tiêu đề ESP8266 by ESP community

Trang 7

Khởi động Arduino IDE lại lần nữa

Bước 4: chọn NodeMCU Board trong Arduino IDE

Vào Tools – Boards kéo xuống cuối danh sách chọn NodeMCU 1.0 ( ESP-12EModule)

Trang 8

Chọn tên Port đã kết nối tới nodeMCU, phần còn lại để mặc định

Bước 5: LED Blink – kết nối với led bên ngoài

Chúng ra sẽ nối LED trực tiếp vào chân GPIO16 hoặc D0 của NodeMCU (không cần điện trở hạn dòng)

Bước 6: chạy ví dụ LED Blink

Vào File – Examples – ESP8266 – Blink

Trang 9

Trong video tôi đã sửa lại để LED nháy nhanh hơn, nhưng bạn có thể bỏ qua và up mã nguồn vào ESP xem kết quả

Ghi chú: Nếu bản Arduino IDE 1.6.7 bị lỗi bạn hãy trở lại bản arduino 1.6.5

Trang 10

Dự án 1: Lập trình đồng hồ LED 7 đoạn dùng ESP8266 và DS1307

Trên thị trường có bán sẵn đồng hồ LED 7 đoạn dùng chip thời gian thực, nhưng kích thước các đồng hồ

đó đa số đều nhỏ Trong dự án này, tôi làm 1 đồng hồ dùng LED 7 đoạn loại lớn để hiển thị thời gian Điểm đặc thù của đồng hồ là dùng chip wifi ESP8266 để tự động cập nhật thời gian từ internet, sau đó lưu thông tin thời gian vào DS1307 và hiển thị lên LED 7 đoạn

Ưu điểm

 Cập nhật thời gian thực từ Internet

 Loại bỏ các phím nhấn vật lý

Linh kiện phần cứng

1 LED 7 đoạn loại lớn sử dụng nguồn dương chung

2 Module wifi ESP8266 nodeMCU

3 Module đồng hồ thời gian thực DS1307 hoặc tương đương

4 Pin CMOS dùng cho module đồng hồ

Trang 11

Module giảm áp DC dùng hiển thị

Sơ đồ khối hiển thị

Tôi tự quy ước các chân của LED 7 đoạn, theo quy ước thì chúng ta sẽ không sử dụng chân số 3 và chân

số 6 Trước khi bạn sử dụng LED 7 đoạn, bạn cần kiểm tra các phân đoạn có giống trong hình tôi mô tả hay không, nếu không bạn hãy tự vẽ lại thứ tự các phân đoạn theo LED thực tế

Chúng ta sẽ kết nối 4 LED 7 đoạn lại với nhau, các phân đoạn sẽ được nối song song với nhau, các đoạn

từ A đến G sẽ kết nối với nhau thành từng dây dẫn điện riêng cho mỗi đoạn Các chân nguồn của LED 7 đoạn sẽ được nối vào chân C của transistor A1015 Chân B của A1015 nối với điện trở 1K hoặc 10K dùng cho chân tín hiệu từ 74HC595 Chân E của A1015 dùng cấp nguồn cho LED 7 đoạn

Như vậy chúng ta có 11 đường tín hiệu trên khối LED 7 đoạn gồm 7 đường tín hiệu phân đoạn và 4 đường điều khiển tắt mở các LED, chúng ta có 1 ma trận 7X4 dùng để hiển thị thông tin

Trang 12

Sơ đồ kết nối 4 LED 7 đoạn thành ma trận 7x4 Đường màu đỏ chính là chân số 10 trên LED 7 đoạn

Trang 14

Sơ đồ kết nối LED 7 đoạn với 74HC595

Theo thiết kế IC1 sẽ điều khiển 7 đường dữ liệu hiển thị số và IC2 sẽ tắt mở 1 trong 4 LED, như vậy trong

1 thời gian chỉ có 1 LED 7 đoạn được hiển thị, do chạy với tốc độ cao bạn sẽ thấy cả 4 LED hiển thị cùng lúc

Theo sơ đồ thiết kế dưới thì dữ liệu hiển thị LED 7 đoạn xuất trước rồi mới tới dữ liệu tắt mở 1 trong 4 led 7 đoạn Nếu trong quá trình thi công thứ tự 2 IC bị đảo lại khi lập trình cũng phải đảo lại thứ tự xuất

dữ liệu ra IC 74HC595

Trang 16

Sơ đồ IC đồng hồ DS1307

Sơ đồ kết nối DS1307 – ESP8266 – 74HC595

Trang 17

Vấn đề cấp nguồn

Do các LED 7 đoạn chạy điện áp tối đa là 4.3V, dư

dụng module hạ áp DC Mini để điều ch

cũng làm nguồn cung cấp cho module ESP8266

Lấy mức điện áp 3.3V trên module ESP8266 đ

ESP8366 chỉ nên sử dụng ở mức 3.3V và c

chỉ sáng ở mức 1.8V, cần sử dụng thêm đi

nháy giây này

Lập trình hiển thị LED 7 đoạn

//Pin connected to latch pin (ST_CP) of 74HC595

#define LATCH_PIN 15 //D8

//Pin connected to clock pin (SH_CP) of 74HC595

#define CLOCK_PIN 14 //pin D5

i đa là 4.3V, dưới mức này, LED có thể sẽ không sáng nên ta c

u chỉnh điện áp cho nó để đảm bảo LED sử dụng lâu b

p cho module ESP8266

n áp 3.3V trên module ESP8266 để cung cấp cho module DS1307 vì các tín hi

c 3.3V và cũng lấy mức điện áp này cung cấp cho LED báo giây vì LED

ng thêm điện trở 330ohm tại chân dương của LED để hạ

latch pin (ST_CP) of 74HC595

//Pin connected to clock pin (SH_CP) of 74HC595

g nên ta cần sử

ng lâu bền, đồng thời

p cho module DS1307 vì các tín hiệu xuất cho

p cho LED báo giây vì LED đỏ

ạn dòng cho LED

Trang 18

//Pin connected to Data in (DS) of 74HC5

#define DATA_PIN 13 //pin D7

#define SDA_PIN 5

#define SCL_PIN 4

//Các biến lưu dữ liệu

byte numbers[10]; //biến lưu giá trị từ 0 đến 9

byte selectNumber[4]; // biến lưu giá trị tắt mở các LED từ 0 đến 3

Trang 19

displayNumber[0] = numbers[minute % 10];

for (int j = 0; j < 4; j++) {

//ground latchPin and hold low for as long as you are transmitting digitalWrite(LATCH_PIN, 0);

shiftOut(DATA_PIN, CLOCK_PIN, selectNumber[j]);

shiftOut(DATA_PIN, CLOCK_PIN, displayNumber[j]);

digitalWrite(LATCH_PIN, 1);

delay(5);

}

}

// viết lại hàm shiftOut thay cho hàm của Arduino

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { int i = 0;

int pinState;

Trang 20

pinState = myDataOut & (1 << i) ? 1 : 0;

//Sets the pin to HIGH or LOW depending on pinState

Lập trình hiển thị đồng hồ và cập nhật thời gian từ Internet

Trong mã nguồn, sử dụng thư viện Time để xử lý thông tin thời gian Xem trong mã nguồn đính kèm tài liệu này

Múi giờ của Việt Nam là 7

Địa chỉ của chip đồng hồ là 0x68

#include <Wire.h>

#include <ESP8266WiFi.h>

Trang 21

#include <WiFiUdp.h>

#include <TimeLib.h>

//Pin connected to latch pin (ST_CP) of 74HC595

#define LATCH_PIN 15 //D8

//Pin connected to clock pin (SH_CP) of 74HC595

#define CLOCK_PIN 14 //pin D5

////Pin connected to Data in (DS) of 74HC5

#define DATA_PIN 13 //pin D7

#define SDA_PIN 5

#define SCL_PIN 4

#define DS1307 0x68

#define WLAN_SSID "ten_mang"

#define WLAN_PASS "password_mang_wifi"

// khai báo các biến và mảng lưu giá trị thời gian

int my_second, my_minute, my_hour, my_day, my_wday, my_month, my_year; byte numbers[10];

byte selectNumber[4];

byte displayNumber[4];

unsigned int localPort = 2390; // local port to listen for UDP packets

// A UDP instance to let us send and receive packets over UDP

static const char ntpServerName[] = "time.nist.gov";

const int timeZone = 7;

/* Số byte dữ liệu sẽ đọc từ DS1307 */

const byte NumberOfFields = 7;

Trang 22

const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message

byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

WiFiUDP Udp;

time_t getNtpTime();

//khai báo các hàm, trong các phiên bản mới hơn của Arduino có thể bỏ qua bước này

void digitalClockDisplay();

void printDigits(int digits);

void sendNTPpacket(IPAddress &address);

Trang 23

WiFi.begin (WLAN_SSID, WLAN_PASS);

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

Trang 24

for (int j = 0; j < 4; j++) {

digitalWrite(LATCH_PIN, 0);

shiftOut(DATA_PIN, CLOCK_PIN, displayNumber[j]); shiftOut(DATA_PIN, CLOCK_PIN, selectNumber[j]); digitalWrite(LATCH_PIN, 1);

Trang 25

while (Udp.parsePacket() > 0) ; // discard any previously received packets Serial.println("Transmit NTP Request");

// get a random server from the pool

uint32_t beginWait = millis();

while (millis() - beginWait < 1500) {

int size = Udp.parsePacket();

if (size >= NTP_PACKET_SIZE) {

Serial.println("Receive NTP Response");

Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer unsigned long secsSince1900;

// convert four bytes starting at location 40 to a long integer

secsSince1900 = (unsigned long)packetBuffer[40] << 24;

secsSince1900 |= (unsigned long)packetBuffer[41] << 16;

secsSince1900 |= (unsigned long)packetBuffer[42] << 8;

secsSince1900 |= (unsigned long)packetBuffer[43];

return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; }

}

Serial.println("No NTP Response :-(");

Trang 26

return 0; // return 0 if unable to get the time

// Initialize values needed to form NTP request

// (see URL above for details on the packets)

packetBuffer[0] = 0b11100011; // LI, Version, Mode

packetBuffer[1] = 0; // Stratum, or type of clock

packetBuffer[2] = 6; // Polling Interval

packetBuffer[3] = 0xEC; // Peer Clock Precision

// 8 bytes of zero for Root Delay & Root Dispersion

packetBuffer[12] = 49;

packetBuffer[13] = 0x4E;

packetBuffer[14] = 49;

packetBuffer[15] = 52;

// all NTP fields have been given values, now

// you can send a packet requesting a timestamp:

Udp.beginPacket(address, 123); //NTP requests are to port 123 Udp.write(packetBuffer, NTP_PACKET_SIZE);

Udp.endPacket();

}

Trang 28

int bcd2dec(byte num)

{

return ((num / 16 * 10) + (num % 16));

}

/* Chuyển từ Decimal sang BCD */

int dec2bcd(byte num)

{

return ((num / 10 * 16) + (num % 10));

}

/* cài đặt thời gian cho DS1307 */

void setTime(byte hr, byte min, byte sec, byte wd, byte d, byte mth, byte yr) {

Trang 29

void printDigits(int digits) {

// các thành phần thời gian được ngăn chách bằng dấu : Serial.print(":");

if (digits < 10)

Serial.print('0');

Serial.print(digits);

}

// viết lại hàm shiftOut thay cho hàm của Arduino

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { int i = 0;

int pinState;

Trang 30

pinState = myDataOut & (1 << i) ? 1 : 0;

//Sets the pin to HIGH or LOW depending on pinState

Trong trường hợp SCL và SDA không thể kết nối được bạn hãy đảo chân 2 chân này

Quá trình cập nhật thời gian đôi khi không thể cập nhật được và có hiện tượng hiển thị sai hoặc hiển thị

4 số 0 Bạn hãy reset chip ESP8266 vài lần

Trang 31

Thứ tự 2 IC 74HC595 dùng trong việc truyền dữ liệu và điều khiển tắt mở các đèn LED 7 đoạn khác nhau thì thứ tự truyền trong phần mềm cũng cần điều chỉnh lại thì mới hiển thị được

Dự án 2: Điều khiển ESP8266 bằng giọng nói với Google Assistant

Genk.vn từng có bài giới thiệu giải pháp điều khiển bằng giọng nói sử dụng Raspberry Pi kết hợp với Google Home, hoặc điện thoại Tuy nhiên, sử dụng Raspberry Pi vẫn chưa thực sự kinh tế, nó chỉ phù hợp để làm server điểu khiển nhiều thiết bị Nếu chỉ điều khiển 1 thiết bị hoặc điều khiển nhiều lỗ cắm điện trên cùng một hệ thống thì sử dụng chip ESP8266 kinh tế hơn

Trong bài hướng dẫn này, tôi hướng dẫn các bước căn bản để điều khiển module ESP8266 bằng giọng nói với sự giúp đỡ của Google Assistant, dịch vụ IFTTT, và Adafruit IO Tôi điều khiển ESP8266 để tắt hoặc mở 2 rờ le, tích hợp chúng vào ổ cắm điện với chi phí khoảng 200 ngàn

Linh kiện:

1 Module ESP8266 (ESP-12E)

2 Rờ le loại điều khiển bằng điện áp 5V

3 Nguồn điện 5V, dây nguồn và một số thứ khác

4 Ổ cắm điện

Trang 32

Phần mềm

Cài app Google Assistant lên điện tho

Đăng ký dịch vụ trực tuyến

Để điều khiển được ESP8266, bạn c

Dịch vụ adafruit, bạn chọn đăng ký gói mi

Đăng ký dịch IFTT tại link https://platform.ifttt.com/

với tài khoản IFTTT

Bước 1: Cài đặt Adafruit IO

Adafruit IO là nền tảng IOT xây dựng d

Đây là một giao thức truyền thông đi

sử dụng băng thông thấp, độ tin cậy cao và có kh

ổn định

Trong Adafruit IO, sau khi đã tạo tài kho

bên trái màn hình Chọn Actions từ

Tiếp theo, vào Dashboards, menu bên trái Ch

mới (dashboard), đặt tên là "LightSwitch" M

tượng dấu cộng (+) màu xanh sẽ cho b

Khi được nhắc chọn 1 feed, bạn chọ

định

Tới đây là kết thúc mọi việc với Adafruit IO Ti

n thoại (Có sẵn trên chợ ứng dụng Android và iPhone)

n cần đăng ký tài khoản ở 2 dịch vụ trực tuyến:

n đăng ký gói miễn phí Đăng ký tại link : https://io.adafruit.com

atform.ifttt.com/ Bạn phải dùng tài khoản Google Assistant chung

ng dựa theo giao thức Message Queue Telemetry Transport

n thông điệp (message) theo mô hình publish/subscribe (xuấ

y cao và có khả năng hoạt động trong điều kiện đườ

o tài khoản tại Adafruit IO, bạn trở lại trang home, chọn menu "Feeds" menu sổ xuống và tạo 1 feed mới gọi là "onoff"

Dashboards, menu bên trái Chọn mục Actions từ menu sổ, vào tạo một b

t tên là "LightSwitch" Mở bảng theo dõi mới, bắt đầu với 1 trang tr

cho bạn tạo mới linh kiện Bây giờ, chúng ta sẽ tạo 1 nút nh

ọn feed đã tạo trước đó, và tất cả những thứ còn lại đAdafruit IO Tiếp theo kết nối ESP8266 tới MQTTBroker

ng Android và iPhone)

https://io.adafruit.com

n Google Assistant chung

Message Queue Telemetry Transport (MQTT)

ất bản – theo dõi), ờng truyền không

Trang 34

Kết nối ESP8266

Trước khi lập trình, bạn sẽ cần cài đ

của Arduino (Sketch > Include Library > Library Manage

Client” và cài vào chương trình

Mở code mẫu từ trong ví dụ Adafruit MQTT Client/mqtt_esp8266.ino.

Có 3 thư viện bạn cần trong chương tr

n cài đặt thư viện Adafruit MQTT Client, vào mục quản lý th

Sketch > Include Library > Library Manager ) Tìm thư viện với từ khóa “

Trang 35

Cấu hình tài khoản mạng wifi nhà bạn

#define WIFI_SSID "<Tên Wifi nhà bạn>"

#define WIFI_PASS "<Mật khẩu wifi nhà bạn>"

#define AIO_SERVER "io.adafruit.com"

#define AIO_SERVERPORT 1883

#define AIO_USERNAME "<Tên đăng nhập tại Adafruit IO >"

#define AIO_KEY "<Mã IO Key trên Adafruit IO>"

Những khai báo này dùng kết nối tới tài khoản Adafruit IO Khóa Adafruit IO là chuỗi ký tự bạn có thể tìm thấy bằng cách nhấn vào menu "View AIO Key" bên trái của Adafruit IO

Tiếp theo, tạo đối tượng WiFiClient và Adafruit_MQTT_Client như là các biến toàn cục:

// Setup a feed called 'onoff' for subscribing to changes

Trang 36

// Setup MQTT subscription for onoff feed

pinMode(D1, OUTPUT); //khai báo ngõ ra cho relay

digitalWrite(D1, HIGH); //tắt relay

}

Kết nối với Google Assistant thông qua IFTTT

Bước cuối cùng, chúng ta sẽ kết nối Google Assistant tới Adafruit IO MQTT Broker để điều khiển tắt mở bằng giọng nói Chúng ta sử dụng nền tảng IFTTT (If This Then That) có hàng trăm dịch vụ khác nhau

Địa chỉ truy cập https://ifttt.com/my_applets Chọn nút "New Applet" để tạo Applet điều khiển bằng giọng nói Chọn ("If This") để cài đặt khẩu lệnh và chọn ("Then That") để chọn feed đã tạo trước đó Mỗi Applet chỉ phục vụ cho 1 khẩu lệnh, nên bạn có 2 lệnh tắt, mở thiết bị thì bạn cần tạo 2 applet

Trong "Google Assistant" chọn "Say a simple phrase" để cài đặt câu lệnh ví dụ như "Turn the light on,"

"Turn on the light," và "Switch the light on" Hiện tại Google Assistant chưa hỗ trợ tiếng Việt, nên bạn chỉ

có thể sử dụng tiếng Anh

Phần cuối của applet là Action, phản hồi tới Trigger Trong phần dịch vụ chọn "Adafruit", và xác định điều khiển Action, chọn "Send data to Adafruit IO" Chọn Adafruit IO feed bạn sẽ gửi dữ liệu, trong trường hợp này là "onoff" Nhập dữ liệu sẽ gửi, ví dụ "ON", dữ liệu này sẽ được gửi tới chip ESP8266 trong khoảng 1 giây Tương tự, bạn tạo thêm applet để gửi lệnh "OFF" tới ESP8266

Chạy thử

Nếu không có Google Home, bạn có thể sử dụng điện thoại cài app Google Assistant Mở app và đọc khẩu lệnh như đã tạo trong các applet Phần mềm sẽ tìm kiếm và trả về lệnh theo như đã khai báo ở trên Nếu mọi thứ đã suôn sẻ, thiết bị của bạn sẽ hoạt động như ý bạn mong muốn

Các vấn đề gặp phải

Trang 37

Có những nơi bạn điều khiển bằng giọng nói không được, thì bạn cần kiểm tra một vài thứ

Trạng thái tắt mở có thể hiện trên bảng điều khiển Adafruit IO không? Nếu không, ESP8266 chưa kết nối tới máy chủ, các feed Kiểm tra ESP8266 trên Serial Monitor

Google Assistant dịch có chính xác những gì bạn nói không ?

Google Assistant có trả lại dữ liệu không? Nếu không, bạn cần kiểm tra tài khoản Google và tài khoản IFTTT có cùng 1 tài khoản hay không

Bảng điều khiển Adafruit IO không cập nhật các applet IFTTT? Nếu không, kiểm tra tài khoản Adafruit IO

và tài khoản IFTTT có kết nối không

Ngày đăng: 30/03/2018, 15:26

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w