My binary math skills end at 1+1=10; want cleaner code
cica
Posts: 11
Hi-
I'm in the process of building a console to be used as part of a geocaching game. Upon the successful entry of a 4-digit code by a player, the console will display the longitude and latitude of the next location in their hunt.
The code as attached allows a 4-digit code on a 4-digit keypad to store the result in a byte VAR. There are 256 possible combinations, so the result will be in the range of 0-255. I should probably leave well enough alone, but always strive to write tighter code. I'm most concerned by the way I convert a binary number into a variable. I was wondering if there is a cleaner way through binary math to store the 256 possiblilities. As written, the first digit will store from {0-3}; the second will then add {0-3}*4; the third adds {0-3}*16; and the fourth adds {0-3}*16. I also don't allow multiple presses and require the button to be released (press=0) before accepting the next button. Also, I have a timer that puts the whole thing to sleep if nothing is pressed for an extended period of time. The console will be activated by a button causing a reset to the BS2.
Any help would be appreciated.
Thanks,
-Tom
I'm in the process of building a console to be used as part of a geocaching game. Upon the successful entry of a 4-digit code by a player, the console will display the longitude and latitude of the next location in their hunt.
The code as attached allows a 4-digit code on a 4-digit keypad to store the result in a byte VAR. There are 256 possible combinations, so the result will be in the range of 0-255. I should probably leave well enough alone, but always strive to write tighter code. I'm most concerned by the way I convert a binary number into a variable. I was wondering if there is a cleaner way through binary math to store the 256 possiblilities. As written, the first digit will store from {0-3}; the second will then add {0-3}*4; the third adds {0-3}*16; and the fourth adds {0-3}*16. I also don't allow multiple presses and require the button to be released (press=0) before accepting the next button. Also, I have a timer that puts the whole thing to sleep if nothing is pressed for an extended period of time. The console will be activated by a button causing a reset to the BS2.
Any help would be appreciated.
Thanks,
-Tom
Comments
Not quite sure what your project does (perhaps you're not done yet), but I can help you a bit (pun intended).
Multiplying by 4 is the same as shifting left by two, but faster. This can be implemented 1 of 2 ways, first is storing the digits in reverse order where the line:
site = site + ((btns-1)*keypos) would be replaced with site = site << 2 + (btns-1).
or If you want to preserve the kepress order you can do site = site + (btns-1) << keypos
where keypos would start at 0 and be incremented by 2 each iteration.
I can see this project turning into something really cool, you could make maybe a dozen of these, scout out locations to hide the boxes and mark the GPS coordinates. Program these coordinates into UTM tables within the boxes and create randomized sequences (order in which the boxes are to be visited, each team having a different order)·for however many teams would be participating. Each team would have an iButton and each box would have an iButton receiver. The box upon receiving the iButton code would look up and display the GPS coordinates for the team's next box to visit and record the time at which the iButton was placed in the receiver. The team to make contact with all boxes in the proper sequence first wins. You could even weight determine the paths to make them as close to equidistant as possible (each team's total distance to travel is roughly equal).
You could also use RFID instead of iButtons, however if you employ iButtons which have storage capability and store the box numbers in sequence in the iButtons, you could determine the winner without having to collect the boxes and retrieve the data from each.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
1+1=10
Post Edited (Paul Baker) : 5/31/2006 7:32:27 PM GMT
I posted a stripped down version of the current program to make it easier to follow the logic. The actual console will have 4 buttons that correspond to the four symbols on www.geocaching.com's logo. I have these symbols load as custom LCD characters. The actual program displays these symbols as they are being entered. I am in decimal mode because it is easier for me to code in decimal. After I have recognized the 4-digit code, I'm going to use a SELECT...CASE statement like:
SELECT site
CASE = 15
GOTO Result0
CASE = 75
GOTO Result0
CASE = 125
GOTO Result0
CASE = 202
GOTO Result0
CASE ELSE
' Return bogus long/lat coordinates
ENDSELECT
Paul-
The order pressed is what is allowing me to have 256 possiblities. That's why I'm using the multiplier. I'll definitely give these ideas a shot. While iButtons sound cool, they might be cost prohibitive, as would building a dozen of these. As it stands, after adding an LCD, a battery with a solar charger, some lexan, blue LEDs and a speaker, I'm going to be into this "small project" for about $200.
My idea is a little more cost effective where the player will have to "tag back" at the console. Each destination will have a new code to enter at the base. And there will be bogus locations if a person just randomly enters a code. The person will have enough information after visiting 4 sites to locate a fifth site where I will hide the geocache.
I could forsee having this console used for more than one geocache location. All I need are a few more CASE statements to return valid coordinates.
I think you just touched upon my second question[noparse]:)[/noparse] I don't need to calculate anything with respect to the long/lat data. I just need the result to cause the LCD to display the corresponding longitude/latitude. My program currently has the following statements:
As I mentioned before, I have enough room on the stamp to be a little sloppy with the code, but is there a way to store this long/lat data more compactly? My initial plan is to have a subroutine that would assign these values then call the display routine that contains the two SEROUT commands. I could also simply write a single SEROUT command that wraps and displays all of the data and do away with these variables entirely. Thinking long term, I might want to store quite a few coordinates.
What do you think?
-Tom
- READ X,A,B,C
- X = X + 3
- SEROUT TX,LcdBaud,[noparse][[/noparse] ... ,DEC2 A,0,DEC2 B&%111111,".",DEC3 (B<<2)|C]
Then repeat for the next line
First of all, thanks for all your help. I did some further research and discovered that:
NDeg can be in the range of 0-90 (in the northern hemisphere)
NMin can be in the range of 0-59
NSec can be in the range of 0-999
WDeg can be in the range of 0-180 (west of the meridian)
WMin can be in the range of 0-59
WSec can be in the range of 0-999
For all intensive purposes, a change of 1 degree is about 67 miles. For my purposes, 42N and 71W degrees covers Eastern Massachusetts. So, I don't really need to store these. However, in the interest of portability and readability, I probably will anyway. Also, WDeg will not hit 100 until I go west to Nebraska. That being said, I tried the following code and could easily fit 100 DATA statements as follows:
I would never need more than 30 site codes, so I can afford to be inefficient code-wise, but would like to learn more about compacting data. Knowing the possible ranges, what would be a more compact way to store this data? I know I could set NDeg and WDeg as offset numbers from a constant, but I'want to try to retain readability.
Thanks
-Tom
Thanks
- Site000 DATA 42,((718>>2)&%11000000)|27,718,71,((858>>2)&%11000000)|05,858
Note that the DATA statement normally only stores the least significant byte of any value greater than 255 (see the Stamp Basic manual) unless you prefix the value with "WORD".
I tried to use your DATA statement:
but it errors out at the second parenthesis with an "Expected a constant" error.
- Site00 DATA 42, 718>>2 & %11000000 | 27, 718, 71, 858>>2 & %11000000 | 05, 858
By comparing your DATA statement with mine (using WORD) I can see you are able to compact the data to 6 bytes while I end up using 8 bytes. I can also see if I had used a B2e, I could have just filled one bank with 256 8-byte values and maintained readability. While this is a great lesson, I might just limit my usage to about 30 values and sacrifice eprom space for readability.
Thanks again. I actually learned something.
-Tom