WIFI&蓝牙(ESP32)转CAN总线&串口TTL模块 - 接收和发送CAN数据并打印

发布时间 2023-07-13 19:32:59作者: 广源时代

<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)

 

6,点击下载

 

 

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

 

 

7,打开串口监视器

 

波特率选择115200

 

 

8,如果接收到数据串口会打印接到的数据

 

程序说明

#include <CAN.h>
/*设置CAN引脚*/
#define CanRxPin GPIO_NUM_16
#define CanTxPin GPIO_NUM_17
/*设置CAN 比特率 kbps*/
#define CanBitrate 250E3 //500E3, 250E3, 200E3, 125E3, 100E3, 80E3, 50E3, 40E3, 20E3, 10E3, 5E3

/*设置发送的数据*/
unsigned char can_send_packet[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};//标准帧数据
unsigned char can_send_extended_packet[8] = {0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18};//扩展帧数据

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println("CAN Sender");
  
  CAN.setPins(CanRxPin, CanTxPin);
  if (!CAN.begin(CanBitrate*2)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
  CAN.onReceive(onReceive);//注册CAN数据接收回调函数
}

void loop() {
  CAN.beginPacket(0x12);//设置标准帧ID
  CAN.write(can_send_packet, 8);//设置要发送的数据
  CAN.endPacket();//发送
  delay(1000);
  
  CAN.beginExtendedPacket(0xabcdef);//设置扩展帧ID
  CAN.write(can_send_extended_packet, 8);//设置要发送的数据
  CAN.endPacket();//发送
  delay(1000);
}

/*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:");
    while (CAN.available())//如果有可读的字节数
    {
      Serial.print(CAN.read(),HEX);//读取一个数据并打印(打印16进制数)
      Serial.print(" ");
    }
  }
  Serial.println();
}