WIFI&蓝牙(ESP32)转CAN总线&串口TTL模块-A2-蓝牙和CAN总线透传通信(经典蓝牙主机)

发布时间 2023-07-28 15:26:42作者: 广源时代

<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("..");

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.