Hello, I built a rolling ball sculpture and I'm finally working on the electronics part. I have 15 micro switches mounted on the track that trigger whenever a ball rolls over them. But the 'on' time of the switches is extremely short. I figured I could use interrupts, but even the MEGA only has 6 interrupt pins.
Any ideas on how to handle sensing each of the switches?
Well, have you only got the 15 inputs? what about outputs?
You could connect ALL of the switches to a single pin change interrupt, AND each switch to it's own digital input (remember the pins labeled analog can also be used for digital).
Then when one of the switch closes, it trips the interupt, and the first thing it does is read the inputs to see which one has been tripped.
This may sound like a dumb question, but do the switches all do something different? or do they just need to trigger an event?
There are multiplexers out there that can take 16 inputs and output a 4 digit bcd value. That would be an easy way to get the data into the controller using minimal pins.
I just can't think of a part number right off hand. Maybe someone else can think of one??? :-?
But the 'on' time of the switches is extremely short.
Yea, but an Arduino running at 16mhz is even more extremely fast relative to such mechanical timings. Depending on what else you have to process you might find just simple digitalReads will keep up nicely. Don't forget to debounce those switches no matter how you end up reading them.
I'll have to get a MEGA because I also have about 15 groups of LEDs that respond to the switches, plus the screw-lift motors and an LCD to drive. I should still have plenty of digital IO on the mega. I'm just not sure how to detect the switches. I like your idea of using an interrupt and a digital pin. Although I'm wondering how quickly I can scan 15 pins each time there's an interrupt.
I'm thinking maybe there's a way to make each switch trigger a latch or mono-stable circuit - basically something that stays high or low after the switch is done. Then have the Arduino reset that or something.
Each switch controls one LED or group of LEDs - with the option to do more, being a microcontroller and all - so I need to detect each switch and do something specific for each.
I guess I should just try it first and see how it goes. If the Arduino is fast enough to detect the switches directly, I'll be stoked.
Only eight pins are needed to read 16 pushbuttons. Wire the buttons in a 4x4 array with four output pins connected to the rows and four input pins connected to the columns. Have an outer loop energize the output pins one by one in order and then have an inner loop scan the four input pins one by one in order. When an input signal is detected, then the program knows that the pushbutton in that row and column has been pressed. This should work as long as the loop is fast enough relative to the input and if not more than one button is active at a time.
Only eight pins are needed to read 16 pushbuttons.
.. or a single pin only if you connect all 16 switches to an analog input pin with a unique resistor that allow you to differentiate between switches through analogRead.
I think this could be done with one pin and an interrupt, if the switches are always triggered in the same order. You could just keep track of the switch being triggered in software.
This will of course only work if there is only one ball rolling at a time.
Remenber to take switch debouncing into account no matter what way you do it !
The number of pins isn't really a problem. I'm looking for a way to be sure the Arduino detects the state change of each switch. The switches are clicking on and then off very quickly - in human terms anyway.
.. or a single pin only if you connect all 16 switches to an analog input pin with a unique resistor that allow you to differentiate between switches through analogRead.
Just a quick point.
Arduino analogRead cannot be done very quickly though due to the time for the analog to digital converter.
Arduino analogRead cannot be done very quickly though due to the time for the analog to digital converter.
That is true, but fast/slow is always relative to what you need. An Arduino Duemillanove at 16MHz will use 104 microseconds per conversion. This would allow for 10 samples per millisecond which may be sufficient to catch a mechanical switch.
There is of course more to actually implementing this as a purpose built rewrite of the analogRead function would be required in order to free up the conversion time for other tasks. This is all doable as the ADC hardware runs on its own clock independent of the CPU, but it will require stepping out of the comfort zone of standard Arduino functionality.
Yes I suppose it would be plenty fast enough for sensing a mechanical switch. If you had a switch flicking that fast then I think there would be a few issues coming up!
If the microswitches are SPDT, there's a simple trick of using an RS flip-flop to reliably debounce them. A google search will turn up examples and explanations of how it works.
With an ATMega168 or 328, you may be able to use the "port pin change" interrupts to catch switch depressions. That'll depend, in part, on what other functions you have assigned to the pins: there are no masks available for turning off the interrupts from individual pins, so you might find yourself getting interrupts you don't want. Those interrupts were sacrificed for additional external interrupts on the 128, though.
There are some I2C port expander chips (Microchip MCP23008 and MCP23017. Maybe others.) that have an "interrupt on change" feature, too.
But none of the above have latching to remember interrupt requests, so you have a risk of missing interrupts due to race conditions or the CPU being busy while the input pulse comes and goes. There are specialized interrupt controller chips for some CPU families that might be adaptable to your purpose. But the cheapest approach might be to use something like a 40-pin PIC, and dedicate it to polling its inputs and maintaining a queue of detected interrupt requests that it could feed to the Arduino through a parallel port with handshaking.
Don't overlook the problem of electrical noise: if your machine is bigger than a breadbox, all those wires going to the switches could turn into a "noise antenna farm". I'd be inclined to use stereo headphone-type cables to connect them: it's cheap because it's made in huge volumes, relatively thin, and gives you shielded conductors for Vcc and data.