<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESP32_CAN" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
实现的功能说明
设备作为经典蓝牙主机, 然后连接蓝牙名字为 ESP32_SLAVE_BT 的从机设备;
设备连接上从机蓝牙之后, 把蓝牙接收到数据通过CAN总线输出;
设备从CAN总线接收的数据通过蓝牙发送给蓝牙从机;
程序说明(连接啥的没问题, 数据通信会重启...貌似中断嵌套了,稍后看看啥问题)
#include "BluetoothSerial.h" #include <esp_bt_device.h> #include <CAN.h> #define LEDPIN 5 //LED /*设置CAN引脚*/ #define CanRxPin GPIO_NUM_16 #define CanTxPin GPIO_NUM_17 /*设置CAN 比特率*/ #define CanBitrate 250E3 //500E3, 250E3, 200E3, 125E3, 100E3, 80E3, 50E3, 40E3, 20E3, 10E3, 5E3 #define CanExPacket 0 //0:标准帧 1:扩展帧 BluetoothSerial SerialBT; //定义一个蓝牙对象 uint8_t CanRcvBuf[8]; uint8_t CanRcvBufCnt=0; uint8_t BtRcvBuf[100]; uint8_t BtRcvBufCnt=0; uint8_t ConnectedFlag=1; void setup() { pinMode(LEDPIN, OUTPUT); Serial.begin(9600); /*BT*/ SerialBT.register_callback(Bluetooth_Event); //设置事件回调函数 连接 断开 发送 接收 SerialBT.begin("ESP32_MASTER_BT",true); //本机蓝牙的名字,设为主机 /*CAN*/ CAN.setPins(CanRxPin, CanTxPin); if (!CAN.begin(CanBitrate*2)) { Serial.println("Starting CAN failed!"); while (1); } CAN.onReceive(onReceive);//注册CAN数据接收回调函数 /*日志打印*/ Serial.println("start"); } void loop() { /*检测蓝牙连接状态,如果断开则自动重连*/ if(ConnectedFlag != SerialBT.connected()) { ConnectedFlag = SerialBT.connected(); if(ConnectedFlag) { Serial.println("Connected Success"); digitalWrite(LEDPIN, LOW); } else { digitalWrite(LEDPIN, HIGH); Serial.println("Connected......"); if(!SerialBT.connect("ESP32_SLAVE_BT")) { ConnectedFlag = 1-ConnectedFlag; Serial.println("Connected Fail"); SerialBT.disconnect(); } } } } void Bluetooth_Event(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) //蓝牙事件回调函数 { if(event == ESP_SPP_OPEN_EVT || event == ESP_SPP_SRV_OPEN_EVT) //蓝牙连接 { } else if(event == ESP_SPP_CLOSE_EVT)//蓝牙断开 { } else if(event == ESP_SPP_DATA_IND_EVT) //数据接收标志 { uint8_t len=0; BtRcvBufCnt=0; while(SerialBT.available()) { /*把数据拷贝到数组*/ BtRcvBuf[BtRcvBufCnt] = SerialBT.read(); /*日志打印*/ // Serial.print(BtRcvBuf[BtRcvBufCnt],HEX);//读取一个数据并打印(打印16进制数) // Serial.print(" "); BtRcvBufCnt++; } len = BtRcvBufCnt-1; /*把蓝牙接收到的数据通过CAN总线输出*/ if(len > 0 && len<=8) { // /*使用CAN总线发送*/ // #if (CanExPacket==0) //使用标准帧 // CAN.beginPacket(0x12);//设置标准帧ID // CAN.write(BtRcvBuf, len);//设置要发送的数据 // CAN.endPacket();//发送 // #else // CAN.beginExtendedPacket(0xabcdef);//设置扩展帧ID // CAN.write(BtRcvBuf, len);//设置要发送的数据 // CAN.endPacket();//发送 // #endif } } else if(event == ESP_SPP_WRITE_EVT)//数据发送标志 { // Serial.write(" send complete! \r\n"); } } /*CAN数据接收回调函数*/ void onReceive(int packetSize) { /*日志打印*/ // Serial.println("CAN Rceive:"); if (CAN.packetExtended())//接收的是扩展帧 { /*日志打印*/ // Serial.println("extended"); } if (CAN.packetRtr())//判断有没有RTR { /*日志打印*/ // Serial.println("RTR"); } /*获取ID*/ char id = CAN.packetId(); /*日志打印*/ // Serial.print("packet id 0x"); // Serial.print(id, HEX); // Serial.println(); if (CAN.packetRtr())//远程帧没有数据只打印数据长度 { /*日志打印*/ // Serial.print("requested length:"); // Serial.print(CAN.packetDlc());//打印DLC // Serial.println(); } else//打印数据 { /*日志打印*/ // Serial.print("data length:"); // Serial.print(packetSize); // Serial.println(); // Serial.print("data:"); CanRcvBufCnt=0; while (CAN.available())//如果有可读的字节数 { /*把Can数据拷贝到数组*/ CanRcvBuf[CanRcvBufCnt] = CAN.read(); /*日志打印*/ // Serial.print(CanRcvBuf[CanRcvBufCnt],HEX);//读取一个数据并打印(打印16进制数) // Serial.print(" "); CanRcvBufCnt++; } //把接收的CAN 数据通过蓝牙发送出去 if(SerialBT.connected())//蓝牙处于连接中 { SerialBT.write((const uint8_t*)CanRcvBuf, packetSize);//发送数据 } } /*日志打印*/ // Serial.println(); } //SerialBT.println("..");
.