SPDT switch to control LED strips code

I'm trying to make a sunrise alarm clock with 2 different modes using 2 individually-addressable LED strips, an rtc module, and an SPDT switch. I've tested simpler codes and they work fine, so I'm pretty positive that it's not an issue with the connections. However, when I try the actual code, I cannot get it to work. I'm new to coding so I don't even know where to look.

What I'm trying to do: When switch is in position 1 (connected to Pin 3), run the sunrise & sunset functions at its respective times. When it's in position 2 it's off, and when it's in position 3 (connected to Pin 5), run the work, rest, and night functions at its respective times.

Here's the code:

#include <DS3231.h> //Include the clock library RTC_DS3231 rtc
#include <FastLED.h>

// Changable Vars
CRGB leds[84];
CRGB leds2[84];
const int switchPin = 3;
const int switchPin2 = 5;
int fadeTime = 30; // How long the light will fade to max
int setHour = 8; // Set hours to wake (military time)
int setMin = 30; // Set minute to wake
int z = 21;
int i = 0;
int x = 41;
int bedHour = 11; // Set hour to bed
int bedMin = 0; // Set minute to bed
int workHour = 10;
int workMin = 0;
int restHour = 6;
int restMin = 0;
int nightHour = 0;
int nightMin = 0;


// Set up Vars
DS3231  rtc(SDA, SCL);
Time t;
void start();
 
void setup()
{
  FastLED.addLeds<WS2812, 10, GRB>(leds, 84);
  FastLED.addLeds<SK6812, 9, GRB>(leds2, 84);
  pinMode(3, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  Serial.begin(9600); // Match to serial monitor
  rtc.begin();
}

void loop()
{
  t = rtc.getTime(); // Make a time class called 't'
  
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());
  
if (digitalRead(3) == HIGH && digitalRead(5) == LOW){
  if (t.hour == setHour && t.min == setMin) // Check if it's time to wake up!
  {
    sunrise();
  }
  
  if (t.hour == bedHour && t.min == bedMin)
  {
    sunset();
  }
else if (digitalRead(3) == LOW && digitalRead(5) == HIGH){
  if (t.hour == workHour && t.min == workMin)
  {
    work();
  }
  else if (t.hour == restHour && t.min == restMin)
  {
    rest();
  }
  else if (t.hour == nightHour && t.min == nightMin)
  {
    night();
  }
}
}
else {
  for(int i = 0; i <= 83; i++)
  {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
  // Wait one second before repeating
  delay (1000);
}
}

void sunrise()
{
  // segment 1 
  for(int i = 0; i <= 20; i++)
  {
    leds[i] = CRGB(100, 0, 0);
    leds2[i] = CRGB(200, 0, 0);
    FastLED.show();
  }
  delay((fadeTime * 60000)/8);
  // segments 2 & 4
  for(int i = 83; i >= 63; i -= 3)
 {
    leds[i] = CRGB(50, 5, 0);
    leds2[i] = CRGB(10, 0, 200);
    leds[i - 1] = CRGB(50, 5, 0);
    leds2[i - 1] = CRGB(10, 0, 200);
    leds[i - 2] = CRGB(50, 5, 0);
    leds2[i - 2] = CRGB(10, 0, 200);
    leds[z] = CRGB(50, 5, 0);
    leds2[z] = CRGB(10, 0, 200);
    leds[z + 1] = CRGB(50, 5, 0);
    leds2[z + 1] = CRGB(10, 0, 200);
    leds[z + 2] = CRGB(50, 5, 0);
    leds2[z + 2] = CRGB(10, 0, 200);
    FastLED.show();
    z += 3; 
    delay((fadeTime * 60000)/8);
  }
  // segment 3 
  for(int i = 42; i <= 62; i++)
  {
    leds[i] = CRGB(50, 5, 5);
    leds2[i] = CRGB(10, 0, 200);
    FastLED.show();
  }
  }

  
void sunset()
{
  // beginning
for(int i = 0; i <= 20; i++)
{
  leds[i] = CRGB(100, 20, 0);
  leds2[i] = CRGB(200, 0, 0);
  FastLED.show();
}
for(int i = 21; i <= 41; i++)
{
  leds[i] = CRGB(0, 0, 0);
  leds2[i] = CRGB(255, 0, 100);
  FastLED.show();
} 
for(int i = 42; i <= 62; i++)
{
  leds[i] = CRGB(5, 0, 100);
  leds2[i] = CRGB(0, 0, 0);
  FastLED.show();
}
for(int i = 63; i <= 83; i++)
{
  leds[i] = CRGB(0, 0, 0);
  leds2[i] = CRGB(255, 0, 100);
  FastLED.show();
}

delay(fadeTime * 60000);
  // segment 1 
  for(int i = 42; i <= 62; i++)
  {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
  delay((fadeTime * 60000)/8);
  // segments 2 & 4
  for(int i = 63; i <= 83; i += 3)
 {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    leds[i + 1] = CRGB(0, 0, 0);
    leds2[i + 1] = CRGB(0, 0, 0);
    leds[i + 2] = CRGB(0, 0, 0);
    leds2[i + 2] = CRGB(0, 0, 0);
    leds[x] = CRGB(0, 0, 0);
    leds2[x] = CRGB(0, 0, 0);
    leds[x - 1] = CRGB(0, 0, 0);
    leds2[x - 1] = CRGB(0, 0, 0);
    leds[x - 2] = CRGB(0, 0, 0);
    leds2[x - 2] = CRGB(0, 0, 0);
    FastLED.show();
    x -= 3; 
    delay((fadeTime * 60000)/8);
  }
  // segment 3 
  for(int i = 0; i <= 20; i++)
  {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
  }

  void work()
  {
    for(int i = 0; i <= 20; i++)
    {
      leds[i] = CRGB(0, 0, 0);
      leds2[i] = CRGB(0, 50, 200);
      FastLED.show();
    }
    for(int i = 21; i <= 83; i++)
    {
      leds[i] = CRGB(0, 50, 200);
      leds2[i] = CRGB(0, 200, 0);
      FastLED.show();
    }
  }

  void rest()
{
   for(int i = 0; i <= 20; i++)
    {
      leds[i] = CRGB(100, 20, 0);
      leds2[i] = CRGB(255, 0, 100);
      FastLED.show();
    }
    for(int i = 21; i <= 41; i++)
    {
      leds[i] = CRGB(0, 0, 0);
      leds2[i] = CRGB(255, 0, 100);
      FastLED.show();
    }
     for(int i = 42; i <= 62; i++)
    {
      leds[i] = CRGB(5, 0, 200);
      leds2[i] = CRGB(0, 0, 0);
      FastLED.show();
    }
    for(int i = 63; i <= 83; i++)
    {
      leds[i] = CRGB(0, 0, 0);
      leds2[i] = CRGB(255, 0, 100);
      FastLED.show();
    }
}

void night()
{
  for(int i = 0; i <= 20; i++)
  {
    leds[i] = CRGB(100, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
  for(int i = 21; i <= 83; i++)
  {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
}

I can make the Pin 3 functions to work but a) the code basically stops running after that (ie. stops reading the time in the serial monitor, b) it will stay on even if i flip the switch to another position. Pin 5 functions do not work.
I'm sure this is some really ugly code in general, any advice to make it more efficient is welcome. Thanks!

Why not use only one strip for all switch positions (one switch showing one pattern when switched to one pin)?

One of them is RGB and the other one is WWA, so they have to be used simultaneously but controlled separately

Do you have the switch center pin connected to GND?

If both inputs are pulled-up, why do the if tests check for high/low conditions at both inputs?

3 can be low or 5 can be low. Or they can also both be high.

Could this be one of those things where if you must check both conditions you need extra sets of parens maybe?

if ((digitalRead(3) == HIGH) && (digitalRead(5) == LOW))

Switches are not just on and off. They have two methods of switching: (1) make before break and (2) break before make. MbB never has an open condition, but has two closed conditions. BbM can have an open condition, but never has two closed conditions.

I would test your switch checking on a minimal sketch to show the position for "3" or "5" ... then run your sketch with a hard-coded "3" or "5" and see if it "stops running" (has it stopped, or is it in a loop? which loop? how will it exit the loop?).

The more modular your code (functions that can run independently) the easier it will be to add functions later.

OK, I totally thought the OP described an SPDT switch that had an off position.

But yeah, modular for the win!

I agree. SPST can be "open" (floating), so not really a state. SPDT has two states. "Off" is a valid state.

So turns out it was just a misplaced }. It's working fine except the functions will only start running if the switch is flipped to that position at or before the time it's supposed to start. For example, if I had sunrise() on pin 3 and work() on pin 5 both set to start at 1:00pm, I can flip back and forth between them at 1:00pm, but at 1:01pm, they won't start. Any ideas?

2 Likes

Post your working sketch. I do not see 1:00 p.m. on your previous sketch.

yeah sorry, 1pm was just an example, but I changed the code to include it to show you what i mean

#include <DS3231.h> //Include the clock library RTC_DS3231 rtc
#include <FastLED.h>

// Changable Vars
CRGB leds[84];
CRGB leds2[84];
const int switchPin = 3;
const int switchPin2 = 5;
int fadeTime = 30; // How long the light will fade to max
int setHour = 13; // Set hours to wake (military time)
int setMin = 0; // Set minute to wake
int z = 21;
int i = 0;
int x = 41;
int bedHour = 23; // Set hour to bed
int bedMin = 0; // Set minute to bed
int workHour = 13;
int workMin = 0;
int restHour = 17;
int restMin = 0;
int nightHour = 0;
int nightMin = 0;


// Set up Vars
DS3231  rtc(SDA, SCL);
Time t;
void start();
 
void setup()
{
  FastLED.addLeds<WS2812, 10, GRB>(leds, 84);
  FastLED.addLeds<SK6812, 9, GRB>(leds2, 84);
  pinMode(3, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  Serial.begin(9600); // Match to serial monitor
  rtc.begin();
}

void loop()
{
  t = rtc.getTime(); // Make a time class called 't'
  
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());

if (digitalRead(3) == HIGH && digitalRead(5) == LOW){
  if (t.hour == setHour && t.min == setMin) // Check if it's time to wake up!
  {
    sunrise();
  }
  
  if (t.hour == bedHour && t.min == bedMin)
  {
    sunset();
  }
  }

else if (digitalRead(3) == LOW && digitalRead(5) == HIGH){
  if (t.hour == workHour && t.min == workMin)
  {
    work();
  }
  else if (t.hour == restHour && t.min == restMin)
  {
    rest();
  }
  else if (t.hour == nightHour && t.min == nightMin)
  {
    night();
  }
  }

else {
  for(int i = 0; i <= 83; i++)
    {
      leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
  // Wait one second before repeating
  delay (1000);
}
}

void sunrise()
{
  // segment 1 
  for(int i = 0; i <= 20; i++)
  {
    leds[i] = CRGB(100, 0, 0);
    leds2[i] = CRGB(200, 0, 0);
    FastLED.show();
  }
  delay((fadeTime * 60000)/8);
  // segments 2 & 4
  for(int i = 83; i >= 63; i -= 3)
 {
    leds[i] = CRGB(50, 5, 0);
    leds2[i] = CRGB(10, 0, 200);
    leds[i - 1] = CRGB(50, 5, 0);
    leds2[i - 1] = CRGB(10, 0, 200);
    leds[i - 2] = CRGB(50, 5, 0);
    leds2[i - 2] = CRGB(10, 0, 200);
    leds[z] = CRGB(50, 5, 0);
    leds2[z] = CRGB(10, 0, 200);
    leds[z + 1] = CRGB(50, 5, 0);
    leds2[z + 1] = CRGB(10, 0, 200);
    leds[z + 2] = CRGB(50, 5, 0);
    leds2[z + 2] = CRGB(10, 0, 200);
    FastLED.show();
    z += 3; 
    delay((fadeTime * 60000)/8);
  }
  // segment 3 
  for(int i = 42; i <= 62; i++)
  {
    leds[i] = CRGB(50, 5, 5);
    leds2[i] = CRGB(10, 0, 200);
    FastLED.show();
  }
  }

  
void sunset()
{
  // beginning
for(int i = 0; i <= 20; i++)
{
  leds[i] = CRGB(100, 20, 0);
  leds2[i] = CRGB(200, 0, 0);
  FastLED.show();
}
for(int i = 21; i <= 41; i++)
{
  leds[i] = CRGB(0, 0, 0);
  leds2[i] = CRGB(255, 0, 100);
  FastLED.show();
} 
for(int i = 42; i <= 62; i++)
{
  leds[i] = CRGB(5, 0, 100);
  leds2[i] = CRGB(0, 0, 0);
  FastLED.show();
}
for(int i = 63; i <= 83; i++)
{
  leds[i] = CRGB(0, 0, 0);
  leds2[i] = CRGB(255, 0, 100);
  FastLED.show();
}

delay(fadeTime * 60000);
  // segment 1 
  for(int i = 42; i <= 62; i++)
  {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
  delay((fadeTime * 60000)/8);
  // segments 2 & 4
  for(int i = 63; i <= 83; i += 3)
 {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    leds[i + 1] = CRGB(0, 0, 0);
    leds2[i + 1] = CRGB(0, 0, 0);
    leds[i + 2] = CRGB(0, 0, 0);
    leds2[i + 2] = CRGB(0, 0, 0);
    leds[x] = CRGB(0, 0, 0);
    leds2[x] = CRGB(0, 0, 0);
    leds[x - 1] = CRGB(0, 0, 0);
    leds2[x - 1] = CRGB(0, 0, 0);
    leds[x - 2] = CRGB(0, 0, 0);
    leds2[x - 2] = CRGB(0, 0, 0);
    FastLED.show();
    x -= 3; 
    delay((fadeTime * 60000)/8);
  }
  // segment 3 
  for(int i = 0; i <= 20; i++)
  {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
  }

  void work()
  {
    for(int i = 0; i <= 20; i++)
    {
      leds[i] = CRGB(0, 0, 0);
      leds2[i] = CRGB(0, 50, 200);
      FastLED.show();
    }
    for(int i = 21; i <= 83; i++)
    {
      leds[i] = CRGB(0, 50, 200);
      leds2[i] = CRGB(0, 200, 0);
      FastLED.show();
    }
  }

  void rest()
{
   for(int i = 0; i <= 20; i++)
    {
      leds[i] = CRGB(100, 20, 0);
      leds2[i] = CRGB(255, 0, 100);
      FastLED.show();
    }
    for(int i = 21; i <= 41; i++)
    {
      leds[i] = CRGB(0, 0, 0);
      leds2[i] = CRGB(255, 0, 100);
      FastLED.show();
    }
     for(int i = 42; i <= 62; i++)
    {
      leds[i] = CRGB(5, 0, 200);
      leds2[i] = CRGB(0, 0, 0);
      FastLED.show();
    }
    for(int i = 63; i <= 83; i++)
    {
      leds[i] = CRGB(0, 0, 0);
      leds2[i] = CRGB(255, 0, 100);
      FastLED.show();
    }
}

void night()
{
  for(int i = 0; i <= 20; i++)
  {
    leds[i] = CRGB(100, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
  for(int i = 21; i <= 83; i++)
  {
    leds[i] = CRGB(0, 0, 0);
    leds2[i] = CRGB(0, 0, 0);
    FastLED.show();
  }
}

This says the hour and the minute must both be true to make sunrise() occur. So, a minute not setMin would evaluate false, skipping sunrise()

(same with sunset)

right, so for the pin 5 functions, could i potentially do something like this:

if (t.hour >= workHour && t.hour < restHour && t.min >= workMin && t.min < restMin)
{
work();
}

sunrise and sunset may be more complicated because they fade in and out rather than just being static colors, and i theoretically want to make it so that if i turn on pin 3 several minutes after sunrise() would have started, it would light up as if it had started at the correct time (so already partially faded in/out)

You are correct for allowing a range in your conditional (x >= a && x < b). If you want a precise value, use ==.

it worked! thanks for the help!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.