Hi,
I'm building an arduino project to control some lighting in my room. The general idea is that the Arduino uses a 433 MHz transmitter to control 4 switches that turn on and off my lights. Also, the arduino is driving RGB led strips. On top of that it needs to be able to communicate to the PC, and it contains an DS3232 RTC.
To control the RF switches I need 10 toggle buttons, 8 to turn on and off each individual light (there are 4 lights), and 2 buttons to turn off and on all lights.
The DS3232 requires 2 pins (A4 and A5), and the RF transmitter requires 1 pin. In addition I want to a a rotory encoder and a pot-meter to control the led strips color and brightness.
This is what I had in mind:
pin 13: RF transmitter
pin 12: Master on switch
pin 11, 10, 9: RGB Leds
pin 8, 7: rotory encoder
pin 6, 5, 4, 3: lights on buttons
pin A5, A4: DS3232
A3: potmeter
A2; Master off switch
A1, A0: lights off buttons
This uses up all available pins (except 0 and 1, they are needed for serial comm), but I still need 2 buttons to turn my lights off. There are ofcourse some options that I considered, first is to scrap the master switches. The second option is to not use individual off and on switches, but toggle switches (this woould free up 5 pins). Another option is to scrap the DS3232. And lastly I considered buying a bigger arduino.
None of these options seem very attractive to me, is there any thing that I'm overlooking? Anything I can do to get those 2 extra pins?
I think you should control pins 11, 10, 9, 6, 5, 4, 3 with shift register: http://www.arduino.cc/en/Tutorial/ShiftOut
A4 and A5 is I2C bus and you could use - SparkFun I2C Expander Breakout - PCF8575 - BOB-08130 - SparkFun Electronics - to extend with 16 I/O lines that can be used for the RGB LED and I/O pins.
Furthermore could you combine these into one switch??? or a switch in the powerline? or is the master switch just pausing the sketch...?
pin 12: Master on switch
A2; Master off switch
Also get 5 switches on 1 Analog pin this way:
http://arduino-direct.com/sunshop/index.php?l=product_detail&p=117
DISCLAIMER: I mentioned stuff from my own Shop...
You can cut down the pins you use with PISO and SIPO shift registers and shifting in and out. I'm building something at the moment which has 16 outputs and even more inputs, but I'm only using something like 10 pins.
PISO (parallel in, serial out) and SIPO (serial in, parallel out) shift registers basically use three pins: Data, Clock and Latch, the difference is that the Data pin with a PISO register is an input and with a SIPO it's an output. I use 4021 PISO registers as inputs and 595 SIPO registers as outputs. Essentially, what a PISO register does is convert voltages on 8 of it's pins into a byte, which the arduino can then read. The SIPO register does the opposite, the arduino gives it a byte and then it converts that into output voltage.
These links were invaluable to me to work out this stuff:
http://www.arduino.cc/en/Tutorial/ShiftIn,
http://arduino.cc/en/Reference/ShiftOut and
Arduino Playground - BitMath.
If you just want to have a few switches to turn on a corresponding light, then you could just shift in what the PISO is reading and shift that straight out to the SIPO, but for the switch to turn all the lights on or off you'll want to read up on Bit Math, which can be used to convert a byte that is, say, 10000000 (one switch high, all others low) into 11111111 (all outputs high). It's surprisingly simple, that link explains it very well.
If you've never used shift registers before they can be quite confusing, but they're very well documented. This is quite a good link which might help:
http://conductiveresistance.com/interactive-595-shift-register-simulator/.
But if I use a shift register to connect the buttons to the Arduino I'd have to poll them, because the shift register can't interrupt the Arduino as far as I can tell. Polling is kind of out of the question, because sending the RF data takes around half a second, while it's sending the program will block, which means that a button press at that moment will go by unnoticed. Although if there are no better options I guess I'll use a shift register and polling.
About that master switch, it's just a switch that will send the RF signal to all receivers when it's pressed. Basically it would do exactly the same thing as pressing all buttons in rapid succession :).
KE7GKP:
sending the RF data takes around half a second
That does not sound right. If it is true then you have great opportunity for optimization. I suspect that it is a tiny fraction of that. Blocking shouldn't be a problem with a user interface unless something is wrong with your RF transmission code somewhere. Furthermore, there ARE shift registers or multiplexers that feature built-in interrupt handling so that if any input changes, it consolidates all the interrupts and sends one back to Arduino which can then do the poll and sort out which button was pressed, etc.
The problem with the RF transmitter is that sending the signal once doesn't take long at all. Like you said, it shouldn't pose a problem. However, I need to retransmit the signal a couple times to ensure that it's picked up by the receiving end. Even the remote control that was packaged with it takes this long, sometimes I have to hold the button a second before the receiver responds. It might be the cheapness of the set :).
I'm going to look for one of the shift registers.
But if I use a shift register to connect the buttons to the Arduino I'd have to poll them, because the shift register can't interrupt the Arduino as far as I can tell.
There is a better option. You really should look into using an I/O expander which is designed specifically to do what is being proposed with the general purpose shift register. The Microchip MCP23017 (I2C) and MCP23S17 (SPI) can generate the interrupts that you need.
Don