未验证 提交 803d4ec7 编写于 作者: I Ian Bebbington 提交者: GitHub

Make MotorHat compatible with Waveshare Motor Driver Hat (#1764)

上级 62d161bf
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Iot.Device.MotorHat
{
/// <summary>
/// <see cref="MotorPinProvider"/> implementation for AdaFruit/Aliexpress
/// </summary>
/// <remarks>
/// These correspond to motor hat screw terminals M1, M2, M3 and M4.
/// </remarks>
public class AdafruitMotorPinProvider : IMotorPinProvider
{
/// <inheritdoc/>
public MotorPins GetPinsForMotor(int index)
{
return index switch
{
1 => new MotorPins(8, 9, 10),
2 => new MotorPins(13, 12, 11),
3 => new MotorPins(2, 3, 4),
4 => new MotorPins(7, 6, 5),
_ => throw new ArgumentException(nameof(index), $"MotorHat Motor must be between 1 and 4 inclusive. {nameof(index)}: {index}")
};
}
}
}
......@@ -19,6 +19,11 @@ namespace Iot.Device.MotorHat
/// </summary>
public const int I2cAddressBase = 0x60;
/// <summary>
/// The <see cref="IMotorPinProvider"/> to use
/// </summary>
private readonly IMotorPinProvider _pinProvider;
/// <summary>
/// Motor Hat is built on top of a PCa9685
/// </summary>
......@@ -40,9 +45,26 @@ namespace Iot.Device.MotorHat
/// Setting the frequency above or below this range will cause PWM hardware to be set at its maximum or minimum setting.
/// </remarks>
public MotorHat(I2cConnectionSettings settings, double frequency = 1600)
: this(settings, frequency, MotorPinProvider.Default)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MotorHat"/> class with the specified I2C settings and PWM frequency.
/// </summary>
/// <param name="settings">The I2C settings of the MotorHat.</param>
/// <param name="frequency">The frequency in Hz to set the PWM controller.</param>
/// <param name="pinProvider">The <see cref="IMotorPinProvider"/> that provides <see cref="MotorPins"/> for various hats.</param>
/// <remarks>
/// The default i2c address is 0x60, but the HAT can be configured in hardware to any address from 0x60 to 0x7f.
/// The PWM hardware used by this HAT is a PCA9685. It has a total possible frequency range of 24 to 1526 Hz.
/// Setting the frequency above or below this range will cause PWM hardware to be set at its maximum or minimum setting.
/// </remarks>
public MotorHat(I2cConnectionSettings settings, double frequency = 1600, IMotorPinProvider? pinProvider = default)
{
I2cDevice device = I2cDevice.Create(settings);
_pca9685 = new Pca9685(device);
_pinProvider = pinProvider ?? MotorPinProvider.Default;
_pca9685.PwmFrequency = frequency;
}
......@@ -71,49 +93,11 @@ namespace Iot.Device.MotorHat
/// </remarks>
public DCMotor.DCMotor CreateDCMotor(int motorNumber)
{
if (motorNumber < 1 || motorNumber > 4)
{
throw new ArgumentOutOfRangeException(nameof(motorNumber), $"Must be between 1 and 4, corresponding with M1, M2, M3 and M4. (Received: {motorNumber}");
}
// The PCA9685 PWM controller is used to control the inputs of two dual motor drivers.
// These correspond to motor hat screw terminals M1, M2, M3 and M4.
// Each motor driver circuit has one speed pin and two IN pins.
// The PWM pin expects a PWM input signal. The two IN pins expect a logic 0 or 1 input signal.
// The variables speed, in1 and in2 variables identify which PCA9685 PWM output pins will be used to drive this DCMotor.
// The speed variable identifies which PCA9685 output pin is used to drive the PWM input on the motor driver.
// And the in1 and in2 variables are used to specify which PCA9685 output pins are used to drive the xIN1 and xIN2 input pins of the motor driver.
int speedPin, in1Pin, in2Pin;
switch (motorNumber)
{
case 1:
speedPin = 8;
in2Pin = 9;
in1Pin = 10;
break;
case 2:
speedPin = 13;
in2Pin = 12;
in1Pin = 11;
break;
case 3:
speedPin = 2;
in2Pin = 3;
in1Pin = 4;
break;
case 4:
speedPin = 7;
in2Pin = 6;
in1Pin = 5;
break;
default:
throw new ArgumentException(nameof(motorNumber), $"MotorHat Motor must be between 1 and 4 inclusive. {nameof(motorNumber)}: {motorNumber}");
}
var motorPins = _pinProvider.GetPinsForMotor(motorNumber);
var speedPwm = _pca9685.CreatePwmChannel(speedPin);
var in1Pwm = _pca9685.CreatePwmChannel(in1Pin);
var in2Pwm = _pca9685.CreatePwmChannel(in2Pin);
var speedPwm = _pca9685.CreatePwmChannel(motorPins.SpeedPin);
var in1Pwm = _pca9685.CreatePwmChannel(motorPins.In1Pin);
var in2Pwm = _pca9685.CreatePwmChannel(motorPins.In2Pin);
_channelsUsed.Add(speedPwm);
_channelsUsed.Add(in1Pwm);
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Iot.Device.MotorHat
{
/// <summary>
/// Represents a provider for <see cref="MotorPins"/>
/// </summary>
public interface IMotorPinProvider
{
/// <summary>
/// Gets the <see cref="MotorPins"/> for motor at the specified <paramref name="index"/>
/// </summary>
/// <param name="index">The index of the motor to get pins for</param>
/// <returns></returns>
public abstract MotorPins GetPinsForMotor(int index);
}
/// <summary>
/// Static class providing known <see cref="IMotorPinProvider"/> instances
/// </summary>
public static class MotorPinProvider
{
/// <summary>
/// <see cref="IMotorPinProvider"/> for AdaFruit motor hat
/// </summary>
public static readonly IMotorPinProvider AdaFruit = new AdafruitMotorPinProvider();
/// <summary>
/// <see cref="IMotorPinProvider"/> for Aliexpress motor hat
/// </summary>
public static readonly IMotorPinProvider Aliexpress = AdaFruit;
/// <summary>
/// <see cref="IMotorPinProvider"/> for Waveshare motor hat
/// </summary>
public static readonly IMotorPinProvider Waveshare = new WaveshareMotorPinProvider();
/// <summary>
/// Default <see cref="IMotorPinProvider"/>
/// </summary>
public static readonly IMotorPinProvider Default = AdaFruit;
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Iot.Device.MotorHat
{
/// <summary>
/// Represents a Motor PinConfiguration
/// </summary>
/// <param name="SpeedPin">The pin controlling the speed of the motor</param>
/// <param name="In1Pin">The first pin for controlling direction</param>
/// <param name="In2Pin">The second pin for controlling direction</param>
/// <remarks>
/// The PCA9685 PWM controller is used to control the inputs of two dual motor drivers.
/// Each motor driver circuit has one speed pin and two IN pins.
/// The PWM pin expects a PWM input signal. The two IN pins expect a logic 0 or 1 input signal.
/// The variables SpeedPin, In1Pin and In2Pin variables identify which PCA9685 PWM output pins will be used to drive this DCMotor.
/// The speed variable identifies which PCA9685 output pin is used to drive the PWM input on the motor driver.
/// And the In1Pin and In2Pin are used to specify which PCA9685 output pins are used to drive the xIN1 and xIN2 input pins of the motor driver.
/// </remarks>
public record MotorPins(int SpeedPin, int In1Pin, int In2Pin);
}
......@@ -9,6 +9,7 @@ It also provides 4 extra PWM Outputs, that can be used for anything that require
- [Adafruit](https://www.adafruit.com/product/2348)
- [Aliexpress](http://s.click.aliexpress.com/e/mTB4ZB2s)
- [Waveshare](https://www.waveshare.com/wiki/Motor_Driver_HAT)
## Usage
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Iot.Device.MotorHat
{
/// <summary>
/// <see cref="MotorPinProvider"/> implementation for Waveshare
/// </summary>
/// <remarks>
/// These correspond to motor hat screw terminals M1 and M2
/// </remarks>
public class WaveshareMotorPinProvider : IMotorPinProvider
{
/// <inheritdoc/>
public MotorPins GetPinsForMotor(int index)
{
return index switch
{
1 => new MotorPins(0, 1, 2),
2 => new MotorPins(5, 4, 3),
_ => throw new ArgumentException(nameof(index), $"MotorHat Motor must be either 1 or 2. {nameof(index)}: {index}")
};
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册