PDA

View Full Version : How do I start a machine every 1/20 sec?


xar
06-22-03, 06:32 PM
Hi,
just wrapped my superservo to the IsoPod and I was trying to schedule a machine that should run every 1/20 of sec.
This will read the encoders, compute the current X,Y and theta(heading) of the robot.

Another machine will use the variables computed here and will drive the PWM.

I should suppose I will write a single state machine that will loop but how do I efficiently schedule it to run only 20 times in a second?

I would like to lower this limit up to 5 times in a second, while if I remember well, EVERY 50000 cycles still means 100 times in a second and you could not go higher than 65535.

TIA,

Giuseppe Marullo

RMDumse
06-22-03, 09:35 PM
Yes, it is easy to use the scheduler to run a machine at say, 100 times a second, with 50000 SCHEDULE-RUNS. But there is no reason you can't put a Forth definition in a machine chain, and let it count off 5 ticks, or 20 ticks, or whathaveyou. It can then call your machine. Result? You can run your machine once every-so-many times scheduled.

xar
06-23-03, 03:17 PM
Thanks Randy.
I tried this one, and while using YELLED TOGGLE as action, it worked with a 1 sec cycle.
However, when I tried to read the encoders and print out the result, the IsoPod printed eight times -1 and the hanged. -1 is not the encoder's reading, I double checked it.
I can't imagine what could be wrong, but eight seems a magic number...stack?

LOOPINDEX CYCLE-COUNTER
DECIMAL 100 CYCLE-COUNTER END
1 CYCLE-COUNTER START

MACHINE UPDATEPOSITION
ON-MACHINE UPDATEPOSITION
APPEND-STATE UPDATE

IN-STATE UPDATE
CONDITION CYCLE-COUNTER COUNT
CAUSES
HEX E57 2@ D.
THEN-STATE UPDATE
TO-HAPPEN

UPDATE SET-STATE
INSTALL UPDATEPOSITION
EVERY 50000 CYCLES SCHEDULE-RUNS UPDATEPOSITION


-----------------
I though that maybe I needed to put the whole
thing into ee so I tried this but it did't work either:

SCRUB
LOOPINDEX CYCLE-COUNTER EEWORD
DECIMAL 100 CYCLE-COUNTER END
1 CYCLE-COUNTER START

MACHINE UPDATEPOSITION EEWORD
ON-MACHINE UPDATEPOSITION
APPEND-STATE UPDATE EEWORD

IN-STATE UPDATE EEWORD
CONDITION CYCLE-COUNTER COUNT
CAUSES
HEX E57 2@ D.
THEN-STATE UPDATE
TO-HAPPEN IN-EE

UPDATE SET-STATE
INSTALL UPDATEPOSITION EEWORD
EVERY 50000 CYCLES SCHEDULE-RUNS UPDATEPOSITION

It hangs while "downloading"...
Argh, I have a JTAG adapter in my hand and SmallC in the other....help :)

nmitech
06-23-03, 03:45 PM
To recover the crash, put a jumper wire or a short on pin 2 & 4 on J5 then press reset, or toggle the DTR by press ALT+T on the keyboard, or recycle the power to get the IsoMax prompt, then enter SCRUB to erase the bad code. Now remove the jumper wire on pin 2 & 4 and reload your new program.

xar
06-23-03, 03:47 PM
If I power cycle it It recovers. But why the first listing does not print out the encoder readings and hangs exactly after eight -1 ?
TIA,

nmitech
06-23-03, 04:49 PM
IN-STATE UPDATE
CONDITION CYCLE-COUNTER COUNT
CAUSES
HEX E57 2@ D.
THEN-STATE UPDATE
TO-HAPPEN

the HEX E57 number is considered as runtime #. Instead you should do this,

HEX
IN-STATE UPDATE
CONDITION CYCLE-COUNTER COUNT
CAUSES
E57 2@ D.
THEN-STATE UPDATE
TO-HAPPEN

xar
06-23-03, 04:53 PM
Thanks for your answer.

I adapted an IsoMax example from
http://www.newmicros.com/store/product_manual/loopindex.pdf Page3.

This is the original listing:


LOOPINDEX CYCLE-COUNTER
DECIMAL 100 CYCLE-COUNTER END
1 CYCLE-COUNTER START
MACHINE SLOW_GRN
ON-MACHINE SLOW_GRN
APPEND-STATE SG_ON
APPEND-STATE SG_OFF
IN-STATE SG_ON
CONDITION CYCLE-COUNTER COUNT
CAUSES GRNLED OFF
THEN-STATE SG_OFF
TO-HAPPEN
IN-STATE SG_OFF
CONDITION CYCLE-COUNTER COUNT
CAUSES GRNLED ON
THEN-STATE SG_ON
TO-HAPPEN
SG_ON SET-STATE
INSTALL SLOW_GRN

I only reduced to one state, and It behaved correctly if I put a YELLED TOGGLE instead of HEX E57 @2 D. in my source.

I finally found the problem:

HEX E57 2@ D. ) DOES NOT WORK

E57 2@ D. ) DOES WORK!

:p

I just got you reply, while writing this!

RMDumse
06-23-03, 05:04 PM
There's another problem I see.

Here is a snip of your listing:


SCRUB
LOOPINDEX CYCLE-COUNTER EEWORD
DECIMAL 100 CYCLE-COUNTER END
1 CYCLE-COUNTER START

MACHINE UPDATEPOSITION EEWORD
ON-MACHINE UPDATEPOSITION
APPEND-STATE UPDATE EEWORD

IN-STATE UPDATE EEWORD
CONDITION CYCLE-COUNTER COUNT
CAUSES
HEX E57 2@ D.
THEN-STATE UPDATE
TO-HAPPEN IN-EE


Notice there is an extra EEWORD in the transition definition "IN-STATE UPDATE EEWORD". This could have very bad results. Transitions are moved to EEPROM with IN-EE. The result is a bit hard to imagine. Perhaps TASK and part of the transition definition were moved to Flash. In any case, I don't think it was good.

xar
06-23-03, 05:50 PM
Thanks for your patience, as you may note, my knowledge of Forth/IsoMax is very limited.

Now I need to put this machine into flash so I could keep it on the IsoPod.

This is the latest release of my code:

SCRUB

HEX
100 PWMA0 PWM-PERIOD
100 PWMA1 PWM-PERIOD
8000 PWMA0 PWM-OUT
8000 PWMA1 PWM-OUT

LOOPINDEX CYCLE-COUNTER
DECIMAL 100 CYCLE-COUNTER END
1 CYCLE-COUNTER START EEWORD
MACHINE UPDATEPOSITION EEWORD
ON-MACHINE UPDATEPOSITION
APPEND-STATE UPDATE EEWORD


HEX
IN-STATE UPDATE
CONDITION CYCLE-COUNTER COUNT
CAUSES
E47 2@ D.
0.0 E47 2!
E57 2@ D. CR
0.0 E57 2!
YELLED TOGGLE
THEN-STATE UPDATE
TO-HAPPEN IN-EE


: CIPPA
HEX
100 PWMA0 PWM-PERIOD
100 PWMA1 PWM-PERIOD
8000 PWMA0 PWM-OUT
8000 PWMA1 PWM-OUT
UPDATE SET-STATE
DECIMAL
EVERY 50000 CYCLES SCHEDULE-RUNS UPDATEPOSITION
; EEWORD

--------------------------------
It works, I hope that there are not too many errors.

Thanks again for your help.

nmitech
06-23-03, 06:05 PM
To keep all the new words in the WORDS listing you must do SAVE-RAM. Otherwise, when the power is cut off, the new words will not show up on the WORDS listing next time you power up

xar
06-29-03, 02:49 PM
Now I need to precisely start a machine/status/routine every 1/5 - 1/20 of second.
I noticed that using the loop variable I don't get constant results.
Since I need to sample the wheels' encoders I need the interval be always the same.

I could test a timer bit into a isomax machine to change, but I was wondering if there is a better (=async) method to get the job done.
Just like old interrupts, you know.

Another thing that is not clear to me is how the Isopod will wait for a command coming from the serial port.
I would like it to wait for commands/parameters coming from a RF radio module.

RMDumse
06-29-03, 07:24 PM
I'd like to get into the office and look at this further, but I see no reasons LOOPINDEX shouldn't work for a "five times" counter. In thinking about this, I notice you don't reset the counter back to its start, so maybe that is why you aren't getting repeatable results.

In the CAUSEs term, add a CYCLE-COUNT RESET command.

But a question. You are using a decimal 50,000 as your SCHEDULE-RUNS value, and I don't see a HALFSPEEDCPU anywhere, so you will be getting a run every 100th of a second. Why are you using 100 CYCLE-COUNT END instead of just 5 LOOPINDEX CYCLE-COUNT to count 5 1/100ths of a second?

xar
06-29-03, 07:49 PM
Hi Randy,
I've found the *bug* (my fault).

let me explain better.
I am building a PWM table, to try to linearize the driving of the motor.

So I am trying to execute the update status once in a second.
This is the code I am using(with your suggestion about the reset):

SCRUB
HEX
100 PWMA0 PWM-PERIOD
100 PWMA1 PWM-PERIOD
8000 PWMA0 PWM-OUT
8000 PWMA1 PWM-OUT

: INIT_PWM
HEX
100 PWMA0 PWM-PERIOD
100 PWMA1 PWM-PERIOD
8000 PWMA0 PWM-OUT
8000 PWMA1 PWM-OUT
; EEWORD

: INIT_ENCODERS
0.0 E47 2!
0.0 E57 2!
; EEWORD
VARIABLE TEST EEWORD

LOOPINDEX CYCLE-COUNTER
100 CYCLE-COUNTER END
1 CYCLE-COUNTER START EEWORD

MACHINE UPDATEPOSITION EEWORD
ON-MACHINE UPDATEPOSITION
APPEND-STATE UPDATE EEWORD
APPEND-STATE SAFE EEWORD

IN-STATE UPDATE
CONDITION CYCLE-COUNTER COUNT
CAUSES
( E47 2@ D.
( 0.0 E47 2!
DECIMAL
TEST @ .
DECIMAL
E57 2@ D. CR
DECIMAL
TEST @ 200 + TEST !
TEST @ PWMA1 PWM-OUT
0.0 E57 2!
YELLED TOGGLE
PWMA0 TOGGLE
CYCLE-COUNTER RESET
THEN-STATE UPDATE
TO-HAPPEN IN-EE

: CIPPA
DECIMAL
0 TEST !
TEST @ .
INIT_PWM
INIT_ENCODERS
UPDATE SET-STATE
EVERY 50000 CYCLES SCHEDULE-RUNS UPDATEPOSITION
; EEWORD

This code is supposed to be invoked once in a second, but in reality it does take at least 4.
I was thinking that the amount of code inside the machine could modify the timing, I was wrong.

The reason it was not working is the lack of a DECIMAL statement before the LOOPINDEX definition.

BTW, the LOOPINDEX example is taken from your documentation and there is no CYCLE-COUNTER reset.

Have you seen my email?

RMDumse
07-18-03, 04:08 PM
I stripped the example down to its bare essential, so anyone returning to this thread could see how to run a machine action slower than the SCHEDULE rate.


SCRUB


DECIMAL

LOOPINDEX CYCLE-COUNTER
100 CYCLE-COUNTER END ( DO UPDATE ONCE A SECOND
1 CYCLE-COUNTER START EEWORD


MACHINE UPDATEPOSITION EEWORD
ON-MACHINE UPDATEPOSITION
APPEND-STATE UPDATE EEWORD

IN-STATE
UPDATE
CONDITION
CYCLE-COUNTER COUNT
CAUSES
GRNLED TOGGLE
CYCLE-COUNTER RESET
THEN-STATE
UPDATE
TO-HAPPEN IN-EE



SAVE-RAM

UPDATE SET-STATE
DECIMAL
EVERY 50000 CYCLES SCHEDULE-RUNS UPDATEPOSITION

RMDumse
07-18-03, 04:25 PM
Showing further methods, you could have the machine remain "clean" of any extra timing regards, and use another word to call the machine at the periodicity you wanted.

SCRUB


DECIMAL

LOOPINDEX CYCLE-COUNTER
100 CYCLE-COUNTER END ( DO UPDATE ONCE A SECOND
1 CYCLE-COUNTER START EEWORD


MACHINE UPDATEPOSITION EEWORD
ON-MACHINE UPDATEPOSITION
APPEND-STATE UPDATE EEWORD

IN-STATE
UPDATE
CONDITION
TRUE
CAUSES
GRNLED TOGGLE
THEN-STATE
UPDATE
TO-HAPPEN IN-EE


: THREAD2MACHINE
CYCLE-COUNTER COUNT
IF
UPDATEPOSITION
CYCLE-COUNTER RESET
THEN
; EEWORD

SAVE-RAM

UPDATE SET-STATE
DECIMAL
EVERY 50000 CYCLES SCHEDULE-RUNS THREAD2MACHINE

lat
08-27-03, 05:09 PM
Hi,
I thought a LOOPINDEX would implicitly be reset if <i>&lt;loopindex&gt;</i> COUNT returned TRUE, so the line CYCLE-COUNTER RESET is unnecessary?

<pre>: THREAD2MACHINE
CYCLE-COUNTER COUNT
IF
UPDATEPOSITION
CYCLE-COUNTER RESET
THEN
; EEWORD
</pre>

RMDumse
08-28-03, 09:38 PM
No, it doesn't automatically reset. Brad thought it would be better to let it count on unless specifically reset.

lat
08-31-03, 12:20 AM
Could you please refer to paragraph 113 in the 10-July-2003 isopod/isomax manual at &lt;http://www.newmicros.com/store/product_manual/IsoPod.pdf&gt; which mentions "<b>If it [COUNT] has [passed its limit] COUNT will return TRUE (non-zero), and it will also reset the loopindex value to the START value</b>"? I <i>am</i> relying on your features behaving as documented. :rolleyes: