Help with Stargate project running out of memory
I am working on a project building a stargate as in Stargate SG1. I am using a servo to turn the inner wheel and a cherry picker switch to count grooves that correspond to the symbols on the wheel. The switch will later be changed out for an opto coupler for greater accuracy.
I have a BS2e and I am using an infrared remote control to select a symbol
from 1 to 39.· I enter the number then press enter on the remote.
··
After entering the number the stargate moves left until it counts to the first chevron then it moves right to the second chevron, then it moves the selected symbol to the home position.
·
I have gotten it to work. However, I can only program about 15 or so symbols before I run out of memory on the BS2.· I would also like the wheel to pause for about 2 seconds after it reaches each destination and light an led.· i have had limited luck ith this.···
·
I had a BS2 stamp and when I ran out of memory I bought the BS2E thinking it would handle it.
·
Can anyone look at this program and tell me if there is a better way to do these functions without using up all my memory?
·
· Right now I only have one case to make things easier to follow.
Thanks,
·
I have a BS2e and I am using an infrared remote control to select a symbol
from 1 to 39.· I enter the number then press enter on the remote.
··
After entering the number the stargate moves left until it counts to the first chevron then it moves right to the second chevron, then it moves the selected symbol to the home position.
·
I have gotten it to work. However, I can only program about 15 or so symbols before I run out of memory on the BS2.· I would also like the wheel to pause for about 2 seconds after it reaches each destination and light an led.· i have had limited luck ith this.···
·
I had a BS2 stamp and when I ran out of memory I bought the BS2E thinking it would handle it.
·
Can anyone look at this program and tell me if there is a better way to do these functions without using up all my memory?
·
· Right now I only have one case to make things easier to follow.
Thanks,
·
' {$STAMP BS2e}
' {$PBASIC 2.5}
' -----[noparse][[/noparse] I/O Definitions ]-------------------------------------------------
' SONY TV IR remote declaration - input receives from IR detector
IrDet PIN 9
Speaker PIN 4
' -----[noparse][[/noparse] Constants ]-------------------------------------------------------
' SONY TV IR remote constants for non-keypad buttons.
Enter CON 11
' -----[noparse][[/noparse] Variables ]-------------------------------------------------------
' SONY TV IR remote variables'
irPulse VAR Word ' Single-digit remote variables
remoteCode VAR Byte
index VAR Nib
value VAR Word ' Stores multi-digit value
pulsecount VAR Word
counter VAR Word
newin7 VAR Bit
oldin7 VAR Bit
oldin7 = IN7
led VAR Bit
'------------------------------------------------------------------------------
start:
DO
DEBUG "Enter a value: ", CR
GOSUB Get_Multi_Digit_Value
DEBUG "The value is: ", DEC value, CR, CR
' DEBUG ? counter
SCAN:
newin7 = IN7
counter = counter + (newin7 ^ oldin7 & newin7) ' increment on 0-->1 transition
oldin7=newin7
'******************************************************************
SELECT value ' Value is the remote code entered
CASE 1
DO
'DEBUG ? counter
IF (counter <= 8) THEN 'fisrt stop
GOSUB forward
ELSEIF counter = 9 THEN ' feeble attempt at turning on an led at the 9th count
GOSUB led1
ELSEIF (counter >= 9) AND (counter<=14) THEN ' 2nd stop
GOSUB back
ELSEIF counter = 15 THEN '3rd stop
ELSEIF (counter >= 15) AND (counter<=20) THEN '4th stop,I deleted the other 2 stops for memory
GOSUB forward
ELSEIF counter = 21 THEN
GOSUB reset 'reset
ENDIF ' more cases later
GOTO scan
LOOP
ENDSELECT
LOOP
'-----------------------------routines
forward:
PULSOUT 13, 800
PAUSE 20
RETURN
Back:
PULSOUT 13, 700
PAUSE 20
RETURN
led1:
HIGH 1
PAUSE 100
LOW 1
GOSUB forward
RETURN
reset:
HIGH 1
PAUSE 200
LOW 1
PAUSE 200
HIGH 1
PAUSE 200
LOW 1
counter = 0
GOTO start
' -----[noparse][[/noparse] Subroutine - Get_Ir_Remote_Code ]---------------------------------
' SONY TV IR remote subroutine loads the remote code into the
' remoteCode variable.
Get_Ir_Remote_Code:
remoteCode = 0 ' Clear all bits in remoteCode.
DO ' Wait for rest between messages.
RCTIME IrDet, 1, irPulse
LOOP UNTIL irPulse > 1000
PULSIN IrDet, 0, irPulse ' Measure pulse.
IF irPulse > 500 THEN remoteCode.BIT0 = 1 ' Set (or leave clear) bit-0.
RCTIME IrDet, 0, irPulse ' Measure next pulse.
IF irPulse > 300 THEN remoteCode.BIT1 = 1 ' Set (or leave clear) bit-1.
RCTIME IrDet, 0, irPulse ' etc.
IF irPulse > 300 THEN remoteCode.BIT2 = 1
RCTIME IrDet, 0, irPulse
IF irPulse > 300 THEN remoteCode.BIT3 = 1
RCTIME IrDet, 0, irPulse
IF irPulse > 300 THEN remoteCode.BIT4 = 1
RCTIME IrDet, 0, irPulse
IF irPulse > 300 THEN remoteCode.BIT5 = 1
RCTIME IrDet, 0, irPulse
IF irPulse > 300 THEN remoteCode.BIT6 = 1
' Adjust remoteCode so that keypad keys correspond to the value
' it stores.
IF (remoteCode < 10) THEN remoteCode = remoteCode + 1
IF (remoteCode = 10) THEN remoteCode = 0
RETURN
' -----[noparse][[/noparse] Subroutine - Get_Multi_Digit_Value ]------------------------------
' Acquire multi-digit value (up to 65535) and store it in
' the value variable. Speaker beeps each time a key is
' pressed.
Get_Multi_Digit_Value:
value = 0
remoteCode = 0
DO
value = value * 10 + remoteCode
DO
GOSUB Get_Ir_Remote_Code
IF (remoteCode < 10) THEN
DEBUG "You pressed: ", DEC1 remoteCode, CR
GOSUB Beep_Valid
EXIT
ELSEIF (remoteCode = Enter) THEN
DEBUG "You pressed: ENTER", CR
GOSUB Beep_Valid
EXIT
ELSE
DEBUG "Press 0-9 or ENTER", CR
GOSUB Beep_Error
ENDIF
LOOP
LOOP UNTIL (remoteCode = Enter)
RETURN
' -----[noparse][[/noparse] Subroutine - Beep_Valid ]------------------------------------
' Call this subroutine to acknowledge a key press.
Beep_Valid:
FREQOUT Speaker, 100, 3500
PAUSE 200
RETURN
' -----[noparse][[/noparse] Subroutine - Beep_Error ]------------------------------------
' Call this subroutine to reject a key press.
Beep_Error:
FREQOUT Speaker, 100, 3000
PAUSE 200
RETURN

Comments
·· I think the problem might be that you thought you could put a larger program into the BS2e. While it has more EEPROM memory it is split up into 8 program slots.· Please see the following Nuts & Volts article which should help you out.
http://www.parallax.com/dl/docs/cols/nv/vol3/col/nv87.pdf
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
Not sure how to apply it to my application though.
If anyone has any ideas or something to put me on the right track,
It'd be greatly appreciated.
·· Read that article, and plan your program around a slot-oriented architecture and you'll be able to make it work.· Move sections of the program that can run by themselves into other slots, or, if data is taking up a lot of your program space, for example a lot of DEBUG or SEROUT routines, consider making one subroutine and placing the data in another slot.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
I'll see what I can come up with.
·· Don't forget to declare your variables exactly the same in each slot/program to preserve them between banks.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
NerdMaster
For
Life
It's a bit tricky to jump around but I think Im on th right track now.
I'll post a pic when it's done.
kenny
Learning how to use the slot architecture is the most important change, but some of it is just the need to put things more compactly. Express them in the easiest way for the tokenizer. For example, the subroutine: Get_Ir_RemoteCode.
This form takes 200 bytes in code space. I'm not familiar with the physical events you're detecting here, so I'll assume you need to change from pulsin to rctime. But after that original pulsin we can make the coding more efficient: This version takes only 110 bytes. Formatted this way, it's not obvious, but I'm also indenting things like the body of a loop. Good habit to develop. Now, I actually would not code those last two lines of the subroutine·that way. It may be intentional, but it seems odd that you return the same value (zero) for a detected remotecode of 9 or 10. The interaction between if-then statements can be tricky. I prefer the select-case statement. It will cost another three bytes, but will save errors in the long run. My version may not be what you intend since remotecode 9 will return ten and 10 will return zero. But it still only takes 113 bytes. This is a 43% reduction in code space, which adds up quickly. In-line code is generally not as efficient as looping except in special cases.
The select-case form looks like this:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
I have figured out how to do multi bank programming now, so my memory problem is
solved. Now, I just have to get the machine finished and make it all come together.
Thanks for the replies...It's encouraging to know there are so many knowledgeable people here to help.