Shop OBEX P1 Docs P2 Docs Learn Events
coding ascii math problem — Parallax Forums

coding ascii math problem

lfreezelfreeze Posts: 174
edited 2014-02-12 04:29 in Propeller 1
Please help, I have a basic coding problem that I can not solve. If you run the inserted program, it will compile and run correctly.
It is a simple program to convert ascii numbers to the integer values. If you then add another variable “AAAA” to the end of The line:
CON 
  _clkmode      = xtal1 + pll16x    
  _xinfreq      = 5_000_000                                                              
obj  ser:   "fullduplexserial"
PUB  CONVERT | temp,temp1,temp2 ' ,AAAA

 ser.start(31,30,0,19200)      

 temp:=55  'THIS IS THE ASCII VALUE TO CONVERT
 
 repeat
      waitcnt (clkfreq/2 + cnt)
      ser.str(string(13,13," ascii                = "))
      ser.dec(temp)                        'this is the ascii value
      temp1 := temp * 10 + (temp - 48 )    'this and next line converts ascii nbrs to decimal
      temp2:=temp1[3]                       'this eXtracts the third byte of the temp1 long
      ser.str(string(13," converted to decimal = "))
      ser.dec(temp2) 'this is the converted value
      


PUB CONVERT | temp,temp1,temp2,AAAA

The program will compile and run, but now produces the wrong result,
In my tests it will continually show 3 as the converted value. The puzzling part is
That if you add the additional variable “AAAA” to the front of the statement such as:

PUB CONVERT | AAAA,temp,temp1,temp2

The program will run correctly.
Thanks ……
Larry

Comments

  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-02-11 08:56
    An ASCII value implies a string -- here's a routine that will convert a string to a decimal value. It stops when it encounters the end of the string (0) or a non-digit character in the string.
    pub asc_to_dec(p_str) | value, b
    
      value := 0                                            ' initialize output value
    
      repeat
        b := byte[p_str++]                                  ' get character from string
        if ((b => "0") and (b =< "9"))                      ' digit?
          value := (value * 10) + (b - "0")                 ' update value with digit
        else
          quit                                              ' non-digit; break out of loop
    
      return value
    


    You can try it with this:
    conversion := asc_to_dec(string("55"))
    


    I think the problem you're having is that temp is not an ASCII value, it's already a number.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-02-11 11:55
    lfreeze, the program appears to work when you add the dummy variable AAAA because temp1[3] is actually accessing a temporary copy of temp that was put on the stack when executing the previous statement. temp1 was not defined as an array, so temp1[3] is accessing the third variable declared after temp1. Since you don't have three variables defined after temp1 it is grabbing something from the stack.

    Look at Jon's sample code and try to understand what it does. Please ask more questions if it still doesn't make sense.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-02-11 12:32
    Piggybacking on Dave's point, sometimes we want to work with bytes inside a method where locals are only longs. We can use the .byte[] (and .word[]) modifiers when this is the case. Here's an example of a program I writing for the EFX-TEK HC-8+ which is serving as a DMX master for lighting control on a display built by a Hollywood prop shop.
    pri flames(p_dest) | ch, level[2], delay                        ' runs in separate cog
    
      repeat ch from 0 to 7
        level.byte[ch] := prng.random
                               
      repeat
        bytemove(p_dest, @level, 8)
        delay := (prng.random >> 1) // 4 + 3
        pause(delay)
        repeat ch from 0 to 7
          if (level.byte[ch] > 25)
            level.byte[ch] -= 5
          else
            level.byte[ch] := (prng.random >> 1) // 164 + 92
    


    This very simple code creates a randomized, slightly-wobbly reverse-sawtooth waveform on eight of the DMX channels -- with the LEDs and smoke effect being used, it provides a nice simulation of flames. DMX is a byte-oriented system, but local vars in methods are always longs. Note how I declared a local array of two longs (level[]) but treat it as an array of eight bytes.

    For those interested, the p_dest value is a pointer into the DMX output array. This strategy lets me direct the "flames" animation to any output I desire. In this case, it's the DMX stream. While testing, I used local outputs on the HC-8+.
  • lfreezelfreeze Posts: 174
    edited 2014-02-11 18:00
    Thank you for the responses. I will incorporate Jonnymacs code into my application. I will review the
    comments made by Dave, i am still confused about why there is no third byte in the result of my original
    program. I will spend some more time with the manual and try to expand my understanding.

    Larry
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-02-11 21:52
    I don't think you should be not concerned about your original program; use the information provided by others to rewrite your routine. Remember, the value you're attemping to convert is not ASCII -- it's already decimal.

    Other issues:
    -- locals are not initialized by the compiler; you could end up with junk in them, depending on where the routine is called.
    -- Technically, temp1[3] is undefined; temp1 is the same as temp1[0], temp2 is the same thing as temp1[1] -- temp1[3] is an unknown from the stack
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-12 04:29
    lfreeze wrote: »
    ... i am still confused about why there is no third byte in the result of my original
    program.
    Why do you think you need the 3rd byte?
Sign In or Register to comment.