Shop OBEX P1 Docs P2 Docs Learn Events
String --> Dec Conversion — Parallax Forums

String --> Dec Conversion

crgwbrcrgwbr Posts: 614
edited 2007-01-23 19:17 in Propeller 1
Hey Everyone,
I'm using a PINK module for data entry to the Propeller.· The user will be entering data such as 4.032; this is of coarse stored in a PINK variable.· When the Propeller retrieves this data from the pink, it is in a string format.· How can I convert a string (like "4.032") to a usable decimal number (like 4.032)?· One idea I had on how to do this was to somehow seperate the string into one charecter strings (like "4" "." "0" "3" "2" ).· Then I think I could just subtract 48 from each charecter to get there decimal equiveilent.

Thanks in advance for your help,
crgwbr

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
NerdMaster
For
Life

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 17:07
    Martin Hebel recently posted an extension to FullDuplexSerial that does this kind of input conversion. See this thread http://forums.parallax.com/showthread.php?p=624624.
  • crgwbrcrgwbr Posts: 614
    edited 2007-01-22 17:19
    Cool, Thanks. This should help a lot.· Although I just noticed one thing, for rxDec to work, the string must be followed by a CR.· The pink module does not do this.· I'm thinking what I'll have to do is recieve the string normally, then resend the string through one IO pin to another·followed by CR.· Then I can receive this with·rxDec runing in another cog.· It's a bit old school, but should work, right?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    NerdMaster
    For
    Life


    Post Edited (crgwbr) : 1/22/2007 5:31:14 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 18:52
    I think you're overdoing the "just add another cog" sort of thing with this idea. How about just modifying Martin's routine to use whatever delimiter or fixed number of digits that PINK requires? It's not that your idea wouldn't work ...
  • crgwbrcrgwbr Posts: 614
    edited 2007-01-22 20:17
    Ok, I'll attempt to do it the "correct way."· Here is the code in the rxDec block:

    PUB rxDec : Value | place, ptr, x
    {{
    ·· Accepts and returns serial decimal values, such as "1234" as a number.
    ·· String must end in a carriage return (ASCII 13)
    ·· x:= Serial.rxDec···· ' accept string of digits for value
    }}··
    ··· place := 1··········································
    ··· ptr := 0
    ··· value :=0············································
    ··· dataIn[noparse][[/noparse]ptr] := RX······
    ··· ptr++
    ··· repeat while DataIn[noparse][[/noparse]ptr-1] <> 13······················
    ······ dataIn[noparse][[/noparse]ptr] := RX····························
    ······ ptr++
    ··· if ptr > 2
    ····· repeat x from (ptr-2) to 1···························
    ······· if (dataIn[noparse][[/noparse]x] => ("0")) and (datain[noparse][[/noparse]x] =< ("9"))
    ········· value := value + ((DataIn[noparse][[/noparse]x]-"0") * place)······
    ········· place := place * 10······························
    ··· if (dataIn[noparse][[/noparse]0] => ("0")) and (datain[noparse][[/noparse]0] =< ("9"))
    ····· value := value + (DataIn[noparse][[/noparse]0]-48) * place
    ··· elseif dataIn[noparse][[/noparse]0] == "-"·································
    ········ value := value * -1
    ··· elseif dataIn[noparse][[/noparse]0] == "+"······························
    ········ value := value
    ···

    I'll need to make it so that instead of CR (13) meaning the end of the string, it just accepts 5 digits (1.345).· Unfornuatly though I'm still very green in Spin.· Anyone have an Idea of where to start?

    Thanks,
    crgwbr

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    NerdMaster
    For
    Life
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 20:37
    Looking at the 3rd line ("dataIn[noparse][[/noparse]ptr] := RX") through the end of the repeat, this buffers the characters in dataIn before doing the conversion. One simple thing would be to add a parameter ("PUB rxDec(maxSize) : Value | place, ptr, x") and make the repeat conditional on either a CR or the maximum length. Change the "dataIn[noparse][[/noparse]ptr] := RX" to
       if ptr = maxSize
         dataIn[noparse][[/noparse]ptr] := 13
       else
         dataIn[noparse][[/noparse]ptr] := RX
    
    


    This would allow from 1 to a specified number of characters, essentially forcing a CR after the number of characters specified has been received.
  • Goran (Sweden)Goran (Sweden) Posts: 68
    edited 2007-01-22 22:23
    Mike since you have answerd here or anyone else

    I try to use the keyboard for setting time in the DS1307 demo Project coded by Beau Schwabe.

    Seeing this post I tried to use the "extension to FullDuplexSerial " to convert for example 07 , typed from the keyboard·to use for setting the Year in the DS1307.

    As a newbie I cant figure out how to pass this to the:

    Extended_FDSerial.spin.....................

    PUB rxDec : Value | place, ptr, x
    {{
    ·· Accepts and returns serial decimal values, such as "1234" as a number.
    ·· String must end in a carriage return (ASCII 13)
    ·· x:= Serial.rxDec···· ' accept string of digits for value
    }}··

    ..........................

    WHere should the string "06" be when calling the above routine?

    Is it······ "06":= Serial.rxDec··,If so how to get the result?

    For debugging and to se that it is ok I like to use the tv_text output to confirm.

    OR is it a simplier approache to·pass the input from the·keyboard and place it in the following:

    ··· DS1307.SetBCDValue(07,Year_,0,99,$FF)·············· 'Set Year

    Where it should be in BCD format i.e 07··

    Any help would be welcome.

    Regards, Goran

    It seems to be a long way to go to Spin from pure asm!!

    But I will not give upsmile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 22:31
    The Extended_FDSerial routines are written to use serial input directly. These routines get their input with a call to RX. You could try modifying the rxDec routine by changing the RX to key.getkey (if key is the name you've given to the keyboard object). Keep in mind that these routines (rxDec) don't process a backspace keypress nor do they echo what you type to the display. You would have to add those to your routine. Since rxDec buffers all its input (up to a CR), it should be easy to add this.
  • Goran (Sweden)Goran (Sweden) Posts: 68
    edited 2007-01-22 22:55
    Thanks again Mike,

    I took the "PUB rxDec : Value | place, ptr, x ....."routine and past it in my DS1307 Object and it works fine so far. When I type 07 on the keyboard I got $07 on the TV screen.

    Now, how to convert this to BCD format variable which I can place in the

    ······ DS1307.SetBCDValue(07,Year_,0,99,$FF)·············· 'Set Year

    Any idea?

    regards, Goran
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 23:05
    For BCD, you're better off starting with the ASCII characters. To convert two characters to BCD (without error checking) just do:
    PRI asciiToBcd(firstDigit, secondDigit)
       return (firstDigit & $F) << 4 | (secondDigit & $F)
    


    As you can see, BCD just uses 4-bit "nibbles" to hold the digits. If, for some reason, you need a 4 digit BCD value in a 16 bit word, just do:
    PRI asciiToBcd(Digit1,Digit2,Digit3,Digit4)
       return (Digit1 & $F) << 12 | (Digit2 & $F) << 8 | (Digit3 & $F) << 4 | (Digit4 & $F)
    
  • Goran (Sweden)Goran (Sweden) Posts: 68
    edited 2007-01-22 23:18
    Thanks Mike,

    Now I can go on with my project, a board with a DS1307, a SD-Card and some sensors, all for long time logging of data.

    The SD-Card works fine, now I can add the DS1307 to give me timestamps and the neccesary time for the Date & time when opening a file on the SD-card.

    When done (no timeframe yet) If anyone intrested I can post the whole basic project (whithout the sensor part)

    With this you should be able to set nessecary parameters from your keyboard, se what your doing on the TV-screen ,save it on the SD-Card and when done restart the propeller without the TV and keyboard, with correct time and parameters load from the SD-card and logg whatever to the another file (not the parameter file).

    When done take the SD-card to a PC and evaluate the loggfile.

    Regards/Goran
  • Goran (Sweden)Goran (Sweden) Posts: 68
    edited 2007-01-23 00:44
    Sorry Mike,

    But I cant figure it out,

    PRI·asciiToBcd(firstDigit,·secondDigit)
    ···return·(firstDigit·&·$F)·<<·4·|·(secondDigit·&·$F)

    How to call this? and whats expected

    I type 07 on the keyboard which is $37 or 7dec or ascii ▶

    The result from:

    PRI·asciiToBcd(firstDigit,·secondDigit)
    ···return·(firstDigit·&·$F)·<<·4·|·(secondDigit·&·$F)

    is 0

    Her is the code:

    *****************************************

    · y:= rxDec
    · term.dec(y)·················· '=7
    · term.out(y)·················· '=▶
    asciiToBcd(y,z)················ 'tried asciiToBcd(z,y) and all possible variants

    · term.dec(result)············· '=0

    *****************************************

    PRI asciiToBcd(firstDigit, secondDigit)
    ·· return (firstDigit & $F) << 4 | (secondDigit & $F)

    *****************************************

    Am·I stupid or? (getting late her)confused.gif

    Regards/Goran
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-23 01:33
    You have to start with the characters, not rxDec like this:
    pri get2digits | a, b
      a := key.getkey
      b := key.getkey
      return asciiToBcd(a,b)
    
    


    If you want to start with a numeric value between 0 and 99 (instead of characters) do:
    pri valueTo2Bcd(v)
       return (v / 10) << 4 | (v // 10)
    
    
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-23 01:36
    If you want 4 BCD digits do:
    pri valueTo4Bcd(v)
       return (v / 1000) << 12 | ((v / 100) // 10) << 8 | ((v / 10) // 10) << 4 | (v // 10)
    
    
  • crgwbrcrgwbr Posts: 614
    edited 2007-01-23 14:17
    Mike Green said...
    Looking at the 3rd line ("dataIn[noparse][[/noparse]ptr] := RX") through the end of the repeat, this buffers the characters in dataIn before doing the conversion. One simple thing would be to add a parameter ("PUB rxDec(maxSize) : Value | place, ptr, x") and make the repeat conditional on either a CR or the maximum length. Change the "dataIn[noparse][[/noparse]ptr] := RX" to
       if ptr = maxSize
         dataIn[noparse][[/noparse]ptr] := 13
       else
         dataIn[noparse][[/noparse]ptr] := RX
    
    


    This would allow from 1 to a specified number of characters, essentially forcing a CR after the number of characters specified has been received.
    Thanks Mike, this worked well.· Altough, while watching the telnet debug from the Pink I noticed one thing I didn't know before, It ends it's strings with CLS (ASCII 0).· So, with that knowledge, I could change the 6th line from:

    repeat while DataIn[noparse][[/noparse]ptr-1] <> 13

    ············· To:

    repeat while DataIn[noparse][[/noparse]ptr-1] <> 0

    I think this would work; any thoughts.· Again forgive me if I'm nowhere close, I'm not exactly sure what this line of code is doing, it's just the only line where I could find the number 13.

    Thanks,
    crgwbr

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    NerdMaster
    For
    Life
  • Goran (Sweden)Goran (Sweden) Posts: 68
    edited 2007-01-23 16:25
    Mike,

    Guess I was tired yesteday night

    I have it all OK now, ManyThanks, Goran
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-23 16:39
    crgwbr,
    The change you're making should work. Are you sure the PINK strings end with a zero? I haven't looked at the documentation since the product came out. It may be so.

    The REPEAT line (and the code around it) just copies the data to a buffer (called dataIn) and stops when a specific character is found (13 or 0 or whatever). The number of characters put into the buffer (ptr) is used to control the loop that actually converts the characters to a value.
    Mike
  • crgwbrcrgwbr Posts: 614
    edited 2007-01-23 19:17
    Thanks Mike.· It works great with the CLS end instead of the CR.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    NerdMaster
    For
    Life
Sign In or Register to comment.