PDA

View Full Version : How to Measure 2 or more digital inputs a the same time



longpole001
- 26th April 2013, 08:12
Hi Guys ,

I need to measure the pulse width of 4 signals that start at the exactly the same time but have varying pulse width , how can i do this using Pulsin or RCtime commands ?

the pulse widths are small at about 10us up to 7ms , i am using a clock of 32Mhz

A link to code references would be good


Cheers

Sheldon

HenrikOlsson
- 26th April 2013, 08:23
Hi,
Using RCTime or PulsIn you just can't measure them simultanously, you have to grab them one after the other.

There may be other solutions depending on which PIC you're using and what type of resolution and accuracy you require. On the leading edge of the pulse(s) you start a hardware timer, then you poll each input and on the trailing edge of each pulse you grab the timer value. There will be some measurement jitter but perhaps it'll work. Another solution might be to just dedicate a small 8-pin PIC to measure each of the pulse and send the result to the master.

/Henrik.

longpole001
- 26th April 2013, 08:57
Thanks Henrik , the timer approach looks possible as a starting point , accuracy of upto 5us is required , as a change between pins can be small as 5us , do you have any examples how best to pole the pins to ensure i dont miss the change ? , i am starting to think i may need some asm in here again lol

Cheers

Sheldon

longpole001
- 26th April 2013, 09:17
would a D to A approch work for this hendrik in that i can sample multi ports at same time against a time base give the inputs a value weight when reading for the change , and assign that to the time base ref ???

HenrikOlsson
- 26th April 2013, 09:47
Hi,
I'm not sure this will give enough performance to guarantee a granularity of 5us but it MIGHT. It's not tested but it does compile, perhaps you can use it as a starting point.

T1CON = %00000000 'TMR1 clocked by FOsc/4, prescaler 1:1 = 125ns per tick

@Timer1 = TMR1L ' Create alias to TMR1 in order to access it as a WORD
Timer1 VAR WORD EXT ' Let PBP know of its existance

TMR1IF VAR PIR1.0 ' Alias to TMR1 Interrupt flag, set on overlfow

Pulse1 VAR WORD ' Holding variables for pulsewidths
Pulse2 VAR WORD
Pulse3 VAR WORD
Pulse4 VAR WORD

PulseCount VAR BYTE ' Keep track of how many pulses we've grabbed.

'--------------------------------------------------------------------------
Setup:
Pulse1 = 0 ' Clear all pulsewidhts
Pulse2 = 0
Pulse3 = 0
Pulse4 = 0
PulseCount = 0 ' Clear pulsecounter
T1CON.0 = 0 ' Timer 1 OFF
Timer1 = 0 ' Clear TMR1
TMR1IF = 0 ' Clear interrupt flag

'--------------------------------------------------------------------------
WaitForLeadingEdge:
While !PortB.0 : WEND ' Wait for rising edge on PortB.0
T1CON.0 = 1 ' Start TMR1

'--------------------------------------------------------------------------
WaitForTrailingEdge:
IF !PortB.0 THEN ' First input is low
Pulse1 = Timer1 ' Grab timer value
PulseCount = PulseCount + 1
ENDIF

IF !PortB.1 THEN ' Second input is low
Pulse2 = Timer1 ' Grab timer value
PulseCount = PulseCount + 1
ENDIF

IF !PortB.2 THEN ' Third input is low
Pulse3 = Timer1 ' Grab timer value
PulseCount = PulseCount + 1
ENDIF

IF !PortB.3 THEN ' Fourth input is low
Pulse4 = Timer1 ' Grab timer value
PulseCount = PulseCount + 1
ENDIF


' Now check if we've got all four pulses.
IF PulseCount = 3 THEN WeAreDone

' Verify that the timer hasn't overflowed. At 125ns per tick the
' timer overflows after 8.192ms.
IF TMR1IF THEN ABORT

' Not all pulses grabbed and no overflow, continue waiting.
Goto WaitForTrailingEdge
'--------------------------------------------------------------------------

WeAreDone:
HSEROUT["Done.",13]
HSEROUT["Pulsewidth 1: ", #Pulse1,13]
HSEROUT["Pulsewidth 2: ", #Pulse2,13]
HSEROUT["Pulsewidth 3: ", #Pulse3,13]
HSEROUT["Pulsewidth 4: ", #Pulse4,13]
Goto Setup

Abort:
HSEROUT["ERROR! Timer overflow.",13]
GOTO Setup

/Henrik.

EDIT: Just saw your second post, don't know I understand the D/A approach. If you mean that you're going to convert the the pulsewidth to analog voltage and read that with the ADC I don't think it's going to help because the ADC in the PIC can only sample one input at the time anyway. (Some PICs have dual channel S/H circuits but most don't). In that case you might as well measure pulse 1 then measure pulse 2 then pulse 3 and so on.

longpole001
- 26th April 2013, 11:22
thanks henrik , thats good starting point to run from , yes i was not aware that the d to A could only sample one input at a time , guess i should have.

cheers

Sheldon

longpole001
- 26th April 2013, 11:40
hendrik you mentioned other solutions what would they be , i have been asked to look at another project where i have to look at upto 15 inputs digital , sample the time , and at least record the time inputs for further use ,

and i am concerned that the pics i am looking at will not cut it even at 64mhz any suggestion on how to choose pics with this in mind

HenrikOlsson
- 26th April 2013, 12:24
Well, the first idea that springs to mind is to use the CCP module in capture mode.
It does the same thing as the code above tries to emulate but it does it automatically, in hardware, in the background and can generate an interrupt whenever it captures the timer value so that the software can handle it.

You initially mentioned "2 or more", then 4 and now up to 15 inputs so I'm not sure. There are 18F devices with up to 10 capture modules (3CCP and 7ECCP) but I don't know about 15....

Is it really mandatory to sample all pulses at the same time instead of one after the other. You mention the pulsewidth of each pulse being 10-7000us but what is the frequency or repetition rate? If the repetition rate is fairly high and the pulsewidth isn't expected to change much over 15 periods (or however many "channels" you want) then I think you can still do it with a small PIC and PulsIn.

/Henrik.

longpole001
- 26th April 2013, 13:14
thanks hendrik . for this part of the project, 4 is all that is required at same time . as they all start at the same time and end at dif times and need to be compaired against each other . the times vary on each new start so i cant see how i could do each individually and then see ?

many CCP approach with may be 2 pics running at same time ( that be new for me )with an external trigger to sync the start may be the go

ill sort the 4 input out first and get this working , in another 4 weeks ill look more at the larger input requirements , but have to consider the requirements if only to order the parts to try address a larger number

i should have got all the timer side test done by monday , will let you know the outcome

cheers

Sheldon

Heckler
- 26th April 2013, 15:37
If they all start at "exactly" the same time then just pick one input to start a timer and then use interrupt on change as each input goes low(or high) to read the timer to determine each individual pulse width.

Heckler
- 26th April 2013, 15:56
How about if you used 1 little 8 pin pic in each input to keep track of the pulse width on that pin and have a larger pic read the value from each of those pics to do your math and other software requirments.

Distributed processing...

longpole001
- 26th April 2013, 17:03
yep i am thinking about that way of going , although for the 4 input its is sort of working using just the timer as the base ref at the moment will see if it see all it should , but thinking pic with a alot of CCp might be worth a run as well , have some 16F1825 here which has few CCP in it see if that works as well.

still big learn curve to make this work at all

Cheers

Sheldon

longpole001
- 29th April 2013, 02:23
well the timer option works but barely , on 4 inputs , i need to go faster than 32mhz to be reliable using this method , i have seen faster process at 70mhz- 120mhz , are these supported , been tried by anyone using picbasic?