On Mar 18, 8:47 am, Andrew Smallshaw <andr...@sdf.lonestar.org> wrote:
> On 2008-03-18, Andrew Smallshaw <andr...@sdf.lonestar.org> wrote:
>
>
>
> > If it is low then you have the falling edge. Copy the timer into
> > another variable fallTime. Subtract fallTime from riseTime to give
> > the pulse duration.
>
> Subtract riseTime from fallTime...
>
> --
> Andrew Smallshaw
> andr...@sdf.lonestar.org
Andrew,
Thank you very much. Like you said in your response, I was caught up
in the whole concept of using the "input capture" peripheral and I was
blinded to the much simpler solution of using a free-running timer and
just looking at the timer values every-time the internal comparator
switched state. I already had 2 comparators sitting there and didnt
even realize it!! This solved my software problem (timing and
interrupts) and also my hardware problem (undetermined voltage levels
due to battery sag). It worked great. Thank you.
respect,
frenchy
Reply by Andrew Smallshaw●March 18, 20082008-03-18
On 2008-03-18, Andrew Smallshaw <andrews@sdf.lonestar.org> wrote:
>
> If it is low then you have the falling edge. Copy the timer into
> another variable fallTime. Subtract fallTime from riseTime to give
> the pulse duration.
Subtract riseTime from fallTime...
--
Andrew Smallshaw
andrews@sdf.lonestar.org
Reply by Andrew Smallshaw●March 18, 20082008-03-18
On 2008-03-17, frenchy <deja@houseofharmonystudios.com> wrote:
> Howdy,
> What input capture mode is best for capturing a servo PPM using a
> PIC24FJ64GA002? I need to capture every edge (ICM2:ICM0 = 001), but
> then the time between two captures isn't necessarily always the pulse
> I am looking for....it might be the 18ms "dead time" between pulses.
> I wish I could set it to capture the falling, then rising edges and
> interrupt on the latter (my polarity is reversed if I use an inverting
> common emitter buffer for interfacing). But according to the below
> choices, if I want to detect both rising AND falling, it has no
> intelligence as to whether the interrupt was caused by rising or
> falling. Using a hardware peripheral like this, I didnt think I had
> to implement all kinds of software checking to see what I ended up
> with (to keep the ISR short)..
I'm not familar with the PIC24 chips so I'll limit my comments to
general notes only. It seems as though you are getting lost in
details and losing sight of general principals anyway.
You don't need a lot of specialised peripherals to do this in a
fairly straightforward manner, just a timer and a reasonably simple
ISR. The first requirement is a free running timer. The speed of
the timer is not critical provided that it does not wrap around
within the maximum pulse length, say 2.5ms (it's supposed to be
2ms but some manufacturers have apparently started to take liberties
there). However since you're using a 16 bit machine that shouldn't
be a problem.
At the other end of the scale you need it to be fast enough to give
sufficent resolution. The receiver is designed with servos in mind
that typically have a resolution of around 7 bits, so an equivalent
resolution in your device would imply a minimum timer frequency of
around 100kHz. Obviously, faster would give you better resolution.
Set your input to interrupt on change. In your ISR the first thing
to do is check the state of the pin - you need both rising and
falling edges of the pulse.
If it is high you have found the rising edge of the pulse. Stash
the timer value in a variable somewhere, eg riseTime, and return
from interrupt.
If it is low then you have the falling edge. Copy the timer into
another variable fallTime. Subtract fallTime from riseTime to give
the pulse duration. If the timer was at a fairly high count at
riseTime it is possible that the timer has overflowed during the
pulse but don't worry about it - if that is the case then the
subtraction will underflow and the duration will still be correct.
Store the duration into another variable where it can be accessed
by the surrounding program and return from interrupt.
Bear in mind that the value recorded using the method described
here is the pulse duration, including the initial 1ms that is simply
there to denote the presence of the pulse. This is may need some
further conversion into a logical value to go from 0 to whatever
maximum value you want, or a signed value centred on 1.5ms. However,
what is appropriate depends on your circumstances and preferences
so I'll leave it to you to decide what to do with the value obtained.
--
Andrew Smallshaw
andrews@sdf.lonestar.org
Reply by frenchy●March 17, 20082008-03-17
Howdy,
What input capture mode is best for capturing a servo PPM using a
PIC24FJ64GA002? I need to capture every edge (ICM2:ICM0 =3D 001), but
then the time between two captures isn't necessarily always the pulse
I am looking for....it might be the 18ms "dead time" between pulses.
I wish I could set it to capture the falling, then rising edges and
interrupt on the latter (my polarity is reversed if I use an inverting
common emitter buffer for interfacing). But according to the below
choices, if I want to detect both rising AND falling, it has no
intelligence as to whether the interrupt was caused by rising or
falling. Using a hardware peripheral like this, I didnt think I had
to implement all kinds of software checking to see what I ended up
with (to keep the ISR short)..
any comments would be helpful.
respectfully,
frenchy
bit 15-14 Unimplemented: Read as =910=92
bit 13 ICSIDL: Input Capture x Module Stop in Idle Control bit
1 =3D Input capture module will halt in CPU Idle mode
0 =3D Input capture module will continue to operate in CPU Idle mode
bit 12-8 Unimplemented: Read as =910=92
bit 7 ICTMR: Input Capture x Timer Select bit
1 =3D TMR2 contents are captured on capture event
0 =3D TMR3 contents are captured on capture event
bit 6-5 ICI1:ICI0: Select Number of Captures per Interrupt bits
11 =3D Interrupt on every fourth capture event
10 =3D Interrupt on every third capture event
01 =3D Interrupt on every second capture event
00 =3D Interrupt on every capture event
bit 4 ICOV: Input Capture x Overflow Status Flag bit (read-only)
1 =3D Input capture overflow occurred
0 =3D No input capture overflow occurred
bit 3 ICBNE: Input Capture x Buffer Empty Status bit (read-only)
1 =3D Input capture buffer is not empty, at least one more capture value
can be read
0 =3D Input capture buffer is empty
bit 2-0 ICM2:ICM0: Input Capture x Mode Select bits(1)
111 =3D Input capture functions as interrupt pin only when device is in
Sleep or Idle mode (rising edge
detect only, all other control bits are not applicable)
110 =3D Unused (module disabled)
101 =3D Capture mode, every 16th rising edge
100 =3D Capture mode, every 4th rising edge
011 =3D Capture mode, every rising edge
010 =3D Capture mode, every falling edge
001 =3D Capture mode, every edge (rising and falling) =96 ICI<1:0> bits do
not control interrupt generation
for this mode
000 =3D Input capture module turned off
thx,
frenchy