為什么選擇CanBus?
CAN-BUS是一種常見(jiàn)的工業(yè)總線,因?yàn)樗男谐叹嚯x長(zhǎng),通訊速度中等可靠性。它常見(jiàn)于現(xiàn)代機(jī)床上,例如汽車(chē)診斷總線。
在本教程中,我將使用SeedStudio CanBus模塊。它與SPI接口配合使用,并且添加了OBD-II轉(zhuǎn)換器電纜并導(dǎo)入了OBD-II庫(kù),您可以構(gòu)建板載診斷設(shè)備或數(shù)據(jù)記錄器。
硬件概述
Arduino Uno R3
CanBus模塊

DB9接口
V_OBD
終端 - CanH,CanL
Arduino Uno Pinout
串行槽連接器
I2C槽連接器
ICSP引腳
收發(fā)
結(jié)果
可以總線消息
讓我向您解釋一下CanBus消息。每條消息都包含一個(gè)ID和一些數(shù)據(jù)。 Id的起始位置為0x000,十六進(jìn)制為0x7FF或十進(jìn)制為0至2047.
每條消息的數(shù)據(jù)可以是1到8個(gè)字節(jié), 每個(gè)字節(jié)的值可以是0到255之間的值。
CAN總線可以以高達(dá)1 Mbit/s的幾種不同速度運(yùn)行。典型速率為100 kbit/s,125 kbit/s和500 kbit/s。較慢的速率允許更長(zhǎng)的總線。 總線上的所有設(shè)備必須以相同的速度傳輸。
Arduino代碼
讓我們開(kāi)始編寫(xiě)代碼。我將簡(jiǎn)單地將一個(gè)電位計(jì)數(shù)據(jù)和按鈕數(shù)據(jù)發(fā)送到CanBus模塊上的另一個(gè)Arduino。確保你使用一個(gè)Arduino作為主(發(fā)件人)而另一個(gè)作為奴隸(接收者)。

你應(yīng)該從這里下載CanBus庫(kù)。
現(xiàn)在我們開(kāi)始編寫(xiě) 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模塊的 庫(kù)。 “const int SPI_CS_PIN = 10;”MCP_CAN CAN(SPI_CS_PIN);“ 代碼用于初始化模塊。最后我們添加變量。 potPin,potValue,cantxValue 整數(shù)用于讀取和發(fā)送電位計(jì)值和 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!”);
}
在設(shè)置功能中,我們啟動(dòng)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ì)值和按鈕值。我已經(jīng)提到消息值應(yīng)該在0到255之間。如你所知,potensiometer值可能在0 - 1025之間。因此我們將potensiometer值從0-1025映射到0-255,代碼為“cantxValue = map(potValue,0,1025,0,255);“。
我們是串行打印值,以檢查everthing工作正常。然后我們創(chuàng)建一個(gè)數(shù)據(jù)包來(lái)發(fā)送Slaver(Receiver)。數(shù)據(jù)包可以是8個(gè)字節(jié),但我們只使用2個(gè)字節(jié)。
創(chuàng)建數(shù)據(jù)包后,我們將它傳遞給Slaver。 “CAN.sendMsgBuf(0x07B,0,8,canMsg);”命令有4個(gè)參數(shù),我在代碼中解釋過(guò)。
多數(shù),我們將數(shù)據(jù)發(fā)送給Slaver。你可以在和看到完整的代碼。
現(xiàn)在,讓我們來(lái)吧寫(xiě) Slaver(接收器)代碼 來(lái)讀取我們的數(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;
再次,我們正在添加必要的庫(kù)。我們創(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”);
}
我們?cè)俅螜z查模塊是否正常工作。
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ù),我們會(huì)讀取發(fā)送方CanBus ID,并將緩沖區(qū)分配給要在函數(shù)中使用的變量。然后我們串行打印值以檢查它們是否正確。
-
編程
+關(guān)注
關(guān)注
90文章
3707瀏覽量
96709 -
CANBUS
+關(guān)注
關(guān)注
2文章
33瀏覽量
19006 -
Arduino
+關(guān)注
關(guān)注
190文章
6514瀏覽量
195855
發(fā)布評(píng)論請(qǐng)先 登錄
UART發(fā)送數(shù)據(jù)后,接收端未收到數(shù)據(jù),原因有哪些?
UART接口數(shù)據(jù)線接收和發(fā)送數(shù)據(jù)
請(qǐng)問(wèn)rt_thread的uart下如何支持9位數(shù)據(jù)的發(fā)送和接收?
變頻器CANBUS網(wǎng)絡(luò)通訊異常深度解析
移植CANfestival,發(fā)現(xiàn)can無(wú)法接收數(shù)據(jù),為什么?
如何確定PSoC? Creator 中綁定數(shù)據(jù)的行/位置?
磁致伸縮位移傳感器CANbus數(shù)字輸出
2.4GHZ 發(fā)送/接收 ZIGBEE RFEIC,帶分集開(kāi)關(guān) skyworksinc
CYUSB3014數(shù)據(jù)接收異常的原因?
為UART、MCXA142實(shí)現(xiàn)ISP通信的主機(jī)端,發(fā)送Ping數(shù)據(jù)包并收到預(yù)期的響應(yīng),發(fā)送和接收數(shù)據(jù)包的典型順序是什么?
STM32F427串口接收和發(fā)送中斷同時(shí)使能,為什么會(huì)出現(xiàn)接收中斷丟數(shù)的情況?
RL-TCPNet UDP通信,板子能接收網(wǎng)絡(luò)調(diào)試助手數(shù)據(jù),不能發(fā)送數(shù)據(jù)到網(wǎng)絡(luò)調(diào)試助手
RL-TCPNet UDP通信,板子能接收網(wǎng)絡(luò)調(diào)試助手數(shù)據(jù),不能發(fā)送數(shù)據(jù)到網(wǎng)絡(luò)調(diào)試助手!?。。?/a>
使用TSS721過(guò)程中,只能接收數(shù)據(jù)不能發(fā)送數(shù)據(jù)怎么解決?
Air780E模組LuatOS開(kāi)發(fā)實(shí)戰(zhàn) —— 手把手教你搞定數(shù)據(jù)打包解包

如何使用CanBus發(fā)送和接收特定數(shù)據(jù)
評(píng)論