Multiple Pulsin Measurements


Closed Thread
Results 1 to 14 of 14
  1. #1
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35

    Default Multiple Pulsin Measurements

    Does anyone have any experience of multiple PULSIN measurements - ie simultaneous on more than one pin - obviously would need to sample for a full sample period - 65535 cycles to be sure no pulses received on any other pin even if received on one pin. Also would need to handle a partially measured (ie ongoing beyond the sample period) pulse. So I am thinking of a full port pulse sample, result to an word array (Period[7]), where Period[n] = 0 if no pulse, 65535 if an incomplete pulse and a result otherwise. I am planning to write if no one has done already - any interest?

  2. #2
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    OK - I have written a PicBasic routine to do mPULSIN - a bit slow as you would expect, but works
    Code:
                for i = 0 to 7 : Period[i] = 0 : next
                pCount = 65535                  ' PULSIN_MAX
                k = Mask
    cycle0:     j = mPort & k                   'Port AND Mask
                for i = 0 to 7
                    if (j & dcd i) = dcd i then 'Bit i set - Pulse found
                        Period[i] = Period[i] + 1
                    else                        'Pulse ended or no pulse
                        if Period[i] >0 then    'Already received a pulse
                            k = k & (~dcd i)    'Clear i'th bit in mask
                        endif
                    endif
                next
                if k = 0 then return
                pCount = pCount - 1
                if pCount <> 0 then cycle0
                return
    I have also written in assembler but need to test before posting....
    Peter

  3. #3
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    OK - here it is in Assembler - disappointingly not that much faster!
    Code:
    '**** mPULSIN defines ***
    Period  var word[7]
    mPort   var PortB
    Mask    con %00000011   'Mask of port pins to check
    i       var byte
    j       var byte
    k       var byte
    pCount  var word
    sample  var byte
    CALL mPULSIN
    END
    
    asm
    _mPULSIN:   CLRF    _Period         ;Period[0] = 0
                CLRF    _Period + 1
                CLRF    _Period + 2     ;Period[1] = 0
                CLRF    _Period + 3
                CLRF    _Period + 4     ;Period[2] = 0
                CLRF    _Period + 5
                CLRF    _Period + 6     ;Period[3] = 0
                CLRF    _Period + 7
                CLRF    _Period + 8     ;Period[4] = 0
                CLRF    _Period + 9
                CLRF    _Period + 10    ;Period[5] = 0
                CLRF    _Period + 11
                CLRF    _Period + 12    ;Period[6] = 0
                CLRF    _Period + 13
                CLRF    _Period + 14    ;Period[7] = 0
                CLRF    _Period + 15
                
                MOVLW   0xFF
                MOVWF   _pCount  
                MOVLW   0x0F 
                MOVWF   _pCount + 1 ;pCount = $FFF  = 4095
                MOVLW   _Mask
                MOVWF   _k          ;k = Mask
                CLRF    _sample     ;clear sample flag
                
    cycle:      MOVF    _mPort, W   ;Sample the Port
                ANDWF   _k, W
                MOVWF   _j          ;j = Port AND Mask
                
    B0:         BTFSS   _j,0        ;Bit set? Pulse high
                GOTO    B0Clear
                BSF     _sample,0   ;flag that now sampling
                INCFSZ  _Period     ;Period[0] = Period[0] + 1
                GOTO    B1
                INCF    _Period + 1
                GOTO    B1
    B0Clear:    BTFSS   _sample,0   ;Pulse low - already sampling?
                GOTO    B1
                BCF     _k,0        ;Clear Bit in Mask
    B1:         BTFSS   _j,1        ;Bit set? Pulse high
                GOTO    B1Clear
                BSF     _sample,1   ;flag that now sampling
                INCFSZ  _Period + 2 ;Period[1] = Period[1] + 1
                GOTO    B2
                INCF    _Period + 3
                GOTO    B2
    B1Clear:    BTFSS   _sample,1   ;Pulse low - already sampling?
                GOTO    B2
                BCF     _k,1        ;Clear Bit in Mask
    B2:         BTFSS   _j,2        ;Bit set? Pulse high
                GOTO    B2Clear
                BSF     _sample,2   ;flag that now sampling
                INCFSZ  _Period + 4 ;Period[2] = Period[2] + 1
                GOTO    B3
                INCF    _Period + 5
                GOTO    B3
    B2Clear:    BTFSS   _sample,2   ;Pulse low - already sampling?
                GOTO    B3
                BCF     _k,2        ;Clear Bit in Mask
                
    B3:         BTFSS   _j,3        ;Bit set? Pulse high
                GOTO    B3Clear
                BSF     _sample,3   ;flag that now sampling
                INCFSZ  _Period + 6 ;Period[3] = Period[3] + 1
                GOTO    B4
                INCF    _Period + 7
                GOTO    B4
    B3Clear:    BTFSS   _sample,3   ;Pulse low - already sampling?
                GOTO    B4
                BCF     _k,3        ;Clear Bit in Mask
              
    B4:         BTFSS   _j,4        ;Bit set? Pulse high
                GOTO    B4Clear
                BSF     _sample,4   ;flag that now sampling
                INCFSZ  _Period + 8 ;Period[4] = Period[4] + 1
                GOTO    B5
                INCF    _Period + 9
                GOTO    B5
    B4Clear:    BTFSS   _sample,4   ;Pulse low - already sampling?
                GOTO    B5
                BCF     _k,4        ;Clear Bit in Mask
    B5:         BTFSS   _j,5        ;Bit set? Pulse high
                GOTO    B5Clear
                BSF     _sample,5   ;flag that now sampling
                INCFSZ  _Period + 10 ;Period[5] = Period[5] + 1
                GOTO    B6
                INCF    _Period + 11
                GOTO    B6
    B5Clear:    BTFSS   _sample,5   ;Pulse low - already sampling?
                GOTO    B6
                BCF     _k,5        ;Clear Bit in Mask
    B6:         BTFSS   _j,6        ;Bit set? Pulse high
                GOTO    B6Clear
                BSF     _sample,6   ;flag that now sampling
                INCFSZ  _Period + 12 ;Period[6] = Period[6] + 1
                GOTO    B7
                INCF    _Period + 13
                GOTO    B7
    B6Clear:    BTFSS   _sample,6   ;Pulse low - already sampling?
                GOTO    B7
                BCF     _k,6        ;Clear Bit in Mask
    B7:         BTFSS   _j,7        ;Bit set? Pulse high
                GOTO    B7Clear
                BSF     _sample,7   ;flag that now sampling
                INCFSZ  _Period + 14 ;Period[7] = Period[7] + 1
                GOTO    Next
                INCF    _Period + 15
                GOTO    Next
    B7Clear:    BTFSS   _sample,7   ;Pulse low - already sampling?
                GOTO    Next
                BCF     _k,7        ;Clear Bit in Mask
    Next:       MOVF    _k, F       ;Is Mask = 0?
                BTFSC   STATUS,Z    ;Branch on No Zero
                RETURN              ;Finished all samples
                DECFSZ  _pCount
                GOTO    cycle
                DECFSZ  _pCount + 1
                GOTO    cycle
                RETURN              ;pCount reached 0 - Timeout
    ENDASM

  4. #4
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    Can't you use the gated timers or interrupts to do what you want?
    Charles Linquist

  5. #5
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    Quote Originally Posted by Charles Linquis View Post
    Can't you use the gated timers or interrupts to do what you want?
    That would be too easy.
    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  6. #6
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    I need to make 8 simultaneous (relatively) measurements of pulsewidth on 8 different input pins - is there a PIC that could handle this with timers or interrrupts?

  7. #7
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    Can we get just a little more info about the pulses? for instance are you trying for a Logic storage type thing or reading R/C Rx pulses. Both need to have 8 bits read, but the Logic storage needs to get the states and go back watching while the Rx has at least 2mS before the next pulses may show up. Do you have an anticipated max/min pulse width?
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  8. #8
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    Also can you expand on the first was "slow"? Do you mean it was to slow to react to the pulses? were they accurate but offset? How much percision and resolution do you need?
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  9. #9
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    OK - the scenario is measuring multiple (8) pulses arising from eight simple 12F675 circuits outputing pulses - I can change that to whatever I want, currently 1mSec pulse every 50 mSec, but the 12F675 has an LC circuit driving its oscillator so the pulse width is altered by the LC circuit (and any adjacent metal/tuned circuit etc.

    When I say the Picbasic routine was slow I mean the precision or resolution - using PB PULSIN gives a resolution of 40/OSC uSec - ie. 0.833 uSec at 48 MHz - so a 1000 uSec pulse gives a Pulsin answer of around 1224 - using my PicBasic routine I get a measurement (ie number if cycles of sampling) of only around 300 (ie 3 uSec resolution) and using assembler a similar result, unless I only sample one bit in which case it rises to arounf 800 (ie 1.1 uSec resolution). So a PULSIN resolution of 40/OSC is pretty impressive!

    Interestingly, a sequence of several PULSIN commands on each successive pin gives a much better (more precise) result - maybe I should never have started this idea and stuck to dirty successive PULSINs!
    Last edited by FinchPJ; - 1st November 2011 at 15:14.

  10. #10
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    Sorry to be dense but here goes -
    so for a 1000 uS pulse you get as a result-
    1224 for pulsin
    1300 for your routine
    1100 for just 1 bit sampled?

    You can see I don't think I have this right. If I do, they are all crap IMHO. best being off by 10%!

    I am crafting up a possible solution, but these numbers are messing with me.

    On to more fun stuff. So you have around 50 mS to wait for the next series of pulses correct? If so, what about this:
    when the first pulse starts (or all of them at once, whatever) start a timer.
    XOR the 8 bits (faster if they are all on the same port)
    keep checking until one of more change.
    when they do, grab the counter value and store it with the port value.
    When you have done this 8 times, you will have the counter differences for each bit.

    Now go process the information to determine how long each pulse lasted. Plenty of time left to get back and wait for the next series of 8 pulses. Now if you wanted to use interrupts, have all 8 on IOC pins, then when the ISR fires, grab the counter and states there. This will take a feww cycles longer though.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  11. #11
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    Thanks for your advice - I will think about your "Fun stuff" - actually the actual timings/test results are the opposite of what you understood from my description:
    so for a 1000 uS pulse you get as a result-
    1224 for pulsin - correct (=~ 1000*48/40)
    1300 for your routine - No I get an answer of around 300
    1100 for just 1 bit sampled? - No I get an answer of around 800

    Whilst using interrrupts etc as you suggest may be a purist answer, I think 8 successive PULSINs are going to be much easier - I cant guarantee the pulses will arrive synchronously, but it is the precision I am worried about, not the sample time it takes (hence the 50 mSec pause between pulses)

  12. #12
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    I dont know about the "purist" part, and IMHO anything needing better then 5uS accuracy is not well suited for interrupts.
    Now I understand your numbers, 300 is really 300 iterations of the loop. so its as accurate as the loop takes (given 1000uS pulse, 3.333uS loop time)

    I propose you can achieve 1uS with my suggestion, maybe better. But if you can get the XOR to be 2-3 instructions, 2 jumps = 4more (to the grab time and back), then a couple of instructions to save the timer count and port states. You will be right around 12 instructions I think. So not much better then the pulsein, but nicer in the respect you can get all 8 at once.

    I am assuming you are using this to check the speed of the 8 uP's. something else to consider :
    If they are sending the pulses every 50 mS, you could measure the low pluse (50mS long) instead of the high pulse. This will give you a much bigger window to check the the duration against. 1% is 500 uS in this case. so being off by 3 or 4 uS would then be peanuts.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  13. #13
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    Thanks so much for your helpful thoughts - I will go away and work at your suggestion - I agree interrupts may not be accurate enough - you are quite correct I am monitoring the 8 baby PICs' oscillator speeds and I agree a longer pulse is easier (more accurate) to measure.
    Peter

  14. #14
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default Re: Multiple Pulsin Measurements

    I decided to try and make the assembler less ugly first by using indirect addressing to access the Period[8] array but it is no faster than my laborious method and this one will only run on an 18F4550 due to the use of the helpful POSTINC0 operator representing INDF(0) with a post Increment:
    Code:
    _xPULSIN    MOVLW   0xFF
                MOVWF   _pCount  
                MOVLW   0x0F 
                MOVWF   _pCount + 1     ;pCount = $FFF  = 4095
                MOVLW   _Mask
                MOVWF   _k              ;k = Mask
                CLRF    _sample         ;clear sample flag
                
    cycleX      MOVF    _mPort, W       ;Sample the Port
                ANDWF   _k, W
                MOVWF   _j              ;j = Port AND Mask
                MOVLW   High(_Period)   ;Set up FSR to point to Period[0] 
                MOVWF   FSR0H
                MOVLW   Low(_Period)
                MOVWF   FSR0L
                MOVLW   1
                MOVWF   _i              ;Bit Marker = 00000001
    CheckJ      RRCF    _j
                BTFSS   STATUS,C        ;Bit i Set
                    GOTO BCLR
                INCFSZ  POSTINC0        ;Yes - Period[i] = Period[i]+1
                    GOTO NoRoll
                INFSNZ  POSTINC0        ;=Inc and always skip - Period.Hi never Zero
    NoRoll      MOVF    POSTINC0,F      ;=NOP except inc FSR
                MOVF    _i,W
                IORWF   _sample,F       ;Now sampling bit i
    Nexti       RLCF     _i             ;i = i<<1
                BTFSS   STATUS,C        ;Carry set = 8 rotations?
                    GOTO    CheckJ      ;No - Loop round
                MOVF    _k,F            ;Is Mask = 0?
                BTFSC   STATUS,Z
                    RETURN              ;Yes - Finished all samples
    DecCount    DECFSZ  _pCount         ;No - Update counter 
                GOTO    cycleX
                DECFSZ  _pCount + 1
                GOTO    cycleX
                RETURN                  ;Countdown = 0 - Timeout?
    BCLR        MOVF    POSTINC0,F      ;=NOP except inc FSR
                MOVF    POSTINC0,F      ;=NOP except inc FSR
                MOVF    _i,W
                ANDWF   _sample,W       ;Pulse low - already sampling?
                BTFSC   STATUS,Z
                    GOTO    Nexti       ;No - do nothing
                MOVF    _i,W
                XORWF   _k,F            ;Yes - Clear Bit in Mask
                GOTO    Nexti
                
    ;-----------------------------------------------------------------------------            
    _PeriodZ    MOVLW   High(_Period)   ;Set Period[0 to 7] = 0
                MOVWF   FSR0H
                MOVLW   Low(_Period)
                MOVWF   FSR0L
                CLRF    _i          ; i = 0 (counter)
    clr         CLRF    POSTINC0    ;CLRF INDF0 then inc FSR0
                INCF    _i
                BTFSS   _i,4        ; i.4 set = 16        
                    GOTO    clr
                RETURN

Members who have read this thread : 1

You do not have permission to view the list of names.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts