Go Down

### Topic: Multiple switch state coding help (Read 5498 times)previous topic - next topic

#### technochris1

#15
##### Aug 05, 2010, 11:16 am
the solid State Relays activate with 5v, and for timing, id rather there be a 1-2 second delay if there needs to be any.

#### PaulS

#16
##### Aug 05, 2010, 01:30 pm
A stack sounds like it is what you need. Push onto the stack the value of the switch that is pressed (1 to 5).

The length of the stack is what determines which A relay is active. 0 means no A relays active. 1 means A1 is active. 2 or more means A2 is active.

The values in the stack get popped at the appropriate time, and used to activate a B relay.

What isn't clear from your problem statement, yet, is how long the A or B relays are to stay open.

I'd venture a guess that the A1 relay is open as long as any one B relay is open, and that the A2 relay is open as long as any 2 B relays are open (which is the maximum number of B relays that can be open at any one time).

But, what causes a B relay to close?

The C++ standard template library includes a stack class, so Google is going to return thousands of hits for "stack" that don't help. But, implementing a stack is not that difficult, especially if you have a reasonable limit to the size of the stack.

#### technochris1

#17
##### Aug 07, 2010, 09:35 pmLast Edit: Aug 07, 2010, 10:58 pm by Technochris1 Reason: 1
If Switch_1 goes High B1 will Go High, and go Low when Switch_1 goes low.
If Switch_2 goes High B1 will Go High, and go Low when Switch_2 goes low.
If Switch_3 goes High B1 will Go High, and go Low when Switch_3 goes low.
If Switch_4 goes High B1 will Go High, and go Low when Switch_4 goes low.
If Switch_5 goes High B1 will Go High, and go Low when Switch_5 goes low.

A1 will follow the First Switch_X to Go High, and Low.
A2 will follow the Second Switch_X to go High and Low.
If a third switch goes high the relay attached to that same switch CAN NOT go High.

so if i can get a "stack / queue" code in there, i need write a number to it, for every Switch that can go active. this way once a certain number is populated or however the code works, any switch that is activated Third, the relay will not turn on.

#### technochris1

#18
##### Nov 30, 2010, 10:36 pmLast Edit: Nov 30, 2010, 10:38 pm by Technochris1 Reason: 1
Im Back,

Instead of making a new Topic, Ill just update the current one.

[size=14]SIMPLE VERSION:

There are 5 120v Power sources (from the power company), and 2 backup generators.

If one of the Power sources fail, a Backup generator starts up, and switches the Load From the Power companys supply to the Generated supply.

If More than 2 power sources fail, than the third must not be switched, because there is no generator to supply it with power.

[/size]

MY "IDEA":

S1-S5 represent an Error contact closure from Audio amplifiers. When a channel on an Amp fails, the output Closes. So if S1 is Pressed Amp 1 is in an error state. If an Amp Is in Error, a Backup Amp will take its place. The Red LED's represent Relays that will switch the audio channels from the normal amp, to the backup amp. The Blue LED's represent the Backup Amps. When an Amp reports error, whichever backup amp is not in use needs to take its place by first activating the Backup LED, then the LED that represents the amp that failed. If only 2 backups are configured, then a MAX of 2 amps can go into error at the same time.

Heres a Fritzing image.

MY CODE:
Code: [Select]
`//define switchesint switch_1 = 2;int switch_2 = 3;int switch_3 = 4;int switch_4 = 5;int switch_5 = 6;//define led pinsint led_1 = 8;int led_2 = 9;int led_3 = 13;//define Relay Outputsint Relay_A1 = 11;int Relay_A2 = 12;int Relay_B1 = 14;int Relay_B2 = 15;int Relay_B3 = 16;int Relay_B4 = 17;int Relay_B5 = 18;//define total variableint total = 0;void setup(){  //turn on serial communication for debugging only  Serial.begin(9600);  //declare switch pins as INPUTS  pinMode(switch_1, INPUT);  pinMode(switch_2, INPUT);  pinMode(switch_3, INPUT);  pinMode(switch_4, INPUT);  pinMode(switch_5, INPUT);  //declare led pins as OUTPUT  pinMode(led_1, OUTPUT);  pinMode(led_2, OUTPUT);  pinMode(led_3, OUTPUT);  pinMode(Relay_A1, OUTPUT);  pinMode(Relay_A2, OUTPUT);  pinMode(Relay_B1, OUTPUT);  pinMode(Relay_B2, OUTPUT);  pinMode(Relay_B3, OUTPUT);  pinMode(Relay_B4, OUTPUT);  pinMode(Relay_B5, OUTPUT);}void loop(){  total = 0;  if(digitalRead(switch_1) == HIGH){    total += 1;    digitalWrite(Relay_B1, HIGH);  }  else{    if(digitalRead(switch_1) == LOW){    digitalWrite(Relay_B1, LOW);    }  }  if(digitalRead(switch_2) == HIGH){    total += 1;    digitalWrite(Relay_B2, HIGH);  }  else{    if(digitalRead(switch_2) == LOW){    digitalWrite(Relay_B2, LOW);    }  }  if(digitalRead(switch_3) == HIGH){    total += 1;    digitalWrite(Relay_B3, HIGH);  }  else{    if(digitalRead(switch_3) == LOW){    digitalWrite(Relay_B3, LOW);    }  }  if(digitalRead(switch_4) == HIGH){    total += 1;    digitalWrite(Relay_B4, HIGH);  }  else{    if(digitalRead(switch_4) == LOW){    digitalWrite(Relay_B4, LOW);    }  }  if(digitalRead(switch_5) == HIGH){    total += 1;    digitalWrite(Relay_B5, HIGH);  }  else{    if(digitalRead(switch_5) == LOW){    digitalWrite(Relay_B5, LOW);    }  }    switch (total){    case 0:    // No ERROR    digitalWrite(led_1, LOW);    digitalWrite(led_2, LOW);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, LOW);    digitalWrite(Relay_A2, LOW);    break;    case 1:    digitalWrite(led_1, HIGH);    digitalWrite(led_2, LOW);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, LOW);    break;    case 2:    digitalWrite(led_1, HIGH);    digitalWrite(led_2, HIGH);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, HIGH);    break;    default:    digitalWrite(led_1, HIGH);    digitalWrite(led_2, HIGH);    digitalWrite(led_3, HIGH);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, HIGH);  }}`

MY PROBLEM:

I cant seem to get the third activated button to NOT Light the corresponding LED.

#### PaulS

#19
##### Dec 01, 2010, 12:26 pm
Welcome back.

Thank you for finally putting in some concrete details. This makes it so much easier to understand what you are trying to do.

Code: [Select]
`  if(digitalRead(switch_1) == HIGH){    total += 1;    digitalWrite(Relay_B1, HIGH);  }  else{    if(digitalRead(switch_1) == LOW){    digitalWrite(Relay_B1, LOW);    }  }`
Is the state of switch_1 likely to have changed between readings?

You are setting Relay_B1 to the same state as switch_1, so, this code is much simpler:
Code: [Select]
`int val = digitalRead(switch_1);if(val == HIGH)   total++;digitalWrite(Relay_B1, val);`

Instead of 9 lines of code to debug, there are only 4. Since you do similar things 5 times, you could lose 25 lines of code.

You have a Serial.begin() statement in setup(), but no Serial.print() or Serial.println() statements in loop(). Why not? You could use Serial.print() to print out total, to see if it has the right value at the switch statement. If it does, then the problem is in the switch statement. Otherwise, the problem is in reading the switches.

In either case, the area where the problem occurs has been cut in half. Keep using the divide and conquer approach to nail that little bugger.

#### technochris1

#20
##### Dec 01, 2010, 02:55 pm
Quote
Is the state of switch_1 likely to have changed between readings?

any reading will last more than 5 seconds...The amps test their selves and the speakers only when a Page is sent.

Before i implement the code you suggest, i added some more to it. This is my attempt to get the third and greater input to not activate an LED.

Code: [Select]
`//define switchesint switch_1 = 2;int switch_2 = 3;int switch_3 = 4;int switch_4 = 5;int switch_5 = 6;//define led pinsint led_1 = 8;int led_2 = 9;int led_3 = 13;//define Relay Outputsint Relay_A1 = 22;int Relay_A2 = 23;int Relay_B1 = 24;int Relay_B2 = 25;int Relay_B3 = 26;int Relay_B4 = 27;int Relay_B5 = 28;//define total variableint total = 0;int BackupsInUse = 0;void setup(){  //turn on serial communication for debugging only  Serial.begin(9600);  //declare switch pins as INPUTS  pinMode(switch_1, INPUT);  pinMode(switch_2, INPUT);  pinMode(switch_3, INPUT);  pinMode(switch_4, INPUT);  pinMode(switch_5, INPUT);  //declare led pins as OUTPUT  pinMode(led_1, OUTPUT);  pinMode(led_2, OUTPUT);  pinMode(led_3, OUTPUT);  pinMode(Relay_A1, OUTPUT);  pinMode(Relay_A2, OUTPUT);  pinMode(Relay_B1, OUTPUT);  pinMode(Relay_B2, OUTPUT);  pinMode(Relay_B3, OUTPUT);  pinMode(Relay_B4, OUTPUT);  pinMode(Relay_B5, OUTPUT);}void loop(){  total = 0;      if(digitalRead(switch_1) == HIGH)  {    if (BackupsInUse <= 1)    {      total += 1;      digitalWrite(Relay_B1, HIGH);    }  }  if(digitalRead(switch_1) == LOW)  {    digitalWrite(Relay_B1, LOW);  }      if(digitalRead(switch_2) == HIGH)  {    if (BackupsInUse <= 1)    {      total += 1;      digitalWrite(Relay_B2, HIGH);    }  }  if(digitalRead(switch_2) == LOW)  {    digitalWrite(Relay_B2, LOW);  }      if(digitalRead(switch_3) == HIGH)  {    if (BackupsInUse <= 1)    {      total += 1;      digitalWrite(Relay_B3, HIGH);    }  }  if(digitalRead(switch_3) == LOW)  {    digitalWrite(Relay_B3, LOW);  }  if(digitalRead(switch_4) == HIGH)  {    if (BackupsInUse <= 1)    {      total += 1;      digitalWrite(Relay_B4, HIGH);    }  }  if(digitalRead(switch_4) == LOW)  {    digitalWrite(Relay_B4, LOW);  }      if(digitalRead(switch_5) == HIGH)  {    if (BackupsInUse <= 1)    {      total += 1;      digitalWrite(Relay_B5, HIGH);    }  }  if(digitalRead(switch_5) == LOW)  {    digitalWrite(Relay_B5, LOW);  }  switch (total){    case 0:    // No ERROR    BackupsInUse = 0;    digitalWrite(led_1, LOW);    digitalWrite(led_2, LOW);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, LOW);    digitalWrite(Relay_A2, LOW);    break;    case 1:    BackupsInUse = 1;    digitalWrite(led_1, HIGH);    digitalWrite(led_2, LOW);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, LOW);    break;    case 2:    BackupsInUse = 2;    digitalWrite(led_1, HIGH);    digitalWrite(led_2, HIGH);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, HIGH);    break;    default:    BackupsInUse = 2;    digitalWrite(led_1, HIGH);    digitalWrite(led_2, HIGH);    digitalWrite(led_3, HIGH);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, HIGH);  }}`

#### technochris1

#21
##### Dec 01, 2010, 03:45 pm
is there a way to code this:

If (val1 + val2 + val3 + val4 + val5 <= 2){

}

#### Grumpy_Mike

#22
##### Dec 01, 2010, 06:05 pm
Well that is the way to do that. It will add up five variables ans see if the sum is less than or equal to 2.

If you want to see if any variable is less than or equal to 2 then use the logical or operator:-

if( (val1 <=2) || (val2 <=2) || (val3 <=2) || (val4 <=2) || (val5 <=2) ) {

#### PaulS

#23
##### Dec 01, 2010, 08:41 pm
Quote
Before i implement the code you suggest, i added some more to it. This is my attempt to get the third and greater input to not activate an LED.

Before I get out of this hole I dug, let me dig it a little deeper. OK. Whatever.

#### technochris1

#24
##### Dec 01, 2010, 08:51 pm

Quote
Before I get out of this hole I dug, let me dig it a little deeper. OK. Whatever.

LOL, Awsome response. I get your point, and tried out a couple more things.

Code: [Select]
`//define switchesint switch_1 = 2;int switch_2 = 3;int switch_3 = 4;int switch_4 = 5;int switch_5 = 6;//define led pinsint led_1 = 8;int led_2 = 9;int led_3 = 13;//define Relay Outputsint Relay_A1 = 22;int Relay_A2 = 23;int Relay_B1 = 24;int Relay_B2 = 25;int Relay_B3 = 26;int Relay_B4 = 27;int Relay_B5 = 28;//define total variableint total = 0;int BackupsInUse = 0;int Amp1InError = 0;int Amp2InError = 0;int Amp3InError = 0;int Amp4InError = 0;int Amp5InError = 0;void setup(){  //turn on serial communication for debugging only  Serial.begin(9600);  //declare switch pins as INPUTS  pinMode(switch_1, INPUT);  pinMode(switch_2, INPUT);  pinMode(switch_3, INPUT);  pinMode(switch_4, INPUT);  pinMode(switch_5, INPUT);  //declare led pins as OUTPUT  pinMode(12, OUTPUT);  pinMode(led_1, OUTPUT);  pinMode(led_2, OUTPUT);  pinMode(led_3, OUTPUT);  pinMode(Relay_A1, OUTPUT);  pinMode(Relay_A2, OUTPUT);  pinMode(Relay_B1, OUTPUT);  pinMode(Relay_B2, OUTPUT);  pinMode(Relay_B3, OUTPUT);  pinMode(Relay_B4, OUTPUT);  pinMode(Relay_B5, OUTPUT);}void loop(){  int val1 = digitalRead(switch_1);  int val2 = digitalRead(switch_2);  int val3 = digitalRead(switch_3);  int val4 = digitalRead(switch_4);  int val5 = digitalRead(switch_5);    total = 0;      if(val1 == HIGH)  {    if (val1 + val2 + val3 + val4 + val5 <= 2)    {      total++;      Amp1InError = 1;      digitalWrite(Relay_B1, val1);    }  }    if(val2 == HIGH)  {    if (val1 + val2 + val3 + val4 + val5 <= 2)    {      total++;      Amp2InError = 1;      digitalWrite(Relay_B2, val2);    }  }    if(val3 == HIGH)  {    if (val1 + val2 + val3 + val4 + val5 <= 2)    {      total++;      Amp3InError = 1;      digitalWrite(Relay_B3, val3);    }  }    if(val4 == HIGH)  {    if (val1 + val2 + val3 + val4 + val5 <= 2)    {      total++;      Amp4InError = 1;      digitalWrite(Relay_B4, val4);    }  }    if(val5 == HIGH)  {    if (val1 + val2 + val3 + val4 + val5 <= 2)    {      total++;      Amp5InError = 1;      digitalWrite(Relay_B5, val5);    }  }      switch (total){    case 0:    // No ERROR    BackupsInUse = 0;    digitalWrite(led_1, LOW);    digitalWrite(led_2, LOW);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, LOW);    digitalWrite(Relay_A2, LOW);    break;    case 1:    BackupsInUse = 1;    digitalWrite(led_1, HIGH);    digitalWrite(led_2, LOW);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, LOW);    break;    case 2:    BackupsInUse = 2;    digitalWrite(led_1, HIGH);    digitalWrite(led_2, HIGH);    digitalWrite(led_3, LOW);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, HIGH);    break;    default:    BackupsInUse = 2;    buzz(12);    digitalWrite(led_1, HIGH);    digitalWrite(led_2, HIGH);    digitalWrite(led_3, HIGH);    digitalWrite(Relay_A1, HIGH);    digitalWrite(Relay_A2, HIGH);  }}void buzz(int targetPin) {  int frequency = 100;  int length = 10;    long delayValue = 1000000/frequency/2; // calculate the delay value between transitions  //// 1 second's worth of microseconds, divided by the frequency, then split in half since  //// there are two phases to each cycle  long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing  //// multiply frequency, which is really cycles per second, by the number of seconds to  //// get the total number of cycles to produce for (long i=0; i < numCycles; i++){ // for the calculated length of time...    digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram    delayMicroseconds(delayValue); // wait for the calculated delay value    digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram    delayMicroseconds(delayValue); // wait againf or the calculated delay value  }} `

you can currently ignore the AmpxInError lines.

#### PaulS

#25
##### Dec 01, 2010, 09:14 pm
Where do you ever set Relay_Bn LOW again? Are the Relay_Bn relays also constrained to have no more than 2 HIGH at a time?

Where are the Serial.print(ln) statements?

Code: [Select]
`    if (val1 + val2 + val3 + val4 + val5 <= 2)`
Wouldn't it be better to simply add all 5 values once, and compare the sum? Is this even necessary? Shouldn't total reflect the number of A relays that should be set HIGH (if there were enough of them to go around)?

#### technochris1

#26
##### Dec 02, 2010, 02:13 am
the B relays are the only ones that need the Max 2 restraint. the A relays are the backups, which only 2 backup amps exist.

im going to add another button to Switch all values to 0, like a reset switch.

Im a super beginner with big hopes, so any tips on how i should format my coding would help alot.

#### PaulS

#27
##### Dec 02, 2010, 01:07 pm
Quote
Im a super beginner with big hopes, so any tips on how i should format my coding would help alot.

First hint:
Quote
the B relays are the only ones that need the Max 2 restraint.

State all the requirements up front. This is the first time that you have mentioned this critical fact.

Second hint:
Quote
the A relays are the backups

"A" can, in no way, be considered an abbreviation of Backup.
Make variable names meaningful. BackupRelay1 and BackupRelay2 make far more sense than relay_A1 and relay_A2.

If "A" stands for backup, do I dare ask what "B" (relay_Bn) stands for?
Does it, by any chance, stand for Amplifier?

Go Up

Please enter a valid email to subscribe