Go Down

Topic: Getting a Third Interrupt Pin on Duemilanove (Read 2884 times) previous topic - next topic


Hello there,

I've made an omnidirectional robot the uses a standard RC transmitter and receiver to wirelessly communicate. This means that the outputs of the joysticks I have are in servo-style PWM signals (0.7 to 1.8 ms pulses every 20ms or so). Currently my code uses both of the duemilanove's interrupts to record when the individual pins go high and then back low and get the timing. However, when I want to add a third (or maybe even fourth) signal, things get tricky, and I have a few questions.

Is there a way to add a third interrupt? I've looked at some of the interrupt pin change things, but I don't really understand them and it would seem as if they just change the pin used rather than add another one.
Is there another way to read servo-style PWM signals with arduino besides using hardware interrupts? The rest of my code is pretty intense (it has to do things with a gyroscope and calculate the turn rates of its three wheels).

Basically: I need a way to read 3-4 servo signals on an Arduino Duemilanove.

I attached my current code, but I doubt it would be much help to understand my position.


This has been covered a few times, but I can't find the most recent case, which had a pretty good solution. Try this though:


Basically you can use diodes to "or" multiple inputs to a single interrupt pin, and also connect them to dedicated pins. Thus, via the isolating diode, if one goes low it registers on its dedicated pin, and through the diode also causes an interrupt. The diode prevents it pulling all the other pins low at the same time.

In the interrupt routine you just read all the connected pins to work out which one caused the interrupt.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Coding Badly

Search for "pin change interrupts".  There are code and examples on the playground and in the forum.


Here are some nice diagrams showing how to wire up the diodes for either an AND or an OR approach.

Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics


The problem with that is that I don't know if the pulses will be at different times. Is there another way to read servo signals?


I did an example of the wired-or configuration here:


It includes wiring and a sample sketch that handles the interrupts.

There would be a potential for an interrupt to be missed if two came in quick succession. The interrupt service routine in my example reads all the pins, so if they came together it would detect them. But if one arrived during the interrupt it might miss it. You could minimize that likelihood by keeping the ISR very short (for example, read all the pins in a single "port read" rather than using digitalRead). So if the ISR basically had a single instruction, to read the port, and then exit, you are reducing the time for missing the extra interrupt to a few microseconds.

There would be other ways, maybe a port-expander chip. They can generate interrupts. For example I looked at one here:


That can handle 16 inputs and generate one or two interrupts. But you potentially still have problems if the ports change in very quick succession.

Another approach would be to use a Mega, or have two Atmega328s working together. There will always be some sort of solution, and whatever you choose will eventually not cope, depending on the data rate. But it may well work acceptably well.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics


Well all the multirotor flight controllers do the RC reading using pin change interrupts and they work fine with 6 channel receivers, google for multiwiicopter, download the source code from the googleCode repository and then understand it, also you can look to the AeroQuad and the ArduPilot projects that do the same.

Go Up