為什么選擇CanBus?
CAN-BUS是一種常見的工業(yè)總線,因為它的行程距離長,通訊速度中等可靠性。它常見于現(xiàn)代機床上,例如汽車診斷總線。
在本教程中,我將使用SeedStudio CanBus模塊。它與SPI接口配合使用,并且添加了OBD-II轉換器電纜并導入了OBD-II庫,您可以構建板載診斷設備或數(shù)據(jù)記錄器。
硬件概述
Arduino Uno R3
CanBus模塊
DB9接口
V_OBD
終端 - CanH,CanL
Arduino Uno Pinout
串行槽連接器
I2C槽連接器
ICSP引腳
收發(fā)
結果
可以總線消息
讓我向您解釋一下CanBus消息。每條消息都包含一個ID和一些數(shù)據(jù)。 Id的起始位置為0x000,十六進制為0x7FF或十進制為0至2047.
每條消息的數(shù)據(jù)可以是1到8個字節(jié), 每個字節(jié)的值可以是0到255之間的值。
CAN總線可以以高達1 Mbit/s的幾種不同速度運行。典型速率為100 kbit/s,125 kbit/s和500 kbit/s。較慢的速率允許更長的總線。 總線上的所有設備必須以相同的速度傳輸。
Arduino代碼
讓我們開始編寫代碼。我將簡單地將一個電位計數(shù)據(jù)和按鈕數(shù)據(jù)發(fā)送到CanBus模塊上的另一個Arduino。確保你使用一個Arduino作為主(發(fā)件人)而另一個作為奴隸(接收者)。
你應該從這里下載CanBus庫。
現(xiàn)在我們開始編寫 Master (發(fā)件人) 代碼。
//Canbus Send Data (MASTER)
#include
#include
#include
const int SPI_CS_PIN = 10;
MCP_CAN CAN(SPI_CS_PIN);
int potPin = A0;
int btnPin = 8;
int potValue = 0;
int cantxValue = 0;
int btnValue = 0;
我們包括 和用于Canbus模塊的 庫。 “const int SPI_CS_PIN = 10;”MCP_CAN CAN(SPI_CS_PIN);“ 代碼用于初始化模塊。最后我們添加變量。 potPin,potValue,cantxValue 整數(shù)用于讀取和發(fā)送電位計值和 btnPin,btnValue 整數(shù)用于讀取和發(fā)送按鈕值
void setup()
{
Serial.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS)) // baudrate 500kbps
{
Serial.println(“CAN BUS Shield init fail”);
Serial.println(“Init CAN BUS Shield again”);
delay(100);
}
Serial.println(“CAN BUS Initialisation Succesful!”);
}
在設置功能中,我們啟動Serial Comminication并檢查模塊是否正常工作。
void loop()
{
potValue = analogRead(potPin);
btnValue = digitalRead(btnPin);
cantxValue = map(potValue,0,1025,0,255);
Serial.print(“cantxValue: ”);
Serial.println(cantxValue);
Serial.print(“btnValue: ”);
Serial.println(btnValue);
//Create CanBus data pack
unsigned char canMsg[8] = {cantxValue, btnValue, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//Send Data Construction: id = 0x07B --- standart Flame --- data lenght = 8 ---- stmp:data buf
CAN.sendMsgBuf(0x07B, 0, 8, canMsg);
delay(100);
}
在循環(huán)功能中,我們讀取了電位計值和按鈕值。我已經(jīng)提到消息值應該在0到255之間。如你所知,potensiometer值可能在0 - 1025之間。因此我們將potensiometer值從0-1025映射到0-255,代碼為“cantxValue = map(potValue,0,1025,0,255);“。
我們是串行打印值,以檢查everthing工作正常。然后我們創(chuàng)建一個數(shù)據(jù)包來發(fā)送Slaver(Receiver)。數(shù)據(jù)包可以是8個字節(jié),但我們只使用2個字節(jié)。
創(chuàng)建數(shù)據(jù)包后,我們將它傳遞給Slaver。 “CAN.sendMsgBuf(0x07B,0,8,canMsg);”命令有4個參數(shù),我在代碼中解釋過。
多數(shù),我們將數(shù)據(jù)發(fā)送給Slaver。你可以在和看到完整的代碼。
現(xiàn)在,讓我們來吧寫 Slaver(接收器)代碼 來讀取我們的數(shù)據(jù)。
// CAN-BUS Receive Data
#include “mcp_can.h”
#include
#include
#define INT8U unsigned char
const int SPI_CS_PIN = 10;
MCP_CAN CAN(SPI_CS_PIN);
INT8U len = 0;
INT8U buf[8];
unsigned char canId;
char str[20];
int btnvalue;
int potvalue;
再次,我們正在添加必要的庫。我們創(chuàng)建變量以協(xié)助收到數(shù)據(jù)。
void setup()
{
Serial.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS)) // canbus baudrate 500kbps
{
Serial.println(“CAN BUS Shield init fail!??!”);
Serial.println(“Init CAN BUS Shield again.。.”);
delay(100);
}
Serial.println(“CAN BUS Initialisation Succesful”);
}
我們再次檢查模塊是否正常工作。
void loop()
{
while (CAN_MSGAVAIL == CAN.checkReceive())
{
CAN.readMsgBuf(&len, buf);
canId = CAN.getCanId();
potvalue = buf[0];
btnvalue = buf[1];
}
Serial.print(“ Potensiometer Value : ”);
Serial.print(potvalue);
Serial.print(“ Button Value : ”);
Serial.println(btnvalue);
}
}
在循環(huán)函數(shù)中,我們檢查是否有任何帶代碼的消息“while(CAN_MSGAVAIL == CAN.checkReceive())”如果有任何接收數(shù)據(jù),我們會讀取發(fā)送方CanBus ID,并將緩沖區(qū)分配給要在函數(shù)中使用的變量。然后我們串行打印值以檢查它們是否正確。
-
編程
+關注
關注
88文章
3614瀏覽量
93686 -
CANBUS
+關注
關注
2文章
31瀏覽量
18431 -
Arduino
+關注
關注
188文章
6468瀏覽量
186958
發(fā)布評論請先 登錄
相關推薦
評論