Giao tiếp giữa hai mạch Arduino bất kỳ

Giới thiệu, nội dung cần nắm

Giao tiếp giữa mạch Arduino là rất quan trọng, vì có nhiều dự án phức tạp và việc lập trình trên 1 Arduino là điều không thể. Hôm nay, mình sẽ hướng dẫn bạn cách giao tiếp giữa 2 mạch Arduino bất kỳ bằng việc sử dụng thư viện Serial Command.

Phần cứng

Thư viện

Chúng ta sẽ sử dụng thư viện Serial Command để xây dựng các "câu lệnh" (command). Bạn download thư viện ấy tại đây. Sau đó bạn tạo thư mục mang tên "Serial Command" tại thư mục <thư mục cài đặt arduino>\libraries. Sau đó bạn giải nén file thư viện vừa rồi vào thư mục vừa tạo là ok! Cuối cùng bạn tắt Arduino IDE rồi mở lại Arduino IDE.

Hoặc đối với Arduino IDE 1.6.x, chúng ta có thể thêm thư viện bằng cách như hình dưới. Sau đó chọn file zip đã download ở trên là ok.

 

Lắp mạch

Click vào ảnh để xem rõ hơn nhé

Giải thích và lập trình

Ở đây, tớ có ý định dùng Arduino UNO (HOST) gửi lệnh đến Arduino Nano (CLIENT) để điều khiển các đèn LED (thiết bị ngoại vi). Bạn cần hiểu rằng, định nghĩa HOST và CLIENT là do mình tự đặt, vì vậy bạn hoàn toàn có thể dùng Arduino Nano để điều khiển Arduino UNO hoặc tốt hơn nữa là biến nó thành 2 Server trong một "mạng kín" (nghĩa là 2 con này sẽ tự tương tác lẫn nhau, mỗi con vừa là HOST vừa là SLAVE cùng một lúc).

Bạn upload đoạn code sau vào HOST.

void setup() {
  Serial.begin(9600);// Bạn khởi tạo một cổng Serial tại baudrate 9600. Ở Client, bạn cũng phải mở một cổng Serial cùng Baudrate với HOST
}

int Step = 0;

void loop() {
  if (Step == 0) {
    Serial.println("LED_RED 1"); // Đèn đỏ sáng. 1 == HIGH
  } else if (Step == 1) {
    Serial.println("LED_RED 0"); // Đèn đỏ tắt . 0 == LOW
  } else if (Step == 2) {
    Serial.println("LED_BLUE 1");// Đèn xanh sáng
  } else if (Step == 3) {
    Serial.println("LED_BLUE 0");// Đèn xanh tắt
  }
  
  Step = (Step + 1) % 4; //Step sẽ tuần tự tuần hoàn các giá trị trong khoảng từ 0 --> 3
  
  delay(1000);// Dừng một giây giữa các lần gửi
}

Bạn upload đoạn code sau vào CLIENT


#include <SerialCommand.h> // Thêm vào sketch thư viện Serial Command

SerialCommand sCmd; // Khai báo biến sử dụng thư viện Serial Command

int red = 2, blue = 3;

void setup() {
  //Khởi tạo Serial ở baudrate 9600 (trùng với HOST)
  Serial.begin(9600);
  
  //pinMode 2 đèn LED là OUTPUT
  pinMode(red,OUTPUT);
  pinMode(blue,OUTPUT);
  
  
  // Một số hàm trong thư viện Serial Command
  
  sCmd.addCommand("LED_RED",   led_red);  // Khi có câu lệnh tên là LED_RED sẽ chạy hàm led_red
  sCmd.addCommand("LED_BLUE",   led_blue);
  
}

void loop() {
  sCmd.readSerial();
  //Bạn không cần phải thêm bất kỳ dòng code nào trong hàm loop này cả
}

// hàm led_red sẽ được thực thi khi gửi hàm LED_RED
void led_red() {
  //Đoạn code này dùng để đọc TỪNG tham số. Các tham số mặc định có kiểu dữ liệu là "chuỗi"
  char *arg;
  arg = sCmd.next();
  
  int value = atoi(arg); // Chuyển chuỗi thành số
  digitalWrite(red,value);
}

// hàm led_blue sẽ được thực thi khi gửi hàm LED_BLUE
void led_blue() { 
  //Đoạn code này dùng để đọc TỪNG tham số. Các tham số mặc định có kiểu dữ liệu là "chuỗi"
  char *arg;
  arg = sCmd.next();
  
  int value = atoi(arg); // Chuyển chuỗi thành số
  digitalWrite(blue,value);
}

Sau khi upload 2 đoạn code này thì cứ sau mỗi một giây thì đèn đỏ sáng rồi tắt tiếp đến là đèn xanh. Tại sao như vậy?

Bởi vì cứ sau mỗi một giây thì HOST lại gửi lệnh đến CLIENT. Và tùy thuộc vào câu lệnh CLIENT sẽ chuyển hướng đến các hàm khác nhau. Vậy như thế nào là lệnh và cách đọc tham số của mỗi lệnh là như thế nào?

  1. Lệnh là gì?

    • Lệnh là một chuỗi gồm có các thành phần sau:
      • Từ đầu tiên được gọi là tên câu lệnh (command name).
      • Các từ sau đó được gọi là tham số.
      • Một lệnh buộc phải có tên câu lệnh
      • Một lệnh có thể có một hoặc nhiều hoặc không có tham số.
    • Ở trong đoạn code mà tớ upload lên mạch HOST, tớ đã tự xây dựng 2 lệnh:
      • LED_RED <tham số 1>
        • LED_RED là tên câu lệnh
        • <tham số 1> là trạng thái sẽ truyền cho led đỏ (sáng - 1 hoặc tắt - 0)
      • LED_BLUE <tham số 1>
        • LED_BLUE là tên câu lệnh
        • <tham số 1> là trạng thái sẽ truyền cho led xanh (sáng - 1 hoặc tắt - 0)
    • Các lệnh thực chất chỉ là một chuỗi được kết thúc bởi ký tự xuống dòng (\n) (nếu bạn dùng hàm Serial.println() thì không cần quan tâm đến ký tự này. Nhưng nếu dùng hàm Serial.print() thì bạn cần thêm một ký tự \n ở cuối mỗi câu lệnh. Ví dụ:
      • Serial.print("LED_RED 1\n");
        
  2. Làm sao để đọc được lệnh từ HOST ở CLIENT?

    • Bạn đã sử dụng thư viện Serial Command cho việc này, vì vậy bạn không cần phải tốn thời gian nghiên cứu việc này. Mình sẽ giải thích câu hỏi này một cách cặn cẽ hơn ở một bài sau trong chuyên mục "Chương trình mẫu > Level: Advanced - Nâng cao".
  3. Làm thế nào để đọc các tham số trong một lệnh ở CLIENT

    • Cực kỳ đơn giản, bạn chỉ cần dùng đoạn code trong hàm led_red() hoặc led_green() để tiến đọc. Mình khuyên bạn chỉ nên gửi các tham số là số nguyên để dễ dàng cho việc xử lý, không nên gửi các tham số là chuỗi, vì bạn cần chuyển sang kiểu String để dùng các phép so sánh, điều này là không nên. Còn nếu muốn gửi một câu ra một màn hình LCD (chẳng hạn) thì bạn phải tự phát triển thêm một tí xíu nữa cho việc đọc tham số. Mình sẽ viết ở mục bình luận. 

Kết luận

Hãy sáng tạo với mô hình HOST --> CLIENT và bạn sẽ thấy rất thú vị đấy. Trong tương lai, mình sẽ hướng dẫn các bạn dùng máy tính để giao tiếp với Arduino (vấn đề này khá là nâng cao nên bạn có thể sẽ đợi khá lâu từ bài viết này đấy, nhưng mình hứa sẽ có smiley).

Nào, bạn hãy thử chế một mô hình HOST / CLIENT <--> CLIENT / HOST xem nào, không khó đâu!

Chúc bạn vui vẻ và thành công!

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

Select any filter and click on Apply to see results

Các bài viết cùng tác giả

analogRead()

Nhiệm vụ của analogRead() là đọc giá trị điện áp từ một chân Analog. Trên mạch Arduino UNO có 6 chân Analog In, được kí hiệu từ A0 đến A5. Trên các mạch khác cũng có những chân tương tự như vậy với tiền tố "A" đứng đầu, sau đó là số hiệu của chân.

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