Using multiple conditions

Hi guys, I'm new to programming and need some advice on how best to get my project working.

Essentially I need the program to control relays based on 2 separate sets of conditions. Firstly, 4 digital inputs set the arrangement that the 8 analog inputs (being used as digital inputs) should see when reading the output of a set of relays, eg.

Digital read LOW LOW LOW LOW from the 4 pins says all analog ins should read LOW, or

Digital read HIGH HIGH LOW LOW says analog pins 0, 1 and 5 should be HIGH, and the rest LOW

If an analog pin reads HIGH instead of LOW or vice versa, it needs to trigger another digital output to switch the corresponding relay.

I've got code that defines what the analog pins SHOULD read, based on the 4 digital inputs (although I'm unsure whether 'for', 'while' or another command will be the most suitable, as the digital inputs will change arbitrarily). I'm struggling with how best to have the program read the analog inputs and then activate digital outputs accordingly, without it being totally inefficient.

If anyone can point me in the right direction in terms of which control commands to use it would be a great help. If I've left out any key info or made no sense, please let me know!

Thanks to anyone willing to take the time and help,

Gareth

What Arduino board are you using that has 8 analog inputs?

I think the way I would deal with your problem is to assign a number to each of the "analog" inputs - 1,2,4,8,16,32, 64 and 128.

Then for every HIGH input I would add the appropriate value to create a total. For example if inputs 0, 2 and 6 were high (and the rest low) it would give a total of (1 + 4 + 64) = 69. Every combination will be unique.

The code to do this can be simple

pinTotal = 0;
basePin = A0; // or whatever
for (n = 0; n < 8; n++) {
   pinVal = digitalRead(basePin + n);
   pinTotal += pinVal << n; 
}

Then if you want to check whether (using your example) 0, 1 and 5 are HIGH you would check to see if the total is (1 + 2 + 32) = 35. If you know when writing the code that you will need to test for the number 35 that can be programmed in rather than calculated at run time.

...R

Hi, thanks for the help!

I'm using a ch340 nano clone, same specs as the Arduino nano.

That seems like the easiest way to do it, assuming I've understood it correctly... Do I only need to use that code once to read the condition of all 'analog' inputs, or do I need individual 'for' statements for each input?

Would it be best to use in conjunction with an if...else condition to set the required number and action?

eg

if(digitalRead(dig1Pin) = HIGH);
  (digitalRead(dig2Pin) = HIGH); 
  (digitalRead(dig3Pin) = LOW); 
  (digitalRead(dig4Pin) = LOW);
  (pinTotal = 35);

{

//do nothing

}

else

{

//fire the correct digital output/s to make make the outcome true

}

There may well be a better way to address the digital inputs, instead of individually testing them, I haven't quite got my head around anything beyond basic steps yet...

gbt8964:
There may well be a better way to address the digital inputs, instead of individually testing them, I haven't quite got my head around anything beyond basic steps yet...

Might be an idea to look at ports as distinct from pins, and you'll probably be wanting to look at arrays soon.

(Aside: May I suggest that you stop referring to 'analog' pins here?- if they're being used as digital pins, they're digital pins. I don't know the Nano pin numbering, but on an Uno, the analog pins A0-A5 can merely continue the digital numbering. So when I use those pins as extra digital pins I number them from 14-19.)

gbt8964:
Would it be best to use in conjunction with an if...else condition to set the required number and action?

if(digitalRead(dig1Pin) = HIGH);

(digitalRead(dig2Pin) = HIGH);
 (digitalRead(dig3Pin) = LOW);
 (digitalRead(dig4Pin) = LOW);
 (pinTotal = 35);

{

I am a bit confused. I think you are confusing the 4 selection pins with the 8 action pins. It is the action pins that produce the pinTotal (using the code I posted).

So I think you need code like this (assuming you have read the 4 selection pins)

if (dig1Val == HIGH && dig2Val == HIGH && dig3Val == LOW && dig4Val == LOW && pinTotal == 35) {

Having written all that out it occurs to me that you could use the same system for getting a total for the 4 input pins 1,1,0,0 would give 3 and the test could be simplified to

if (digTotal == 3 && pinTotal == 35) {

With 4 selection pins and 8 other pins there is a huge number of possibilities so think VERY CAREFULLY to make sure you are covering the correct cases in your tests.

...R

Thanks again to you both, you've sent me in the right direction.

I've ended up using that same system for both sets of pins after your first suggestion, Robin2, though the code you just put up is way simpler than I wrote.

As for the number of variables, I think I have a solution for it. I assigned each pin a value as you suggested, and in the event that pinTotal is different to expected, each individual pin's value is tested against pinTotal to establish a) if something is off that should be on, b) if something is on that should be off, or c) is already correct.

edit The output pins in the arrangement are controlling transistors that are mimicking momentary switches connected to another circuit. That's why the on/off states for the outputs are either seemingly backwards or very brief.

if (digTotal == 3 && pinTotal - a0Val < pinTotal) {
  digitalWrite(control1Pin, LOW); 

//if desired relay is already on from previous arrangement

}
else if (digTotal == 3 && pinTotal - a0Val == pinTotal) {
  digitalWrite(control1Pin, HIGH);
  delay(10); // delay is to mimic a momentary switch
  digitalWrite(control1Pin, LOW);

//if desired relay is off from previous arrangement
}

Testing each pin individually in sequence may not be the most efficient way of doing it, but it seems like it will work. I haven't got my circuit wired up yet to test, hopefully I'll have it together in the nest few days.

I'll go through and tweak the code sometime today, and try and post a sample soon.

Thanks again for your help, it really has been useful.

Gareth

pinTotal - a0Val == pinTotal can only be true if a0val == 0 and can be replaced with a0val == 0.
pinTotal - a0Val < pinTotal can only be true if a0val > 0 and can be replaced with a0val > 0.

gbt8964:
and in the event that pinTotal is different to expected,

How could that possibly happen?
The total IS what the pins represent.

...R