Wednesday 6 January 2016

Droidbot #2 - DC Motor control

In this article I will describe the software & hardware driver for the DC motors.

Instead of configuring directly the uController registers, I've chosen to use the Texas Instruments API's from the TivaWare librare... a far more efficient and reliable methot.

So, the two motors are separately powered from the battery and the uController provides only the  "On/Off" signal for them.

On the hardware side, I chosen to use a dual motor driver from Pololu (more details in here).
On the left side, you have the interface with the uController and on the right side, with the battery and DC motors.

Motor driver interfaceAINx, BINx - PWM input from uC
GND - Ground connection - common, VIN - (+) terminal from battery
AOUTx, BOUTx - Analog outputs for the DC motors A and B
Lets name the two motors A and B.
To spin A in one direction, it's necessary to supply PWM signal to either AIN1 or AIN2. To spin it in the opposite direction, you need to supply PWM signal to the other AINx pin. The same is valid for motor B.
When one PWM signal is provided to spin in one direction, the other PWM signal should be disabled.
The rotation speed of the motors depend on the duty cycle of the PWM.
A few words about PWM:
  • PWM is a method of generating "analog" signal with a digital output
  • It's basically a square wave signal with a defined amplitude and frequency
  • the RPM is controlled by the % of high signal (50% duty cycle means high signal duration = low signal duration)


The connection between the uController and the motor driver is according to the following table:

Connection table
Now let's take a look to the SW side...

As you see in the above table, the motor driver is connected to PF2, PF3, PD0 and PD1 pins on the uController. You need to check the controllers data sheet for the details regarding the PWM configuration on this port (more details here).
On our project the PD0 and PD1 is connected to the PWM module 1 / generator 0; and the PF2 and PF3 is connected to PWM module 1 / generator 3. So this need to be configured.

In the SW code I have a few separate functions:

  • Initialize PWM output on PF2 and PF3 (forward motion) ->  void PWM_motor_init(unsigned long PWM_Period)
  • Set duty cycle on PF2 and PF3 -> void PWM_right_motor_duty_cycle(unsigned long PWM_duty_cycle) and void PWM_left_motor_duty_cycle(unsigned long PWM_duty_cycle)
  • Initialize PWM output on PD0 and PD1 (backward motion) -> void PWM_motor_reverse_init(unsigned long PWM_Period, unsigned short PWM_duty_cycle)
  • Disable PWM output on PD0 and PD1 -> void PWM_motor_reverse_stop(void)

This functions you can find in my GIT repository... over HERE :)
Igonore the other functions from this file for the moment.

A few thing that require more attention:

  • PWM pwripherial and GPIO port need to be clocked
    ex. SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
    Pins with PWM functionality need to be configured
    ex. GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2);
  • Generator needs to be configured and initial duty cycle set.
  • Use 1% duty cycle instead of 0%.
  • When 0% duty cycle is needed to stop the motors, just disable the PWM output.
  • If input parameter for duty cycle setting is >99% than 99% will be set.

If you have any questions about the project or the article, just comment.
I appreciate constructive criticism :)

Stay tuned, as in the next article I will write about the interrupts that tell when the motors should move or not.

No comments:

Post a Comment