I'm looking for a bit of guidance on feasibility. My project is to create a laser tag system. I'm just looking at the basics, and with just a 16x2 LCD and the Adafruit Wave Shield, I only have a few pins left for things like an XBee, a sensor, buttons, and the like. My question is, how do I save pins? I see pictures with giant stacks of shields on top of Arduinos - how do they do it?
You can use a shift register to turn three pins (data, shift, latch) into 8, 16, 24, etc. output pins. If you run the shift registers off the SPI outputs (data to MOSI and shift to SCK) you just need a 'slave select' pin for the latch. Similarly you can hook a number of shift registers to the SPI input pin (MISO) and simultaneously bring in the same number of inputs as outputs (SPI transfers are always bi-directional).
To help you save pins, we need to know what pins are being used for what. You can't just say, here, I have 5 pins, help me make it work with all the stuff I want to connect to.
Using a shift register is the best way for most purposes but as has been said knowing what you are using them for can be useful too.
Have a look at the 4000 and 74 series chips there are a number of useful devices there.
A shift register creates a little work between your chip and the input so MAY not be ideal when you have fast data coming in so multiplexing is another alternative.
A 74150 for example has 16 inputs and one output. This can be controlled by 4 outputs from the arduino (for the address) plus the 1 input. Not as good as the shift register BUT once the 4 address lines are setup the input requires no work and is full speed just like a normal input.
So now you have another possibility, you can even mix the two! ie a pair of 74150s and a shift register would give you 2 inputs from 32 (or basically a pair of 1 from 16s) for 5 GPIO ports and at full speed with no extra work once the address lines are set.
I just bought 24 ex russian military new 74150s for £22 (about $27 ish)
If you want a set of functions for manipulating the 74150 let me know and I will upload them.
And of course the 6 analog pins on an UNO - what board do you have? - can be used as digital pins too.
Furthermore if you use NewSoftSerial for serial-out only you can define the RXpin as -1 or if you only have serial-in declare the TXpin as -1.
liudr:
To help you save pins, we need to know what pins are being used for what. You can't just say, here, I have 5 pins, help me make it work with all the stuff I want to connect to.
Sorry
Okay...I have an UNO. The project will (hopefully) use the following components:
A 16x2 LCD, so 6 pins that can go anywhere
A series 2 XBee, so pins 0 and 1
A TSAL6200 LED, which will require one pin, because a relay will be needed, as it needs 250 mA of current (while I'm at it, does anyone know a cheap relay that can handle 250 mA?)
9 TSOP34856 sensors, when wired together with 3 of these, should only need 1 pin
One button, to be used as the trigger button, 1 pin
3 more buttons, to indicate to the gun whether it has a magazine in it, and which one (to keep track of empty magazines), 3 pins
That's the basics. Once I have those working, I'd like to start adding in other stuff:
An Adafruit Wave Shield, uses pins 11, 12, and 13 for the SD card, then any 5 other pins
Some sort of rumble motor, haven't figured this out yet, I imagine I'd need another relay, so 1 pin (I imagine)
VirtualWire, probably, I just need a really short range radio (5-10 feet max), seems to need only 1 pin (only a using receiver in the gun)
In the future, I may want to replace the 16x2 LCD with this. 10 digital pins and 2 analog. Ouch.
I don't know if a shift register would work, as this is a laser tag game; things move very fast - and thus, the Arduino must as well. Multiplexing sounds better, but I don't have a clue how to do that. Does anyone have a link to a guide?
Thanks a bunch everyone, and sorry for the late response!
Edit: I wouldn't be surprised if I missed something, just putting that out there
as this is a laser tag game; things move very fast
Compaired to the speed of an arduino your tag game moves at the speed of a glacier.
As usual, I worded it poorly. Think about it this way: say one gun is fired. That gun outputs a short pulse of IR light. If the receiving gun is not polling its sensors at that time, then the shot would count as a miss, even if it was right on target.
cowasaki:
A shift register creates a little work between your chip and the input so MAY not be ideal when you have fast data coming in so multiplexing is another alternative.
I'm not sure exactly how much delay there is, but judging by cowasaki's post, it seems that shift registers would not work.
robtillaart:
A 16x2 LCD, so 6 pins that can go anywhere
Use a serial LCD, it uses only one pin....
Would that not be slower than a regular 16x2 LCD? As I said, it needs to be very fast - no delay. Also, I bought a couple regular LCDs already, so I'd like to make those work. However, if it becomes necessary, I will definitely take this into consideration - thanks!
Would that not be slower than a regular 16x2 LCD? As I said, it needs to be very fast - no delay
No, LCDs take an age to refresh the extra time to send it serial data is not significant.
Polling sensors is never a good idea but if you get round them fast enough you will not miss a hit. How long is your pulse? You have to get round all your sensors in that time. I suspect a pulse value of 10mS will more than cover it, and it is more likely you will want a 100mS pulse.
Grumpy_Mike:
Polling sensors is never a good idea but if you get round them fast enough you will not miss a hit. How long is your pulse? You have to get round all your sensors in that time. I suspect a pulse value of 10mS will more than cover it, and it is more likely you will want a 100mS pulse.
What alternative is there to polling sensors?
It shouldn't matter anyway. Due to the way the PCBs are wired, hitting just the one "Hit" data pin covers all of the sensors.
My pulse probably won't be a singular pulse - it will probably consist of multiple 10, 15, or 20 mS pulses so that I can encode the shooting player's ID in the shot, so each player's gun knows who shot who. If you say that a 10 mS pulse will more than cover it, than I think I'm set.
Grumpy_Mike:
it seems that shift registers would not work.
I would beg to differ.
How much lag does the shift register create between the Arduino and the sensors/other parts?
I looked up some more stuff on multiplexing. Seems great for when if I have a bunch of simple parts (which I have some of, and it would make a great fit), but what if I'm using Arduino libraries? Is it possible to just go in and edit the LiquidCrystal library (or any other one, for that matter) so that I can set the pins being used through the multiplexer?
How much lag does the shift register create between the Arduino and the sensors/other parts?
Less than 30uS.
What alternative is there to polling sensors?
Having them generate an interrupt.
Is it possible to just go in and edit the LiquidCrystal library (or any other one, for that matter) so that I can set the pins being used through the multiplexer?
Yes it is quite easy, the bit that actually writes out to the pins is in one or two functions right at the end of the code for the library.
How much lag does the shift register create between the Arduino and the sensors/other parts?
Less than 30uS.
Awesome, it will work then! Thanks!
Grumpy_Mike:
What alternative is there to polling sensors?
Having them generate an interrupt.
Thanks for the idea. I just want to know...do interrupts have any real benefit over polling as long as the sensor is checked...lets say, at least every 3 mS? (Not sure if that's accurate at all)
Using a shift register is the best way for most purposes ...
Why would a shift register be better than an I/O extender?
Can a shift register also be used for input and can it generate an interrupt based on these inputs?
Don
Does that mean shift registers can't be used for input? I will definitely need inputs...does that mean multiplexers are my best bet?
EDIT: Strike that, so shift registers can be used for input. What about output? If it can, can a shift register do both, like a multiplexer? Or just one?
CrossRoads:
Universal shift register such as 74AC299PC (56 cents at Newark.com) can shift in & out, and do parallel in & out also.
So wait, then what's the difference between a shift register and a multiplexer, practically, other than the one pin and the ease of programming? It seems easier to program with a multiplexer, but that's just what I think, I haven't seen much about shift registers - they seem harder to program, especially when you take reprogramming libraries into account.
... then what's the difference between a shift register and a multiplexer ...
It's probably easier to compare their similarities. For starters they are both available in a dual-inline-package.
Don
[Edit] OK here's some more. Let's compare an 8-input multiplexer with an 8-bit parallel to serial shift register. They both have 8 inputs and one output.
The multiplexer has three 'address selector' lines. You input a binary number (000-111 or 0-7) to those lines and they select which of the eight inputs is connected to the output. You can change the binary number to any other value and the corresponding input is connected to the output. It works like a rotary switch where the address selector lines turn the rotor.
The shift-register typically has a latch line and a strobe line. When you activate the latch the values present on the eight inputs are 'captured'. Each time you subsequently activate the strobe one of the captured bits is sent to the output. The bits are pushed out sequentially on each activation of the strobe, sort of like pushing toothpaste out of a tube.
Shift-in register can be thought of as capture a piece of time for 8 pins, the uC examine those captures.
Multiplexer is like opening a channel that remains active until another channel is selected, and uC looks at signal in real time.
Shift-out register is the opposite - 8 bits are set high or low, output devices then do something with them.
Demultiplexer is the same channel comparison, one output toggles under direct uC control, the other do not change (and typically (see the indivdual datasheet) are left in a high state).
Shift register can things that multiplexer cannot - say you were multiplexing an LED array. You could have the uC control the columns, and have a shift register to control the row that gets turned on.
So you setup the column bits to be on/off. Then clock a 0 into the shift register output 1 (assume all outputs were set up as 1s to start).
Then set up next set of columns, and clock the 0 into the next row position, output 2.
Continue for 6 more cycles, and repeat.
With a universal shift register, you can clock that bit left & right also. You can capture data in parallel, and shift it into the uC. You can serially shift data in and then look at the bits on individual input uC pins if wired that way. From a hardware designers perspective, its very handy.
At other times, you need that fast direct access to an external source, so mux/demux is also a handy part.