Shop OBEX P1 Docs P2 Docs Learn Events
Red Herring — Parallax Forums

Red Herring

ZeusZeus Posts: 79
edited 2011-12-17 11:01 in BASIC Stamp
Hello again everyone,

So for the past week I have been having trouble with my alarm clock code not executing the alarm sub routine. Last night I stumbled on something that might explain things...

I can now get the alarm to enter the sub routine however it will only do so if the alarm is set to an alarm time of anywhere from 0 - 9 minutes, for example 7:03. Once the alarm is set to anything greater than 7:09 the alarm no longer will enter the sub routine. Now I am guessing that more than half of the people reading this post have already written the solution to my problem in their heads, and don’t think that this is not appreciated, however what I was hoping for was an explanation of how to employ hexadecimal formatting. I understand the basic principal of hex notation however I do not have a good understanding of how to actually use it. I have been looking for some time now for a good resource of how to apply hexadecimal notation, can someone point me in the right direction?

Thanks... Zeus

P.S. My code currenlty reads and writes to memory in HEX but the arguments which it uses to evaluate the alarm/sub routine portion are formatted in DEC by default.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2011-12-16 15:24
    Hexadecimal and decimal notation is just for humans to read and write. Inside the computer, it's all groups of bits. In Parallax Stamp Basic, you can write the same number as 12 or $0C or %1010. All 3 forms translate to the same bit pattern inside the computer and that value can be displayed in a variety of forms including those 3. When you write this number to an EEPROM location, it's the same collection of bits no matter how you think about it or write it on paper or the computer screen. If you're using a Real-Time-Clock, many of those store their values as BCD (Binary Coded Decimal) and you have to translate back and forth from the binary values used everywhere else. Read the Wikipedia article on Binary Coded Decimal for examples and details. Although BCD is sometimes confused with hexadecimal notation, they're different concepts.

    A binary value of 23 is represented in hexadecimal and binary as $17 and %10111 respectively. As a BCD value, each decimal digit is stored in a 4-bit portion of an 8-bit value. When you write this in hexadecimal, this would come out as $23 which is convenient for reading (or %00100011). $23 is not the same value though as 23.
  • ZeusZeus Posts: 79
    edited 2011-12-16 15:32
    Thanks for the reply Mike,

    So if I am understanding you the stamp does not care it translates everything to BCD regardless of how it comes in or leaves the momory location?

    If that is true that then there is no merrit to my theory that my problem stems from translation problem within my argument (mins = AlmMins)? Or are you saying what I think you are saying and that is that I do in fact have to define how the variables formatted within each argument?

    Zeus
  • Mike GreenMike Green Posts: 23,101
    edited 2011-12-16 16:23
    The Stamp itself doesn't automatically translate anything. The Stamp Editor will translate 23 or $17 or %10111 into the same binary value which gets downloaded to the Stamp as part of your program. The Stamp itself will translate characters on input with the SERIN (or other input statement) when you use one of the formatters like DEC or HEX or BIN. It will translate to characters for output with the SEROUT (or other output statement) when you use DEC or HEX or BIN. There's no translation when you copy values into variables or copy items to or from EEPROM.

    If you're using a Real Time Clock that expects values to be in BCD, you'll have to do the translating yourself. To go from a number to BCD, do

    BCD = ((number / 10) << 4) | (number // 10)

    To go the other way, do

    number = ((BCD >> 4) * 10) + (BCD & %1111)
  • ZeusZeus Posts: 79
    edited 2011-12-16 17:50
    Mike,

    Okay let me back up for a second before I get too far away from the heart of the problem. Do you agree that there is some sort of problem with how my code compares (mins = AlmMins) or am pointing myself in the wrong direction again?

    Zeus

    P.S. I'm bit lost. If I am understanding you correctly there should not be a conflict with my (mins = AlmMins) statement, yet I am observing one. What am I missing here?
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2011-12-16 17:59
    Hi Zeus, expanding on Mikes explanation.

    I'm thinking the confusion is in the way the DS 1302 provides its time data and that is because as Mike says it is BCD (binary coded decimal).

    For example lets look at the minutes and lets say that the time is 7:23.

    The DS 1302 sends 1 byte of information that contains the minutes 23, this value is stored as BCD.

    The way it stores 23 as BCD is it splits the byte into two four bit nibbles, the lower nibble would be binary 0011 ( 3 ) and the high nibble would be binary 0010 ( 2 ) so put together the whole byte would look like this 00100011 ( 35 not 23 )

    If the alarm was actually set to alarm at 7:23 then mins=AlmMins is not going to work because what that equates to is IF 35=23 THEN...

    What you have to do before you can use mins as a comparison is to decode the value of 35 into the decimal number it represents (23).

    This is a simple operation, multiply the high nib ( 2 ) by ten which equals 20 and then add the low nib (3) which will give us our decoded value of 23.

    This is the equation

    mins=(mins.HIGHNIB * 10) + (mins.LOWNIB)

    With regard to you not being able to set your alarm beyond 9 minutes. Each half of the BCD value holds only 1 digit so when you have a value of 9 minutes the BCD value will have a high nibble of 0000 and a low nibble of 1001, combined that gives us 00001001 which is still 9 and works.

    When you roll over to 10 or higher you will have a high nibble of 0001 and a low nibble of 0000, combined that is 16, totally wrong and that is the importance of splitting the two nibbles away from the byte.

    Jeff T.

    EDIT: another thing that can be misleading , when you try debugging the BCD value for example DEBUG HEX2 mins it will display 23, this is because that is what a HEX number is, its a value divided into nibbles , in this case for display purposes only, the number continues to have a value of 35
  • Mike GreenMike Green Posts: 23,101
    edited 2011-12-16 18:55
    Equal comparisons, like mins = AlmMins, work the same no matter how the value is encoded, so that's not it.
  • ZeusZeus Posts: 79
    edited 2011-12-16 19:28
    Just when I thought I was close.

    What would exhibit behavior like I am observing?
  • ZeusZeus Posts: 79
    edited 2011-12-16 19:34
    Jeff,

    Thanks for expanding on Mike's explanation. I missed your post the first time around, but after reading it now things are becoming a little clearer. I will try and apply it tomorrow and post how it goes.

    Zeus
  • Mike GreenMike Green Posts: 23,101
    edited 2011-12-16 20:18
    Perhaps you should provide more information on the behavior you are observing. It's not enough to say it doesn't work. Provide some of those numbers you were observing when you put in the long DEBUG statement just before the IF statement for the GOSUB Alarm. You can copy and paste from the Stamp Editor's DEBUG window.
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2011-12-17 04:54
    Equal comparisons, like mins = AlmMins, work the same no matter how the value is encoded, so that's not it.

    In this case thats not true, AlmMins is a byte value and mins is two nibble values encoded into a byte.

    So if the byte value of AlmMins is 23 to do an equals comparison with mins then mins must be decoded from a two nibble value of 35 to a single byte value of 23, this is achieved with the provided equation which must be used before the comparison.

    Jeff T.
  • ZeusZeus Posts: 79
    edited 2011-12-17 11:01
    The conversion worked! Thank you both.

    I still struggle with the fundamentals of why storage works the way it does but my code is now working again and I hope as I continue that it will start to make more sense.

    Thanks again.

    Zeus
Sign In or Register to comment.