Subject:
|
Re: "Servo" Driver for NQC
|
Newsgroups:
|
lugnet.robotics
|
Date:
|
Thu, 31 Jan 2002 03:52:14 GMT
|
Reply-To:
|
Dick Swan <dickswa@&stopspam&sbcglobal.net>
|
Highlighted:
|
(details)
|
Viewed:
|
973 times
|
| |
| |
This is a long post. It covers the following:
1. How the "WAIT x 10 msec" opcode is implemented and its inherent
inaccuracy for low delays. And suggests an alternative code implementation
2. How RCX motor PWM is implemented. And the implication that C-code trying
to pulse motor for very short duration might generate seemingly inconsistent
behavior.
3. RCX inserts 60 - 100 milli-second delay when changing direction of
powered motors. And how to bypass it.
4. Explanation that motor "BRAKE" command actually has 8 levels of braking
depending on the last motor power level.
Hope these tidbits are useful in implementing a "servo" driver.
Elimination of 'WAIT x 10 msec'
--------------------------------
Regarding earlier posts on "servo" driver code. I'd suggest eliminating the
"WAIT" commands from "ON; Wait(1); BRAKE; Wait(1)" loop. The RCX interpreter
is pretty slow and there is 3 to 4 milliseconds between each interpreter
opcode. Just use the inherent delay between opcodes.
The "Wait(nnn)" opcode simply sets the value 'nnn' into a timer that is
decremented once every 10 msec within the 1 msec interrupt handler. So, when
nnn = 1, the delay could be from almost zero up to the full 10 msec
depending on what is the current position within the 10 msec period.
Assume your code is something like the following:
[1] while (rotation Sensor != value)
[2] {
[3] ON;
[4] WAIT(1);
[5] BRAKE;
[6] WAIT(1);
[7] }
The time to execute one loop of the above code is approximately 21 - 41
milliseconds. All lines except [2] generate one RCX opcode.
[1] 3.5 msec <for conditional branch instruction>
[3] 3.5 msec
[4] 3.5 - 13.5 msec depending on duration of wait
[5] 3.5 msec
[6] 3.5 - 13.5 msec depending on duration of wait
[7] 3.5 msec <for unconditional branch instruction>
The 'brake' interval will range from 14 - 24 msec -- opcodes in lines 6, 7,
1, 3 -- and the 'on' interval will range from 7 - 17 msec.
If you replace the loop with the following you should get be able to get
much finer control with a loop that takes about 10.5 msecs to execute. Loop
should have three instructions only for statments on [3], [4] and [5].
You'll get much shorter pulses -- 3.5 msec on; 7 msec brake.
[1] while (true)
[2] {
[3] ON;
[4] BRAKE;
[5] if ((rotation Sensor != value)
[6] break;
[7] }
Using a "while(true)" block and putting the condition testing at the end of
the loop should allow the compiler to only generate a single conditional
branch instruction instead of the two branches in the first loop. [I use a
different compiler and not NQC so I'm assuming that NQC generates tight
code.]
Above timings assuming only a single task is executing. If you're running
more than one simultaneous task, then expect even longer delays since
running tasks are scheduled round robin with a "timeslice" of one opcode.
8 Levels of 'Braking'
--------------------
There's another item to watch out for when timing very short motor powering
that I'll cover off here for completeness, although they may not apply to
your case since you're always using full power. These are from an earlier
post that I don't have so I can't give proper credit to the source. The
"BRAKE" command follows the PWM waveform from the motor power level. The
BRAKE command is actually a PWM of brake and float. So if the power level
was 1; i.e. 1 msec on and 7 msec of float then the "BRAKE" command would be
1 msec of brake and 7 msec of float.
PWM Waveforms
------------------
The actual PWM waveforms themselves may also cause unexpected results when
timing very short motor movements. The PWM waveform is stored in a byte
value for each motor. Every msec, it is rotated and the current high bit is
used to indicate whether the motor should be "powered" or floated. In this
case "powered" is any of the four cases: forward, reverse, float or brake.
There's an eight element array of PWM waveform bytes stored in ROM with
values as follows:: 00000001, 00000011, 00000111, 00001111, 00011111,
00111111, 0111111, 1111111. What this means is that for power level 4, the
motor is on for 4 msec and off for 4 msec. I would have thought that PWM
constants would have been set up to distribute the "powered" msecs so that
for power level 4 motor would be on for 1 msec and off for 1 msec. Any PWM
electronics experts out there to comment on whether 00001111 or 01010101
would have been the best choice?
60 - 100 mSec Delay when flipping motor direction
---------------------------------------------------
"Jerry Kalpin" <jdkalpin@sympatico.ca> wrote in message
news:GqrA4F.51M@lugnet.com...
>
> <snip>
> >
> >
> > ----------------------------- Steve Baker -------------------------------
> Right, but in the firmware PWM, it is 'on-float-on-float' not
> 'on-brake-on-brake' I think (but I'm not sure).
Yes. You are correct. The firmware implements 'on-float-on-float'. 'Brake'
is not used.
> In fact, the 'on-brake-on-brake' is a neat way to get fine control to
(say)
> just crack a pneumatic valve to move a piston without much force. But
it is
> very jittery and I wonder if I am destroying the motor gearing.
I don't know about gear destruction for this case, but Lego must have some
experience with this potential problem. Quoting from the 2.0 SDK, page 96,
"There is a 60 ms delay after each direction change to reduce tear and wear
on the motors if they are heavily loaded." This is a topic that I haven't
seen mentioned before in this newsgroup and I wonder if anyone has found it
to be a problem in their real world programs. I could see it as a cause of
unexpected behavior if you were trying rapid forward / reverse / forward
movements to do precise positioning. [Note: the documentation says 60 msec
but I think the firmware actually uses 100 msec].
I believe there is a way to circumvent this delay. I think the code checks
to see if motor is both powered and going in the wrong direction before it
starts the 100 msec delay timer. If you go through the sequence forward --
off -- reverse, I don't think the delay timer is triggered.
|
|
Message has 2 Replies: | | Re: "Servo" Driver for NQC
|
| <snip> (...) <snip> (...) Really good post! Just a loose end: If you press the 'stop' button on the RCX while a motor is running the motor stops in the 'brake' condition. If you connect a spare motor to a gray battery box with the switch in a (...) (23 years ago, 31-Jan-02, to lugnet.robotics)
| | | Re: "Servo" Driver for NQC
|
| "Dick Swan" <dickswan@sbcglobal.net> wrote in message news:GqsAv4.GL1@lugnet.com... (...) <snip> Dick, let me first say thank you for the post. I've implemented some of your suggestions and my robot has gone from unuseable to operating as I had (...) (23 years ago, 1-Feb-02, to lugnet.robotics)
|
Message is in Reply To:
| | Re: "Servo" Driver for NQC
|
| (...) <snip> (...) Right, but in the firmware PWM, it is 'on-float-on-float' not 'on-brake-on-brake' I think (but I'm not sure). In fact, the 'on-brake-on-brake' is a neat way to get fine control to (say) just crack a pneumatic valve to move a (...) (23 years ago, 30-Jan-02, to lugnet.robotics)
|
18 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
This Message and its Replies on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|