Main Page   Hardware Class Hierarchy   Hardware API     Mapping Class Hierarchy  Mapping API 

oDCmotor Class Reference

An object to control a direct current (DC) motor using any standard H-bridges available (L293, L298, SN754410). The hardware configuration can either be sign magnitude, toggling enable pin sign magnitude enable tied high toggling either A or B channel, or locked antiphase. More...

#include <odcmotor.h>


Public Member Functions

 oDCmotor (IOLINE, PORT, IOLINE, PORT, IOLINE, uint8 subclass=0)
 SIGN_MAGNITUDE method #2 (forward/reverse/speed(TPU)).

 oDCmotor (IOLINE, PORT, IOLINE, uint8 subclass=0)
 SYNCRONOUS_MAGNITUDE method #3 (forward/speed(TPU)).

 oDCmotor (IOLINE, uint8 subclass=0)
 LOCKED_ANTIPHASE (TPU line for PWM) method #1.

void WSwrite (void)
 Write object to simulator.

void forward (void)
 start motor in forward

void forward (POWER)
 start motor forward at specified POWER.

void reverse (POWER)
 starts motor in reverse at specified POWER.

void reverse (void)
 starts motor in reverse.

void brake (void)
 applies brake to motor (both high).

void power (POWER)
 0-100 (percantage of maximum)

void operate (bool)
 cuts off PWM's (low) if false.

void frequency (FREQUENCY f)
 Sets PWM signal frequency. (cycles per second).

void power_resolution (POWER p)
 Sets the number of increments for power from 0...user set maximum.

void priority (PRIORITY p)
 Sets the TPU channel execution priority (Ref. TPU Channel Utilization) for the speed control line. Default MIDDLE_PRIORITY. Priority should be set before you begin operation.

bool stop (void)
 true if motor stoppped. Needed for EncodedMotor to know whether to apply "cruise_control".

MICROSECOND get_hightime (void)
 return current high time [DOS only]

MICROSECOND get_lowtime (void)
 return current low time [DOS only]

void hightime (MICROSECOND high)
 Hightime set the on time for the pulse measured in micro-seconds.

void nexthigh (MICROSECOND high)
 Used when oPWM is not operating to set new hightime when activated.

void lowtime (MICROSECOND low)
 Lowtime is the off time for the pulse measured in micro-seconds.

void nextlow (MICROSECOND low)
 Used when oPWM is not operating to set new lowtime when activated.

void value (bool onoff) const
 For oDO1_TPU.


Static Public Member Functions

int TCR1 (void)
void TMCR (int iarb)
bool HSQR (int chan, int val)
 Configures the host sequence register.

bool HSRR (int chan, int val)
 Configures the host sequence request register.

bool CPR (int chan, int val)
 Configures the channel priority register (Ref. TPU Channel Utilization).

bool CIER (int chan, int cie)
 Configures the channel interrupt enable register.

int CISR (int chan)
 Returns the channel interrupt status register.

void CISR_clear (int chan)
 Clears the channel interrupt status register for the channel.

bool TICR (int cirl, int cibv)
 Configures the TPU interrupt configuration register.

int tpu_vector (IOLINE channel)
 Given a channel, returns the vector number to use for an interrupt.


Detailed Description

An object to control a direct current (DC) motor using any standard H-bridges available (L293, L298, SN754410). The hardware configuration can either be sign magnitude, toggling enable pin sign magnitude enable tied high toggling either A or B channel, or locked antiphase.

Remarks
Because when the PWM is disabled, the pin goes high, the operate method does not disable the PWM, but simply sets the signal to 0. Thus, once initialized, the PWM is never disabled.
As of version 2.1, added the ability to configure the motor in locked antiphase configuration. The previous default configuration was sign magnitude where the enable pin on the H-bridge is attached to the PWM. The locked antiphase configuration has the enble pin always high and uses only one siganl line; a PWM and its inverse to control the motor (Ref. Motion Control by Larry Barello)
There are actually four ways to hook up DC motor. Locked antiphase, sign magnitude, and two similar methods where the enable is also always on, and one signal is controlled through a discrete output and the other is controlled through a PWM.
In sign-magnitude, usually, we are just using 1/2 an H-bridge; the TPU pin should be tied to the chip enable; one of the port pins goes to the chip #1 input with chip #1 output going to motor, with remaining port going to #2 input.
In Locked antiphase, we also can use 1/2 an H-bridge; the enable pin is tied high, the PWM signal is split with one line going to input #1 of H-bridge with other line being inverted and going to input #2 of H-bridge.
if the motor goes reverse rather than forward when started, you can simply switch the declarations for the forward/reverse pins and port in sign magnitude or you can use the new orientation method.
Frequency/Power_Resolution Relationship
A byproduct of the frequency and power_resolution. At very high frequencies, it turns out because the minimum time on the oPWM is 1 microsecond that the real operating range of the power gets reduced. For instance at 5K Hz the range is 0-200. at 10K its 100; thus power_resolution only helps if its possible to specify this range in the frequency you have specified. Thus it is the frequency that takes priority and not the power_resolution. One benefit is that since the oDCmotor will scale the resolution automatically to fit the specified frequency, a higher resolution can be specified so you can fit your resolution magnitude to your PID equation.
Warning:
Be aware that each motor controller chip/board has limits on the frequency it can be driven at. Be sure to set the frequency below you're motor controller's maximum frequency. The default frequency for sign magnitude is 1Khz, and 5Khz for the other two methods (5Khz will be too slow for Locked Anti-phase!).
Locked-Antiphase
The locked antiphase has a interesting feature. Since the TPU pin will initialize to either high or low before the PWM is initialized, therefore the motor will start full speed until the PWM is fully intialized. At first, I figured setting a discrete one bit object to control the enable signal on the H-bridge would do the trick, but unfortunately, it seems everything seems to initialize to a high state. Thus, there are two ways to compensate for this, but unfortunately they both require additional hardware (please let me know if someone knows how to boot with the E/F channels to low). The first is to start the program and wait until fully initialized before throwing a seperate motor switch. The second way, which takes advantage of excess capacity in my 14 pin inverter chip, is to send the oDO1 output into the inverter and into the H-bridge enable. thus, it initializes low, but we must set the oDO1 object to false to activate the motor. Similarly, in locked antiphase, the only way you can truly shut off the motor is to attach the enable pin to a one bit discrete output (oDO1), or add a sepearte motor switch.
Note:
even with the inverter, the motor would sometimes activate for a fraction of a second (probably related to capacitors or other timing issues). Thus, a seperate motor switch is usually the fail proof method.
I succesfully was able to use anti-lock with a SN775410 and a gutted servo motors, but this required reducing the cycle time from 10,000 microseconds (100Hz) to 100 microseconds (10KHz) in the base PWM. On switching to another motor due to encoder problems, I found it was drawing too much current and generating too much heat. I enclose the following responses from a post I made on PART concerning maybe how to resolve this:
Unless I am mistaken, locked anti-phase is when you have 50% modulated duty
cycle equal to zero current, or voltage, through the motor. The heat and
current draw problems described are typical of low PWM frequency.

The method of PWM power control only works because a motor is not a
resistive load. The inductance of the motor's windings filters the PWM, and
rounds off the squares into a constant level of voltage and current.
However, the PWM frequency must be high enough so that this takes place
correctly. Very small motors, especially Maxon motors which don't have an
iron core, have very low inductance. This means that a 10kHz or 20kHz PWM
won't fly.

What to do? Well, you could skip the PWM and go to linear amplifiers. This
is OK for an amp or two of current. If you have a + and - power supply, all
you need is two power transistors and an op amp and that's it.

Or, add a filter choke. This would be connected in series, so that the
effective inductance is that of the motor plus that of the choke. You can
get some at Radio Shack, or from catalogs such as Marlin P. Jones.

Oh, you're wondering why only the 50% modulation gets hot and not the sign
magnitude? That's just because the rotor is standing still. Moving rotor
cools itself down somewhat. But the problem still exists.

Mark Medonis

And the following response was from Larry Barello:
10 ms PWM rate is way too slow. The core of the motor saturates
almost
instantly and draws stall currents while trying to accelerate.
Then, you
switch directions. Net result is lots of heat and buzzing. You
need
something more like 50 us PWM rate. The SN754410 is not rated for
more than
5-7khz, although I use them at 20khz with no apparent problems on
small
motors.

As Mark said, you can put a series choke to help smooth out the
power, but
it is going to be a pretty big coil since it needs lots of
inductance and be
able to carry lots of current. As an example, the inductors inside
PC power
supplies run at 100khz or more (some up to 1mhz) so they can be quite small
for the currents they carry.

There are three ways you can drive the SN754410 (and equivalents):
1. Locked anti-phase - great if you have a high inductance motor (e.g. cheap
servos)
2. Sign-mag toggling the ENABLE line. This is traditional, but doesn't work
that great.
3. Sign-mag by toggling the A (or B) side, and using the other side for
direction

My personal favorite is #3. It implements "synchronous rectification" which
just means you are using the bridge to conduct the recirculating currents,
rather than the protection diodes. This always provides better speed
control for me (better low % output operation). If you are using really
slow PWM rates (10ms would qualify) #2 would be a better choice because
during synchronous rectification the motor is essentially shorted out. I
also really like #1, but, as Mark mentioned, the really high quality motors
tend to be very low inductance and it is hard to get a driver (or a CPU/PWM
generator) that works that fast

You pretty much understand the drawbacks of Locked Antiphase. The benefits,
if you can do it, are: one control line and automatic 4 quadrant operation:
You get automatic regenerative braking without any additional logic.

Thanks Guys! Now I just need time to digest all the information and more importantly time to try again!
Addendum
With a new controller board, I have sucessfully retested with locked antiphase. At 20Khz, 30V Pittman motors still whines a small bit. I thus switched to #3 method above as suggested by Larry Barello which at 10Khz runs without the noise problem. This method also doesn't seem to suffer from the irritation that the wheels start spinning at 100% power, between the time that the microcontroller boots and the power is first applied.
References
Sample Code
#include &lt;oDCmotor.h>
int main()
{
oDCmotor motor(0,PORT_E,1,PORT_E,0);&nbsp; // on E port 0/1; TPU port 0
int i;
&nbsp; motor.frequency(1000); // 1 Khz
&nbsp; motor.forward(10);
&nbsp; motor.operate(true);
&nbsp; for (i=0; i&lt;=200000; i++) ;
&nbsp; motor.power(25);
&nbsp; for (i=0; i&lt;=200000; i++) ;
&nbsp; motor.power(50);
&nbsp; for (i=0; i&lt;=200000; i++) ;
&nbsp; motor.power(75);
&nbsp; for (i=0; i&lt;=200000; i++) ;
&nbsp; motor.power(100);
&nbsp; for (i=0; i&lt;=200000; i++) ;
&nbsp; motor.operate(false);
}


Constructor & Destructor Documentation

oDCmotor IOLINE  ,
PORT  ,
IOLINE  ,
PORT  ,
IOLINE  ,
uint8  subclass = 0
 

SIGN_MAGNITUDE method #2 (forward/reverse/speed(TPU)).

Parameters:
forward channel.
forward channel PORT.
reverse channel.
reverse channel PORT.
channel on TPU connected to enable pin of motor controller.

oDCmotor IOLINE  ,
PORT  ,
IOLINE  ,
uint8  subclass = 0
 

SYNCRONOUS_MAGNITUDE method #3 (forward/speed(TPU)).

Parameters:
IOLINE "forward" or channel A.
PORT channel A port.
IOLINE Pulse width modulated channel on TPU port.

oDCmotor IOLINE  ,
uint8  subclass = 0
 

LOCKED_ANTIPHASE (TPU line for PWM) method #1.

Parameters:
IOLINE channel on TPU port.


Member Function Documentation

bool CIER int  chan,
int  cie
[static, inherited]
 

Configures the channel interrupt enable register.

Parameters:
int: channel
int: 1 enables; 0 disables

bool CPR int  chan,
int  val
[static, inherited]
 

Configures the channel priority register (Ref. TPU Channel Utilization).

Parameters:
int: channel
int: priority

bool HSQR int  chan,
int  val
[static, inherited]
 

Configures the host sequence register.

Parameters:
int: channel
int dependent upon function (CFSR) selected

bool HSRR int  chan,
int  val
[static, inherited]
 

Configures the host sequence request register.

Parameters:
int: channel
int: dependend upon function

void nexthigh MICROSECOND  high  )  [inherited]
 

Used when oPWM is not operating to set new hightime when activated.

DCmotor (and maybe like objects) needs this, because the only way to stop the PWM (that I know of) is to set hightime to 0--thus loosing the previous value of hightime. thus if you set the hightime while the object is non-operational, you want it to be set to that value the next time the object goes operational (see dcmotor.cpp to know what I'm talking about).

int TCR1 void   )  [static, inherited]
 

misnomer--should be TCR1 divisor--return number of clocks (PSCK,TCR1P modifications) Globally available object. Can be used in combination with TPU_REGISTER definition to say TPU_REGISTER->CFSR.BITS...

void TMCR int  iarb  )  [static, inherited]
 

was tpu_init Configures the channel function select register


The documentation for this class was generated from the following file:
Generated on Mon Oct 8 19:32:45 2007 for OOMRM Hardware API by doxygen1.3