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ả

Xây dựng phong trào "Chia sẻ tình yêu với Arduino"

Với mong muốn cháy bỏng, đó là xây dựng được một cộng đồng Arduino Việt Nam, nơi mà ở đó, các bạn có thể học tập, trao đổi, chia sẻ mọi thứ từ kiến thức, module cho đến kinh phí làm dự án với tinh thần chia sẻ và quan tâm. Với tinh thần đó, hiện nay, Cộng đồng Arduino Việt Nam của chúng ta đã trở thành nơi duy nhất có uy tín trong cộng đồng Việt Nam, nơi quy tụ các bạn yêu thích Tự động hóa nói chung và Arduino nói riêng, cùng nhau chia sẻ những khối kiến thức được tích lũy qua quá trình học tập nghiên cứu. Trên tinh thần đó, hôm nay, chúng ta sẽ cùng nhau đi xa hơn với việc cùng nhau gây dựng phong trào chia sẻ module, chia sẻ tình yêu với Arduino. Hãy cùng đọc, cảm nhận và tham gia cùng chúng tôi nhé.

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

noTone()

Hàm này có nhiệm vụ kết thúc một sự kiện tone() trên một pin nào đó (đang chạy lệnh tone()). Nếu không có bất kỳ hàm tone() nào đang hoạt động thì hàm này sẽ không gây bất kỳ ảnh hưởng gì đến chương trình.

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