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

Raspberry Pi4调用Iot.Device.MotorHat的CreateDCMotor报占空比异常

问题场景

在运行Debian-bullseye 11系统的Raspberry Pi 4设备上,使用Iot.Device.MotorHat库通过PCA9685电机Hat控制直流电机运行,实现代码如下:

public class DCMotorController : BaseClass
{
    public void StartMotor()
    {
        using (var motorHat = new MotorHat(1000d, 0x40))
        {
            var dcMotorOne = motorHat.CreateDCMotor(1); // 异常在此处抛出

            dcMotorOne.Speed = 1;
            Wait(1500);
            dcMotorOne.Speed = 0;
        }
    }
}

代码执行到CreateDCMotor方法调用时抛出未处理异常,异常堆栈信息如下:

Unhandled exception. System.InvalidOperationException: Unexpected value of duty cycle (9766, 10280)
   at Iot.Device.Pwm.Pca9685.<OnOffToDutyCycle>g__OnOffToDutyCycleSampled|16_0(UInt16 onCycles, UInt16 offCycles)
   at Iot.Device.Pwm.Pca9685.OnOffToDutyCycle(UInt16 on, UInt16 off)
   at Iot.Device.Pwm.Pca9685.GetDutyCycle(Int32 channel)
   at Iot.Device.Pwm.Pca9685PwmChannel.get_ActualDutyCycle()
   at Iot.Device.Pwm.Pca9685PwmChannel..ctor(Pca9685 parent, Int32 channel)
   at Iot.Device.Pwm.Pca9685.CreatePwmChannel(Int32 channel)
   at Iot.Device.MotorHat.MotorHat.CreateDCMotor(Int32 motorNumber)
   at projectV2.DCMotorController.StartMotor() in /home/pi/test/DCMotorController.cs:line 13
异常原因

这个报错是PCA9685芯片寄存器残留非法值导致的:

  • PCA9685每个PWM通道的ON/OFF计数寄存器是12位位宽,合法取值范围是0~4095,超过这个范围的数值都是无效值
  • 电机Hat如果上电时没有触发硬件复位,通道寄存器会保留上电随机数或者上次运行的残留数据,本次报错里读到的9766、10280都远大于4095的上限,属于典型的脏数据
  • 库的PCA9685驱动在创建PWM通道(也就是CreateDCMotor内部初始化通道的环节),会先读取当前通道的占空比做合法性校验,检测到超出范围的无效值就会抛出这个InvalidOperationException
  • 当前使用的库版本在初始化MotorHat实例时,默认不会主动重置所有通道寄存器,所以没法自动清掉这些脏数据。
修复方案

按优先级从高到低尝试以下操作即可解决:

  • 软复位(绝大多数场景直接生效):创建MotorHat实例后,先调用PCA9685的复位方法清空所有寄存器的脏数据,再创建电机对象,修改后的代码如下:
public void StartMotor()
{
    using (var motorHat = new MotorHat(1000d, 0x40))
    {
        // 对底层PCA9685芯片执行软复位,清除所有通道寄存器残留值
        motorHat.Pca9685.Reset();
        var dcMotorOne = motorHat.CreateDCMotor(1);

        dcMotorOne.Speed = 1;
        Wait(1500);
        dcMotorOne.Speed = 0;
    }
}

如果你当前安装的Iot.Device.Bindings版本找不到Reset()方法,直接把Nuget包升级到2.1.0及以上稳定版本即可。

  • 硬件复位:如果软复位无效,断开树莓派和电机Hat的所有供电(包括给电机单独供电的外接电源),等待30秒让板载电容余电完全放完再重新上电,芯片寄存器的随机脏数据会被自动清空。
  • 版本兼容修复:如果前两个操作都无效,检查项目引用的System.Device.Gpio和Iot.Device.Bindings版本,2.0以下的部分旧版本存在PCA9685初始化逻辑缺陷,升级到2.2.0以上稳定版本即可修复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:39:38