- Giới thiệu về CAN
- So sánh CAN so với SPI & I2C
- Ứng dụng giao thức CAN
- Cách sử dụng giao thức CAN trong Arduino
- Thành phần bắt buộc
- Sơ đồ mạch
- Kết nối giữa hai mô-đun MCP2515 CAN
- Lập trình Arduino cho giao tiếp CAN
- Giải thích mã phía máy phát CAN (Arduino Nano)
- Giải thích mã phía máy thu CÓ THỂ (Arduino UNO)
- Hoạt động của giao tiếp CAN trong Arduino
Ngày nay, bất kỳ ô tô trung bình nào cũng có khoảng 60 đến 100 đơn vị cảm biến trong đó để cảm nhận và trao đổi thông tin. Với việc các nhà sản xuất ô tô không ngừng làm cho chiếc xe của họ thông minh hơn với các tính năng như lái xe tự động, hệ thống túi khí, giám sát áp suất lốp, hệ thống kiểm soát hành trình, v.v. con số này dự kiến sẽ còn tăng cao. Không giống như các cảm biến khác, các cảm biến này xử lý thông tin quan trọng và do đó dữ liệu từ các cảm biến này phải được giao tiếp bằng các giao thức truyền thông ô tô tiêu chuẩn. Ví dụ, dữ liệu hệ thống kiểm soát hành trình như tốc độ, vị trí bướm ga, v.v. là các giá trị quan trọng được gửi đến Bộ điều khiển điện tử (ECU)để quyết định mức độ tăng tốc của ô tô, thông tin sai lệch hoặc mất dữ liệu ở đây có thể dẫn đến những hỏng hóc nghiêm trọng. Do đó, không giống như các giao thức truyền thông tiêu chuẩn như UART, SPI hoặc I2C, các nhà thiết kế sử dụng các giao thức giao tiếp trên ô tô đáng tin cậy như LIN, CAN, FlexRay, v.v.
Trong số tất cả các giao thức có sẵn, CAN được sử dụng nhiều hơn và phổ biến hơn. Chúng ta đã thảo luận về CAN là gì và CAN hoạt động như thế nào. Vì vậy, trong bài viết này chúng ta sẽ xem xét lại những điều cơ bản và cuối cùng chúng ta cũng sẽ trao đổi dữ liệu giữa hai Arduinos bằng cách sử dụng giao tiếp CAN. Nghe thật thú vị phải không! Vậy hãy bắt đầu.
Giới thiệu về CAN
CAN hay còn gọi là Mạng vùng điều khiển là một bus truyền thông nối tiếp được thiết kế cho các ứng dụng công nghiệp và ô tô. Nó là một giao thức dựa trên tin nhắn được sử dụng để liên lạc giữa nhiều thiết bị. Khi nhiều thiết bị CAN được kết nối với nhau như hình dưới đây, kết nối tạo thành một mạng hoạt động giống như hệ thống thần kinh trung ương của chúng ta cho phép bất kỳ thiết bị nào nói chuyện với bất kỳ thiết bị nào khác trong nút.
Một CAN Mạng sẽ chỉ gồm hai dây CAN cao và có thể thấp để truyền dữ liệu hai chiều như trình bày ở trên. Thông thường, tốc độ truyền thông cho CAN nằm trong khoảng từ 50 Kbps đến 1Mbps và khoảng cách có thể từ 40 mét ở 1Mbps đến 1000 mét ở 50kpbs.
Định dạng của Tin nhắn CAN:
Trong giao tiếp CAN, dữ liệu được truyền trong mạng dưới dạng một định dạng tin nhắn cụ thể. Định dạng thông báo này bao gồm nhiều phân đoạn nhưng hai phân đoạn chính là mã định danh và dữ liệu giúp gửi và trả lời các tin nhắn trong CAN bus.
Định danh hoặc CAN ID: Định danh còn được gọi là ID CAN hoặc còn được gọi là PGN (Số nhóm tham số). Nó được sử dụng để xác định các thiết bị CAN có trong mạng CAN. Độ dài của số nhận dạng là 11 hoặc 29 bit dựa trên loại giao thức CAN được sử dụng.
Chuẩn CAN: 0-2047 (11-bit)
CAN mở rộng: 0-2 29 -1 (29-bit)
Dữ liệu: Đây là dữ liệu cảm biến / điều khiển thực tế phải được gửi từ thiết bị này sang thiết bị khác. Dữ liệu kích thước có thể có độ dài từ 0 đến 8 byte.
Mã độ dài dữ liệu (DLC): 0 đến 8 cho số byte dữ liệu hiện có.
Dây được sử dụng trong CAN:
Giao thức CAN bao gồm hai dây là CAN_H và CAN_L để gửi và nhận thông tin. Cả hai dây hoạt động như một đường phân biệt, có nghĩa là tín hiệu CAN (0 hoặc 1) được biểu diễn bằng sự khác biệt tiềm năng giữa CAN_L và CAN_H. Nếu sự khác biệt là dương và lớn hơn một điện áp tối thiểu nhất định thì nó là 1 và nếu sự khác biệt là âm thì nó là 0.
Thông thường cáp xoắn đôi được sử dụng cho giao tiếp CAN. Một điện trở 120 ohm duy nhất thường được sử dụng ở hai đầu của mạng CAN như trong hình, điều này là do đường dây cần được cân bằng và gắn với cùng một điện thế.
So sánh CAN so với SPI & I2C
Vì chúng ta đã học cách sử dụng SPI với Arduino và IIC với Arduino, chúng ta hãy so sánh các tính năng của SPI và I2C với CAN
Tham số | SPI | I2C | CÓ THỂ |
Tốc độ | 3Mbps đến 10Mbps | Chuẩn: 100Kbps | 10KBps đến 1MBps Cũng phụ thuộc vào độ dài của dây được sử dụng |
Nhanh: 400 Kb / giây | |||
Tốc độ cao: 3,4Mbps | |||
Kiểu | Đồng bộ | Đồng bộ | Không đồng bộ |
Số lượng dây | 3+ (MISO, MOSI, SCK, SS1, SS2… SS (n)) | 2 dây (SDA, SCL) | 2 dây (CAN_H, CAN_L) |
Song công | Song công đầy đủ | Một nửa hai mặt | Một nửa hai mặt |
Ứng dụng giao thức CAN
- Do tính mạnh mẽ và độ tin cậy của giao thức CAN, chúng được sử dụng trong các ngành công nghiệp như Ô tô, Máy công nghiệp, Nông nghiệp, Thiết bị y tế, v.v.
- Vì độ phức tạp của hệ thống dây được giảm xuống ở CAN, chúng chủ yếu được sử dụng trong các ứng dụng ô tô như xe hơi.
- Chi phí thực hiện thấp và giá linh kiện phần cứng cũng thấp hơn.
- Dễ dàng thêm và loại bỏ các thiết bị bus CAN.
Cách sử dụng giao thức CAN trong Arduino
Vì Arduino không chứa bất kỳ cổng CAN tích hợp nào, nên một mô-đun CAN có tên MCP2515 được sử dụng. Mô-đun CAN này được giao tiếp với Arduino bằng cách sử dụng giao tiếp SPI. Hãy cùng xem chi tiết về MCP2515 và cách nó được giao tiếp với Arduino.
MCP2515 Mô-đun CAN:
Mô-đun MCP2515 có bộ điều khiển CAN MCP2515 là bộ thu phát CAN tốc độ cao. Kết nối giữa MCP2515 và MCU thông qua SPI. Vì vậy, có thể dễ dàng giao tiếp với bất kỳ vi điều khiển nào có giao diện SPI.
Đối với những người mới bắt đầu muốn học CAN Bus, mô-đun này sẽ hoạt động như một khởi đầu tốt. Bảng CAN SPI này lý tưởng cho tự động hóa công nghiệp, tự động hóa gia đình và các dự án nhúng ô tô khác.
Tính năng và đặc điểm kỹ thuật của MCP2515:
- Sử dụng bộ thu phát CAN tốc độ cao TJA1050
- Kích thước: 40 × 28mm
- Điều khiển SPI để mở rộng giao diện bus Multi CAN
- Bộ dao động tinh thể 8MHZ
- Điện trở đầu cuối 120Ω
- Có phím độc lập, chỉ báo LED, chỉ báo nguồn
- Hỗ trợ hoạt động CAN 1 Mb / s
- Hoạt động ở chế độ chờ hiện tại thấp
- Có thể kết nối tới 112 nút
Sơ đồ chân của Mô-đun MCP2515 CAN:
Tên ghim |
SỬ DỤNG |
VCC |
Chân đầu vào nguồn 5V |
GND |
Chốt nối đất |
CS |
Chân chọn SPI SLAVE (Hoạt động ở mức thấp) |
VÌ THẾ |
SPI chính đầu vào nô lệ đầu ra dẫn |
SI |
Đầu vào nô lệ đầu ra chính SPI |
SCLK |
Chân đồng hồ SPI |
INT |
Chân ngắt MCP2515 |
Trong hướng dẫn này, chúng ta hãy xem cách gửi dữ liệu cảm biến độ ẩm & nhiệt độ (DHT11) từ Arduino Nano đến Arduino Uno thông qua mô-đun bus CAN MCP2515.
Thành phần bắt buộc
- Arduino UNO
- Arduino NANO
- DHT11
- Màn hình LCD 16x2
- MCP2515 Mô-đun CAN - 2
- Chiết áp 10k
- Breadboard
- Kết nối dây
Sơ đồ mạch
Kết nối ở phía Máy phát CAN:
Thành phần - Pin |
Arduino Nano |
MPC2515 - VCC |
+ 5V |
MPC2515 - GND |
GND |
MPC2515 - CS |
D10 (SPI_SS) |
MPC2515 - SO |
D12 (SPI_MISO) |
MPC2515 - SI |
D11 (SPI_MOSI) |
MPC2515 - SCK |
D13 (SPI_SCK) |
MPC2515 - INT |
D2 |
DHT11 - VCC |
+ 5V |
DHT11 - GND |
GND |
DHT11 - HẾT |
A0 |
Kết nối mạch ở phía máy thu CAN:
Thành phần - Pin |
Arduino UNO |
MPC2515 - VCC |
+ 5V |
MPC2515 - GND |
GND |
MPC2515 - CS |
10 (SPI_SS) |
MPC2515 - SO |
12 (SPI_MISO) |
MPC2515 - SI |
11 (SPI_MOSI) |
MPC2515 - SCK |
13 (SPI_SCK) |
MPC2515 - INT |
2 |
LCD - VSS |
GND |
LCD - VDD |
+ 5V |
LCD - V0 |
Tới mã PIN của trung tâm chiết áp 10K |
LCD - RS |
3 |
LCD - RW |
GND |
LCD - E |
4 |
LCD - D4 |
5 |
LCD - D5 |
6 |
LCD - D6 |
7 |
LCD - D7 |
số 8 |
LCD - A |
+ 5V |
LCD - K |
GND |
Kết nối giữa hai mô-đun MCP2515 CAN
H - CÓ THỂ Cao
L - CÓ THỂ Thấp
MCP2515 (Arduino Nano) |
MCP2515 (Arduino UNO) |
H |
H |
L |
L |
Khi tất cả các kết nối đã được thực hiện, phần cứng của tôi trông như thế này bên dưới
Lập trình Arduino cho giao tiếp CAN
Đầu tiên chúng ta phải cài đặt một thư viện cho CAN trong Arduino IDE. Giao tiếp MCP2515 CAN Module với Arduino trở nên dễ dàng hơn bằng cách sử dụng thư viện sau.
- Tải xuống tệp ZIP của Thư viện Arduino CAN MCP2515.
- Từ Arduino IDE: Sketch -> Bao gồm Thư viện -> Thêm Thư viện.ZIP
Trong hướng dẫn này, mã hóa được chia thành hai phần một là mã bộ phát CAN (Arduino Nano) và phần khác là mã bộ thu CAN (Arduino UNO), cả hai đều có thể tìm thấy ở cuối trang này. Lời giải thích cho điều tương tự như sau.
Trước khi viết chương trình để gửi và nhận dữ liệu, hãy đảm bảo rằng bạn đã cài đặt thư viện theo các bước trên và mô-đun CAN MCP2515 được khởi tạo trong chương trình của bạn như sau.
Khởi tạo mô-đun CAN MCP2515:
Để tạo kết nối với MCP2515, hãy làm theo các bước:
1. Đặt số pin nơi SPI CS được kết nối (10 theo mặc định)
MCP2515 mcp2515 (10);
2. Đặt tốc độ truyền và tần số dao động
mcp2515.setBitrate (CAN_125KBPS, MCP_8MHZ);
Tỷ giá Baud có sẵn:
CAN_5KBPS, CAN_10KBPS, CAN_20KBPS, CAN_31K25BPS, CAN_33KBPS, CAN_40KBPS, CAN_50KBPS, CAN_80KBPS, CAN_83K3BPS, CAN_95KBPS, CAN_100KBPS, CAN_125_500KBPS, CAN_200KBPS, CAN_200KBPS, CAN_200KBPS, CAN_2_500KBPS, CAN_200KBPS, CAN_200KBPS.
Tốc độ Đồng hồ Có sẵn:
MCP_20MHZ, MCP_16MHZ, MCP_8MHZ
3. Đặt các chế độ.
mcp2515.setNormalMode (); mcp2515.setLoopbackMode (); mcp2515.setListenOnlyMode ();
Giải thích mã phía máy phát CAN (Arduino Nano)
Trong phần bộ phát, Arduino Nano đã giao tiếp với mô-đun MCP2515 CAN thông qua các chân SPI và DHT11 gửi dữ liệu Nhiệt độ và Độ ẩm đến bus CAN.
Đầu tiên bao gồm các thư viện bắt buộc, Thư viện SPI để sử dụng Giao tiếp SPI, Thư viện MCP2515 để sử dụng Giao tiếp CAN và Thư viện DHT để sử dụng cảm biến DHT với Arduino . Trước đây chúng tôi đã giao tiếp DHT11 với Arduino.
#include
Bây giờ tên chân của DHT11 (chân OUT) được kết nối với A0 của Arduino Nano được xác định
#define DHTPIN A0
Ngoài ra, DHTTYPE được định nghĩa là DHT11.
#define DHTTYPE DHT11
Một canMsg struct kiểu dữ liệu để lưu trữ định dạng tin nhắn CAN.
struct can_frame canMsg;
Đặt số pin nơi SPI CS được kết nối (10 theo mặc định)
MCP2515 mcp2515 (10);
Ngoài ra, đối tượng dht cho lớp DHT có chân DHT với Arduino Nano và kiểu DHT là DHT11 được khởi tạo.
DHT dht (DHTPIN, DHTTYPE);
Tiếp theo trong void setup ():
Bắt đầu giao tiếp SPI bằng cách sử dụng câu lệnh sau
SPI.begin ();
Và sau đó sử dụng câu lệnh dưới đây để bắt đầu nhận các giá trị Nhiệt độ và độ ẩm từ cảm biến DHT11.
dht.begin ();
Tiếp theo MCP2515 đang được ĐẶT LẠI bằng lệnh sau
mcp2515.reset ();
Bây giờ MCP2515 được đặt tốc độ 500KBPS và 8MHZ làm đồng hồ
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
Và MCP2525 được đặt ở chế độ bình thường
mcp2515.setNormalMode ();
Trong vòng lặp void ():
Câu lệnh sau nhận giá trị Độ ẩm và Nhiệt độ và lưu trữ trong một biến số nguyên h và t.
int h = dht.readHumidity (); int t = dht.readTempentic ();
Tiếp theo, CAN ID được đưa ra là 0x036 (Theo lựa chọn) và DLC là 8 và chúng tôi cung cấp dữ liệu h và t cho dữ liệu và dữ liệu và đặt tất cả dữ liệu bằng 0.
canMsg.can_id = 0x036; canMsg.can_dlc = 8; canMsg.data = h; // Cập nhật giá trị độ ẩm trong canMsg.data = t; // Cập nhật giá trị nhiệt độ trong canMsg.data = 0x00; // Khôi phục tất cả bằng 0 canMsg.data = 0x00; canMsg.data = 0x00; canMsg.data = 0x00; canMsg.data = 0x00; canMsg.data = 0x00;
Sau cùng, để gửi tin nhắn đến CAN BUS, chúng ta sử dụng câu lệnh sau.
mcp2515.sendMessage (& canMsg);
Vì vậy, bây giờ dữ liệu nhiệt độ và độ ẩm được gửi dưới dạng tin nhắn đến CAN bus.
Giải thích mã phía máy thu CÓ THỂ (Arduino UNO)
Trong phần đầu thu, Arduino UNO đã giao tiếp với MCP2515 và màn hình LCD 16x2. Tại đây Arduino UNO nhận Nhiệt độ và Độ ẩm từ bus CAN và hiển thị dữ liệu nhận được trên màn hình LCD.
Đầu tiên, các thư viện bắt buộc được bao gồm, Thư viện SPI để sử dụng Giao tiếp SPI, Thư viện MCP2515 để sử dụng Giao tiếp CAN và Thư viện LiquidCrsytal để sử dụng LCD 16x2 với Arduino .
#include
Tiếp theo, các chân LCD được sử dụng để kết nối với Arduino UNO được xác định.
const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8; LiquidCrystal lcd (rs, en, d4, d5, d6, d7);
Một kiểu dữ liệu struct được khai báo để lưu định dạng thông báo CAN.
struct can_frame canMsg;
Đặt số pin nơi SPI CS được kết nối (10 theo mặc định)
MCP2515 mcp2515 (10);
Trong thiết lập void ():
Đầu tiên, màn hình LCD được đặt ở chế độ 16x2 và một thông báo chào mừng được hiển thị.
lcd.begin (16,2); lcd.setCursor (0,0); lcd.print ("ĐOẠN MẠCH"); lcd.setCursor (0,1); lcd.print ("CÓ THỂ ARDUINO"); chậm trễ (3000); lcd.clear ();
Bắt đầu giao tiếp SPI bằng cách sử dụng câu lệnh sau.
SPI.begin ();
Tiếp theo MCP2515 đang được ĐẶT LẠI bằng lệnh sau.
mcp2515.reset ();
Bây giờ MCP2515 được đặt tốc độ 500KBPS và 8MHZ làm đồng hồ.
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
Và MCP2525 được đặt ở chế độ bình thường.
mcp2515.setNormalMode ();
Tiếp theo trong vòng lặp void ():
Câu lệnh sau được sử dụng để nhận thông báo từ CAN bus. Nếu tin nhắn được nhận, nó sẽ đi vào điều kiện if .
if (mcp2515.readMessage (& canMsg) == MCP2515:: ERROR_OK)
Trong điều kiện if , dữ liệu được nhận và lưu trữ trong c anMsg , dữ liệu có giá trị độ ẩm và dữ liệu có giá trị nhiệt độ. Cả hai giá trị được lưu trữ trong một số nguyên x và y.
int x = canMsg.data; int y = canMsg.data;
Sau khi nhận các giá trị, các giá trị nhiệt độ và độ ẩm được hiển thị trên màn hình LCD 16x2 bằng cách sử dụng câu lệnh sau.
lcd.setCursor (0,0); lcd.print ("Độ ẩm:"); lcd.print (x); lcd.setCursor (0,1); lcd.print ("Nhiệt độ:"); lcd.print (y); chậm trễ (1000); lcd.clear ();
Hoạt động của giao tiếp CAN trong Arduino
Khi phần cứng đã sẵn sàng, hãy tải lên chương trình cho bộ phát CAN và bộ thu CAN (các chương trình hoàn chỉnh được đưa ra bên dưới) trong các bảng Arduino tương ứng. Khi được cấp nguồn, bạn sẽ thấy giá trị nhiệt độ do DHT11 đọc được sẽ được gửi đến Arduino khác thông qua giao tiếp CAN và hiển thị trên màn hình LCD của Arduino thứ 2 như bạn có thể thấy trong hình dưới đây. Tôi cũng đã sử dụng điều khiển từ xa AC để kiểm tra xem nhiệt độ hiển thị trên màn hình LCD có gần với nhiệt độ phòng thực tế hay không.
Hoạt động hoàn chỉnh có thể được tìm thấy tại video được liên kết bên dưới. Nếu bạn có bất kỳ câu hỏi nào, hãy để lại chúng trong phần bình luận hoặc sử dụng diễn đàn của chúng tôi cho các câu hỏi kỹ thuật khác.