Contradictory statements - toggle switch - need a bit of help

hi all,

So, i am trying to finish a little project but ran into an issues with 2 toggle switches and not sure how to solve it.

So here is what i have...

2 single throw toggle switches.

Switch one (nightModeSwitchControl) which when HIGH turns off all my 7 segments displays.
Switch two (powerSavingSwitch) which when high activates statement "powerSaving();" which then turns off all 7 segment displays at a certain time during the night.

this is the code i have:

void nightModeSwitchControl() {

if(digitalRead(nightModeSwitch) == HIGH) {
      turnDisplaysOff();
      }
      else  {
        turnDisplaysOn();
      }
}



void powerSavingSwitch() {

if(digitalRead(powerSaveSwitch) == HIGH) {
      digitalWrite(LED_POWERSAVING, HIGH);
      powerSaving();
      }
      else {
        digitalWrite(LED_POWERSAVING, LOW);
        
      }
}

void powerSaving(){

  // turn off displays at 2am
  if (hour() == 02 && minute() == 00) {
    turnDisplaysOff(); 
  } else if 
    (hour() == 06 && minute() == 00) 
    turnDisplaysOn(); 
}

Now, how this should work is, i toggle switch two and activate power saving mode. This works ok BUT, as switch one has a contradictory statement and is almost always in LOW state which in turn turns the displays ON, contradicts the power saving statement that turns the displays OFF. So when power saving kicks in, displays try to turn OFF and then flicker as "night model switch" is in displays ON state.

If i turn off the power saving switch, night mode switch works like a charm, it toggles the displays ON and OFF as it should.

What i would like to have is a "power saving" option to turn OFF displays regardless in what state the "night mode" switch is and ideally, when the power saving is on and displays turned off, to be able to somehow turn ON the displays if needed.

So if power saving turns the displays OFF at 2am and keeps them OFF until 6am, i would like to be able to turn ON displays at any time between 2am and 6am by either disabling the power saving or by manipulating night mode switch...

I hope my explanation is clear.

Any help would be highly appreciated.

Many thanks,
Alek

“ I hope my explanation is clear.”

No.

Draw a state diagram.

larryd:
“ I hope my explanation is clear.”

No.

Draw a state diagram.

Hahaha, sorry!
Basically one switch is trying to turn displays ON while the second switch is in HIGH state which tells the displays to turn OFF.

Not sure how that diagram should look like.

Many thanks,
Alek

Example state diagram below. Mr. Google will be happy to show you many others.
While making the one that describes your program, you will likely discover how to correctly analyze and solve the problem.

Thanks anyway guys,
Alek

Conversely, if you can't draw a state (or logic) diagram, then your initial assumptions are wrong.

Try again with three switches.

elcrni:
Now, how this should work is, i toggle switch two and activate power saving mode. This works ok BUT, as switch one has a contradictory statement and is almost always in LOW state which in turn turns the displays ON, contradicts the power saving statement that turns the displays OFF. So when power saving kicks in, displays try to turn OFF and then flicker as "night model switch" is in displays ON state.

If i turn off the power saving switch, night mode switch works like a charm, it toggles the displays ON and OFF as it should.

What i would like to have is a "power saving" option to turn OFF displays regardless in what state the "night mode" switch is and ideally, when the power saving is on and displays turned off, to be able to somehow turn ON the displays if needed.

So if power saving turns the displays OFF at 2am and keeps them OFF until 6am, i would like to be able to turn ON displays at any time between 2am and 6am by either disabling the power saving or by manipulating night mode switch...

Making the two switches work together should be straightforward. Something like this pseudo code

if (powerSwitch == lightsOff position) {
   lightsAlwaysOff == true
}
else {
   lightsAlwaysOff == false
}
if (nightSwitch == nightSavingPosition)
   lightsOffAtNight == true
}
else {
   lightOffAtNight == false
}

if (lightsAlwaysOff == true) 
  turnLightsOFF()
}
else if (it is nightTime and lightsOffAtNight == true) {
    turnLightsOff()
  }
else {
   turnLightsOn()
}

...R

Thanks guys!

@Robin2, thanks man, looks interesting and might actually work, have to test it.

Now, i have made a sort of a diagram, hope this makes things clearer.

The main problem is, powerSaving can not kick in as the "night mode" switch is telling the display to stay ON...

Many thanks for any tips,
Alek

Hi,
Can you post a table of all your input combinations possible and what you want as output to occur.

Its called a truth diagram.

How have you wired your switches, are you using pullup or pulldown resistor.

Tom... :slight_smile:

hi all,

I got it working with "Robin2" code!!! Many thanks man.

Now, just to fine tune the details :slight_smile:

This is my code now:

void powerSavingSwitch() {

int lightsAlwaysOff;
int lightsOffAtNight;

if(digitalRead(nightModeSwitch) == HIGH) {
  lightsAlwaysOff = true;
  }
else {
   lightsAlwaysOff = false;
}


if(digitalRead(powerSaveSwitch) == HIGH) {
  lightsOffAtNight = true;
}
else {
   lightsOffAtNight = false;
}


if (lightsAlwaysOff == true) {
  turnDisplaysOff();
}


else if ((hour() == 12 && minute() == 35) && (lightsOffAtNight == true)) {
    turnDisplaysOff();
  }
else {
   turnDisplaysOn();
}
}

PowerSaving now kicks in at 12:35 (for test purposes) and should end at ie. 01:00...
I know how to make this but, is there a way to declare the "range" of time, that is a time period between ie 12:35 and 01:00 as right now, powerSaving option works only if the time is 12:35, during this minute i can engage and disengage powerSaving but if i disengage it at 12:36 the powerSaving option doesnt engage any more as the specified minute has passed.

Hope this makes sense.

Many thanks,
Alekl

specifically, i would need to declare time period FROM - TO in this one:

else if ((hour() == 12 && minute() == 35) && (lightsOffAtNight == true)) {
    turnDisplaysOff();
  }

So if the time is between 02am and 06 am && lightsOffAtNight == true
turnDisplaysOff();

many thanks,
Alek

Maybe something like this - but I’m not familiar with the time library you are using

if ( (hour() >== 2 and hour() <= 6) and (lightsOffAtNight == true) ) {

…R

Yep, figured it out, it works!!!
Many thanks Robin2

one more thing please.

I have a LED that goes ON when a "brightness control" switch is HIGH. Now i would like to turn off that LED if the display is OFF but again without contradicting statements.

My code looks like this

void brightnessControlManual(){

  if(digitalRead(switch_pin) == HIGH){
    encoder_brightness();
    digitalWrite(MANUAL_BRIGHTNESS_PIN, HIGH);
    }
}

So i would like to execute "encoder_brightness();" whenever (switch_pin) == HIGH, but to "digitalWrite(MANUAL_BRIGHTNESS_PIN, HIGH);" ONLY if (lightsAlwaysOff == false)

Many thanks,
Alek

elcrni:
one more thing please.

I have a LED that goes ON when a "brightness control" switch is HIGH. Now i would like to turn off that LED if the display is OFF but again without contradicting statements.

I think the time has come for you to take a few hours and try to absorb the lessons of the suggestions you have already received and consider how to apply that learning to your new problem.

...R

Thanks Robin2, i did learn a lot since my last post but i would still need a bit of help involving the third switch into the combination.

so here is my code:

void powerSavingSwitch() {

if ((hour() >= 21 && minute() >= 10) && (hour() <= 21 && minute() < 12)) {
  powerSavingTime = true;
} else {
  powerSavingTime = false;
}

if(digitalRead(nightModeSwitch) == HIGH) {
  lightsAlwaysOff = true;
  }
else {
   lightsAlwaysOff = false;
}




if(digitalRead(powerSaveSwitch) == HIGH) {
  lightsOffAtNight = true;
  digitalWrite(LED_POWERSAVING, HIGH); 
}
else {
   lightsOffAtNight = false;
   digitalWrite(LED_POWERSAVING, LOW);  
}




if(digitalRead(status_LED_switch) == HIGH) {
  statusLEDon = true;
} else {
  statusLEDon = false;
}





if (lightsAlwaysOff == true) {
  turnDisplaysOff();
  digitalWrite(LED_relay, LOW);
}

else if ((powerSavingTime == true) && (lightsOffAtNight == true)) {
    turnDisplaysOff();
    digitalWrite(LED_relay, LOW);
  }

else {
   turnDisplaysOn();
   digitalWrite(LED_relay, HIGH);   
}


}

Now i need this switch:

if(digitalRead(status_LED_switch) == HIGH) {
  statusLEDon = true;
} else {
  statusLEDon = false;
}

to be able to digitalWrite(LED_relay, HIGH); and digitalWrite(LED_relay, LOW);
but ONLY when powerSavingTime == false and lightsAlwaysOff == false.

As i am writing this it still sounds easy but whatever i do, it messes something else up.

Any help would be highly appreciated. This would be the last bit of a problem i have before i can finish my project.

Many thanks,
Alek

elcrni:
Now i need this switch:

if(digitalRead(status_LED_switch) == HIGH) {

statusLEDon = true;
} else {
  statusLEDon = false;
}






to be able to digitalWrite(LED_relay, HIGH); and digitalWrite(LED_relay, LOW); 
but ONLY when powerSavingTime == false and lightsAlwaysOff == false.

It will be much easier to help if you post the code that represents your best attempt at the combined program. At the moment I don't know what you are having trouble with.

...R

Thanks Robin!

void powerSavingSwitch() {

if ((hour() >= 21 && minute() >= 06) && (hour() <= 21 && minute() < 9)) {
  powerSavingTime = true;
} else {
  powerSavingTime = false;
}

if(digitalRead(nightModeSwitch) == HIGH) {
  lightsAlwaysOff = true;
  }
else {
   lightsAlwaysOff = false;
}




if(digitalRead(powerSaveSwitch) == HIGH) {
  lightsOffAtNight = true;
  digitalWrite(LED_POWERSAVING, HIGH); 
}
else {
   lightsOffAtNight = false;
   digitalWrite(LED_POWERSAVING, LOW);  
}




if(digitalRead(status_LED_switch) == HIGH) {
  statusLEDon = true;
} else {
  statusLEDon = false;
}





if (lightsAlwaysOff == true) {
  turnDisplaysOff();
  digitalWrite(LED_relay, LOW);
}

else if ((powerSavingTime == true) && (lightsOffAtNight == true)) {
    turnDisplaysOff();
    digitalWrite(LED_relay, LOW);
  }

else {
   turnDisplaysOn();
   digitalWrite(LED_relay, HIGH);   
}

if (statusLEDon == true) {
  digitalWrite(LED_relay, LOW);
}

}

This code below works but, when i set LED_relay LOW like this, LEDs still flicker slightly which led me to believe that there is a contradictory statement somewhere…

if (statusLEDon == true) {
  digitalWrite(LED_relay, LOW);
}

When i use this :

if (lightsAlwaysOff == true) {
  turnDisplaysOff();
  digitalWrite(LED_relay, LOW);
}

It turns OFF LEDs as it should and they do not flicker.

this is bugging me for a whole day now, hahah, i am so close and probably missing just a small stupid thing, in a right place

many thanks,
Alek

I see that this one

if (statusLEDon == true) {
  digitalWrite(LED_relay, LOW);
}

contradicts one which is above it:

else {
   turnDisplaysOn();
   digitalWrite(LED_relay, HIGH);   
}

But not sure how to combine them correctly.

If i put the first one as another ELSE IF... then it also turns ON the displays in FALSE state which it should not...

In Reply #15 you said

to be able to digitalWrite(LED_relay, HIGH); and digitalWrite(LED_relay, LOW);
but ONLY when powerSavingTime == false and lightsAlwaysOff == false.

but in the code in Reply #17 you have this code outside the tests for powerSavintTime etc.

if (statusLEDon == true) {
  digitalWrite(LED_relay, LOW);
}

Why did you do that?

By the way you MUST have a reason for everything you do in a program - otherwise it is just a random collection of gobbledegook.

I think it should be like this

   else {
        turnDisplaysOn();
        if (statusLEDon == false) {
            digitalWrite(LED_relay, HIGH);
        }
        else {
            digitalWrite(LED_relay, LOW);
        }
    }

...R

PS ... before posting code always format it using the AutoFormat tool as it makes it much easier to read. You will benefit also.