Skip to content

Arduino – Truyền thông nối tiếp – Serial

Arduino – Truyền thông nối tiếp – Serial

Truyền thông nối tiếp là một khái niệm quan trọng giúp chúng ta có thể dễ dàng nắm bắt những nội dung về một số chuẩn giao tiếp thông dụng của Arduino như I2C, SPI, 1-Wire, Serial…​ sẽ được giới thiệu ở các phần tiếp theo.

Trong thực tế, khi xây dựng một ứng dụng sử dụng Arduino, giả sử chúng ta cần trao đổi thông tin giữa 2 thiết bị (giữa máy tính với board Arduino hoặc giữa các board Arduino với nhau hay có thể là giữa Arduino với các module…​), thông tin trao đổi gồm có 8 bit, vậy đâu là giải pháp cho vấn đề này? Có lẽ cách dễ dàng tiếp cận nhất đó là sử dụng 8 dây data, ứng với mỗi dây data, mỗi bit sẽ được truyền từ bộ phát đến bộ thu, đây được gọi là phương pháp truyền song song (Parallel Communication), phương pháp này có ưu điểm tốc độ truyền tải nhanh, dễ dàng cài đặt, tuy nhiên nhược điểm lớn nhất là số lượng đường truyền cần phải lớn, thật khó chấp nhận đối với các dòng vi điều khiển có số lượng chân I/O là hạn chế. Do đó truyền thông nối tiếp (Serrial Communication) được ra đời để giải quyết vấn đề này. Cụ thể, để thực hiện việc truyền tải dữ liệu, ta chỉ cần sử dụng 1 (hoặc một số) đường truyền, và dữ liệu cần trao đổi sẽ được truyền lần lượt từng bit theo đường truyền này. Do đó, trong các ứng dụng thực tế, ta thường lựa chọn phương pháp truyền thông nối tiếp thay vì truyền song song dù cho tốc độ truyền thấp hơn, nhưng làm tiết kiệm số lượng đường truyền và chân điều khiển của các loại vi điều khiển được sử dụng.

serial
Hình 1. Giao tiếp nối tiếp và giao tiếp song song (Nguồn Wikipedia)

Ngoài ra, với phương pháp truyền thông nối tiếp, để đảm bảo tính chính xác của thông tin truyền nhận giữa bộ truyền và bộ nhận cần có những tiêu chuẩn cụ thể. Một số giao thức như I2C, SPI,…​ sử dụng một đường truyền phát xung (CLOCK) có chức năng đồng bộ quá trình trao đổi thông tin. Ví dụ, thiết bị thứ nhất muốn truyền một bit data, thiết bị này sử dụng thêm một dây tín hiệu chuyển từ mức thấp lên mức cao để thông báo cho thiết bị thu biết đang có dữ liệu gửi đến. Đây là một cách giúp giảm thiểu rủi ro sai lệch thông tin trong quá trình giao tiếp, được gọi là phương pháp truyền thông đồng bộ (Synchronous). Khác với truyền thông đồng bộ, truyền thông không đồng bộ (Asynchronous) có những cách chuẩn hóa riêng giữa các thiết bị giao tiếp với nhau và sẽ không cần dùng đến dây tín hiệu phát xung. Ứng với cách này, giả sử ta quy định cho bộ truyền và bộ nhận rằng cứ mỗi 1 micro giây thì bộ truyền sẽ gửi 1 bit dữ liệu, do đó cứ mỗi 1 micro giây bộ nhận sẽ chỉ cần kiểm tra và tiếp nhận thông tin, sau đó tổng hợp để thu được dữ liệu có nghĩa.

Giao tiếp Serial

Trong phần này chúng ta sẽ cùng tìm hiểu về chuẩn giao tiếp Serial (Serial protocol) một chuẩn giao tiếp đại diện điển hình nhất của phương pháp truyền thông nối tiếp không đồng bộ (Asynchronous Serial). Nội dung phần này sẽ lần lượt trình bày các khái niệm cơ bản xoay quanh giao tiếp Serial cũng như những ví dụ thực tế từ chuẩn giao tiếp này.

Những khái niệm cơ bản

Chuẩn giao tiếp Serial là gì?

Serial là chuẩn giao tiếp truyền thông nối tiếp không đồng bộ (được trình bày trong phần trước), sử dụng UART (Universal Asynchronous Receiver-Transmitter, một bộ phận phần cứng được tích hợp bên trong chip ATmega328 của board Arduino Uno) kết hợp với mức logic TTL (mức điện áp cao tương ứng với 5V hoặc 3.3V và mức điện áp thấp tương ứng với 0V). Trong thực tế, chúng ta vẫn có thể kết hợp UART và các mức logic khác để tạo ra một số chuẩn truyền khác chẳng hạn RS232, nhưng trong khuôn khổ quyển sách này chúng ta chỉ khảo sát mức logic TTL là chính.

UART là tên gọi để chỉ một bộ phận phần cứng dùng để chuyển đổi thông tin từ thanh ghi chứa nội dung cần trao đổi ra bên ngoài (thông thường có 8 bits) thành 2 dây tín hiệu Serial, phục vụ cho chuẩn giao tiếp Serial chứ không phải là tên gọi của một chuẩn giao tiếp.
rs232 ttl
Hình 2. RS232 và TTL

Như đã giới thiệu từ phần trước, khi sử dụng chuẩn giao tiếp Serial, để trao đổi thông tin một cách hiệu quả, đòi hỏi các thiết bị giao tiếp với nhau cần phải thống nhất với nhau một số quy cách riêng như tốc độ baud (baudrate), khung truyền (frame), start bit, stop bits,…​ và sau đây chúng ta sẽ lần lượt tìm hiểu:

Baudrate

Như trong ví dụ về việc truyền 1 bit data sau mỗi 1 micro giây, ta nhận thấy rằng để việc giao tiếp diễn ra thành công, giữa 2 thiết bị cần có những thống nhất rõ ràng về khoảng thời gian truyền cho mỗi bit dữ liệu, hay nói cách khác tốc độ truyền cần phải được thống nhất với nhau. Tốc độ này được gọi là tốc độ baud (baudrate), được định nghĩa là số bit truyền trong mỗi giây. Ví dụ, nếu tốc độ baud được sử dụng là 9600, có nghĩa thời gian truyền cho 1 bit là 1/9600 = 104.167 micro giây.

Khung truyền (frame)

Bên cạnh tốc độ baud, khung truyền đối với chuẩn giao tiếp Serial cũng hết sức quan trọng để đảm bảo việc truyền nhận được diễn ra chính xác. Khung truyền quy định về số lượng bit truyền trong mỗi lần truyền, bao gồm start bit, các bit data, stop bits, ngoài ra còn có thể có parity bit (kiểm tra lỗi dữ liệu trong quá trình truyền nhận).

frame uart
Hình 3. Ví dụ về một khung truyền

Hình ảnh trên là một ví dụ về khung truyền, bao gồm 1 bit start, 8 bits data và cuối cùng là 1 bit stop.

Start bit

Đây là bit đầu tiên được truyền vào khung truyền, có chức năng thông báo cho thiết bị nhận biết đang có một chuỗi dữ liệu sắp truyền đến. Đối với các dòng AVR nói chung và UnoX nói riêng, ở trạng thái chưa có dữ liệu (Idle) đường truyền luôn kéo lên mức cao. Khi có dữ liệu mới, đường truyền được kéo xuống mức thấp, do đó start bit sẽ được quy định là mức 0.

Dữ liệu (data)

Dữ liệu cần truyền thông thường gồm 8 bits, tuy nhiên chúng ta hoàn toàn có thể tùy chỉnh số lượng bit data cho một gói tin, có thể là 5, 6, 7, 9…​ Trong quá trình truyền, bit có trọng số thấp nhất (LSB) sẽ được truyền trước, và cuối cùng sẽ là bit có trọng số cao nhất (MSB).

Stop bits

Stop bits là một hoặc nhiều bit có chức năng thông báo cho thiết bị nhận biết rằng một gói dữ liệu đã được gởi xong. Đây là bit quan trọng, cần phải có trong một khung truyền. Giá trị của các stop bit luôn bằng mức Idle (mức nghỉ) và ngược với giá trị của start bit. Đối với các dòng vi điều khiển AVR các bit kết thúc này luôn là mức cao.

Sử dụng chuẩn giao tiếp Serial với boad Arduino Uno

Giao tiếp Serial giữa 2 thiết bị với nhau thông thường sẽ có 2 dây tín hiệu, đó là TX (Transmitter) có chức năng truyền tải dữ liệu và RX (Receiver) có chức năng thu nhận dữ liệu. 2 dây tín hiệu này được kết nối chéo nhau giữa 2 thiết bị. Cụ thể, TX của thiết bị 1 kết nối với RX của thiết bị 2 và RX của thiết bị 1 kết nối với TX của thiết bị 2. Điều đặc biệt của Serial đó là quá trình truyền và quá trình nhận dữ liệu được diễn ra hoàn toàn độc lập với nhau.

uart basic connection
Hình 4. Giao tiếp 2 thiết bị sử dụng Serial UART

Hiện nay, các board Arduino đều được hỗ trợ sẵn 1 hoặc nhiều cổng giao tiếp Serial. Đối với board Arduino Uno, cổng Serial được ra chân tại vị trí chân số 1 và chân số 0 trên board), đây được gọi là Hardware Serial, tức là giao tiếp Serial dựa trên phần cứng (có sử dụng UART). Ngoài ra, đối với các vi điều khiển không hỗ trợ UART hoặc trong trường hợp muốn mở rộng nhiều cổng Serial để giao tiếp với nhiều thiết bị có hỗ trợ giao tiêp Serial, chúng ta hoàn toàn có thể giả lập giao tiếp Serial bằng thư viện cho Arduino có tên là SoftwareSerial, chúng ta sẽ tìm hiểu thư viện thú vị này ở phần sau.

uart pin
Hình 5. Vị trí chân giao tiếp UART trên board Arduino Uno

Ứng dụng

Giao tiếp Serial của board Arduino Uno với máy tính cá nhân

Khi kết nối board Arduino Uno với máy tính bằng cable USB, thông qua chip USB-to-Serial CH430E trên board, cổng USB của máy tính sẽ được chuyển đổi thành tín hiệu Serial để kết nối với chân TX, RX của board, lúc này, ta có thể dễ dàng trao đổi dữ liệu giữa board và máy tính. Và đây cũng là cách để nạp chương trình từ máy tính xuống cho board Arduino Uno. Sau đây, ta sẽ xét một số ví dụ đơn giản khi giao tiếp giữa Arduino Uno và máy tính.

1. Lắng nghe dữ liệu từ board Arduino Uno

1.1. Giới thiệu:

Việc máy tính lắng nghe dữ liệu từ board Arduino Uno thông thường được sử dụng khi debug chương trình, qua đó chúng ta có thể quan sát và kiểm tra kết quả trả về từ board trong khi hoạt động thông qua cửa sổ Serial Monitor. Một số hàm cần lưu ý khi sử dụng chức năng này:

  • Serial.begin(baudrate);

  • Serial.print(message);

  • Serial.println(message);

Trong đó:

  • baudrate như đã giới thiệu đó là tốc độ baud, các tốc độ baud thường dùng: 9600, 57600, 115200, 921600,…​ Lưu ý khi sử dụng: giữa 2 thiết bị giao tiếp với nhau cần được khai báo tốc độ baud như nhau để trao đổi dữ liệu được hiệu quả.

  • message ở đây là thông tin mà Arduino muốn truyền qua Serial. Thông tin này có thể là các kiểu dữ liệu như String, int, byte, char, double…​

  • Serial.begin(baudrate) có chức năng khai báo sử dụng Serial với tốc độ baud là baudrate.

  • Serial.print(message) có chức năng truyền Serial với nôị dung là message mà không có kí tự kết thúc dòng. Ta sử dụng hàm này khi cần ghi dữ liệu lên Serial Monitor trên cùng 1 dòng.

  • Serial.println(message) có chức năng truyền Serial với nôị dung là message có kí tự kết thúc dòng. Ta sử dụng hàm này khi cần ghi cần kết thúc dòng nội dung ghi trên Serial Monitor.

1.2. Ví dụ:

Đọc giá trị từ biến trở, xuất kết quả ra Serial Monitor.

Chuẩn bị:

  • Board Arduino Uno

  • 1 biến trở 1KΩ.

  • Breadboard

  • Dây kết nối

Kết nối:

arduino bien tro
Hình 6. Kết nối Arduino với biến trở

Source code:

//Chương trình đọc giá trị từ chiết áp và gửi dữ liệu đến máy tính bằng Serial

const int POT=0; //Sử dụng chân A0 trên board để lấy giá trị từ chiết áp
void setup()
{
    Serial.begin(9600); // Khai báo sử dụng Serial với tốc độ baud = 9600
}
void loop()
{
    int val = analogRead(POT); //Tiến hành đọc giá trị chiết áp
    int per = map(val, 0, 1023, 0, 100); //Chuyển đổi sang phần trăm
    Serial.print("Analog Reading: ");
    Serial.print(val); //In giá trị thô đọc được
    Serial.print(" Percentage: ");
    Serial.print(per); //In giá trị đã chuyển đổi sang phần trăm
    Serial.println("%"); //In kí tự '%' và kết thúc dòng thông tin
    delay(1000); //Đợi 1s sau đó tiếp tục lặp
}

Xem kết quả:

Chọn ToolsSerial Monitor để xem kết quả từ Serial Monitor. Lưu ý: chọn baudrate đúng với giá trị đã khai báo.

serial monitor ex1
Hình 7. Chọn baudrate trên Serial Monitor để xem kết quả

2. Gửi dữ liệu từ máy tính đến board Arduino Uno qua Serial Monitor

2.1. Giới thiệu

Ta thường sử dụng Serial Monitor của Arduino IDE để gửi lệnh đến board Arduino Uno. Một số hàm cần chú ý:

  • Serial.available(): Trả về số lượng kí tự hiện tại đang lưu trữ trong bộ nhớ mà Arduino đã nhận được. Khi giá trị này khác 0, ta sẽ tiến hành đọc dữ liệu được lưu trữ.

  • Serial.read(): Đọc kí tự trong bộ lưu trữ và tự động chuyển đến kí tự tiếp theo (nếu có).

2.2. Ví dụ

Gửi lệnh điều khiển LED từ máy tính xuống board Arduino Uno bằng Serial.

Chuẩn bị:

  • Board Arduino Uno

  • 1 LED đơn.

  • 1 điện trở 330Ω.

Kết nối:

example circuit led
Hình 8. Kết nối LED với board Arduino Uno

Source Code:

//Chương trình sử dụng Serial Monitor để gửi lệnh điều khiển đèn LED

const int LED = 13; //Sử dụng chân 13 trên board để điều khiển đèn LED
String data = "";   //Khai báo biến data lưu lệnh mà người dùng nhập
void setup()
{
  pinMode(LED, OUTPUT);
  digitalWrite(LED,LOW); // Ban đầu cho đèn LED tắt
  Serial.begin(9600); // Khai báo sử dụng Serial với tốc độ baud = 9600
}
void loop()
{
  if (Serial.available() > 0)
  {
      char c = Serial.read(); //Đọc từng kí tự
      // Kiểm tra khi kết thúc câu lệnh
      if (c == '\n'){
        Serial.print("Send to Arduino: ");
        Serial.println(data);
        if (data == "on"){
          digitalWrite(LED, HIGH);
        } else
        if (data == "off"){
          digitalWrite(LED, LOW);
        }
        data = "";
      } else
        data = data + c;

     //Print byte of data
  }
}

Giải thích code

Chương trình trên sử dụng hàm Serial.available() để kiểm tra lệnh được gửi đến board. Bất cứ khi nào giá trị Serial.available() khác 0, ta sẽ dùng biến c kiểu char đọc từng kí tự được gửi đến, nếu c không phải là kí tự kết thúc dòng \n ta sẽ ghép từng kí tự c này vào biến data (data = data + c). Và nếu gặp kí tự kết thúc chuỗi (c == '\n'), tức là đã kết thúc 1 lệnh mà người dùng nhập, ta sẽ tiến hành kiểm tra xem lệnh đó là gì, nếu là "on" thì board Arduino Uno sẽ on LED trên board (digitalWrite(LED,HIGH)) và nếu lệnh "off" thì điều khiển LED tắt (digitalWrite(LED,LOW)). Tất nhiên, nếu người dùng gửi lệnh khác “on” và “off” thì board Arduino Uno sẽ không làm gì cả.

Khi người dùng hoàn thành việc nhập lệnh và click send hoặc nhấn phím Enter đồng nghĩa với chuỗi lệnh mà người dùng gửi đến có kết thúc là kí tự xuống dòng ‘\n’ chương trình trên sử dụng đặc điểm này để nhận biết khi nào là kết thúc 1 chuỗi rồi tiến hành kiểm tra chuỗi đó có nội dung là gì. Để thực hiện việc này ta cần tùy chỉnh chế độ nhập từ Serial Monitor là Newline, ngoài ra cần phải chỉnh tốc độ baud là 9600 như ví dụ trước.
ex2 serial monitor
Hình 9. Tùy chỉnh chế độ nhập của Serial Monitor

Kết quả:

ex2 serial monitor 2
Hình 10. Nhập “on” hoặc “off” trên Serial Monitor

3. Giao tiếp Serial giữa 2 board Arduino qua Serial

Ví dụ tiếp theo chúng ta sẽ thực hiện việc trao đổi thông tin giữa 2 board Arduino Uno, board thứ nhất làm master và board còn lại là slave. Board master sẽ gửi lệnh điều khiển đèn LED xuống board Slave. Board Slave khi nhận được lệnh thì sẽ điều khiển đèn LED có sẵn trên board của chính nó.

3.1. Chuẩn bị

  • 2 Board Arduino Uno

  • Đèn LED

  • Điện trở 330Ω

  • Dây kết nối

3.2. Kết nối chân

Số thứ tự Arduino Uno (Slave) Arduino khác(Master)

1

TXD

RXD

2

RXD

TXD

3

GND

GND

duo arduino
Hình 11. Hình ảnh kết nối 2 board Arduino Uno

Lưu ý: Để hoạt động được, 2 board này cần được cấp nguồn, nguồn này có thể chung hoặc riêng nhưng GND của cả hai board cần được kết nối với nhau.

3.3. Source Code và giải thích

Master code:

// Giao tiếp 2 board Arduino (Master)
void setup() {
  Serial.begin(9600); // Khai báo sử dụng Serial với tốc độ baud là 9600
}

void loop() {
  //Cứ sau 1 giây ta sẽ on rồi sau đó gửi off đến Slave để điều khiển LED
  Serial.print("on\n"); // Lưu ý: cần kèm kí tự kết thúc dòng '\n' ở cuối lệnh cần gửi
  delay(1000);
  Serial.print("off\n");
  delay(1000);
}

Slave code:

//Giao tiếp 2 board Arduino (Slave)
const int LED = 13; //Sử dụng chân 13 điều khiển đèn LED
String data = "";   //Khai báo biến data lưu lệnh mà master gửi đến
void setup()
{
  pinMode(LED, OUTPUT); // Khai báo sử dụng pin số 13 làm OUTPUT
  digitalWrite(LED,LOW); // Ban đầu cho đèn LED tắt
  Serial.begin(9600); // Khai báo sử dụng Serial với tốc độ baud = 9600
}
void loop()
{
  if (Serial.available() > 0) // Nếu có lệnh gửi đến
  {
      char c = Serial.read(); //Đọc từng kí tự
      // Kiểm tra kết thúc câu lệnh
      if (c == '\n'){
        if (data == "on"){
          digitalWrite(LED, HIGH);// Nếu lệnh gửi đến là "on" thì bật đèn LED
        } else
        if (data == "off"){
          digitalWrite(LED, LOW); //Nếu lệnh gửi đến là "off" thì tắt đèn LED
        }
        data = "";
      } else // Nếu chưa phát hiện kí tự kết thúc câu lệnh thì tiết tục ghi nhận.
        data = data + c;
  }
}

3.4. Kết quả

Nếu thành công, ta sẽ thấy đèn LED trên board Arduino Uno chớp tắt theo chu kì 2 giây

3.5. Mở rộng từ ví dụ

Qua ví dụ này, ta đã biết cách giao tiếp giữa 2 board Arduino bằng Serial, điều này phục vụ cho các dự án lớn khi 1 board Arduino là chưa đủ để quản lí hết tất cả các thiết bị, việc thêm 1 hay nhiều board Arduino để chia sẻ tác vụ là hết sức cần thiết. Có nhiều cách để trao đổi thông tin giữa các Arduino, nhưng dùng Serial là giải pháp giúp tiết kiệm số lượng đường truyền với thời gian truyền đáp ứng tốt.

4. Giao tiếp Serial giữa board Arduino Uno và module Sim800

Ví dụ tiếp theo, chúng ta sẽ sử dụng Arduino cùng với thư viện SoftwareSerial để điều khiển module Sim800L nhắn tin đến điện thoại di động.

4.1. Module Sim800

Module Sim800L là một giải pháp hiệu quả cho các ứng dụng về GSM và GPRS (nhắn tin, gọi điện hoặc sử dụng dịch vụ mạng 2G). Nếu bạn đang tìm kiếm một loại module giúp bạn trong các dự án như phát hiện có đối tượng lạ xâm nhập thì cần gọi điện hoặc nhắn tin đến người chủ, điều khiển hệ thống tưới bằng tin nhắn điện thoại, thu thập dữ liệu gửi lên Server bằng dịch vụ GPRS,…​ thì Sim800L là giải pháp bạn cần cân nhắc đầu tiên. Sim800L được hỗ trợ giao tiếp Serial TTL do đó rất dễ sử dụng để giao tiếp với các vi điều khiển thông qua tập lệnh AT.

original
Hình 12. Module Sim800L GSM GPRS

Các thông số kỹ thuật của module Sim800L:

  • Điện áp hoạt động : 3.7 – 4.2V

  • Dòng khi ở chế độ chờ: 10 mA

  • Dòng khi hoạt động: 100 mA đến 1A.

  • Khe cắm SIM : MICROSIM

  • Hỗ trợ 4 băng tần : GSM850MHz, EGSM900MHz, DSC1800Mhz, PCS1900MHz

  • Có thể giao tiếp với vi điều khiển qua Serial TTL

  • 1 LED báo tín hiệu.

4.2. Tập lệnh AT:

Một số module như Sim, GPS, ESP8266, bluetooth…​ được hỗ trợ giao tiếp Serial TTL đi kèm với đó là tập lệnh AT (AT commands), bằng những tập lệnh này thế giới bên ngoài có thể truy cập vào module, đưa ra những câu lệnh về thiết lập, điều khiển hoặc lấy thông tin,…​ Tương tự ví dụ thứ 2 ta sử dụng dụng máy tính để ra lệnh cho Arduino điều khiển đèn LED thông qua chuẩn giao tiếp Serial, tập lệnh AT cũng có chức năng giống vậy tuy nhiên cấu trúc các lệnh AT được chuẩn hóa theo cách riêng.

Ví dụ một số lệnh AT cơ bản đối với module Sim800L:

  • AT: Kiểm tra đáp ứng của Module Sim, nếu trả về OK thì Module hoạt động.

  • AT+IPR=[baud rate] : Cài đặt tốc độ giao tiếp dữ liệu với Module Sim, chỉ cài được các tốc độ sau: 0(auto), 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200.

  • ATD[Số_điện_thoại]: Lệnh thực hiện cuộc gọi.

  • AT+CNMI=2,2: Hiển thị nội dung tin nhắn ngay khi có tin nhắn đến.

Ngoài ra bạn có thể tham khảo thêm các câu lệnh khác tại: SIM800 Series_AT Command Manual_V1.09.pdf (keywords: AT commands for sim800)

4.3. Thư viện SoftwareSerial

Như đã giới thiệu, đối với một số vi điều khiển không được hỗ trợ Serial hoặc số cổng Serial được hỗ trợ là hạn chế như board Arduino Uno thì việc mở rộng giao tiếp với nhiều thiết bị bằng Serial thật sự khó khăn, khi đó việc sử dụng thư viện giúp giả lập giao tiếp bằng Serial là hết sức cần thiết, và SoftwareSerial là thư viện tốt nhất hỗ trợ việc này. Theo đó, ta chỉ cần kết nối bằng 2 chân GPIO bất kì của Arduino rồi khai báo sử dụng 2 này để giao tiếp Serial là ta có thể sử dụng Serial như cách truyền thống.

Khai báo sử dụng Serial ảo: SoftwareSerial mySerial(RX,TX), trong đó TX, RX là các pin sử dụng cho giao tiếp Serial. Kết thúc việc khai báo này, ta có thể sử dụng đối tượng mySerial trong lập trình để đọc, ghi dữ liệu bằng Serial (Giống như biến Serial trong các ví dụ trước).

4.4. Kết nối chân

Trong ví dụ lần này, ta sẽ sử dụng chân 9 và 10 của board Arduino Uno làm TX và RX để giao tiếp bằng Serial với module Sim800L. Vì module Sim800L chỉ có thể hoạt động ở mức điện áp từ 3.7V đến 4.2V do đó để cung cấp đúng mức điện áp cho module ta sử dụng pin 3.7V LiPo.

pin lipo
Hình 13. Pin 3.3V LiPo
Bảng 1. Bảng đấu nối
Số thứ tự Arduino Uno Module Sim800L

1

GND

GND

2

9

RX

3

10

TX

arduino sim800
Hình 14. Hình ảnh kết nối board Arduino Uno với Sim800L

Sau khi hoàn tất kết nối, ta cần lắp thẻ microSim vào khay sim của module.

4.5. Source Code và giải thích

#include <SoftwareSerial.h>         //Khai báo sử dụng thư viện SoftwareSerial

#define TX_PIN 9                    //Sử dụng chân số 9 làm TX
#define RX_PIN 10                   //Sử dụng chân số 10 làm

//Khởi tạo đối tượng serialSIM800 để giao tiếp Serial với sim800L
SoftwareSerial serialSIM800(RX_PIN, TX_PIN);

void setup() {
  //Khai báo sử dụng Serial để giao tiếp với máy tính thông qua Serial Monitor
  Serial.begin(9600);
  //Khai báo sử dụng serialSIM800 để giao tiếp với tốc độ baud là 9600
  serialSIM800.begin(9600);
  delay(1000);
  Serial.println("Setup Complete!");
  Serial.println("Sending SMS...");

  //Thiết lập định dạng tin nhắn là ASCII để có thể gửi tin nhắn dạng text
  serialSIM800.write("AT+CMGF=1\r\n");
  delay(1000);                      //Cứ mỗi lệnh AT ta cần có thời gian delay để Sim800 thực thi

  //Cài đặt số điện thoại muốn gửi tin nhắn đến, và nội dung tin nhắn
  serialSIM800.write("AT+CMGS=\"0162657XXXX\"\r\n");
  delay(1000);

  //Nội dung tin nhắn muốn gửi
  serialSIM800.write("Hello, this is IoT Maker UnoX");
  delay(1000);

  //Gửi kí tự có mã ASCII là 26 ($1A) để thông báo cho Sim800 là đã hoàn thành việc nhập nội dung tin nhắn
  serialSIM800.write((char)26);
  delay(1000);

  Serial.println("SMS Sent!");
}

void loop() {
}
Ta cần khai báo chính xác số điện thoại để Sim800 gửi đúng.

4.6. Kết quả

Kết quả ta sẽ nhận được tin nhắn có nội dung “Hello, this is Arduino Uno” sau vài giây từ khi board Arduino Uno khởi động.

4.7. Mở rộng

Qua ví dụ trên, chúng ta đã biết cách sử dụng thư viện SoftwareSerial để điều khiển module Sim800L gửi tin nhắn đến điện thoại di động, ngoài ra vẫn còn rất nhiều ứng dụng thú vị khác được sử dụng với Sim800L chẳng hạn như thực hiện cuộc gọi hay sử dụng dịch vụ GPRS,…​ Tuy nhiên đối với các ứng dụng phức tạp, để tiện cho sử dụng ta hay dùng thư viện đã module hóa các tác vụ thành các hàm phục vụ cho nhắn tin, gọi điện hay cập nhật dữ liệu qua GPRS,…​ nhưng nguyên lí chung vẫn là sử dụng tập lệnh AT để điều khiển Sim800L. Nếu nắm được bản chất này chúng ta hoàn toàn có thể sử dụng các module khác tương tự như GPS, ESP8266, bluetooth,…​ Chỉ cần tra cứu tập lệnh riêng của từng module là ta có thể áp dụng ngay chúng vào dự án.

Đối với thư viện SoftwareSerial, đây là một công cụ hữu ích giúp chúng ta có thể mở rộng để kết nối nhiều module hỗ trợ Serial với Arduino. Bạn đọc hoàn toàn có thể sử dụng thư viện này để giao tiếp 2 board Arduino như trong ví dụ thứ 3 mà không cần phải sử dụng Serial Hardware.

Tổng kết

Qua chương này, chúng ta đã cùng tìm hiểu về giao thức Serial cũng như những ứng dụng cơ bản xoay quanh chuẩn giao thức này, đó là tiền đề giúp chúng ta có thể xây dựng hệ thống, trong đó có nhiều thiết bị giao tiếp với nhau bằng Serial.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *