Pages: 1 [2]   Go Down
Author Topic: Multiple switch state coding help  (Read 3145 times)
0 Members and 1 Guest are viewing this topic.
Pa, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino Beginner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pa, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino Beginner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

GOOGLE DOC: PRESENTATION - https://docs.google.com/present/edit?id=0Afr09Ho4itTUZGNrcG1yY2RfMThkcWR2cWRnOQ&hl=en&authkey=CMnZ8JUJ

« Last Edit: August 07, 2010, 03:58:27 pm by Technochris1 » Logged

Pa, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino Beginner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
//define switches
int switch_1 = 2;
int switch_2 = 3;
int switch_3 = 4;
int switch_4 = 5;
int switch_5 = 6;
//define led pins
int led_1 = 8;
int led_2 = 9;
int led_3 = 13;
//define Relay Outputs
int 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 variable
int 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. :'(
« Last Edit: November 30, 2010, 04:38:00 pm by Technochris1 » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
 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:
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.
Logged

Pa, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino Beginner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
//define switches
int switch_1 = 2;
int switch_2 = 3;
int switch_3 = 4;
int switch_4 = 5;
int switch_5 = 6;
//define led pins
int led_1 = 8;
int led_2 = 9;
int led_3 = 13;
//define Relay Outputs
int 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 variable
int 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);
  }
}
Logged

Pa, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino Beginner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

is there a way to code this:

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

}
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 34541
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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) ) {
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pa, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino Beginner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


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:
//define switches
int switch_1 = 2;
int switch_2 = 3;
int switch_3 = 4;
int switch_4 = 5;
int switch_5 = 6;
//define led pins
int led_1 = 8;
int led_2 = 9;
int led_3 = 13;
//define Relay Outputs
int 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 variable
int 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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
   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)?
Logged

Pa, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino Beginner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Pages: 1 [2]   Go Up
Jump to: