Shop OBEX P1 Docs P2 Docs Learn Events
byte, long, int - im a bit confused — Parallax Forums

byte, long, int - im a bit confused

timatrontimatron Posts: 16
edited 2008-10-15 20:24 in Propeller 1
hi guys.

i'm working on a piece of code to work through an array of numbers and display them on an analog gauge
using a pwm wave, this is my first time using a dat block and im getting a bit confused. in the past i had
used the fullduplexserial to grab a dec from my input at the terminal and display it using the duty function
which is part of the pwm_8x object (thanks Phil!) So now I would like to loop through an array of values
and display them on the analog gauge, but i'm having trouble.

should i store the data block at bytes or longs, ie what does the duty function expect? i guess i just get a little lost in the type definitions.

below is my code, and i'll include the definition of the duty function below as well.

thanks for any help!

cheers,
tim

CON
  _clkmode = xtal1 + pll16x   
  _xinfreq = 5_000_000
  DIN   = 24                     ' DIN is actually a DOUT on the prop but a DIN on the 7219 
  CLK   = 26
  CS    = 25
  base_pin0      = 0   
  base_pin8      = 8   
  base_pin16     = 16   

OBJ
   
  Debug: "FullDuplexSerialPlus"
  pwm0: "pwm_x8"
  pwm8: "pwm_x8"  
  pwm16: "pwm_x8"
   
pub init | i, gaugeVal
  pwm0.start(base_pin0, %1111_1111, 2000)        'Setup for PWM output on pins A16 - A23 at 23KHz.            
  pwm8.start(base_pin8, %1111_1111, 2000)        'Setup for PWM output on pins A16 - A23 at 23KHz.            
  pwm16.start(base_pin16, %1111_1111, 2000)        'Setup for PWM output on pins A16 - A23 at 23KHz.            
              
  Debug.start(31, 30, 0, 57600)
  waitcnt(clkfreq*2 + cnt)
  Debug.tx(16)
  
  WAITCNT(CLKFREQ*4+CNT)   
  dira[noparse][[/noparse]24..26]~~               ' make these pins outputs
  outa[noparse][[/noparse]CS]~~                    ' chip select idles high
  outa[noparse][[/noparse]CLK]~                    ' clock idles low
  load($0FFF)                   ' intialize test
  WAITCNT(CLKFREQ*2+CNT)         ' wait a little while
  load($0F00)                    ' turn test off
  load($0CFF)                    ' put out of shutdown mode
  
  load($09FF)                    ' address 7219's register 9 which sets the decode mode to BCD on all digits (FF)
  load($0B03)                    ' limit scan (B) to 4 digits (03)
  load($0A00)                   ' intensity register (0A) set to max ($0F)
  repeat
    repeat i from 1850 to 2008
      gaugeVal := warVals[noparse][[/noparse]1850 - i]
      Debug.Dec(gaugeVal)
      Debug.Str(String(13)) 
      display(i)
      'gaugeDisplay(5, gaugeVal)     'this is the line that is broken
      WAITCNT(CLKFREQ/2+CNT) 


pub load(data)                  ' load 16-bit of data into the 7219
  data ><= 16                   ' bit reverse the 16-bits of data (7219 requires most significant bit first)
  outa[noparse][[/noparse]CS]~                     ' start shift cycle
  repeat 16                     ' for 16-bits
    outa[noparse][[/noparse]DIN] := data & 1      ' set DOUT to next bit of data (always in the lsb)
    outa[noparse][[/noparse]CLK]~~                 ' single clock low-high and back to low for each data bit
    outa[noparse][[/noparse]CLK]~
    data >>= 1                  ' shift next bit into the lsb ready for testing
  outa[noparse][[/noparse]CS]~~                    ' done all bits, now release CS at which point the 7219 will use the data
  
pub display(number) | i         ' display the number as 4 digits on the 7219
 repeat i from 1 to 4
   load(((5-i)<<8) + number // 10)  ' find next digit (units) and send to display position (i) encoding this as 16-bits
   number /= 10                   ' shift number right by one decimal digit


pub gaugeDisplay(pin,level)
  if pin => 16
    pwm16.duty(pin, level)     
  elseif pin => 8
    pwm8.duty(pin, level) 
  elseif pin => 0
    pwm0.duty(pin, level)

    
DAT

warVals  byte 0, 0, 1, 1, 0, 0, 0, 1, 0, 2, 22, 25, 19, 18, 16, 11, 10, 11, 5, 10, 11, 7, 5, 7, 7, 11, 12, 
9, 8, 9, 7, 9, 9, 7, 10, 8, 9, 11, 10, 10, 11, 11, 13, 12, 15, 11, 12, 46, 30, 30, 21, 20, 16, 19, 
13, 7, 10, 9, 9, 10, 12, 16, 13, 48, 67, 60, 72, 79, 61, 48, 49, 44, 47, 44, 47, 48, 47, 48, 47, 
48, 51, 54, 49, 46, 51, 51, 55, 55, 76, 94, 98, 0, 0, 113, 113, 97, 90, 77, 75, 82, 75, 66, 63, 
55, 51, 48, 44, 42, 40, 42, 43, 41, 35, 40, 42, 50, 53, 48, 42, 45, 40, 41, 43, 36, 36, 35, 34, 
24, 31, 32, 29, 32, 31, 32, 32, 32, 33, 33, 32, 36, 44, 36, 32, 30, 33, 31, 29, 32, 37, 34, 42, 
42, 55, 47, 37, 40, 37, 21


                                                                                                                                                                                                                                                                               





CON

  resolution    = 2400          'The number of steps in the pulse widths. Must be an integer multiple of 4.
  nlongs        = resolution / 4

VAR

  long  fcb
  long  pwmdata[noparse][[/noparse]nlongs]
  long  pinmask
  long  previndex[noparse][[/noparse]8]
  byte  cogno, basepin

PUB duty(pinno, value) | vindex, pindex, i, mask, unmask

' This method defines a pin's duty cycle. It's arguments are:
'
'     pinno: The pin number of the PWM output to modify.
'
'     value: The new duty cycle (0 = 0% to resolution = 100%)
'
' Returns true on success; false, if pinno or value is invalid.

  if (1 << pinno & pinmask == 0 or value < 0 or value > resolution)
    return false
  pinno -= basepin
  mask := $01010101 << pinno
  unmask := !mask
  vindex := value >> 2
  pindex := previndex[noparse][[/noparse]pinno]
  if (vindex > pindex)
    repeat i from pindex to vindex - 1
      pwmdata[i] |= mask
  elseif (vindex < pindex)
    repeat i from pindex to vindex + 1
      pwmdata[i] &= unmask
  pwmdata[noparse][[/noparse]vindex] := pwmdata[noparse][[/noparse]vindex] & unmask | mask & ($ffffffff >> (31 - ((value & 3) << 3)) >> 1)
  previndex[noparse][[/noparse]pinno] := vindex
  return true
[/i][/i]

Post Edited (timatron) : 10/15/2008 7:00:05 PM GMT

Comments

  • RaymanRayman Posts: 14,364
    edited 2008-10-15 19:25
    I'd say this is your problem:

    repeat i from 1850 to 2008
    gaugeVal := warVals[noparse][[/noparse]1850 - i]


    This makes for negative numbers inside the brackets! You probably want [noparse][[/noparse]i-1850]...
  • timatrontimatron Posts: 16
    edited 2008-10-15 19:36
    what a fresh set of eyes will do.

    it works now, genius!

    thx,
    timhttp://forums.parallax.com/forums/emoticons/idea.gif
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-10-15 20:03
    Hello Tim,

    to analyze your problem I compiled your code.
    First thing was an error that file "pwm_x8" was not found.

    I knew that this file is from the obex so I could download it from there.
    Next time you should attach your complete project to your posting that the forum-members don't have
    to download additional files.

    If your code works with special hardware make a version that could be easily tested WITHOUT special hardware

    Then i tested your code with additional debug-informations like this

    ....
      repeat
        repeat i from 1850 to 2008
        'repeat i from 0 to 10
          Debug.str(string("repeat i from 1850 to 2008:   1850 - i="))
          Debug.Dec(1850 - i)
          gaugeVal := warVals[noparse][[/noparse]1850 - i]
          'gaugeVal := warVals[i]
          Debug.str(string("    gaugeVal := warVals[noparse][[/noparse]1850 - i]="))
          Debug.Dec(gaugeVal)
          Debug.str(string("    warVals[noparse][[/noparse]"))
          Debug.dec(1850 - i)
          Debug.Str(string("]="))
          Debug.dec(warVals[noparse][[/noparse]Index])
          Debug.tx(13) 
          display(i)
          gaugeDisplay(5, gaugeVal)     'this is the line that is broken
          WAITCNT(CLKFREQ/2+CNT) 
    ...
    [/i]
    



    and then it was clear what is wrong
    this is the Debugoutput

    repeat i from 1850 to 2008:   1850 - i=0    gaugeVal := warVals[noparse][[/noparse]1850 - i]=0    warVals[noparse][[/noparse]0]=0
    repeat i from 1850 to 2008:   1850 - i=-1    gaugeVal := warVals[noparse][[/noparse]1850 - i]=2    warVals[noparse][[/noparse]-1]=0
    repeat i from 1850 to 2008:   1850 - i=-2    gaugeVal := warVals[noparse][[/noparse]1850 - i]=192    warVals[noparse][[/noparse]-2]=0
    repeat i from 1850 to 2008:   1850 - i=-3    gaugeVal := warVals[noparse][[/noparse]1850 - i]=4    warVals[noparse][[/noparse]-3]=0
    repeat i from 1850 to 2008:   1850 - i=-4    gaugeVal := warVals[noparse][[/noparse]1850 - i]=120    warVals[noparse][[/noparse]-4]=0
    repeat i from 1850 to 2008:   1850 - i=-5    gaugeVal := warVals[noparse][[/noparse]1850 - i]=1    warVals[noparse][[/noparse]-5]=0
    
    



    the calculation 1850 - i delivers negative values !
    just change it to "i - 1850" and everything should work fine independend of byte word or longs in the DAT-section

    This Debug-demo shows how you can analyze a lot of problems yourself
    just send all kind of interesting variables with a string that explains what the value is to the terminal software


    local variables of methods are always longs
    and as long as you don't make things like giving a word or byte a too high value (byte-values < 256 word-values < 65536)
    this should work

    best regards

    Stefan
  • timatrontimatron Posts: 16
    edited 2008-10-15 20:06
    thanks stefan,

    i think i never really understood bytes vs words vs longs.

    i've always just hacked my way through spin, im less of a developer and more of a i really want to make an art piece with this electronics, why isnt it working!!![noparse]:)[/noparse]

    also, going to bed and looking at it in the morning is a good idea.

    cheers,
    tim
  • RaymanRayman Posts: 14,364
    edited 2008-10-15 20:24
    Tim,

    If you don't have code size issues, the simplest thing is to make everything longs.

    Ray
Sign In or Register to comment.