Ciao to everybody,
I'm new in this Forum, completely new to Arduino (just waiting for my first kit to be delivered), not completely new to domotics.
My question is the following.
Can I use Arduino in an environment that needs, say, 200 input and 200 output without the needs of having several boards, each one with his own source code?
In other words doeas exists a board with a large number of pin os is it possible to "link" more than one board?
If so, it would be great if someone can tell me where can I find some documentation about this feature.
Thanks in advance and hope to be able to payback te favour in the future.
At the moment no such arduino board excist.
If you need that amount of I/O you have to multiplex or find another solution.
Multiplexing so many I/O will be painstaking and maybe to slow.
You can use i2c I/O expanders to get more i/o from a single processor. Typically they provide 16 i/o ports each and use 3 address bits, allowing you to connect 8 of them to the Arduino I2C pins. That gives you 128+18 = 146 i/o pins from a single Arduino Uno or similar.
If the inputs involve buttons, you can drastically reduce the amount pins needed if you form a matrix, and you use 32 pins to sense up to 256 buttons. You need to tell us what inputs and outputs you want to connect to.
Using standard shift-registers could be another option. One will need 3 pins of the arduino, it gives you 8 pins in return and has an data-output or input for the next shift register. It doesn't matter whether you control 1 or 100 shift-registers, all can be controlled with just 3 arduino-pins.
Using 25 SIPO shift-registers (Serial In Parallel Out) you would have 200 output-pins.
Using 25 PISO shift-registers (Parallel In Serial Out) would give you 200 input-pins.
With the right programming 2 of the arduino pins could be used by both types
at the same time costing 4 pins in total. Using 6 pins will be easier to program though.
Costs, close to nothing... with a bit of searching SIPOs (74hc595) can be bought for $0.25-$0.30 a piece and PISOs (74HC165) cost about 5-10 cents more.
Question does remain whether it's an interesting solution for you, depending on what you want to do with your project.
Thanks to all for answers.
Let me explain little more the need.
I would like to control An entire house (3 floor) including lights (internal and external through relé), alarm, gate, Thermostat, Irrigation system, air cond., remote control, etc.
The number of pin I indicated (200) was only an example. A good estimation could be the following:
50 buttons,
1 sunlight sensor
40 alarm sensor (proximity, door/windows open sensor)
2 temperature sensor
1 humidity sensor
1 remote control (if available)
50 lights (rel?)
2 heater
2 air cond.
1 motor for gate opening
8 motors for windows shutter
So I'd need some 170 pin in total.
Could you give me some more information on using matrix for buttons?
With that amount of "security" I/O you might also want to consider using redundant controllers. Say, running 3 arduinos in parallel on a 2-out-of-3 logic voting basis, or get hold of an industrial "certified" PLC with proven reliability and failure rate. (I'm not suggesting the arduino is unreliable)
Jack, what you mean with 'running 3 arduinos parallel"?
Is it possible to have more boards running the same program, so the entire system works anyway in case of outage of one board? Or is more a matter of splitting the logic into 3 different programs?
50 buttons sound a lot. Are they all spread out in the entire house or can you use serial LCD panels at a few locations as controls? Something like this one at a few locations on the wall (this is my design)?
I'd suggest you use one Arduino per subsystem, at least for the more complex subsystems.
Unless you want to know exactly which window is open, you can wire all the window sensors for one zone in a single circuit (e.g. if they are reed switches that are closed when the window is shut, you can wire them in series). Then you only need one pin to read the window sensors in that zone.
To multiplex buttons, see the following image, which shows a 2x2 array (you wouldn't actually use a 2x2 array because it doesn't save any pins, but larger arrays do, e.g. 7x8 = 56 buttons using 15 pins). Pins O1 and O2 are configured as digital outputs, pins I1 and I2 are digital inputs with the internal pullup enabled. To read the buttons, you set one of the output lines low, then you read the inputs so see which have been pulled low, which tells you which buttons attached to that output are pressed.
50 buttons sounds like a very complicated user interface. You could instead design a menu system with a display, a rotary encoder and fewer buttons.
There colud be some 'collateral' effect in case of concurrent activation of more than one button. E.g. Activanting simultaneously buttons 1 and 2. The system could act as if someone press the button 4. Use the technique of have some pin set as input and others set as output suffers of the same problem?
You are right in that if you encode the pushbuttons as bit patterns, you will have that collateral effect. Wiring the pushbuttons in a matrix doesn't have that problem and uses fewer diodes but more pins.
Here is a code example using a 3x3 matrix.
const int numOutputs = 3;
const int numInputs = 3;
const int outputPins[numOutputs] = {2, 3, 4};
const int inputPins[numInputs] = {5, 6, 7};
bool buttons[numInputs * numOutputs];
void setup()
{
for (int i = 0; i < numInputs; ++i)
{
pinMode(inputPins[i], INPUT);
digitalWrite(inputPins[i], HIGH); // enable internal pullup
}
for (int i = 0; i < numOutputs; ++i)
{
pinMode(outputPins[i], OUTPUT);
digitalWrite(outputPins[i], HIGH);
}
Serial.begin(9600);
}
void readButtons()
{
for (int i = 0; i < numOutputs; ++i)
{
digitalWrite(outputPins[i], LOW);
for (int j = 0; j < numInputs; ++j)
{
buttons[(i * numInputs) + j] = (digitalRead(inputPins[j]) == LOW);
}
digitalWrite(outputPins[i], HIGH);
}
}
void loop()
{
readButtons();
for (int i = 0; i < numInputs * numOutputs; ++i)
{
Serial.print("Button ");
Serial.print(i);
Serial.print(" is ");
Serial.println((buttons[i] ? "pressed" : "not pressed"));
}
Serial.println();
delay(1000);
}