SparkFun Forums 

Where electronics enthusiasts find answers.

General project discussion / help
Did you make a robotic coffee pot which implements HTCPCP and decafs unauthorized users? Show it off here!
By Mee_n_Mac
#164692
FWIW I note that the Pro Micro uses a ATMega 32U4 which has 4 external interrupts and 2 16bit timer/counter/CCP units.
https://www.sparkfun.com/products/11098
http://dlnmh9ip6v2uc.cloudfront.net/dat ... ga32U4.pdf


ATmega16/32U4
11. External Interrupts

The External Interrupts are triggered by the INT6, INT3:0 pin or any of the PCINT7..0 pins.
Observe that, if enabled, the interrupts will trigger even if the INT[6;3:0] or PCINT7..0 pins are
configured as outputs. This feature provides a way of generating a software interrupt.
The Pin change interrupt PCI0 will trigger if any enabled PCINT7:0 pin toggles. PCMSK0 Register
control which pins contribute to the pin change interrupts. Pin change interrupts on PCINT7
..0 are detected asynchronously. This implies that these interrupts can be used for waking the
part also from sleep modes other than Idle mode.
The External Interrupts can be triggered by a falling or rising edge or a low level. This is set up
as indicated in the specification for the External Interrupt Control Registers – EICRA (INT3:0)
and EICRB (INT6). When the external interrupt is enabled and is configured as level triggered,
the interrupt will trigger as long as the pin is held low. Note that recognition of falling or rising
edge interrupts on INT6 requires the presence of an I/O clock, described in “System Clock and
Clock Options” on page 27. Low level interrupts and the edge interrupt on INT3:0 are detected
asynchronously. This implies that these interrupts can be used for waking the part also from
sleep modes other than Idle mode. The I/O clock is halted in all sleep modes except Idle mode.
Note that if a level triggered interrupt is used for wake-up from Power-down, the required level
must be held long enough for the MCU to complete the wake-up to trigger the level interrupt. If
the level disappears before the end of the Start-up Time, the MCU will still wake up, but no interrupt
will be generated. The start-up time is defined by the SUT and CKSEL Fuses as described
in “System Clock and Clock Options” on page 27.

14. 16-bit Timers/Counters (Timer/Counter1 and Timer/Counter3)
The 16-bit Timer/Counter unit allows accurate program execution timing (event management),
wave generation, and signal timing measurement. The main features are:
• True 16-bit Design (i.e., Allows 16-bit PWM)
• Three independent Output Compare Units
• Double Buffered Output Compare Registers
• One Input Capture Unit
• Input Capture Noise Canceler
• Clear Timer on Compare Match (Auto Reload)
• Glitch-free, Phase Correct Pulse Width Modulator (PWM)
• Variable PWM Period
• Frequency Generator
• External Event Counter
• Ten independent interrupt sources (TOV1, OCF1A, OCF1B, OCF1C, ICF1, TOV3, OCF3A, OCF3B,
OCF3C and ICF3)


Perhaps an upgrade in HW might make for a better solution ? Use 2 of the timers in external capture mode ? For that matter, what's the longest time expected btw any 2 sensor "pings" ? Perhaps the two 8 bit counters of the Uno are sufficient ?
By lyndon
#164696
I don't use an Arduino, but I do have a project that runs on a 16MHz Mega169 that accepts six simultaneous inputs on the Pin Change Interrupt pins. As far as I can tell it's worked perfectly for years. The procedure is to set up what used to be called a "polled interrupt" structure (probably have some fancy name for it these days).

You link your ISR to the PCI and in the ISR poll the inputs to determine which pin triggered the interrupt and which edge it was. As long as you can get out of the ISR quickly, latency is measured in small numbers of microseconds and is exactly the same each time.

Mee_n_Mac wrote:The interested might want to read this PDF on the testing done to measure average Interrupt latency for various methods; pins 2/3 direct external, "pin change" Interrupts for various code versions. The end few (summary) pages are a must read. I'll reserve further comment except for 2 points;
- latency almost doesn't matter so long it's consistent, except that ...
- you need to find a way to detect and handle 2+ simultaneous interrupts (2 CCP units ?)

http://code.google.com/p/arduino-pincha ... st-2.0.pdf
By Mee_n_Mac
#164703
lyndon wrote:I don't use an Arduino, but I do have a project that runs on a 16MHz Mega169 that accepts six simultaneous inputs on the Pin Change Interrupt pins. As far as I can tell it's worked perfectly for years. The procedure is to set up what used to be called a "polled interrupt" structure (probably have some fancy name for it these days).

You link your ISR to the PCI and in the ISR poll the inputs to determine which pin triggered the interrupt and which edge it was. As long as you can get out of the ISR quickly, latency is measured in small numbers of microseconds and is exactly the same each time.
How does the AVR handle "simultaneous" interrupts ? I might assume it's like PICs in that they pend, an indication remaining in some register, even if the ISR has momentarily turned off some global interrupt enable. The user code should then check that register before doing a clear of it and re-enabling all interrupts. I don't think the hidden Arduino interrupt code normally does this and so, w/o modifications, later but close interrupts get lost.

The OP thinks he needs ~5 usec resolution, should be easily had w/a 62.5 nsec clock, but the link I posted had measured the Pin Change Interrupt "latency" (for a few C/C++ versions of "hidden" handler code) to be on the order of 13+ usec ... w/o the user code for the ISR ... much longer than I'd have guessed. Admittedly the "hidden" library code is finding out which pin changed and storing that, but if another interrupt happens only 1 usec after the 1'st ???

That's why I'm wondering if 2 timers in capture mode might not be the better route, even if it means some more conditioning circuitry btw the piezo and the MCU ... and maybe even a better MCU. I have to read up on the details of how AVRs time external events and how deep the storage of captured times is ? Then the MCU HW does the heavy lifting and the ISR can run a whopping number of usecs to fetch the captured times and see if they are a complete set. Background processing then does the calcs need to compute off-center distances and send/display that info.
By lyndon
#164716
One timer per input would be the ideal situation, but remember that you can always program the Arduino without using their libraries if performance is a problem.
By Mee_n_Mac
#164724
lyndon wrote:... but remember that you can always program the Arduino without using their libraries if performance is a problem.
True enough but I get the feeling that the OP would rather drink a pint of bile than have to learn to program an AVR in Assembly. I'm stumped ATM as to which is the optimal path to recommend, SW interrupts to store timing btw sensors or using the CCP HW, meaning more external circuitry (perhaps) ?
By fkatzenb
#164725
This is going to be a bit odd, but I will put it out there. Convert each of the four signals into a TTL events. You then setup an matrix such that each row column intersection is a high speed binary counter that starts when one of its inputs goes high and stops when its other input goes high. The uC then reads in each of the binary counters to determine the exact time comparisons after a predetermined about of time (single interrupt). So if you have sensors A, B, C, D at locations 0, 90, 180, and 270, you would compare A-B, C-A, A-D, B-C, D-C. This would give you all the positional data you need provided you can achieve a high speed and reliable circuit. You would setup a 8 bit flip flop circuit with a high speed clock as your triggers. The first signal enables the clock and the second signal holds it so that you can read in the state of the binary counters (8 flip flops per comparison circuit). That uC could be a simple Arduino and you read in each flip flop like you would memory addresses. Once you complete, you finish the hold signal to complete the reset.

Off my rocker?

Thanks,
Frank
By Mee_n_Mac
#164756
That's the basic idea in using the onboard timers but so far as I can tell the timers in AVRs don't work as needed, at least not any better than using ext interrupt pins and getting a timestamp via an ISR. Timers in PICs work differently and can time a pulse directly. See the description for Timer1 (Fig 4-6).
http://www.mikroe.com/chapters/view/5/

According to PJRC using the ext interrupt pins (not pin change) on a 32U4 the latency can be under 5 usec ... perhaps that's good enough, with a tweak to check for "simultaneous" interrupts ??
http://www.pjrc.com/teensy/td_libs_Encoder.html
By fkatzenb
#164758
Mee_n_Mac wrote:That's the basic idea in using the onboard timers but so far as I can tell the timers in AVRs don't work as needed, at least not any better than using ext interrupt pins and getting a timestamp via an ISR. Timers in PICs work differently and can time a pulse directly. See the description for Timer1 (Fig 4-6).
http://www.mikroe.com/chapters/view/5/

According to PJRC using the ext interrupt pins (not pin change) on a 32U4 the latency can be under 5 usec ... perhaps that's good enough, with a tweak to check for "simultaneous" interrupts ??
http://www.pjrc.com/teensy/td_libs_Encoder.html
Holy blast from the past on PJRC. I own one of his displays: http://www.pjrc.com/store/mp3_display.html
By Mee_n_Mac
#164759
Musing on how a system using a PIC w/2 such (as above) timers might work ...

You'd set the timers to zero and enable the gate control pins. Keeping with the 4 detector scheme, one timer/2 detectors does vertical off-center timing, the other horizontal, in all other respects the 2 channels are identical. When either of the detectors ... ummm, detects, it generates a pulse to the PIC gate control pin. The timer then counts up from zero. When the other detector detects it resets the pulse, thereby stopping the timer and (IIRC) generating an interrupt. The ISR can leisurely fetch the timer reading for the distance calcs and make ready for the next shot. If the pulse is so short ("simultaneous" detections) that the timer doesn't increment, that's a dead center (along that axis) hit. If the ISRs overlap, so what ... the times are already frozen and will remain until read (or the next shot).

The conditioning circuitry must do a few tasks;
- digitize the analog detector signal
- generate or reset the above pulse
- do the previously mentioned 1 shot function so there's only 1 pulse per hit despite the msec long analog signal
- output some digital indication of which detector (of the pair) went off 1'st so up/down, right/left can be known by the PIC

Whether this approach is any easier for the OP, or necessary, is ???
By fkatzenb
#164760
I still have concerns over basic piezo equipment being reliable. I still think that bolt on knock sensors would be best.