Jon,
I first want to thank you for your eeprom table logic help last fall. My cool 'EFX-TEX' powered coffin allowed my to win 'Most Creative' campsite last year!
While looking at the code and thinking Prop-2 I saw a bit of code that I didn't undestand. I kow it's my lack of unstanding of when Bx and Wx is used. Part of the code is:
SYMBOL dc16 = W1 ' DC-16 outputs
SYMBOL dc16Lo = B2
SYMBOL dc16Hi = B3
SYMBOL rc4 = B3 ' RC-4 outputs
SYMBOL pntr = B4 ' eeprom pointer
SYMBOL ticDelay = W3
I don't understand why B3 was used twice. Perhaps a quick primer on the difference would help. Thanks Jon. Please take your time I know your busy this weekend with the convention, etc.
Ron
Ron,
I can't explain why B3 was used twice (it looks like an error to me, but it's tough to say without seeing the source code), but I'll try to explain the difference between Bx and Wx.
The Parallax "Basic Stamp Syntax and Reference Manual Version 2.2" (http://www.parallax.com/dl/docs/prod/stamps/web-BSM-v2.2.pdf (http://www.parallax.com/dl/docs/prod/stamps/web-BSM-v2.2.pdf)) is very useful here. Table 4.1 (page 86 of 504) shows the BS1 (Basic Stamp 1 which is what the prop-1 uses) RAM Organization. The BS1 has 16 bytes of Variable RAM space.
A couple of useful terms:
1 byte = 8 bits
2 bytes = 16 bits = 1 word
An explaination of bits, bytes, words:
1) A bit can represent two values (0 or 1)
2) A byte can represent a whole number between 0 and 255
3) A word can represent a whole number between 0 and 65535
In BS1, a Bx represents a "byte" and a Wx represents a "word". In your example, the variable "dc16" is held in "W1" (or Word 1) which consists of 16 bits (1 bit per DC-16 output). Each bit can either be "on" (1) or "off" (0) and therefore each output of the DC-126 can be either "on" or "off". W1 (Word 1) is made up of 2 bytes (B2 and B3). The varaible "dc16Lo" is bits 0 - 7 (8 bits) of W1 (Word 1). The variable "dc16Hi" is bits 8 - 15 (8 bits) of W1 (Word 1).
In your example, the variable "pntr" is held in B4 (Byte 4) and can contain a whole number between 0 and 255. In your example, the variable "ticDelay" is held in W3 (Word 3) and can contain a whole number between 0 and 65535.
The use of bytes and words depends on how "big" of a number you need. If a variable is going to be less than the number 256 you should use a "byte". If a variable is going to be larger than 255, but less than 65536 you should use a "word".
The BS1 only allows the user to use 6 "words" (W1 - W5) for variables which can also be accessed by "bytes" (B0 - B11). This is not a lot of space, so use it wisely.
I hope this explains the difference between Bx and Wx.
Ron,
I'll see if I can track down that program -- it does look like an error on the surface, but there's another possibility: if a table line does only DC-16 or RC-4 control, but not both, the re-use would be okay. But, if a given command line holds info for both then there is an error, and I'm sorry if that's my doing.
Many will find the Prop-2 a bit easier to program because it's compiler automatically assigns variable locations, on simply has to tell the compiler how big the variable is (word, byte, nib, or bit). One of the great things about Prop-2 variables is that the all bit access (only B0 and B1 have this on the Prop-1), and none of them are used as the GOSUB stack (as is W6 in the Prop-1) ; this saves a lot of assignment worries.
Things are hectic today as I'm packing to head over the hill (I live in "the valley") to Los Angeles for Haunt X, but I'll see if I can find it and verify a potential problem.
Found it -- it was indeed an error on my part. Here's the correction; thankfully there's plenty of variable space left in this program.
' =========================================================================
'
' File....... Ron_Coffin-RC4-JW.BS1
' Purpose.... Control coffin via Prop1 and DC-16
' Author..... Ron G.
' E-mail..... rguard1@hfhs.org
' Started.... 30 AUG 2006
' Updated.... 16 FEB 2007 -- by Jon Williams
'
' {$STAMP BS1}
' {$PBASIC 1.0}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
' -----[ Revision History ]------------------------------------------------
' -----[ I/O Definitions ]-------------------------------------------------
SYMBOL Sio = 7 ' serial comms
SYMBOL PIR = PIN6 ' active high input
SYMBOL Eyes = 5 ' Skeleton eyes & power to creak
SYMBOL Rats = 4 ' Rats eyes and motion
SYMBOL S4 = 3 ' Extend arm solenoid
SYMBOL S3 = 2 ' Turn solenoid
SYMBOL S2 = 1 ' Body solenoid
SYMBOL S1 = 0 ' Lid solenoid
'Address: 1 = Sound On DC-16
' 2 = Sound Off DC-16
' 3 = Creaking DC-16
' 4 = S.Terry DC-16
' 9 = BLight DC-16
' 10 = Strobe DC-16
' -----[ Constants ]-------------------------------------------------------
SYMBOL Baud = OT2400 ' Connection speed to DC-16
SYMBOL RC4Addr = %11 ' %00 - %11
SYMBOL DC16Addr = %11
SYMBOL Yes = 1
SYMBOL No = 0
' -----[ Variables ]-------------------------------------------------------
SYMBOL tix = B0 ' step timing
SYMBOL tmr10x = BIT7 ' high bit of tix
SYMBOL local = B1 ' Prop-1 outputs
SYMBOL done = BIT15 ' high bit of local
SYMBOL dc16 = W1 ' DC-16 outputs
SYMBOL dc16Lo = B2
SYMBOL dc16Hi = B3
SYMBOL rc4 = B4 ' RC-4 outputs
SYMBOL pntr = B5 ' eeprom pointer
SYMBOL ticDelay = W5
' -----[ EEPROM Data ]-----------------------------------------------------
' Record structure:
' local rc4 dc16hi dc16Lo tix
' | | | | |x|
EEPROM (%00110000, %0000, %00000001, %00000001, %00000101)
EEPROM (%00110000, %0000, %00000001, %00000000, %10000101)
EEPROM (%00110001, %0000, %00000001, %00000100, %00000101)
EEPROM (%00110001, %0000, %00000001, %00000000, %10000010)
EEPROM (%00110001, %0000, %00000011, %00000000, %10000101)
EEPROM (%00110001, %0000, %00000001, %00000000, %10111100)
EEPROM (%00110011, %0000, %00000011, %00000000, %10110010)
EEPROM (%00110111, %0000, %00000001, %00000000, %10000011)
EEPROM (%00110111, %0000, %00000011, %00000000, %10000101)
EEPROM (%00111111, %0000, %00000001, %00000000, %10000101)
EEPROM (%00111111, %0000, %00000010, %00001000, %00000101)
EEPROM (%00111111, %0000, %00000010, %00000000, %10001010)
EEPROM (%00111111, %0000, %00000011, %00000000, %10000101)
EEPROM (%00111111, %0000, %00000001, %00000000, %10000101)
EEPROM (%00111111, %0000, %00000011, %00000000, %10001010)
EEPROM (%00111111, %0000, %00000001, %00000000, %10011110)
EEPROM (%00110111, %0000, %00000010, %00000000, %10001010)
EEPROM (%00110011, %0000, %00000010, %00000000, %10001010)
EEPROM (%00110001, %0000, %00000001, %00000000, %10010100)
EEPROM (%00110000, %0000, %00000001, %00000100, %00000101)
EEPROM (%00000000, %0000, %00000000, %00000000, %10001010)
EEPROM (%00000000, %0000, %00000000, %00000010, %00001010)
EEPROM (%10000000, %0000, %00000000, %00000000, %10111100) ' end of sequence
EEPROM (%00000000, %0000, %00000000, %00000000, %00000000) ' free space
EEPROM (%00000000, %0000, %00000000, %00000000, %00000000)
EEPROM (%00000000, %0000, %00000000, %00000000, %00000000)
EEPROM (%00000000, %0000, %00000000, %00000000, %00000000)
' -----[ Initialization ]--------------------------------------------------
Reset:
DIRS = %00111111 ' setup I/Os
tix = 60 ' delay for PIR warm-up
tmr10x = Yes ' timer mode is seconds
done = Yes ' reset sequence
GOTO Update_Outputs
' -----[ Program Code ]----------------------------------------------------
Main:
IF PIR = No THEN Main ' wait for trigger
pntr = 0 ' reset to start of sequence
Get_Record:
READ pntr, local ' get local pins
pntr = pntr + 1
READ pntr, rc4
pntr = pntr + 1
READ pntr, dc16Hi ' get DC-16 pins
pntr = pntr + 1
READ pntr, dc16Lo
pntr = pntr + 1
READ pntr, tix ' get timing
pntr = pntr + 1 ' point to next record
Update_Outputs:
PINS = local & %00111111
SEROUT Sio, Baud, ("!RC4", RC4Addr, "S", rc4)
SEROUT Sio, Baud, ("!DC16", DC16Addr, "S", dc16Lo, dc16Hi)
Timer_Setup:
ticDelay = 100 ' normal tic = 0.1 sec
IF tmr10x = No THEN Run_Timer
ticDelay = 1000 ' 10x tic = 1 sec
tmr10x = No ' clear multiplier bit
Run_Timer:
IF tix = 0 THEN Timer_Exit
PAUSE ticDelay
tix = tix - 1
GOTO Run_Timer
Timer_Exit:
IF done = No THEN Get_Record
GOTO Main
' -----[ Subroutines ]-----------------------------------------------------
And here's a Prop-2 version that eliminates the DC-16. You can see that some of the "modern" features of PBASIC 2.5 make coding a little more elegant. Not that there's anything wrong with PBASIC 1.0, because it is in fact very efficient (it has to be for such a tiny memory footprint). The Prop-2 version gives you lots of table space.
Note: I didn't port the data table because my brain is mush this morning... and I've got to get going to Haunt X (after another run to Starbucks!).
' =========================================================================
'
' File....... Ron_Coffin-RC4-JW.BS2
' Purpose.... Control coffin via Prop2
' Author..... Ron G.
' E-mail..... rguard1@hfhs.org
' Started.... 30 AUG 2006
' Updated.... 16 FEB 2007 -- by Jon Williams (port to Prop-2)
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
' -----[ Revision History ]------------------------------------------------
' -----[ I/O Definitions ]-------------------------------------------------
Sio PIN 15 ' serial comms
PIR PIN 14 ' active-high input
SoundOff PIN 10
SoundOn PIN 9
Creaking PIN 8
BLight PIN 7
Strobe PIN 6
Eyes PIN 5
Rats PIN 4
Arm PIN 3
Turn PIN 2
Body PIN 1
Lid PIN 0
' -----[ Constants ]-------------------------------------------------------
#SELECT $STAMP
#CASE BS2, BS2E, BS2PE
T2400 CON 396
T4800 CON 188
T9600 CON 84
T19K2 CON 32
T38K4 CON 6
#CASE BS2SX, BS2P
T2400 CON 1021
T4800 CON 500
T9600 CON 240
T19K2 CON 110
T38K4 CON 45
#ENDSELECT
Inverted CON $4000
Open CON $8000
Baud CON Open | T38K4
RC4Addr CON %11
Yes CON 1
No CON 0
' -----[ Variables ]-------------------------------------------------------
tix VAR Byte
tmr10x VAR tix.BIT7
ticDelay VAR Word
local VAR Word
done VAR local.BIT15
rc4 VAR Byte
pntr VAR Byte
' -----[ Initialization ]--------------------------------------------------
Reset:
OUTS = %0000000000000000 ' clear everything
DIRS = %0000011111111111 ' set output pins
tix = 60 ' delay for PIR warm-up
tmr10x = Yes ' timer mode is seconds
done = Yes ' reset sequence
GOTO Update_Outputs
' -----[ Program Code ]----------------------------------------------------
Main:
DO
pntr = 0 ' reset to start of sequence
LOOP UNTIL (PIR = Yes) ' wait for trigger
Get_Record:
READ Sequence1 + pntr, Word local, rc4, tix ' read one record
pntr = pntr + 4 ' point to next record
Update_Outputs:
OUTS = local & %0000011111111111
SEROUT Sio, Baud, ["!RC4", RC4Addr, "S", rc4]
Timer_Setup:
IF (tmr10x = No) THEN
ticDelay = 100 ' normal tic = 0.1 sec
ELSE
ticDelay = 1000 ' 10x tic = 1 sec
tmr10x = No ' clear multiplier bit
ENDIF
Run_Timer:
DO WHILE (tix > 0)
PAUSE ticDelay
tix = tix - 1
LOOP
Check_Next:
IF (done = No) THEN Get_Record
GOTO Main
' -----[ Subroutines ]-----------------------------------------------------
' -------------------------------------------------------------------------
' -----[ EEPROM Data ]-----------------------------------------------------
' Record structure:
' local rc4 tix
' | | |x|
Sequence1 DATA %0000000000000000, %0000, %00000101
DATA %1000000000000000, %0000, %00000000 ' end
Too many overlapping posts :-)
Now I have to pick up a Prop-2!!!!!!
If my primer thank you was lost......thank you. It greatly helps me understand.
-Ron
Always glad to help, Ron.
And I just noticed something -- here's a way to free a few more EEPROM bytes in your BS1 program:
Timer_Setup:
ticDelay = 900 * tmr10x + 100 ' set timing
tmr10x = No ' clear multiplier
If the 10x bit is 1 the timing is set to 1000; if it's 0 the timing is set to 100. Sorry I didn't see this opportunity the first time.