WIFI&蓝牙(ESP32)转CAN总线&串口TTL模块-A1-蓝牙和CAN总线透传(经典蓝牙从机)

发布时间 2023-07-28 01:17:26作者: 广源时代

<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESP32_CAN" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

 

 

 

 

 

 

 

 

 

 

 

实现的功能说明

设备作为经典蓝牙从机, 使用蓝牙调试助手作为蓝牙主机;

蓝牙调试助手和经典蓝牙设备配对并连接,然后通过蓝牙发送数据给设备,设备接收到数据通过CAN总线发送;

设备从CAN总线接收的数据通过蓝牙发送给蓝牙调试助手;

 

测试

1,安装CAN支持库(如果已经安装了不需要安装)

 

主题选择通信,然后输入 CAN, 往下找到对应的库,然后点击安装

 

2,打开这节的工程(放到非中文目录打开)

 

3,使用Type-C数据线连接上设备

 

4,选择设备对应的端口号(根据自己的选择)

 

5,当前设置的CAN速率为250K, 设备蓝牙的名字为 ESP32_SLAVE_BT

 

 

6,点击下载

 

 

7,连接CAN设备(我使用的CAN数据测试仪)

 

 

8,打开手机蓝牙页面, 点击连接配对设备的蓝牙

 

9,安装手机蓝牙调试助手APP

 

10,点击这个(这边这个是测试经典蓝牙)

 

 

11,点击

 

 

 

12,蓝牙调试助手通过蓝牙发送数据给设备

把16进制数据 01 01 02 03 04 通过蓝牙发送给设备

 

可以在CAN 总线上接收到数据, 说明设备把蓝牙接收的数据转发到了CAN

 

 

13,使用CAN测试仪, 通过CAN总线发送数据给设备

 

 

 

可以在手机蓝牙APP上接收到数据, 说明设备把CAN接收的数据转发到了蓝牙上

 

程序说明

程序都有注释,只说下注意的地方

CAN总线最多一次传8字节数据,所以这里做了限制

 

 

#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;

void setup() {
  pinMode(LEDPIN, OUTPUT);
  Serial.begin(9600);
  /*BT*/
  SerialBT.onData(RecvData);   //注册接收回调函数
  SerialBT.begin("ESP32_SLAVE_BT");  //蓝牙的名字

  /*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(SerialBT.hasClient())//蓝牙处于连接中
  {
    digitalWrite(LEDPIN, LOW);
  }
  else
  {
    digitalWrite(LEDPIN, HIGH);
  }
}


/*蓝牙数据接收回调函数*/
void RecvData(const uint8_t *buffer, size_t size)
{
  if(size > 0 && size<=8)
  {
    Serial.write(buffer, size);  //打印出来
    /*使用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
  }
}


/*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.hasClient())//蓝牙处于连接中
    {
      SerialBT.write((const uint8_t*)CanRcvBuf, packetSize);//发送数据
    }
  }
  /*日志打印*/
  Serial.println();
}

//SerialBT.println("..");

 

 

 

 

 

 

 

 

 

 

.