You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32+MCP2515读取Netgain Hyper9 CAN总线word及位掩码求助

ESPHome读取Netgain Hyper9电机CAN数据的修正方案

核心错误说明

原有代码存在两个核心逻辑错误:

  • 2字节小端序WORD解析错误:将字节转为十进制字符串拼接的方式完全不符合数值组合规则,会得到完全错误的结果
  • 系统标志位解析错误:标志位是16位位图,每个比特位独立对应一个状态,可能同时触发多个状态,不能用switch判断整数值

修正后的完整配置

canbus:
  - platform: mcp2515
    id: my_mcp2515
    spi_id: McpSpi
    cs_pin: GPIO14
    can_id: 2
    use_extended_id: false
    bit_rate: 250KBPS
    clock: 8MHZ
    mode: NORMAL
    on_frame:
    - can_id: 0x301 #[canbus:066]: received can message std can_id=0x301 size=8
      use_extended_id: false
      then:
      - lambda: |-
            // 电池SOC,原有逻辑正常
            int soc = x[2];
            id(motor_battery_soc).publish_state(soc);

            // RPM解析:小端序2字节拼16位整数,x[0]是低字节,x[1]是高字节
            uint16_t rpm = (static_cast<uint16_t>(x[1]) << 8) | x[0];
            id(motor_rpm).publish_state(rpm);

            // 系统标志位解析:先拼16位掩码
            uint16_t flag_mask = (static_cast<uint16_t>(x[4]) << 8) | x[3];
            std::vector<std::string> active_flags;
            // 逐位判断标志是否触发,位序号从0到15对应给出的16个状态
            if (flag_mask & (1 << 0)) active_flags.push_back("牵引电池SOC过低");
            if (flag_mask & (1 << 1)) active_flags.push_back("液压系统SOC过低");
            if (flag_mask & (1 << 2)) active_flags.push_back("倒车档激活");
            if (flag_mask & (1 << 3)) active_flags.push_back("前进档激活");
            if (flag_mask & (1 << 4)) active_flags.push_back("驻车制动激活");
            if (flag_mask & (1 << 5)) active_flags.push_back("踏板制动激活");
            if (flag_mask & (1 << 6)) active_flags.push_back("控制器过热");
            if (flag_mask & (1 << 7)) active_flags.push_back("钥匙开关过压");
            if (flag_mask & (1 << 8)) active_flags.push_back("钥匙开关欠压");
            if (flag_mask & (1 << 9)) active_flags.push_back("车辆运行中");
            if (flag_mask & (1 << 10)) active_flags.push_back("牵引系统已启用");
            if (flag_mask & (1 << 11)) active_flags.push_back("液压系统已启用");
            if (flag_mask & (1 << 12)) active_flags.push_back("供电已启用");
            if (flag_mask & (1 << 13)) active_flags.push_back("供电就绪");
            if (flag_mask & (1 << 14)) active_flags.push_back("预充电中");
            if (flag_mask & (1 << 15)) active_flags.push_back("主接触器闭合中");

            std::string flag_output;
            if (active_flags.empty()) {
              flag_output = "无系统告警";
            } else {
              // 多个激活的标志用顿号拼接
              for (size_t i = 0; i < active_flags.size(); i++) {
                if (i > 0) flag_output += "、";
                flag_output += active_flags[i];
              }
            }
            id(motor_system_flags).publish_state(flag_output);

            // 故障码,原有逻辑正常
            int fault_code = x[5];
            id(motor_fault_code).publish_state(fault_code);
            
            // 电机温度,原有逻辑正常
            int temp = x[6] - 40;
            id(motor_temp).publish_state(temp);


text_sensor:
  - platform: template
    id: motor_system_flags
    name: "电机系统标志"

sensor:
  - platform: template
    id: motor_battery_soc
    name: "电机电池SOC"
    accuracy_decimals: 0
  - platform: template
    id: motor_fault_code
    name: "电机故障码"
  - platform: template
    id: motor_temp
    name: "电机温度"
    accuracy_decimals: 0
  # 原RPM是数值,修改为sensor类型,不再用文本传感器
  - platform: template
    id: motor_rpm
    name: "电机转速"
    accuracy_decimals: 0

修改点说明

  • 将RPM从文本传感器改为数值传感器,用位运算直接拼接16位小端序整数,得到正确的转速数值
  • 系统标志位改为逐位判断的位图解析逻辑,支持同时显示多个激活的状态
  • 保留原有正常工作的SOC、故障码、温度解析逻辑

内容的提问来源于stack exchange,提问作者Dennis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 15:15:03