PDA

View Full Version : Converting 16b number to 2 8b numbers


ken
12-03-07, 12:57 PM
Hi
I'm playing with a Roomba Create, and communicating with is via SCI1. It uses 8 bit op codes to send commands and receive data. When receiving data from the Roomba, I figured out how to combine 2 8b numbers into a 16b number by using the following code snip:

: GETV
142 SCI1 TX ( op code for roomba to send a sensor packet )
22 SCI1 TX ( op code for battery voltage. roomba sends unsigned 16b number as 2 8b numbers, high byte first )
SCI1 RX >< ( get first byte. swap bytes. first sent number is now the high byte )
SCI1 RX OR U. ."millivolts" (get second byte. combine the numbers to make the 16b number and print )
;

Now my question is how do I do the reverse. I want to send a drive command, and it takes as a argument a signed
16b number. I have to send this command as 2 8b numbers. I don't know how to split the signed 16b number into 2 8b numbers in FORTH ( n -- 8b, 8b ) without something like a bitshift command (<< or >> in C), which I could not find.

Thanks
Ken

nmitech
12-03-07, 01:23 PM
I can't think of any word that will do a short cut for bit shift. Here is what i came up with,

HEX OK
VARIABLE LSB OK
VARIABLE MSB OK
: >>8 2/ 2/ 2/ 2/ 2/ 2/ 2/ 2/ ; OK

6677 DUP >>8 MSB ! 00FF AND LSB ! OK

MSB @ U. 66 OK
LSB @ U. 77 OK

ken
12-03-07, 01:31 PM
Thanks for the fast reply. I'll try that when I get home.

Ken

RMDumse
12-03-07, 02:01 PM
Think I'd use byteswap again.

DUP >< ( original and >< copy
FF AND ( strip out high byte only
( use 255 if in decimal instead of FF
SCI1 TX ( send
FF AND ( strip out lo byte only
SCI1 TX ( send

ddlawrence
02-13-08, 06:13 PM
Hi. I need to send a VARIABLE from a PlugaPod master to a PlugaPod slave via SCI0. The slave then acts accordingly. I can see what RMDumse is doing for VARIABLE to 2 byte conversion. I also need to convert those 2 bytes back to a VARIABLE.


thanks...........don

RMDumse
02-14-08, 03:51 PM
Essentially, you just go the reverse direction

SCI1 RX ( get character
FF AND ( strip out high byte only
>< ( byteswap to the high order bits
SCI1 RX ( get character
FF AND ( strip out high byte only
OR ( combine the two received char

Watch out because RX will hand waiting for a character. Better to check first to see if they are there. Also realize you are sending 8-bit codes, which some ASCII programs might try to interpret as commands. For instance if your HEX value being sent was 070D, a terminal receiving that would see it as a bell character and a chariage return, so the terminal would do those things, rather than display them.

ddlawrence
02-15-08, 11:48 AM
ok thanks...........don

ddlawrence
02-17-08, 05:48 PM
Things are progressing great. I'm really happy, this is cool. Now I would like to
use NMIterm as a data analyser to monitor the master and slave talking to
each other. But it has to be in hex mode instead of those funny characters.
Is this possible?

The master sends angle commands as an integer 0 to 720 decimal.
The slave responds by echoing it. This works for a hundred or so commands
then the echo does not check correctly and I can't see what is happening.

Also, is there a way of finding out how much memory I have left for large
programs?

thanks.....don

RMDumse
02-17-08, 10:49 PM
Well, instead of hex, since you only need 0 - 720, how about encoding and decoding in ASCII decimal? Then all the characters can go through? So you'll be sending three bytes instead of two, but they will be human readable.

HEX
: TX3
64 /MOD SWAP 30 + EMIT
A /MOD SWAP 30 + EMIT
30 + EMIT
;

: RX3
KEY 30 - A *
KEY 30 - + A *
KEY 30 - +
;

Use SCIx RX if you prefer rather than KEY and SCIx TX rather than EMIT if you want.

64 in hex is 100. So you strip the 100's digit and add 30 to it to make it 30 to 39, or char 0 to char 9. A in hex is 10, so you strip the 10's digit and convert it. Finally the one's digit is left, convert it and send too.

Receiving you get the hundreds digit, strip off the ASCII 30 back to a digit, multiple by A. Then you get the ten's digit, strip off the ASCII 30 back to a digit, add to the hundred's digit (already shifted up by 10) multiple by A. Then you get the one's digit, strip off the ASCII 30 back to a digit, add to the hundred's/ten's combined digits. You've got your number back.

ddlawrence
02-18-08, 02:55 PM
Yeah that should work. I'll try it. It is a little more computational effort and
may cause an overrun. I have to do this at a rate of 200 times a second.

thanks............don

ddlawrence
02-22-08, 06:50 PM
Thanks she worked! (FYI without the SWAP).

Now I have another problem.
The master and slave are talking back and forth happily.
When I add a single line to the master program, the master
resets and they start spewing all kinds of nonsense back and forth.
That single line is:

VARIABLE MYVAR

Which is inserted at the beginning of master with all the other variables.
No other changes to master or slave whatsoever.
I can reproduce this condition time and again.

Now, how can I check for out of memory?

And how can I check for a stack overflow?

I am fairly green at this microcoding stuff and I am running out of ideas.

thanks........don

RMDumse
02-23-08, 11:11 AM
I answer these often at night and on the weekend when I have no board at hand to test with 9as is the case right now), so for the sake of anyone reading let me be sure you've tested the code and it should not have swaps in it like this:

HEX
: TX3
64 /MOD 30 + EMIT
A /MOD 30 + EMIT
30 + EMIT
;

: RX3
KEY 30 - A *
KEY 30 - + A *
KEY 30 - +
;

I have trouble remembering the order of values left by /MOD. Okay.

Now you are asking about out of memory. Likely. We have very little RAM to work with, and quite a bit of flash. When you find adding a simple definition like that gives trouble, and you're all RAM based, yes, you're likely out of RAM.

So you change and switch over to putting somethings away in Flash. To do this, you put EEWORD (named before EEPROM became Flash) after every definition. EEWORD picks up the last definition, relinks it, and moves it to Flash, and recovers the RAM space it was in so we can lay down another definition in RAm.

So in the above example you'd do

VARIABLE MYVAR EEWORD

HEX
: TX3
64 /MOD 30 + EMIT
A /MOD 30 + EMIT
30 + EMIT
; EEWORD

: RX3
KEY 30 - A *
KEY 30 - + A *
KEY 30 - +
; EEWORD

Then you should be good to go. Remember after putting things in flash, the flash will be changed. If you want it back, like you want to redownload your code from the beginning, you do SCRUB to clean it out, so you can reflash the program from the beginning. Otherwise you'll be writing the same definitions over top where they already are, which might work, until the changes start, and the bit patterns clash, and trouble begins. So remember to use SCRUB.

ddlawrence
02-25-08, 12:04 PM
Hi Thanks again for the help. I will move the code into flash.
Still I want to know how much storage my code takes up.
I have much more coding to do and I must know if it will all
fit into the Pod. Is there a way of calculating or estimating
memory requirements?

thanks....don

nmitech
02-26-08, 10:13 AM
AVAIL ? ( return the available data ram memory )
PAVAIL ? ( return the available program ram memory )
PFAVAIL ? ( return the available program flash memory )