Iot: Simplify DCMotor abstraction

Created on 30 Jul 2019  路  6Comments  路  Source: dotnet/iot

DCMotor is one of the devices we will declare as more stable for 3.0 and therefore it needs to be cleaned up to align with our guidelines better.

* This is a bit longer so let's expand it

DC Motor can be connected using 1, 2 or 3 pins:

1 pin mode

One of the motor pins is connected to ground and other pin is PWM which controls the speed. Motor can move only in one direction

2 pin mode

One pin is PWM (similarly as in 1 pin mode) and controls the speed.
Second pin is either 0/1 depending on direction (when 1 then PWM duty cycle is negated since polarity is swapped).

1/2 pin modes can be used to connect small (!) motor directly to microcontroller (although it is always recommended to use H-bridge).

3 pin mode (or the most correct way)

DC motor has 2 pins but H-bridge which should be used to control the motor.
2 pins of H-bridge map almost directly to output pins (except voltage is higher on High state) and third pin is used as "Enable" which is meant for connecting PWM (using it in 2 pin mode might cause a bit more heat to be produced than enable pin)

This effectively makes it so that first two pins control direction (1/0 or 0/1) and PWM controls the speed.

Design issue

Above setup is causing a bit of design pain as the abstraction is really awkward.

Current state

DCMotorSettings represents how things are connected:

  • Pin1, Pin2 tells if and how pins are connected
  • PwmChannel tells how to control the speed
  • UseEnableAsPwm tells if PWM is connected to Enable pin

drawback of that is that valid settings are not clear (and also it's confusing what the options actually mean)

Proposed state

No DCMotorSettings.

(names might be a bit awkward but not sure how to call them better)

class DCMotor
{
  // note that names of pin cannot be any better since the direction is arbitrary depending on how motor got connected
  public static DCMotor Create1Pin(PwmChannel pwmChannel);
  public static DCMotor Create2Pin(PwmChannel pwmChannel, int pin);

  // these could be called directionPin1, directionPin2 but then it would be inconsistent with above
  public static DCMotor Create3Pin(PwmChannel enablePinPwmChannel, int pin1, int pin2);
  // other option is to perhaps drop suffixes and just leave Create

  // options to control DC Motor truncated from here
}

any opinions? cc: @bartonjs

area-device-bindings enhancement

Most helpful comment

If I understand the intent of the abstraction, three pin is controlling both sides of the H-bridge and using the enable pin as overall drive control, so (pwmChannel, directionPin, otherDirectionPin). The direction pins are set opposite for when driving. The enable pin / pwmChannel is pulsed to control motor speed.

All 6 comments

I would recommend just naming all of them Create (with appropriate <summary> descriptions distinguishing the overloads).

I assume that the extra pins are for some sort of VREF, which I'd then call int referencePin (or referencePinNumber) and in the 3-pin variety I'd call it referencePin1, referencePin2. But maybe there's some other fancier name for their purpose.

@garath I assume you've wired many DC motors have to microcontrollers. Do your circuits have names for the non-PWM pins?

Usually the purpose of everything is static, so a multifunction pin would be named for whatever it was to be used for. So, ENABLE, DIRECTION, PWM, etc.

For the two-pin type, pin could be named direction, couldn't it? The actual direction is arbitrary but it still controls direction. Then there would be no disconnect with the three-pin type and those could also get the more descriptive name.

If two-pin is (pwmChannel, directionPin) what's three-pin? (pwmChannel, directionPin, enablePin)? (I seriously have no idea, but you said they could get "the more descriptive name" :smile:)

If I understand the intent of the abstraction, three pin is controlling both sides of the H-bridge and using the enable pin as overall drive control, so (pwmChannel, directionPin, otherDirectionPin). The direction pins are set opposite for when driving. The enable pin / pwmChannel is pulsed to control motor speed.

@garath presumably would calling pin directionPin for 2/1 pin mode be also fine? (or not confusing) - I was leaning toward similar name when talked with @bartonjs in the morning.

NVM, didn't notice your previous response

Certainly make a clear note in the documentation what the states are and how the implementation will use the pins. In my experience that will have the most impact in resolving any ambiguity, especially when hardware gets involved.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PRIMETSS picture PRIMETSS  路  3Comments

krwq picture krwq  路  3Comments

ZhangGaoxing picture ZhangGaoxing  路  3Comments

Tragetaschen picture Tragetaschen  路  5Comments

MarkCiliaVincenti picture MarkCiliaVincenti  路  6Comments