Shop OBEX P1 Docs P2 Docs Learn Events
Pulse Width Measurement — Parallax Forums

Pulse Width Measurement

swampie777swampie777 Posts: 33
edited 2009-05-20 18:56 in Propeller 1
Mike Green was extremely helpful on my last project by showing some mis interpretations i had of the documentation. Ok I'm new to Parallax land. I did run into a bit of strangeness when i tried to upgrade the code to two channels.

The code follows.
CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

VAR
        long stack[noparse][[/noparse]72]
        
        long xxx1
        long iii
        long Idx
        long xsum
        
        long xxx2
        long iii2
        long Idx2
        long xsum2

        long iiii
        long i5
        long Cog  
        
OBJ
  Num   :       "Numbers"
  TV    :       "TV_Terminal"
 ' uart  : "FullDuplexSerial"

  
PUB Main
  xxx1 := 0
  iii  := 0
  xsum := 0

  xxx2  := 0
  iii2  := 0
  xsum2 := 0
    

Num.Init              'Initialize Numbers   
TV.Start(12)          'Start TV Terminal

 Cog := cognew(@pulse_,@xxx1)
' TV.Str(Num.ToStr(Cog, Num#DDEC))
' TV.Out(13)   
          repeat while Idx < 5
  
           xxx1 := -1
           
            repeat  while xxx1 == -1                              
            xsum := xsum + xxx1
             TV.Str(Num.ToStr(xxx1, Num#DDEC))
             TV.Str(Num.ToStr(xsum/(Idx+1), Num#DDEC))                                                      
             TV.Out(13)
             Idx++
Cog := cognew(@pulsea_,@xxx2)

          repeat while Idx2 < 5
  
           xxx2 := -1
           
            repeat  while xxx2 == -1                              
            xsum2 := xsum2 + xxx2
             TV.Str(Num.ToStr(xxx2, Num#DDEC))
             TV.Str(Num.ToStr(xsum2/(Idx2+1), Num#DDEC))                                                      
             TV.Out(13)
             Idx2++ 
    
             
DAT
                        org        0                                                                           
pulse_                  waitpeq   zero,mask
:loop                   waitpne   zero,mask
                        mov       xx1, cnt
                        waitpeq   zero,mask
                        mov       yy1, cnt
                        sub       yy1, xx1
                        wrlong    yy1, PAR
                        jmp       #:loop
                        
pulsea_                 waitpeq   zero,mask2
:loopa                  waitpne   zero,mask2
                        mov       xx2, cnt
                        waitpeq   zero,mask2
                        mov       yy2, cnt
                        sub       yy2, xx2
                        wrlong    yy2, PAR
                        jmp       #:loopa

zero           long    0
mask           long    |<25
xx1            res     1 
yy1            res     1 
Mem            res     1
lll            long    0
mask2          long    |<24
xx2            res     1 
yy2            res     1 





This did not work. It would process the first repeat and send out the results which checked against an o-scope ( pulse width measurement), but the second repeat block was ignored completely.

If i commented out the first block, the second block was still ignored.

Any suggestions will be appreciated.

Thanks.

Swampie777

Post Edited (swampie777) : 5/17/2009 3:57:46 AM GMT

Comments

  • LeonLeon Posts: 7,620
    edited 2009-05-17 02:23
    Use Code tags. And add a subject.

    Leon

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
    Suzuki SV1000S motorcycle
  • ElectricAyeElectricAye Posts: 4,561
    edited 2009-05-17 02:52
    Leon said...
    Use Code tags. And add a subject.

    Leon

    What one-liner Leon is talking about has nothing to do with your code per se. He is suggesting that, first, you click on the little pencil icon near the upper right corner of your post and then add a title to your Subject line so we all know what this post is about. Second, when he suggests you use Code Tags, he's talking about.... See the little boxes (under the upper emoticons), the little boxes that are labelled LIST, QUOTE, CODE, etc.? Before pasting in your code, click on CODE and paste your code after the code tag that will appear. Then click on the CODE* box and the browser should add a tag at the end of your code. The end result is that your code gets put into a neat little box that looks like this:


    Your code is in here instead of looking like regular words
    



    For me and my Mac, this only works for one line of code, but for PCs it should work out okay.

    Do what Leon says and then maybe people who know more than I can come to your rescue.

    Hope that helps,
    Mark

    smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Watching the world pass me by, one photon at a time.
  • mctriviamctrivia Posts: 3,772
    edited 2009-05-17 03:15
    ElectricAye you can also just type in tags like this (code)...(/code) use square brackets though. this will work on your mac for sure

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My new unsecure propmod both 1x1 and full size arriving soon.

    Need to upload large images or movies for use in the forum. you can do so at uploader.propmodule.com for free.
  • ElectricAyeElectricAye Posts: 4,561
    edited 2009-05-17 06:03
    mctrivia said...
    ElectricAye you can also just type in tags like this (code)...(/code) use square brackets though. this will work on your mac for sure

    
    Thanks mctrivia...
    By golly, you're absolutely right!
    I can get more than one line on here by simply typing in the code tags myself.
    Thanks for the tip!
    
    




    smile.gif
  • kuronekokuroneko Posts: 3,623
    edited 2009-05-17 06:35
    swampie777 said...
    This did not work. It would process the first repeat and send out the results which checked against an o-scope ( pulse width measurement), but the second repeat block was ignored completely.
    Well, it's kind of obvious when you think about it. Your pulsea_ routine is loaded at address zero but is compiled for $008 (following pulse_). It should at least have an ORG 0 in the first line. This also means you should relocate variables belonging to pulse_, i.e. kind of like that

    CON
      zero = $1F5   ' outb
      
    DAT                     org       0                                                                                   
    pulse_                  waitpeq   zero,mask
    :loop                   waitpne   zero,mask
                            mov       xx1, cnt
                            waitpeq   zero,mask
                            mov       yy1, cnt
                            sub       yy1, xx1
                            wrlong    yy1, PAR
                            jmp       #:loop
    
    mask           long    |<25
    xx1            res     1 
    yy1            res     1 
    
    DAT                     org       0                      
    pulsea_                 waitpeq   zero,mask2
    :loopa                  waitpne   zero,mask2
                            mov       xx2, cnt
                            waitpeq   zero,mask2
                            mov       yy2, cnt
                            sub       yy2, xx2
                            wrlong    yy2, PAR
                            jmp       #:loopa
    
    mask2          long    |<24
    xx2            res     1 
    yy2            res     1
    


    zero is used by both cogs and could either be redefined as local variable (global doesn't work due to the second ORG getting in the way) or we can use a register which we know is empty (outb in this case).
  • swampie777swampie777 Posts: 33
    edited 2009-05-18 16:02
    I tried the double org idea.

    It didn't work.

    icon8.gif

    If you change··xxx2· xsum2.. to xxx1 and xsum1 ( change everything but the mask and pulsea_) then it works.

    I thought when you did a Cog·:=·cognew(@pulsea_,@xxx2) that a new object was created with the lable segment of machine code pointed to ( (@pulsea_).

    Is this not how you generate different assembly objects for each different cog?

    rolleyes.gif

    Thanks
  • kuronekokuroneko Posts: 3,623
    edited 2009-05-19 00:01
    swampie777 said...
    I tried the double org idea.

    It didn't work.
    Well, it should have [noparse]:)[/noparse] Can you post your code from that stage (i.e. before you renamed the variables)?
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-19 08:26
    DAT
                            [color=red]org        0[/color]
    [color=#ff0000]                        ' this resets the adress pointers which are used in PASM.
                            ' So pules_ now points to long-adress 0, :loop now points to long adress 1 [/color]                        
                            [color=red]' Whenever you use :loop in you PASM it will be replaced by 1[/color]                                                   
    pulse_                  waitpeq   zero,mask
    :loop                   waitpne   zero,mask
                            mov       xx1, cnt
                            waitpeq   zero,mask
                            mov       yy1, cnt
                            sub       yy1, xx1
                            wrlong    yy1, PAR
                            jmp       #:loop
    
     
                            [color=red]' here we are at adress 8 for pulsea_ and 9 for :loopa
    [/color]pulsea_                 waitpeq   zero,mask2
    :loopa                  waitpne   zero,mask2
                            mov       xx2, cnt
                            waitpeq   zero,mask2
                            mov       yy2, cnt
                            sub       yy2, xx2
                            wrlong    yy2, PAR
                            jmp       #:loopa   [color=red]' this says: jump to adress 9
    [/color]
    zero           long    0
    mask           long    |<25
    [color=red]xx1            res     1                    ' Here you have a problem because these Labels will have the same adress as the following longs
    yy1            res     1                    ' xx1 = lll and yy1 = mask2
    Mem            res     1
    [/color]lll            long    0
    mask2          long    |<24
    xx2            res     1 
    yy2            res     1 
    
    
    

    What you do here
    ·Cog·:=·cognew(@pulsea_,@xxx2)
    is, that you load a part of PASM code to a COG. This PASM code will always start at COG-RAM adress 0. But your compiled code assumes that it is starting at adress 8. So when executed the jmp #:loopa will simply jump to the wrong place.

    Let's have a look at Kuroneko's code:
    CON
    [color=red]  zero = $1F5   ' outb      This is a trick to spare a long for the ZERO you had in your code. The propeller does not have a B-Port, but this register[/color]
    [color=red]                ' is available in RAM. As it's always initialized with 0 you can use it as ZERO-variable.[/color]
    [color=red]                ' But in your case you wouldn't even need that
    [/color]  
    DAT                     org       0                                                                                   
    [s]pulse_                  waitpeq   zero,mask
    :loop                   waitpne   zero,mask
    [/s][color=red]pulse_                  waitpne   mask,mask      ' this will do the same job and you can use OUTB for something else
    :loop                   waitpeq   mask,mask
    [/color]                        mov       xx1, cnt
                            waitpeq   zero,mask
                            mov       yy1, cnt
                            sub       yy1, xx1
                            wrlong    yy1, PAR
                            jmp       #:loop
    
    mask           long    |<25
    xx1            res     1 
    yy1            res     1 
    
    [color=red]DAT                     org       0              ' this resets the internal PASM program-adress-counter, so you can do a cognew(@pulsea_,..)[/color]
    [color=#ff0000]                                                 ' that's OK as such, but you have nearly the same code as for pulse_, so it's a waste of[/color]
    [color=#ff0000]                                                 ' HUB-RAM. Once your pulse_ is loaded into the COG you can do with it whatever you want in[/color]
    [color=#ff0000]                                                 ' HUB-RAM. So it's easy to reuse pulse_.[/color]
    [s]pulsea_                 waitpeq   zero,mask2
    :loopa                  waitpne   zero,mask2
                            mov       xx2, cnt
                            waitpeq   zero,mask2
                            mov       yy2, cnt
                            sub       yy2, xx2
                            wrlong    yy2, PAR
                            jmp       #:loopa
    
    mask2          long    |<24
    xx2            res     1 
    yy2            res     1[/s]
    
    

    In your SPIN code you could do:
     cognew( @pulse_, @xxx1 )
     waitcnt( clkfreq/1000+cnt)          ' not sure here how long you have to wait until first cognew is done with loading the code
     mask := |<24
     cognew( @pulse_, @xxx2 )
    
  • swampie777swampie777 Posts: 33
    edited 2009-05-20 17:11
    [noparse][[/noparse]quote]
    pulse_··················waitpeq···zero,mask
    :loop···················waitpne···zero,mask
    pulse_··················waitpne···mask,mask····· ' this will do the same job and you can use OUTB for something else
    :loop ··················waitpeq···mask,mask
    ························mov·······xx1,·cnt
    ························waitpeq···zero,mask
    [noparse][[/noparse]/quote]

    The reason I used zero·-- that is the value to compare the pin to so that the extent of the square wave pulse can be measured.

    You wait while the pin is zero to catch the start of the pulse. Then you capture the cnt. After the pin goes back to zero, you get cnt again and subtract to get the count width of
    the pulse. If you use the mask as both arguements, you'll never see the zero level.

    ······· confused.gif

    Did I mis-read you?
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-20 18:56
    Let's see what waitpeq is doing
    waitpeq zero, mask
    can be translated to
    repeat while INA & mask == 0

    It waits as long as the Pin is 0

    And now have a look at
    waitpne mask, mask
    can be translated to
    repeat while ina & mask != mask

    It waits as long as the Pin is not 1 ... and for a single pin not 1 is equal to 0

    So, both instructions do the same but in my version you don't need an additional long to compare with.
Sign In or Register to comment.