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ả

Arduino Leonardo là gì ?

Chúng ta đã quá quen thuộc với các board mạch Arduino "truyền thống" như Arduino Uno R3, Nano hay phiên bản tối giản là Arduino Pro Mini. Nếu là một người tinh ý, các bạn sẽ dễ dàng nhận thấy board Arduino Leonardo có kích thước giốn với Arduino, pinout cũng tương tự luôn. Thật vậy, với một người yêu thích Arduino, bạn sẽ có một thắc mắc: Tại sao người ta lại làm ra mạch Arduino Leonardo, trong khi nó "khá giống" với Arduino Uno R3, chứ không muốn nói là giống "hệt", liệu nhà phát triển Arduino quá "rãnh"? Vâng, qua bài viết này, bạn sẽ hiểu được vì sao Arduino Leonardo lại ra đời, khi nào nên dùng nó, khi nào không và các thông số kĩ thuật cơ bản.

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

"Độ hoàn toàn" một cổng Terminal RS-232 mà không sử dụng jack 3.5mm

Ở Việt Nam, việc một bạn học sinh mua một mạch Intel Galileo khá là khó. Trong đó, khó nhất là tiền để mua một mạch Intel Galileo, tuy nhiên, khi mua được mạch về, việc bạn có sử dụng hết chức năng của Intel Galileo hay không là một việc khác. Cái hay nhất, theo tớ nghĩ trên Intel Galileo, mà Arduino không có và bạn khó tiếp cận nhất đó là hệ điều hành Linux. Thực sự thì có nhiều cách để vào Linux của Intel Galileo. Tuy nhiên, nếu bạn muốn cài một hệ điều hành xịn như Debian để biến Intel Galileo trở thành một "máy tính" siêu "xịn" thì bạn buộc phải dùng tới cổng RS - 232. Nếu ở các trung tâm công nghệ lớn thì bạn có thể dễ dàng tìm mua các cổng "RS-232 to DB9" để dễ dàng làm theo các bài hướng dẫn trước. Tuy nhiên, không phải ai cũng may mắn như vậy, trong bài viết này, chúng ta sẽ tiếp cận với một cách khác mà tớ đã sử dụng để giải quyết bài toán không có cáp "RS-232 to DB9".

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