#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. | |
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
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.
#include <oDCmotor.h> int main() { oDCmotor motor(0,PORT_E,1,PORT_E,0); // on E port 0/1; TPU port 0 int i; motor.frequency(1000); // 1 Khz motor.forward(10); motor.operate(true); for (i=0; i<=200000; i++) ; motor.power(25); for (i=0; i<=200000; i++) ; motor.power(50); for (i=0; i<=200000; i++) ; motor.power(75); for (i=0; i<=200000; i++) ; motor.power(100); for (i=0; i<=200000; i++) ; motor.operate(false); }
|
||||||||||||||||||||||||||||
|
SIGN_MAGNITUDE method #2 (forward/reverse/speed(TPU)).
|
|
||||||||||||||||||||
|
SYNCRONOUS_MAGNITUDE method #3 (forward/speed(TPU)).
|
|
||||||||||||
|
LOCKED_ANTIPHASE (TPU line for PWM) method #1.
|
|
||||||||||||
|
Configures the channel interrupt enable register.
|
|
||||||||||||
|
Configures the channel priority register (Ref. TPU Channel Utilization).
|
|
||||||||||||
|
Configures the host sequence register.
|
|
||||||||||||
|
Configures the host sequence request register.
|
|
|
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). |
|
|
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... |
|
|
was tpu_init Configures the channel function select register |
1.3