PDA

View Full Version : How to simulate encoder


Newbie
02-10-04, 09:10 AM
I have an IsoPod with an LCD hooked up to it. Can anyone suggest how I could simulate an encoder going into the SPI? All i really need is random 12-bit numbers sent to the IsoPod serially, so that I can start testing code I have to take the numbers from an encoder and display it in degrees on the LCD. Any help would be much appreciated. :)

RMDumse
02-10-04, 10:59 AM
Well... thing is... for your application you'll need to run your IsoPod(TM) as the master for SPI. The slowest it will go is down to 1.25MHz. That's pretty fast. Faster than one could bit bang in high level language. So you'd need to have some external hardware.

It would be very easy to make up a simulator with another 'Pod. Let it be a slave, and your first one the master.

Going without a second computer to simulate your encoder, you might be able to add a shift register, and putting it on the ports of the 'Pod, and feed it bytes. Still, it's a pretty fast process for high level.

When you bring the bytes in, you're just going to stick them in a buffer right? Why not bypass the bringing of them in, and just stick your 12 bytes in the buffer? Then you'd have tested the software from the buffer to the LCD.

Newbie
02-10-04, 11:47 AM
I was hoping to test out a changing input to simulate the resolver actually turning. Could this be achieved maybe with a counter or something?

RMDumse
02-10-04, 12:05 PM
I can't think of anything that really acts like the resolver, so the only way I can see simulating it is to program another micro to simulate it. This is a fairly common approach when missing hardware and wanting to simulate it. Once the interface is made, then you can program the output to be anything you like.

panorama
02-10-04, 02:52 PM
Dear Newbie,
It seem to me that you can easily connect two gpio lines to the timer lines and initialize the quadrature counter. Then when you run your machine loop, you can send a count out the gpio once in a while. Then your program will read the counter and display the angle on the LCD.

Here is the sequence for counting (each value is one gpio pin:)
0 0
1 0
1 1
0 1
start over with 0 0.
To count down, just go in the reverse direction.

There are also grey code encoders, and count/direction encoders. You can simulate those in a similar way.

Tim

RMDumse
02-10-04, 05:17 PM
Yes, it is possible to simulate a quadrature signal from the board. I've done that before. But the decoder Newbie is wanting to simulate is a very specific absolute position one (iirc) which talks through the SPI. He gave a link in another post a few back...

Newbie
02-18-04, 10:11 AM
I have now acquired one of these encoders: .http://embrace.grayhill.com/embrace/IMAGES/PDF/I-53.pdf and I was hoping someone could help me out with how to have the IsoPod read data from it. It is an 8-position encoder that outputs a 4-bit gray code number. How would I get this information from the encoder to the IsoPod, and how would I convert from gray code to hex, dec, or what have you? Would I just hook the data pins up to GPIO? Thank you

RMDumse
02-18-04, 03:25 PM
This is quite a bit different from the last encoder, isn't it. Hum... looks a bit confusing because you say it is an 8-position encoder that outputs a 4-bit gray code number. With 4-bit gray code you can encode 16 numbers. WIth an 8-position encoder it would output a 3-bit gray code. So something is a bit fishy. I'll assume you have an 16-position encoder that outputs a 4-bit gray code and if it is otherwise, let me know.

Okay, data sheet looks like this has one common line and four output lines. Easy way would be hook common to gnd, and the four lines one each to port lines. Pick any four. I'll suggest PB0,1,2,3 to pins 1,2,4,8

Now it is easy to make a Gray code to Hex conversion using a simple look up table.

PHERE
0 P, ( 0 - 0
1 P, ( 1 - 1
3 P, ( 2 - 3
2 P, ( 3 - 2
6 P, ( 4 - 6
7 P, ( 5 - 7
5 P, ( 6 - 5
4 P, ( 7 - 4
C P, ( 8 - 12
D P, ( 9 - 13
F P, ( 10 - 15
E P, ( 11 - 14
A P, ( 12 - 10
B P, ( 13 - 11
9 P, ( 14 - 9
8 P, ( 15 - 8
CONSTANT CONV-TBL-HEX2GRAY

PHERE
0 P, ( 0 - 0
1 P, ( 1 - 1
3 P, ( 2 - 3
2 P, ( 3 - 2
7 P, ( 4 - 7
6 P, ( 5 - 6
4 P, ( 6 - 4
5 P, ( 7 - 5
F P, ( 8 - 15
E P, ( 9 - 14
C P, ( 10 - 12
D P, ( 11 - 13
8 P, ( 12 - 8
9 P, ( 13 - 9
B P, ( 14 - 11
A P, ( 15 - 10
CONSTANT CONV-TBL-GRAY2HEX

So we will use the OO word for ports, and get all of PortB then strip off the four bits we need.

HEX
PORTB GETBYTE F AND

Then we use that gray number to add to our index and convert to the equivalent hex number

CONV-TBL-GRAY2HEX + P@

And there on the stack you have your result.

Newbie
02-19-04, 08:24 AM
Yes, this is quite a bit different than the other encoder I mentioned before. I am still going to use the other encoder in the prototype, but right now for testing purposes, this $15 encoder was a lot easier to talk my superiors into paying for than the other $450 dollar encoder I hope to use in the final design.

It is indeed an eight position encoder. They also offer a 16 position encoder, so I suspect that they use the same housing for both, and the 1st bit is never set on the 8 position kind. I would have gotten the 16 position, but it was on backorder.

I already have an 8 bit lcd connected to PB0-PB7, with RS, R/W, and E on PA0-PA2. Will it still work connecting the encoder to PA4-PA7? How would this change the code below?

I really appreciate all the help. I am a Sophomore Electrical Engineering Major on his first Co-op, and the company I work for is just starting their Co-op program, and has no Electrical Engineers or programmers that I can consult. Your company has great customer service. :)

RMDumse
02-19-04, 09:14 AM
Thanks for the compliment. Customer service is something we've always held as important.

Now, since you're goiing to use high bits on Port A, you will need to shift them down to the low bits before using them as an index into the table... or you're going to need a really big table! Better to just shift them down. As before we get the port and strip the bits we aren't interested in.

HEX
PORTA GETBYTE F0 AND

Then we can shift right one bit quickly with a 2/ which is a direct word to the LSR instruction of the processor. To shift the PA4 into the 0th bit, we'll need to do it four times.

2/ 2/ 2/ 2/

Then it is a 4 bit index we add to convert to the equivalent hex number

CONV-TBL-GRAY2HEX + P@

I guess if we're going to use 2/ four times, we really don't need the F0 AND, since those bits get shifted down and thrown away anyway. But I was afraid if I didn't include the mask as I did last time it might be confusing. Oh well. Use it if it makes you fell secure you're done with the extraneous bits, or don't use it and save 3 words of program space and a few microseconds of run time.

Newbie
02-19-04, 11:46 AM
I need a little help with the coding. Here is what I have so far. Most of this code is taken from or is similiar to code taken from the New Micros Download page. I need some help making "Degrees" loop continuously so it constantly refreshes the screen. Thanks!

EDIT: Is there a way to set it so it only refreshes the lcd when it senses a change in inputs? How would I go about comparing two numbers in the stack and only running DEGREES when they are not equal?

(INSERT 8-BIT LCD CODE FROM DOWNLOAD PAGE HERE)
DECIMAL
PHERE
0 P,
1 P,
3 P,
2 P,
7 P,
6 P,
4 P,
5 P,
360 P, ( 8 - 360
315 P, ( 7 - 315
270 P, ( 6 - 270
225 P, ( 5 - 225
180 P, ( 4 - 180
135 P, ( 3 - 135
90 P, ( 2 - 90
45 P, ( 1 - 45
CONSTANT CONV-TBL-GRAY2DEC

VARIABLE DEG
-2 ALLOT ( BACK OUT THE BYTES ALLOTED FOR THE VARIABLE IN RAM
8 ALLOT ( OPEN A HOLE IN THE CURRENT DICTIONARY FOR THE STRING IN DEG
DEG 8 ERASE ( CLEAN OUT THE HOLE WITH NULS
( NOW LOAD IT
CR ( ADD FROM HERE ) DEG 8 EXPECT
DEG:

VARIABLE NUM1
: DEGREES

DSP-INIT
DEG 5 DSP-TYPE

PORTA GETBYTE
2/ 2/ 2/ 2/ ( SHIFT RIGHT FOUR TIMES TO GET PA4 IN 0TH BIT
CONV-TBL-GRAY2DEC + P@ ( ADD FOUR BIT INDEX
NUM1 !
NUM1 @ .DSP
( DISPLAYS NUMBER ON TOP OF STACK @ LCD
DROP ( ERASES NUMBER FROM STACK
; EEWORD

Newbie
02-20-04, 10:34 AM
Perhaps something like this:

: COMPARE
PORTA GETBYTE
2/ 2/ 2/ 2/ ( SHIFT RIGHT FOUR TIMES TO GET PA4 IN 0TH BIT
CONV-TBL-GRAY2DEC + P@ ( ADD FOUR BIT INDEX
NUM2 !
IF
NUM1 = NUM2
THEN
DROP
DEGREES
COMPARE
ELSE
NUM2 @ .DSP
DROP
DEGREES
COMPARE
; EEWORD

only it won't let me call "COMPARE" in compare. Any help with recursive functions?

RMDumse
02-20-04, 10:58 AM
IF structure is not Forth like, so in wrong order.

: COMPARE
NUM2 @ NUM1 !
PORTA GETBYTE
2/ 2/ 2/ 2/ ( SHIFT RIGHT FOUR TIMES TO GET PA4 IN 0TH BIT
CONV-TBL-GRAY2DEC + P@ ( ADD FOUR BIT INDEX
NUM2 !
NUM2 @ NUM1 @ = NOT
IF
DEGREES
NUM2 @ .DSP
then
; EEWORD

So this saves the old value, gets the new value, and only if the new value is different from the old value, it would redo the display. (I haven't looked closely at the IF -- THEN portion, so I don't know if DEGREES NUM2 @ .DSP will get you waht you want)

only it won't let me call "COMPARE" in compare. Any help with recursive functions?

You don't want to do recursion here, because you will overrun your call stack eventually and everything will blow up.

Basically, you want this process done over and over again. In non IsoStructured format, you'd just loop. So you'd use a BEGIN UNTIL or a BEGIN AGAIN or a BEGIN WHILE REPEAT. If you do this, the word looped around gets every possible cycle of the processors time to be somewhere in that process of saving the last reading, getting the new one, comparing them, and displaying them if they change.

Now, your eye can only see visual changes something like every 20 times a second or so. (Otherwise movies would look jumpy and blurry.) So updating the display something like 20,000 times a second is just a waste of processor time.

So the way you'd do this in IsoStructure is to make a word the updates the dislay (like you have in COMPARE) and install it into a background schedule to run just a bit more often than your eye can actually see, and run periodically and quit. The remainin processor cycles not taken up doing that continuously is left over for other tasks (like still talking to you while the display updates for instance).

So once you've got COMPARE working just the way you want, use install to set it running in the back ground. Your display will always have fresh data shown on it, and it will change faster than even your eye can track, and you'll still have a very high percentage of your processor still available for other things

START-ISOMAX
INSTALL COMPARE

Newbie
02-23-04, 07:33 AM
I have got degrees on the lcd and refreshing, but I am having some trouble displaying fuze seconds. The code I used is below. Is "NUM2 7 / .DSP the correct format for dividing degrees by 7 and displaying? Do I have to store this number at an address first? When I tried the code like it is, it always displays the number "85".

VARIABLE NUM1
VARIABLE NUM2

: DEGREES
PORTA GETBYTE
2/ 2/ 2/ 2/ ( SHIFT RIGHT FOUR TIMES TO GET PA4 IN 0TH BIT
CONV-TBL-GRAY2DEC + P@ ( ADD FOUR BIT INDEX
NUM1 !
( NUM1 @ .DSP ( DISPLAYS NUMBER ON TOP OF STACK @ LCD
DROP ( ERASES NUMBER FROM STACK
; EEWORD

: COMPARE
NUM2 @ NUM1 !
PORTA GETBYTE
2/ 2/ 2/ 2/ ( SHIFT RIGHT FOUR TIMES TO GET PA4 IN 0TH BIT
CONV-TBL-GRAY2DEC + P@ ( ADD FOUR BIT INDEX
NUM2 !
NUM2 @ NUM1 @ = NOT
IF
DSP-INIT
DEG 5 DSP-TYPE
NUM2 @ .DSP
CRLF
FSECS 7 DSP-TYPE
NUM2 7 / .DSP
DEGREES
THEN
; EEWORD

ISOMAX-START
INSTALL COMPARE

]

RMDumse
02-23-04, 07:47 AM
No, NUM2 7 / .DSP is the correct format for dividing the address of degs by 7 and displaying it.

You need to fetch the address to get the contents of the variable. So try NUM2 @ 7 / .DSP

Newbie
02-25-04, 12:07 PM
I am attempting to make a startup message that stays on the LCD screen for 5 seconds before going into my "COMPARE" machine. When I run the code below, it just outputs garbage to the screen.

VARIABLE NUM1
VARIABLE NUM2
VARIABLE SECOND
DECIMAL 0 SECOND !

: DEGREES
PORTA GETBYTE ( captures 4 bit # from port A
2/ 2/ 2/ 2/ ( shift right four times to get PA4 in 0th bit position
CONV-TBL-GRAY2DEC + P@ ( add four bit index
NUM1 ! ( stores number at NUM1
( NUM1 @ .DSP ( displays number on top of stack @ lcd
DROP ( erases number from stack
; EEWORD

: DSP-TICK
50000 PERIOD
0 TCFTICKS !
ISOMAX-START
TCFTICKS @ 100 >
IF
SECOND 1+!
0 TCFTICKS !
THEN
SECOND @ 6 <
IF
DSP-INIT
NTE 7 DSP-TYPE
CRLF
VER 12 DSP-TYPE
THEN
; EEWORD

: COMPARE
DSP-TICK
NUM2 @ NUM1 ! ( stores value of NUM2 at NUM1
PORTA GETBYTE ( gets byte from port A
2/ 2/ 2/ 2/ ( shift right 4 times to get PA4 in 0th bit position
CONV-TBL-GRAY2DEC + P@ ( add 4 bit index
NUM2 ! ( stores number at NUM2
NUM2 @ 6 <
NUM2 @ NUM1 @ = NOT
AND
IF
DSP-INIT
SAFE 8 DSP-TYPE
DEGREES
THEN
NUM2 @ NUM1 @ = NOT ( compares NUM1 to NUM2
IF ( IF -- NUM1 is not equal to NUM2
DSP-INIT ( THEN -- initialize display
DEG 5 DSP-TYPE ( display DEG: on lcd
NUM2 @ .DSP ( display NUM2 on lcd
CRLF ( moves to second line of lcd
FSECS 7 DSP-TYPE ( displays FSECS: on lcd
NUM2 @ 7 / .DSP ( divides NUM2 by 7 and displays result on lcd
DEGREES ( starts degrees
THEN

; EEWORD

ISOMAX-START ( initializes and starts IsoMax
EVERY 50000000 CYCLES SCHEDULE-RUNS COMPARE
INSTALL COMPARE

RMDumse
02-25-04, 01:53 PM
Look at the last lines.

ISOMAX-START ( initializes and starts IsoMax
EVERY 50000000 CYCLES SCHEDULE-RUNS COMPARE
INSTALL COMPARE

Basically if you use INSTALL, you don't use SCHEDULE-RUNS, if you use SCHEDULE-RUNS, you don't use INSTALL.

So you should probably have

ISOMAX-START ( initializes and starts IsoMax
INSTALL COMPARE

or you should have

EVERY 50000000 CYCLES SCHEDULE-RUNS COMPARE

but 65535 is as high as you can go with CYCLEs

EVERY 50000 CYCLES SCHEDULE-RUNS COMPARE

I guess you were thinking 50000000 would be 5 seconds before the next instruction ran, but that's not how it works.

What you would need is something that updated the display, waited for 5 seconds before then turning over control to COMPARE.

I see you were trying something like that in the DSP-TICKS, and playing with PERIOD.


What I would do in this situation would be to set up a machine. It would have three states. The first state would be where it would initialize and start. It would put up the openning message on the display. It would reset a counter. Then go to the second state. The second state would increment (or decrement depending on the way I was counting) the counter until it matched some value. When it matched it would go to the third state which called the COMPARE routine.

Newbie
03-02-04, 08:15 AM
I am having a bit of trouble. I am trying to change my old code so that it displays a floating point number on the lcd. When the code "FCONSTANT CONV-TBL-GRAY2DEC" executes, it IsoMax gives me a ? and says stack is empty. Could you please check over my code and help? Also, could you look over my machine at the bottom and let me know if it is in the right format? Thank you.

: .DSP ( n -- ) DUP ABS 0 <# #S SIGN #> DSP-TYPE ; EEWORD ( formats output

DECIMAL
PHERE
0.00e F,
1.00e F,
3.00e F,
2.00e F,
7.00e F,
6.00e F,
4.00e F,
5.00e F,
40.00e F, ( 8 - 360
35.00e F, ( 7 - 315
30.00e F, ( 6 - 270
25.00e F, ( 5 - 225
20.00e F, ( 4 - 180
15.00e F, ( 3 - 135
10.00e F, ( 2 - 90
5.00e F, ( 1 - 45
FCONSTANT CONV-TBL-GRAY2DEC
( look up table for 8-position 4 bit encoder

VARIABLE DEG
-2 ALLOT ( back out the bytes alloted for the variable in ram
8 ALLOT ( open a hole in the current dictionary for the string in FSECS
DEG 8 ERASE ( clean out the hole with nuls
( now load it
CR ( add from here ) DEG 8 EXPECT
DEG:
( displays DEG: on lcd display

VARIABLE FSECS
-2 ALLOT ( back out the bytes alloted for the variable in ram
10 ALLOT ( open a hole in the current dictionary for the string in FSECS
FSECS 10 ERASE ( clean out the hole with nuls
( now load it
CR ( add from here ) FSECS 10 EXPECT
FSECS:
( displays FSECS: on lcd display

VARIABLE SAFE
-2 ALLOT ( back out the bytes alloted for the variable in ram
10 ALLOT ( open a hole in the current dictionary for the string in FSECS
SAFE 10 ERASE ( clean out the hole with nuls
( now load it
CR ( add from here ) SAFE 10 EXPECT
SAFE

VARIABLE NTE
-2 ALLOT ( back out the bytes alloted for the variable in ram
9 ALLOT ( open a hole in the current dictionary for the string in FSECS
NTE 9 ERASE ( clean out the hole with nuls
( now load it
CR ( add from here 7 ) NTE 9 EXPECT
NTE
( displays NTE on lcd display

VARIABLE VER
-2 ALLOT ( back out the bytes alloted for the variable in ram
13 ALLOT ( open a hole in the current dictionary for the string in FSECS
VER 13 ERASE ( clean out the hole with nuls
( now load it
CR ( add from here ) VER 13 EXPECT
VERSION 1.0
( displays VER on lcd display

FVARIABLE NUM1
FVARIABLE NUM2
VARIABLE SECOND
DECIMAL 0 SECOND !

: F> F< NOT ;

: DEGREES
PORTA GETBYTE ( captures 4 bit # from port A
2/ 2/ 2/ 2/ ( shift right four times to get PA4 in 0th bit position
CONV-TBL-GRAY2DEC + F@ ( add four bit index
NUM1 F! ( stores number at NUM1
( NUM1 F@ .DSP ( displays number on top of stack @ lcd
DROP ( erases number from stack
; EEWORD

: COMPARE
NUM2 F@ NUM1 F! ( compares NUM1 to NUM2 and stores in memory
PORTA GETBYTE ( gets byte from port A
2/ 2/ 2/ 2/ ( shift right 4 times to get PA4 in 0th bit position
CONV-TBL-GRAY2DEC + F@ ( add 4 bit index
NUM2 F! ( stores number at NUM2
NUM2 F@ 6 F<
NUM2 F@ NUM1 F@ = NOT
AND
IF
DSP-INIT
SAFE 8 DSP-TYPE
DEGREES
THEN
NUM2 F@ NUM1 F@ = NOT ( compares NUM1 to NUM2 1
IF ( IF -- NUM1 is not equal to NUM2 5
DSP-INIT ( THEN -- initialize display
DEG 5 DSP-TYPE ( display DEG: on lcd
NUM2 F@ .DSP ( display NUM2 on lcd
CRLF ( moves to second line of lcd
FSECS 7 DSP-TYPE ( displays FSECS: on lcd
NUM2 F@ 7.00e F/ .DSP ( divides NUM2 by 7 and displays result on lcd
DEGREES ( starts degrees 0
THEN

; EEWORD


MACHINE 5SEC
ON-MACHINE 5SEC
APPEND-STATE BOOT
APPEND-STATE UPDATE
APPEND-STATE COMP

IN-STATE BOOT
CONDITION TRUE CAUSES
50000 PERIOD
0 TCFTICKS !
DSP-INIT
NTE 7 DSP-TYPE
CRLF
VER 12 DSP-TYPE
THEN-STATE
UPDATE TO-HAPPEN IN-EE

IN-STATE UPDATE
CONDITION TRUE CAUSES
ISOMAX-START
TCFTICKS @ 100 >
IF
SECOND 1+!
0 TCFTICKS !
THEN
SECOND @ 5 >
IF
STOP-TIMER
THEN
THEN-STATE COMP
TO-HAPPEN IN-EE

IN-STATE COMP
CONDITION TRUE CAUSES
COMPARE
THEN-STATE COMP
TO-HAPPEN IN-EE

SET-STATE BOOT
SCHEDULE-RUNS 5SEC

RMDumse
03-02-04, 08:25 AM
The PHERE result is an address.

FCONSTANT compiles a two word floating point constant.

A one word address and a two word floating point constant are not the same thing. So an extra word is stollen from the stack to make the constant.

You should have used just CONSTANT, not FCONSTANT to name the name of your table. The table may be a table of floating point constants, but it still occurs at a regular address, not a floating point one.

RMDumse
03-02-04, 08:30 AM
MACHINE 5SEC
ON-MACHINE 5SEC
APPEND-STATE BOOT
APPEND-STATE UPDATE
APPEND-STATE COMP

All (except ON-MACHINE which is a command not a definition) should have EEWORD with them.

:F> F< NOT ; also should have an EEWORD

The useage of STOP-TIMER in the state machine troubles me. I don't know your intent, but the effect is, the machine stops running. What can start it again?

RMDumse
03-02-04, 08:32 AM
Another problem I see:

VARIABLE SAFE
-2 ALLOT ( back out the bytes alloted for the variable in ram

was taken from a byte based Forth example.

This is a word based one.

So when you say VARIABLE, you are allotted 1 word, but you do -2 ALLOT which gets you backed up 2 words. So your variables all wind up overlapped by one cell.

Just do -1 ALLOT in those cases.

Newbie
03-02-04, 08:52 AM
It will still not display a floating point. Instead of "DEG: 10 CRLF FSECS: 1" on the lcd, it shows "DEG:" and that's it. When I changed the F@ to P@ on "CONV-TBL-GRAY2DEC + F@, it showed "DEG: 561 CRLF FSECS: " which is still wrong, but is closer. Should it be P@ or F@? Is using "= NOT" a problem, like in "NUM2 F@ NUM1 F@ = NOT". Is there an F= ?

EDIT: Running this code also locks up NMITerm and i have to close it out and restart it before it responds again.

RMDumse
03-02-04, 09:06 AM
Yes there is a F= (See below, as it turns out, no there isn't.)

No, if you use f.p. numers you need f.p. comparisons. so

NUM2 F@ NUM1 F@ = NOT

should instead be

NUM2 F@ NUM1 F@ F= NOT

Once you have done the comparison f.p. style, the answer is just a boolean, so NOT works fine on booleans.

RMDumse
03-02-04, 09:13 AM
It will still not display a floating point.

That's not surprizing, because .DSP is not programmed to display a floating point. Just choosing floading point values doesn't change the program. Whatever data .DSP gets, it just makes the best one-word integer of it it can.

It would be quite complex to write a f.p. display word on the display, so before going to that trouble... what are you trying to do? Do you want to display a number with a decimal point in it? Because this is often very easily done with scaled integers.

Newbie
03-02-04, 09:17 AM
Eventually with the encoder I chose before, It will output a 12-bit number translated to angular position,and I would like to be able to display this angle to two decimal places. Also, in this case with the current encoder, when I divide the degree values I chose by 7 to get fuze seconds, I would like it to display the number to two decimal places instead of just rounding it off.

Newbie
03-02-04, 09:29 AM
Also, the F= is not recognized by IsoMax, it returns "F= ?". Is this something I have to define?

RMDumse
03-02-04, 09:40 AM
Well, I am surprised there is not a F=, but perhaps there is not. Hummm... looking in the manual at the supplied words, I see we have only F0< F0= and F< provided for f.p. comparisons. No matter! We will make one.

: F= F- F0= ; EEWORD

RMDumse
03-02-04, 09:50 AM
I would like to be able to display this angle to two decimal places. ... I would like it to display the number to two decimal places instead of just rounding it off.

Okay then. Two decimal places. Better to use scaled integers than go completely to floating point.

Let me see if I can explain scaled integers. Let's say we multiplied everything you worked on by 100 before storing it, and divided everything by 100 after fetching it, but before using it.

So

1 2 +

now store

100 * TEMP1 !

what is in TEMP1? 300 What if we want to print what is in TEMP1?

TEMP1 @ 100 / .

gives

3 OK

See? The fact the value is scaled by 100 makes little difference. Now what if we scaled the numbers before the store?

100 200 + TEMP1 !

Still 300 in TEMP1.

But!

If we force a decimal point into the result before the last two digits, we will see that value as 3.00

So for some math (addition and subtraction), the values being scaled don't bother anything. For other math (mult, div) you're going to have to rescale afterwards, but you can do this, too.

So let's rewrite a new .DSP that has 2 "apparent" decimal places.

: 2.DSP ( n -- ) DUP ABS 0 <# # # 46 HOLD #S SIGN #> DSP-TYPE ; EEWORD

I think 46 is the ascii character for "." It is inserted into the number as it is constructed. So it looks like the result has a decimal point, instead of being an integer 100 times too big.

HTH's

Newbie
03-02-04, 10:45 AM
Wow, that was a lot easier. Thank you! I've been messing with that floating point for a couple days and it gave me nothing but headaches. I've been still having some trouble with my 5 second boot screen. Every time I try to run it, it freezes at the same spot. "APPEND-STATE UPDATE EEWORD". Also, you said you are worried about the STOP-TIMER. Is it okay to just cut this out and have an IF with no THEN? Or can I have it say
SECOND @ 5 >
IF
THEN-STATE COMP
THEN
TO-HAPPEN IN-EE

EDIT: I got rid of the line ON-MACHINE 5SEC, and now it doesn't freeze up. However, at the end when I say SET-STATE BOOT, it gives me a STACK EMPTY message.

P.S. HTH's ?

nmitech
03-02-04, 12:38 PM
1. Every IF requires a THEN

2. I don't think you can call other STATE within a STATE, but you can do this,

SECOND @ 5 >
IF
COMPARE
THEN
TO-HAPPEN IN-EE

3. You don't want to STOP-TIMER while the program is running. Instead you should save the current TCFTICKS value to your temporary variable, 1SEC then compare with the next TCFTICKS values until it greater than or equal 1 second, or 100 ticks for DECIMAL 50000 PERIOD.

VARIABLE 1SEC
TCFTICKS @ 1SEC !

IN-STATE UPDATE
CONDITION
TCFTICKS @ 1SEC @ - 100 >
CAUSES
\ ISOMAX-START ( put this when you install the machine
TCFTICKS @ 1SEC ! ( reset the temp variable
SECOND 1+!
SECOND @ 5 >
IF
\ STOP-TIMER ( don't stop the timer here
COMPARE ( call compare routine here instead
THEN
TO-HAPPEN IN-EE

Newbie
03-02-04, 01:26 PM
Here's what I have now. It doesn't do anything when I enter the following code. Also, is it okay to use INSTALL COMPARE in update, or do I not need the INSTALL command?

VARIABLE 1SEC
TCFTICKS @ 1SEC !

MACHINE 5SEC EEWORD
APPEND-STATE BOOT EEWORD
APPEND-STATE UPDATE EEWORD

IN-STATE BOOT
CONDITION TRUE CAUSES
50000 PERIOD
0 TCFTICKS !
DSP-INIT
NTE 7 DSP-TYPE
CRLF
VER 12 DSP-TYPE
THEN-STATE
UPDATE TO-HAPPEN IN-EE

IN-STATE UPDATE
CONDITION TCFTICKS @ 1SEC @ - 100 >
CAUSES
0 1SEC !
SECOND 1+!
SECOND @ 5 >
IF
COMPARE
THEN
TO-HAPPEN IN-EE

ISOMAX-START
INSTALL 5SEC

nmitech
03-02-04, 02:24 PM
VARIABLE 1SEC
0 TCFTICKS !
0 1SEC !

MACHINE 5SEC EEWORD
APPEND-STATE BOOT EEWORD
APPEND-STATE UPDATE EEWORD

IN-STATE BOOT
CONDITION TRUE
CAUSES
\ 50000 PERIOD
DSP-INIT
NTE 7 DSP-TYPE
CRLF
VER 12 DSP-TYPE
THEN-STATE
UPDATE TO-HAPPEN IN-EE

IN-STATE UPDATE
CONDITION TCFTICKS @ 1SEC @ - 100 >
CAUSES
\ 0 1SEC !
TCFTICKS @ 1SEC ! ( reset new 1SEC value )
SECOND 1+!
SECOND @ 5 >
IF
COMPARE
THEN
TO-HAPPEN IN-EE

DECIMAL 50000 PERIOD
ISOMAX-START
BOOT SET-STATE ( or state-name-1 SET-STATE )
INSTALL 5SEC

Newbie
03-02-04, 02:45 PM
This code still causes the IsoPod to stop responding. I'm pretty sure it locks up at the line CONDITION TCFTICKS @ 1SEC @ - 100 > . From this point on, NMITerm still accepts lines of code, but does not give an OK after them, and commands like SCRUB do not do anything.

Newbie
03-05-04, 08:15 AM
Can anyone please help? Any ideas? It is now showing my boot screen, but it is refreshing very fast so it looks real dim, and it never calls the COMPARE function, it just stays on the boots screen.

EDIT:
What I think is happening is that in the UPDATE state, since I don't have it going to another state (i.e. THEN-STATE), that everything I type after that is still be appended to the CAUSES command in the UPDATE state, which is why it won't display OK or anything after that point. I don't know how to fix it though.

nmitech
03-05-04, 10:56 AM
Please email me techsupport@newmicros.com your entire program that you are working on. I will find a place to put for others can download to help out also. Thanks!

||
||
\/

Here is the link to Newbie program,
http://www.newmicros.com/temp/NTE.txt

nmitech
03-05-04, 12:09 PM
I took a quick look at your program and here is my suggestions,

- Don't forget to add EEWORD for every VARIABLE & CONSTANT you defined

- You should put all the strings such as DEG:, FSECS, SAFE, etc... in the flash memory so that you can call them when you need to. This way you can free some ram memory for other purposes. The LCD example to store a string is on the download page, or click here,
http://www.newmicros.com/isopod/appnotes/LCD_STRINGS.txt

Newbie
03-05-04, 12:43 PM
Here's what happens when I try to run the code. It all goes through alright until the end when it gets to the line ": STARTUP". It returns "STARTUP ?" like the CAUSES portion of the UPDATE machine still has not ended.

Newbie
03-08-04, 12:38 PM
After being unsuccessful the other way, I am trying a different approach. I used the following code:

: 5SEC 300 0 DO ." NTE VERSION 1.0 " LOOP ; EEWORD

: BOOT
DSP-INIT
NTE 7 DSP-TYPE
CRLF
VER 12 DSP-TYPE
5SEC
ISOMAX-START
INSTALL COMPARE
; EEWORD

and now it shows the boot screen, keeps it on for five seconds, and then displays the first reading from compare, but then it freezes up and I have to Alt + T twice before it will respond to commands again. How can i fix this?

RMDumse
03-10-04, 11:00 PM
Try this way to do your initial machine. I redid the timing with a single Loop Index, which counts to 500. The display initialization is done in STARTUP. WAIT5S state does the 5S wait. DO-COMPARE calls COMPARE repetitively.

( ================ Machines ============ )

LOOPINDEX 5SEC/100
1 5SEC/100 START
500 5SEC/100 END
EEWORD

MACHINE 5SEC EEWORD ( declares a machine and names it 5sec
ON-MACHINE 5SEC
APPEND-STATE WAIT5S EEWORD
APPEND-STATE DO-COMPARE EEWORD

IN-STATE
WAIT5S
CONDITION
5SEC/100 COUNT
CAUSES
( NOTHING, REALLY
THEN-STATE ( then go to the "UPDATE" state
DO-COMPARE
TO-HAPPEN IN-EE

IN-STATE
DO-COMPARE
CONDITION
TRUE
CAUSES
COMPARE
THEN-STATE
DO-COMPARE
TO-HAPPEN IN-EE


( ============= Autostart for 5SEC =========== )
DECIMAL
: STARTUP
DSP-INIT ( then initialize display and show "NTE VERSION 1.0"
NTE 7 DSP-TYPE
CRLF
VER 12 DSP-TYPE
5SEC/100 RESET
50000 PERIOD
ISOMAX-START
WAIT5S SET-STATE
INSTALL 5SEC
; EEWORD

STARTUP

( HEX 3C00 AUTOSTART STARTUP
( SAVE-RAM

Newbie
03-11-04, 07:49 AM
Thank you very much Randy! Now it runs like a champ. :D