Hotline/Zalo: 0919.890.938 (Mr Hơn)
Bài 6. Tìm hiểu về giao tiếp uart trên esp8266 nodemcu
Giao tiếp UART (Universal Asynchronous Receiver/Transmitter) là một chuẩn giao tiếp dùng để truyền và nhận dữ liệu mà đa số hầu hết các loại vi điều khiển đều hỗ trợ, trong đó có ESP8266. Trong bài viết này, Điện thông minh E-smart sẽ cùng bạn tìm hiểu cách sử dụng giao tiếp UART trên ESP8266.
UART hoạt động thế nào?
Giao thức UART sử dụng hai dây cho bên nhận và bên truyền. Theo định nghĩa, UART là một giao thức truyền thông phần cứng dùng giao tiếp nối tiếp bất đồng bộ và có thể cấu hình được tốc độ truyền nhận.
Khi truyền dữ liệu qua UART, dữ liệu được chia thành các khung (frame) và mỗi khung bao gồm các bit start, các bit dữ liệu và các bit stop. Các bit start và stop được sử dụng để đồng bộ hóa quá trình truyền thông giữa các thiết bị. Số lượng bit dữ liệu trong một khung truyền phụ thuộc vào cấu hình của UART.
Bên truyền dữ liệu
Khi bên truyền muốn gửi một khung dữ liệu, nó sẽ đưa tín hiệu trên đường truyền từ mức cao xuống mức thấp để báo hiệu cho bên nhận biết rằng một khung dữ liệu sắp được gửi đi. Sau đó, nó sẽ gửi các bit dữ liệu theo thứ tự từ bit thấp đến bit cao. Khi gửi xong các bit dữ liệu, nó sẽ đưa tín hiệu trên đường truyền từ mức thấp lên mức cao để báo hiệu cho bên nhận biết rằng khung dữ liệu đã được gửi xong.
Bên nhận dữ liệu
Bên nhận sẽ đợi cho tín hiệu start xuất hiện trên đường truyền và sau đó bắt đầu nhận các bit dữ liệu theo thứ tự từ bit thấp đến bit cao. Khi nhận xong các bit dữ liệu, nó sẽ kiểm tra tín hiệu stop để xác định rằng khung dữ liệu đã được nhận xong.
Cách dùng giao tiếp UART trên ESP8266
NodeMCU ESP8266 có hai bộ giao tiếp UART là UART0 và UART1 trong đó UART0 (là 2 chân Rx và Tx) dùng cho quá trình nạp chương trình cũng như giao tiếp UART trực tiếp với máy tính thông qua chíp CP2102/ CH340, UART1 (là 2 chân GPIO2 và GPIO8) trong đó GPIO8 được kết nối với chíp Flash do vậy khi dùng UART1 chúng ta chỉ có thể truyền dữ liệu qua chân GPIO2.
Hardware Serial
Khi dùng Hardware Serial chúng ta có thể giao tiếp UART với ESP8266 NodeMCU trực tiếp qua hai chân Rx và Tx. Cần đảm bảo ngắt kết nối với 2 chân Rx và Tx khi nạp chương trình vì Arduino IDE sẽ nạp chương trình cho ESP8266 NodeMCU qua 2 chân này.
Đây là ví dụ code mẫu chương trình giao tiếp UART giữa máy tính và kít ESP8266 NodeMCU để điều khiển ON/OFF LED bằng cách gửi ký tự 0/1 từ Arduino IDE xuống ESP8266
// Khai báo chân kết nối với led
#define LED_PIN 2 // D4
void setup() {
// Khởi tạo Serial0 để giao tiếp với máy tính và Serial Monitor
Serial.begin(9600);
// Khởi tạo chân led là output
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// Nếu có dữ liệu từ Serial Monitor, gửi và hiển thị nó
if (Serial.available()) {
char c = Serial.read();
Serial.write(c);
// Nếu dữ liệu là '0', tắt led
if (c == '0') {
digitalWrite(LED_PIN, HIGH);
}
// Nếu dữ liệu là '1', bật led
if (c == '1') {
digitalWrite(LED_PIN, LOW);
}
}
}
Software Serial
Ngoài cách giao tiếp UART trực tiếp qua 2 chân Rx và Tx, chúng ta có thể sử dụng thư viện ESPSoftwareSerial để tạo một giao tiếp UART mềm. Nghĩa là chúng ta có thể định nghĩa 2 chân GPIO bất kỳ trên ESP8266 để làm chức năng tương tự cho 2 chân Rx và Tx.
Trong phần này mình sẽ thiết lập giao tiếp UART trên ESP8266 với Arduino UNO R3 qua thư viện ESPSoftwareSerial để điều khiển led trên Arduino UNO R3 ON/OFF bằng cách truyền ký tự 0/1.
Code nạp cho Nodemcu esp8266
#include <SoftwareSerial.h>
// Khai báo các chân RX và TX cho espsoftwareserial
#define RX_PIN 4 // D2
#define TX_PIN 5 // D1
// Tạo một đối tượng espsoftwareserial với tốc độ baud là 9600
SoftwareSerial mySerial(RX_PIN, TX_PIN);
void setup() {
// Khởi tạo cổng nối tiếp phần cứng với tốc độ baud là 115200
Serial.begin(115200);
// Khởi tạo cổng nối tiếp phần mềm với tốc độ baud là 9600
mySerial.begin(9600);
// In ra thông báo khởi động
Serial.println("ESP8266 UART Communication Example");
}
void loop() {
// Nếu có dữ liệu từ cổng nối tiếp cứng, gửi nó sang cổng nối tiếp mềm
if (Serial.available()) {
char c = Serial.read();
mySerial.write(c);
}
// Nếu có dữ liệu từ cổng nối tiếp mềm, gửi nó sang cổng nối tiếp cứng
if (mySerial.available()) {
char c = mySerial.read();
Serial.write(c);
}
}
Trong phần code này chúng ta sử dụng 2 loại giao tiếp UART: 1 là giao tiếp UART giữa ESP8266 với máy tính (sử dụng Hardware Serial), 2 là giao tiếp UART giữa ESP8266 với Arduino Uno (sử dụng Software Serial).
Để nạp được code này vào ESP8266 bạn cần cài đặt thêm thư viện ESPSoftwareSerial vào Arduino IDE.
Code nạp cho Arduino Uno
#include <SoftwareSerial.h> // Thư viện cho cổng nối tiếp mềm
#define RX_PIN 10 // Chân RX của cổng nối tiếp mềm
#define TX_PIN 11 // Chân TX của cổng nối tiếp mềm
#define LED_PIN 13 // Chân kết nối với led
SoftwareSerial mySerial(RX_PIN, TX_PIN); // Tạo một đối tượng cổng nối tiếp mềm
void setup() {
Serial.begin(9600); // Khởi tạo cổng nối tiếp cứng với tốc độ baud là 9600
mySerial.begin(9600); // Khởi tạo cổng nối tiếp mềm với tốc độ baud là 9600
pinMode(LED_PIN, OUTPUT); // Đặt chân kết nối với led là chân đầu ra
}
void loop() {
if (mySerial.available()) { // Nếu có dữ liệu từ cổng nối tiếp mềm
char c = mySerial.read(); // Đọc ký tự điều khiển
mySerial.println(c); // In ra ký tự điều khiển qua cổng nối tiếp mềm
Serial.println(c); // In ra ký tự điều khiển qua cổng nối tiếp cứng
if (c == '0') { // Nếu ký tự là '0'
// Bật led
digitalWrite(LED_PIN, HIGH);
Serial.println("LED is on"); // In trạng thái led qua cổng nối tiếp cứng
}
else if (c == '1') { // Nếu ký tự là 'f'
// Tắt led
digitalWrite(LED_PIN, LOW);
Serial.println("LED is off"); // In trạng thái led qua cổng nối tiếp cứng
}
else { // Nếu ký tự khác
// Không làm gì
Serial.println("Invalid command"); // In báo lỗi qua cổng nối tiếp cứng
}
}
}
Nguyên lý hoạt động của ví dụ này là từ máy tính ta truyền ký tự 0/1 xuống ESP8266, khi ESP8266 nhận được ký tự từ máy tính thì sẽ truyền sang Arduino Uno R3 qua giao tiếp UART mềm (Software Serial), khi Arduino Uno R3 nhận được ký tự ‘0’ thì Bật led tại chân 13, nhận ký tự ‘1’ thì Tắt led.
Kết luận
Qua bài viết này chúng ta đã tìm hiểu cơ bản về cách dùng giao tiếp UART trên ESP8266 NodeMCU. Tuy nhiên, để có thể truyền thông tin và tách thông tin từ chuỗi truyền chúng ta cần áp dụng thêm một số thủ thuật truyền nội dung theo một quy chuẩn nhất định. Khi cần truyền nhiều giá trị từ MCU1 đến MCU2 phải quy định cách đóng khung dữ liệu giữa bên truyền và bên nhận. Trong bài sau mình sẽ hướng dẫn các bạn cách truyền nhiều dữ liệu qua UART giữa hai vi xử lý.