I know this is an old thread, but I'm having a similar problem at the moment.
I was wondering if it's possible (I mean: is it clean code, not a dirty hack that might lead to problems) to do the following:
0. set the EXT to listen to rising edge
1. callback from rising edge
1.1 reconfigure EXT on the fly for falling edge
2. callback from falling edge
2.1 reconfigure EXT on the fly for rising edge
That way the transition (rising or falling) can be read from the channel mode.
I saw there's an extSetChannelModeI() but it's unclear to me whether that's intended for use on a callback's own channel.
Detecting RISING and FALLING edges on BOTH_EDGES interrupt
Moderators: RoccoMarco, lbednarz, tfAteba
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Detecting RISING and FALLING edges on BOTH_EDGES interru
Hi,
There is a mode where the callback is invoked on both edges (EXT_CH_MODE_BOTH_EDGES), no need for dirty hacks. The demos under ./testhal/xxx/EXT do exactly that.
You can read the state of the pin from the callback using palReadPad().
Giovanni
There is a mode where the callback is invoked on both edges (EXT_CH_MODE_BOTH_EDGES), no need for dirty hacks. The demos under ./testhal/xxx/EXT do exactly that.
You can read the state of the pin from the callback using palReadPad().
Giovanni
Re: Detecting RISING and FALLING edges on BOTH_EDGES interru
"Make it idiot-proof and someone will make a better idiot."
... and today, I'm that idiot.
I've attached 3 screenshots of my zero-cross detection output. The first 2 show the jitter on the rising edge, the last one is an overview of zero-cross events. The actual ZC is in the middle of the short pulse of ~0.72 ms. This is why I need to determine both edges: to determine the middle of the pulse (which I really need).
I'm aware that what my logic analyser marks as logic levels may differ slightly from what the controller decides, but I've done a few runs where I log the pin state in a tight loop and the result is comparable.
I've tuned the ZC detector to get rid of jitter, but it just minimizes it - the amount of jitter depends on the time of day (some around 7PM, no jitter at other times). As the screenshots show they're unpredictable in width and I'm not going to introduce loops in the callback to wait an arbitrary time before sampling the pin.
The best I can come up with is this: use 2 pins that listen to the same line, one for rising and one for falling edge. When one is triggered it disables itself and starts a one-shot GPT for 0.5ms. The GPT callback activates the other EXT. Repeat. This last solution doesn't rely on dirty hacks, just the loss of a pin.
Edit: could also do this with one pin where the GPT reconfigures it for rising/falling.
- Attachments
-
- Rising edge @ 25MHz sample
- sampled25MHz_small_peak_40ns.png (33.73 KiB) Viewed 8108 times
-
- Rising edge @ 25MHz sample
- sampled25MHz.png (32.16 KiB) Viewed 8108 times
-
- Zero Crossing events
- global.png (42.86 KiB) Viewed 8108 times
Re: Detecting RISING and FALLING edges on BOTH_EDGES interru
is the zc detector output digital or analog? can you get an oscilloscope trace of the zc input and output?
if your zc circuit uses a comparator you might need to add hysteresis to eliminate the false edges.
it is going to be harder to eliminate the false edges in this digital domain - I would look at the zc detection circuit first.
if your zc circuit uses a comparator you might need to add hysteresis to eliminate the false edges.
it is going to be harder to eliminate the false edges in this digital domain - I would look at the zc detection circuit first.
Re: Detecting RISING and FALLING edges on BOTH_EDGES interru
Looks to me like you are just seeing noise spikes on the AC power input. Try a really stiff low pass filter.
Re: Detecting RISING and FALLING edges on BOTH_EDGES interru
I solved it by using a simplified version of the approach I discussed in my previous post. I'll add the code next Monday since it's much cleaner than I thought and might be useful for someone:
1. configure the EXT for both edges, autostart
2. EXT callback disables itself (extChannelDisable() ) and starts a one-shot GPT with a 250µs delay (the jitter is gone after a few µs). It also saves the event timestamp with halGetCounterValue()
3. GPT callback samples the pin to determine whether it was called after a rising or falling edge and enables the EXT with extChannelEnable(). In case of a rising edge it calculates the location of the previous ZC and next one (every 10ms)
I anticipated poor prediction of the next ZC event but when GPT and EXT are on priority 3 the deviation is less than 2µs (I marked measured ZC and predicted ZC with palSetPad() on two different pins). I should add that I'm in Europe and there's little variation on the mains frequency. But it can change somewhat, so I'm going to use measured values instead of a fixed 10ms.
@jcbarlow: yes, the spikes are from the AC end. They typically concentrate around the zero and come mostly from switching power. There's some filtering going on but since I can't completely get rid of them I decided to deal with worst case (some jitter).
@colin: my oscilloscoop has a dead tube since last week. Currently no time to fix it - contemplating buying a new one.
The circuit is based on this one: http://www.dextrel.net/diyzerocrosser.htm
Some values have been tuned for 240V and narrower pulse (R1,R2 = 470k, R3 = 20k, C1 = 22µF, R4 = 120R). I prefer this implementation because the actual ZC sits in the middle of the pulse.
1. configure the EXT for both edges, autostart
2. EXT callback disables itself (extChannelDisable() ) and starts a one-shot GPT with a 250µs delay (the jitter is gone after a few µs). It also saves the event timestamp with halGetCounterValue()
3. GPT callback samples the pin to determine whether it was called after a rising or falling edge and enables the EXT with extChannelEnable(). In case of a rising edge it calculates the location of the previous ZC and next one (every 10ms)
I anticipated poor prediction of the next ZC event but when GPT and EXT are on priority 3 the deviation is less than 2µs (I marked measured ZC and predicted ZC with palSetPad() on two different pins). I should add that I'm in Europe and there's little variation on the mains frequency. But it can change somewhat, so I'm going to use measured values instead of a fixed 10ms.
@jcbarlow: yes, the spikes are from the AC end. They typically concentrate around the zero and come mostly from switching power. There's some filtering going on but since I can't completely get rid of them I decided to deal with worst case (some jitter).
@colin: my oscilloscoop has a dead tube since last week. Currently no time to fix it - contemplating buying a new one.
The circuit is based on this one: http://www.dextrel.net/diyzerocrosser.htm
Some values have been tuned for 240V and narrower pulse (R1,R2 = 470k, R3 = 20k, C1 = 22µF, R4 = 120R). I prefer this implementation because the actual ZC sits in the middle of the pulse.
Re: Detecting RISING and FALLING edges on BOTH_EDGES interru
Hmmm... the bigger C1 is good. I'd try a bigger C2 and some inductors in series with R1 & R2. Even some big ferrite beads would help. It's usually easier to filter out noise than to cope with it in software.
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Detecting RISING and FALLING edges on BOTH_EDGES interru
I would also evaluate the ICU driver for this, timers do have input filters and the ICU functions would allow to know pulses width allowing to discard filter short ones.
Giovanni
Giovanni
Re: Detecting RISING and FALLING edges on BOTH_EDGES interru
@ jcbarlow: I have some large cylindrical beads somewhere, I'll try that first.
@ Giovanni: thanks for the tip, hadn't looked into that driver. Somehow I feel the urge to knock the desk with my forehead.
@ Giovanni: thanks for the tip, hadn't looked into that driver. Somehow I feel the urge to knock the desk with my forehead.