WIFI&蓝牙(ESP32)转CAN总线&串口TTL模块-A2-蓝牙和CAN总线透传通信(经典蓝牙主机)
<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总线接收的数据通过蓝牙发送给蓝牙从机;
测试
1,安装CAN支持库(如果已经安装了不需要安装)
主题选择通信,然后输入 CAN, 往下找到对应的库,然后点击安装
2,打开这节的工程(放到非中文目录打开)
里面有两个工程 BT_CAN_MASTER 这个工程是咱这节的工程
因为手头没有现成的蓝牙从机设备所以就准备了另一个设备, 烧录上 BT_CAN_SLAVE 工程作为模拟一台蓝牙从机设备
3,提示,如果用户有蓝牙设备,可以直接下载这节的工程连接自己的设备进行测试, 在下面修改为自己的设备的蓝牙名字.
4,我这边就用两个设备进行下载测试演示
5, 我这边的作为模拟从机设备的程序是这样子写的
5,下载完程序以后打开本节工程的串口监视器
蓝牙接收的数据也会转发到了CAN总线上
5,使用CAN测试仪发送数据给设备,模拟设备接收到CAN数据
点击发送以后会发现接着会收到数据;
实际上是设备接收到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; //定义一个蓝牙对象 #define BluetoothName "ESP32_SLAVE_BT" //要连接的蓝牙的名字 /*缓存CAN接收的数据*/ uint8_t CanRcvBuf[8]; uint8_t CanRcvBufCnt=0; /*缓存蓝牙接收的数据*/ uint8_t BtRcvBuf[100]; uint8_t BtRcvBufCnt=0; uint8_t BtConnectedFlag=0;//蓝牙连接状态 uint8_t BtConnectedFirst=0;//蓝牙是否第一次连接上 void setup() { pinMode(LEDPIN, OUTPUT); digitalWrite(LEDPIN, HIGH); Serial.begin(9600); /*BT*/ SerialBT.register_callback(Bluetooth_Event); //设置事件回调函数 连接 断开 发送 接收 // SerialBT.onData(RecvData); //注册接收回调函数 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(BtConnectedFirst==0) { Serial.println("Connected ....."); BtConnectedFirst = SerialBT.connect(BluetoothName); } /*根据蓝牙连接状态控制指示灯*/ if(BtConnectedFlag) { digitalWrite(LEDPIN, LOW); } else { digitalWrite(LEDPIN, HIGH); } } /*蓝牙事件回调函数*/ 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) //蓝牙连接 { BtConnectedFlag=1; Serial.println("Connected Success"); } else if(event == ESP_SPP_CLOSE_EVT)//蓝牙断开 { Serial.println("Connected Disconnect"); BtConnectedFlag=0; SerialBT.disconnect(); Serial.println("Connected ....."); SerialBT.connect(BluetoothName); } else if(event == ESP_SPP_DATA_IND_EVT) //数据接收标志 { BtRcvBufCnt=0; while(SerialBT.available()) { /*把数据拷贝到数组*/ BtRcvBuf[BtRcvBufCnt] = SerialBT.read(); /*日志打印*/ Serial.print(BtRcvBuf[BtRcvBufCnt],HEX);//读取一个数据并打印(打印16进制数) Serial.print(" "); BtRcvBufCnt++; } /*把蓝牙接收到的数据通过CAN总线输出*/ if(BtRcvBufCnt > 0 && BtRcvBufCnt<=8) { /*使用CAN总线发送*/ #if (CanExPacket==0) //使用标准帧 CAN.beginPacket(0x12);//设置标准帧ID CAN.write(BtRcvBuf, BtRcvBufCnt);//设置要发送的数据 CAN.endPacket();//发送 #else CAN.beginExtendedPacket(0xabcdef);//设置扩展帧ID CAN.write(BtRcvBuf, BtRcvBufCnt);//设置要发送的数据 CAN.endPacket();//发送 #endif } } else if(event == ESP_SPP_WRITE_EVT)//数据发送标志 { } Serial.println(); } /*CAN数据接收回调函数*/ void onReceive(int packetSize) { 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(); } /*蓝牙数据接收回调函数*/ //void RecvData(const uint8_t *buffer, size_t size) //{ // Serial.println("read"); // // if(size > 0 && size<=8) // { // /*使用CAN总线发送*/ // #if (CanExPacket==0) //使用标准帧 // CAN.beginPacket(0x12);//设置标准帧ID // CAN.write(buffer, size);//设置要发送的数据 // CAN.endPacket();//发送 // #else // CAN.beginExtendedPacket(0xabcdef);//设置扩展帧ID // CAN.write(buffer, size);//设置要发送的数据 // CAN.endPacket();//发送 // #endif // } //} //SerialBT.println("..");
1,CAN速率配置, 要连接的蓝牙的名字
2,蓝牙接收的数据通过CAN总线输出
3,CAN总线接收的数据通过蓝牙发送
.
.