ESP32-S3与达妙DM-J4310-2EC的CAN FD通信示范

ESP32-S3与达妙DM-J4310-2EC的CAN FD通信示范 

⚠️ 重要说明

ESP32-S3的TWAI模块原生不支持CAN FD,仅支持经典CAN(CAN 2.0,最高1Mbps)。达妙DM-J4310-2EC电机同时支持CAN FD和经典CAN,因此有两种方案:

方案说明推荐度
方案A ESP32-S3 + 外置CAN FD控制器(如MCP2518FD) ⭐⭐⭐⭐ 支持完整CAN FD
方案B ESP32-S3原生TWAI + 经典CAN模式(1Mbps) ⭐⭐⭐⭐⭐ 简单实用

📋 方案B:ESP32-S3原生TWAI经典CAN通信(推荐入门)

1. 硬件连接

ESP32-S3          CAN收发器(TJA1050/ISO1050)     达妙DM-J4310-2EC
─────────         ──────────────────────         ─────────────────
GPIO17 (TX)  ───→ TX                            CAN_H ───────────┐
GPIO18 (RX)  ←─── RX                            CAN_L ───────────┤
3.3V         ───→ VCC                           GND   ───────────┼──→ 共地
GND          ───→ GNC                           24V/48V ─────────┘ (电机电源独立)

2. ESP-IDF 代码示例

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/twai.h"
#include "esp_log.h"

#define TAG "CAN_DAMIAO"

// TWAI引脚配置 (ESP32-S3)
#define TX_GPIO_NUM     17
#define RX_GPIO_NUM     18

// 达妙电机CAN配置
#define DAMIAO_CAN_BAUDRATE     1000000  // 1Mbps
#define MOTOR_ID                1        // 电机ID(需通过调试工具设置)

// 达妙电机CAN报文ID定义
#define CMD_ENABLE_ID           (0x000 + MOTOR_ID)     // 使能命令
#define CMD_CONTROL_ID          (0x100 + MOTOR_ID)     // 控制命令
#define CMD_READ_ID             (0x200 + MOTOR_ID)     // 读取命令
#define FEEDBACK_ID             (0x300 + MOTOR_ID)     // 反馈数据

// 达妙电机控制命令定义
#define CMD_ENABLE_MOTOR        0x0001
#define CMD_DISABLE_MOTOR       0x0000
#define CMD_MIT_MODE            0x0004  // MIT控制模式

// MIT控制数据结构 (8字节)
typedef struct {
    int16_t position_cmd;    // 位置指令 (单位: 0.01°)
    int16_t velocity_cmd;    // 速度指令 (单位: 0.01°/s)
    int16_t torque_cmd;      // 转矩指令 (单位: 0.01Nm)
    int16_t kp;              // 位置刚度系数
    int16_t kd;              // 速度阻尼系数
} mit_control_t;

// 反馈数据结构
typedef struct {
    int16_t position;        // 实际位置
    int16_t velocity;        // 实际速度
    int16_t torque;          // 实际转矩
    int16_t temperature;     // 电机温度
} motor_feedback_t;

// 初始化TWAI驱动
esp_err_t twai_init(void)
{
    // 通用配置
    twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_GPIO_NUM, RX_GPIO_NUM, TWAI_MODE_NORMAL);
    
    // 时序配置 (1Mbps)
    twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS();
    
    // 过滤器配置 (接收所有消息)
    twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
    
    // 安装驱动
    ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config));
    ESP_LOGI(TAG, "TWAI驱动安装成功");
    
    // 启动驱动
    ESP_ERROR_CHECK(twai_start());
    ESP_LOGI(TAG, "TWAI驱动已启动");
    
    return ESP_OK;
}

// 发送CAN消息
esp_err_t can_send(uint32_t id, uint8_t *data, uint8_t len)
{
    twai_message_t message;
    message.identifier = id;
    message.data_length_code = len;
    message.extd = 0;  // 标准帧
    message.rtr = 0;   // 数据帧
    memcpy(message.data, data, len);
    
    esp_err_t ret = twai_transmit(&message, pdMS_TO_TICKS(100));
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "发送失败: %s", esp_err_to_name(ret));
    }
    return ret;
}

// 接收CAN消息
esp_err_t can_receive(twai_message_t *message, TickType_t ticks_to_wait)
{
    return twai_receive(message, ticks_to_wait);
}

// 电机使能
void motor_enable(void)
{
    uint8_t data[8] = {0};
    data[0] = CMD_ENABLE_MOTOR & 0xFF;
    data[1] = (CMD_ENABLE_MOTOR >> 8) & 0xFF;
    can_send(CMD_ENABLE_ID, data, 8);
    ESP_LOGI(TAG, "发送电机使能命令");
}

// 电机禁用
void motor_disable(void)
{
    uint8_t data[8] = {0};
    data[0] = CMD_DISABLE_MOTOR & 0xFF;
    data[1] = (CMD_DISABLE_MOTOR >> 8) & 0xFF;
    can_send(CMD_ENABLE_ID, data, 8);
    ESP_LOGI(TAG, "发送电机禁用命令");
}

// MIT模式控制
void motor_mit_control(int16_t pos, int16_t vel, int16_t tor, int16_t kp, int16_t kd)
{
    uint8_t data[8] = {0};
    data[0] = pos & 0xFF;
    data[1] = (pos >> 8) & 0xFF;
    data[2] = vel & 0xFF;
    data[3] = (vel >> 8) & 0xFF;
    data[4] = tor & 0xFF;
    data[5] = (tor >> 8) & 0xFF;
    data[6] = kp & 0xFF;
    data[7] = (kp >> 8) & 0xFF;
    
    can_send(CMD_CONTROL_ID, data, 8);
}

// 读取电机反馈
void motor_read_feedback(void)
{
    uint8_t data[8] = {0};
    can_send(CMD_READ_ID, data, 8);
}

// 解析反馈数据
void parse_feedback(twai_message_t *msg, motor_feedback_t *fb)
{
    if (msg->identifier == FEEDBACK_ID && msg->data_length_code >= 8) {
        fb->position = msg->data[0] | (msg->data[1] << 8);
        fb->velocity = msg->data[2] | (msg->data[3] << 8);
        fb->torque = msg->data[4] | (msg->data[5] << 8);
        fb->temperature = msg->data[6] | (msg->data[7] << 8);
        
        ESP_LOGI(TAG, "反馈: 位置=%d, 速度=%d, 转矩=%d, 温度=%d",
                 fb->position, fb->velocity, fb->torque, fb->temperature);
    }
}

// 接收任务
void can_receive_task(void *pvParameters)
{
    twai_message_t message;
    motor_feedback_t feedback;
    
    while (1) {
        if (can_receive(&message, pdMS_TO_TICKS(100)) == ESP_OK) {
            parse_feedback(&message, &feedback);
        }
    }
}

// 主应用
void app_main(void)
{
    ESP_LOGI(TAG, "达妙电机CAN通信示例启动");
    
    // 初始化TWAI
    twai_init();
    
    // 创建接收任务
    xTaskCreate(can_receive_task, "can_rx", 4096, NULL, 5, NULL);
    
    // 延时等待
    vTaskDelay(pdMS_TO_TICKS(500));
    
    // 使能电机
    motor_enable();
    vTaskDelay(pdMS_TO_TICKS(100));
    
    // MIT模式控制循环
    while (1) {
        // 位置控制:移动到90度 (9000 = 90.00°)
        motor_mit_control(9000, 0, 0, 100, 50);
        vTaskDelay(pdMS_TO_TICKS(1000));
        
        // 位置控制:移动到0度
        motor_mit_control(0, 0, 0, 100, 50);
        vTaskDelay(pdMS_TO_TICKS(1000));
        
        // 读取反馈
        motor_read_feedback();
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}

3. CMakeLists.txt 配置

cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(damiao_can_motor)

4. menuconfig 配置

Component config → TWAI → 
    ✓ Enable TWAI driver
    ✓ TWAI Alert Enabled
    ✓ TWAI ISR in IRAM

🔧 方案A:外置CAN FD控制器(如需CAN FD高速通信)

硬件连接

ESP32-S3          MCP2518FD           达妙DM-J4310-2EC
─────────         ──────────          ─────────────────
GPIO10 (SCK)  ─→ SCK
GPIO11 (MOSI) ─→ SI
GPIO12 (MISO) ←→ SO
GPIO13 (CS)   ─→ CS
GPIO14 (INT)  ←→ INT
3.3V          ─→ VCC
GND           ─→ GND
                                  CAN_H/L ───────────→ 电机

使用SPI CAN FD库(如ESP-IDF的SPI + MCP2518FD驱动)


📊 达妙电机通信协议摘要

功能CAN ID数据格式说明
使能/禁用 0x000+ID uint16命令+填充 0x0001使能, 0x0000禁用
MIT控制 0x100+ID 位置/速度/转矩/Kp/Kd 各2字节,有符号
位置模式 0x100+ID 目标位置+速度+加速度 -
速度模式 0x100+ID 目标速度+加速度 -
读取反馈 0x200+ID 请求命令 -
反馈数据 0x300+ID 位置/速度/转矩/温度 自动上报或请求后

⚙️ 电机配置步骤

  1. 使用达妙调试工具设置电机ID(1-127)
  2. 设置CAN波特率:经典CAN设为1Mbps
  3. 设置控制模式:MIT/位置/速度
  4. 下载固件到ESP32-S3
  5. 连接CAN总线,确保共地
  6. 测试通信

🔍 常见问题排查

问题可能原因解决方案
无响应 电机ID不匹配 使用调试工具确认ID
通信错误 波特率不一致 确认电机设为1Mbps
数据异常 字节序错误 达妙使用小端序
总线错误 终端电阻缺失 CAN总线两端加120Ω电阻
TWAI错误 引脚配置错误 确认TX/RX引脚正确

如需完整项目代码,可访问达妙官方Gitee仓库获取参考例程。

posted @ 2026-02-24 12:39  txwtech  阅读(3)  评论(0)    收藏  举报