Shop OBEX P1 Docs P2 Docs Learn Events
Using the hundreds value or thousands value of a decimal in spin — Parallax Forums

Using the hundreds value or thousands value of a decimal in spin

Nick McClickNick McClick Posts: 1,003
edited 2008-07-09 21:24 in Propeller 1
I have a big bag of small caps, and I was thinking I could use the RC counter to test the capacitors to help me organize them. My goal is to have the prop charge the cap, flip the pin and read out the discharge time sequentially to my single number LED.

The display has seven segments, and I've put the different display patterns in the DAT section of the code
DAT
Displaypat BYTE %0001000,%0010100



And so on. If I do;
outa[noparse][[/noparse]30..25] := Displaypat[noparse][[/noparse]0]
waitcnt (clkfreq *2 + cnt)
outa[noparse][[/noparse]30..25] := Displaypat



I can alternate between the different display patterns. The problem is that the result of my timing program isn't a single digit, but a big number. So I need to look at each digit in the timing result and display it individually.
Say it took 123456 clocks to discharge the cap, and I store the discharge time as dischargetime.
When I do BYTE[noparse][[/noparse]@dischargetime][noparse][[/noparse]0], 1 doesn't get displayed, but instead some random segments.

This makes sense as 123456 is stored as a long. 123456 is %1_1110_0010_0100_0000, so BYTE[noparse][[/noparse]@dischargetime][noparse][[/noparse]0] is giving me the first 8 bits (1111_0001).

So, how do I grab each value and pass it on for display? I suspect this is more a binary question than a SPIN question.

A few unrelated questions I've been saving up;

1. My Displaypat is type BYTE, but each Displaypat is only seven bits. The eigth bit is padded? Does the eigth bit get set to zero, and does it go in front?

2. All public methods share the VARs declared within the object, right? It makes sense that the @varname equals the address of the var, but why do I need to use it within an object? If one method set the variable dischargetime to 100 and another method grabs the first byte (BYTE[noparse][[/noparse]@dischargetime][noparse][[/noparse]0]), wouldn't that be the same as not using the @?

3. I did a spinner, where one cog would light up 1 of 4 LEDS in a circular fashion, and change the value of the VAR current to the current illuminated LED. Another cog would continuously write the VAR current to a local variable (temp), and then compare temp to current to see if the number had changed. If it did change, it would make a tick sound from the speaker. It didn't really work. Sometimes ticks were made, but they didn't seem to line up with the LED changes, and they weren't regular. I'm thinking I had this problem because one cog was writing to memory at the same time another cog was trying to read, and causing problems. Is there a better way to do it? I was thinking about syncing to clock cycles (switch LEDs every 500_000 clocks), but I want the spinning to slow down when the user pushes a button.

4. Easy one; My Power Supply runs at 6V. The prop is on a separate board with a voltage regulator. What's the component to use in order to bump the 6v to 8v to drive a fan?

Thanks in advance for the help. You guys are all pretty much masters - I've read thru the forum and learned tons of stuff. The Propeller documentation and labs are awesome too. The SPIN tutorial in the manual is helpful. uController.com has a good tutorial on PASM (ucontroller.com/indextutorials.html), which I'm starting to go thru.

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2008-07-07 20:43
    Hello Nick,

    for programming the propeller you have a serial connection to the PC.
    What about using the FullDuplexSerial-object to display the number in a terminalsoftware ?

    For displaying on the 7segment you have to get the digits

    The FullDuplexSerial-object has a method called dec which does this

    PUB dec(value) | i
    
    '' Print a decimal number
    
      if value < 0
        -value
        tx("-")
    
      i := 1_000_000_000
    
      repeat 10
        if value => i
          tx(value / i + "0")
          value //= i
          result~~
        elseif result or i == 1
          tx("0")
        i /= 10
    
    
    




    the line

          tx(value / i + "0")
    
    
    



    creates the ASCII-code of the digit

    if you want to have the digit itself it looks like this
      digit := value / i
    
    
    




    so for the 7segment it looks like this
      i := 1_000_000_000
    
      repeat 10
        if value => i
          Digit := value / i
          value //= i
          result~~
        elseif result or i == 1
          Digit := 0
    
        outa[noparse][[/noparse]30..25] := Displaypat[noparse][[/noparse]Digit]
        waitcnt (clkfreq *2 + cnt)
    
        i /= 10
    
    
    



    as i did this just inside the reply-post textbox
    first test it with hardcoded number like "654321"

    best regards

    Stefan

    Post Edited (StefanL38) : 7/7/2008 8:49:38 PM GMT
  • Chuck RiceChuck Rice Posts: 210
    edited 2008-07-07 20:49
    This is what I use:

    pub showTemp(temperature) | i
    ''   &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;
    ''   &#9474; Converts the passed value into a character string and appends the
    ''   &#9474; unit indicator "F", then sends the result to the display.  
    ''   &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;
     
      buf[noparse][[/noparse] 0 ] := "0"+temperature / 100 // 10                 'Get 1st digit of number and convert to ascii
      buf[noparse][[/noparse] 1 ] := "0"+temperature / 10 // 10                  'Get 2nd digit of number and convert to ascii
      buf[noparse][[/noparse] 2 ] := "0"+temperature / 1 // 10                   'Get 3rd digit of number and convert to ascii
      
      buf[noparse][[/noparse] 3 ] := "F"                                         'Add the Fahrenheit indicator
      buf[noparse][[/noparse] 4 ] := "°"                                         'Add the Degree symbol
      
      buf[noparse][[/noparse] 5 ] := 0                                           'Null terminate
    
      i:=0
      repeat while buf[noparse][[/noparse] i ] == "0"                            'Supress leading zeros
          buf[noparse][[/noparse]i++] := " "
       
      sevenseg.setSegments(@buf)                            'Send the result to the display
    
    
    



    but the key is

      digit1 := temperature / 100 // 10                 'Get 1st digit of number
      digit2 :=temperature / 10 // 10                  'Get 2nd digit of number
      digit3 :=temperature / 1 // 10                   'Get 3rd digit of number
    
    



    You can add more digits by adding powers of ten, and you could make it into a repeat loop (in my case, not worth it for only 3 digits)

    Post Edited (Chuck Rice) : 7/7/2008 8:54:36 PM GMT
  • Nick McClickNick McClick Posts: 1,003
    edited 2008-07-08 01:05
    Sounds like divide by powers of ten, convert to Ascii and store into an index is the easiest solution. So you concatenate a "0" to convert to ascii...
    Answered my voltage step question. A Boost converter seems like the right approach www.powerdesigners.com/InfoWeb/design_center/articles/DC-DC/converter.shtm.
  • Chuck RiceChuck Rice Posts: 210
    edited 2008-07-08 02:43
    Nick McClick said...
    Sounds like divide by powers of ten, convert to Ascii and store into an index is the easiest solution. So you concatenate a "0" to convert to ascii...

    Actually, it is not a concatenation, it is an addition. The "0" is a number. "0" is the same as the number 48 (decimal) or $30 (hex). If you take a look at the character chart (see the propeller tool help menu) it shows all the values.

    So "0" + 3 = "3" = 51 = $33
    Because 48 + 3 = 51 = $33

    Likewise "A" + 2 = "C"
    Because 65 + 2 = 67 and to the computer a 65 represents the character A and 67 represents the character C
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-07-08 05:23
    hello Nick,

    i guess you coded your 7segmentpattern from 0 to 9

      Displaypat show a "2" on the 7segment
      Displaypat[noparse][[/noparse]9] show a "9" on the 7segment
    
    


    right?

    So for displaying the numbers on the 7segment you DON'T have do add a value 48="0" !

    best regards

    Stefan

    Post Edited (StefanL38) : 7/8/2008 5:34:46 AM GMT
  • Nick McClickNick McClick Posts: 1,003
    edited 2008-07-08 20:21
    Makes Sense. I do have the Display patterns sequentially, so Displaypat[noparse][[/noparse]0] will display a zero on the display and so on. Adding "0" makes sense (same as adding 48 and pushing my binary number values up into values that map to the character rom. Because I'm displaying the results on a 7 seg display, I don't need the character rom, but that's a useful tip. Seems spin thinks 0 is binary ( value is %0000_0000) and "0" is %0011_0000 (if both were held in a byte).

    Last night I set it up to display thru my TV using the spin code examples from dave scanlan http://forums.parallax.com/showthread.php?p=574524. I charge up the cap following the examples in the Counters lab (RC decay circuit). Wait a second, and switch the direction of the pin, but it doesn't work. Even if no cap is connected, I get some number. I'll have to do some thinking on that one.

    One question. When I divide 1234 by 1000, the remainder falls off? So the result will be 1, not 1.234? So I can say Displaypat[noparse][[/noparse]1234/1000], and I'll get the 2nd element in the Displaypat index?
  • AleAle Posts: 2,363
    edited 2008-07-09 09:56
    Division is integral, so no decimal part (use remainder, or modulo).
  • Nick McClickNick McClick Posts: 1,003
    edited 2008-07-09 21:24
    Got it. Just looked that up. I think I answered another question of mine, I'll share it for all the other rank amateurs like myself;

    When I define a Byte with 7 bits, the 8th is still there, and it's set to zero. Just like if I write a decimal #3 to a byte. Binary 3 is 11, and the byte I write it to will be set to 0000_0011. So, when I define my display pattern with 7 bits, the Most Significant bit (leftmost) is 0.
Sign In or Register to comment.