PowerSSR Tail Example

Short version: here's some sample PowerSSR Tail code in case anyone finds it useful.

Long version:

My wife is interested in a wake-up light (sunrise light). My original version used LEDs. But it wasn't bright enough.

Version 2 will use a PowerSSR Tail + ZeroCross Tail to manage the dimming of store-bought lights. Trying to save power, I'm using store-bought A19 LED lights. With the sample PowerSSR Tail + ZeroCross Tail code, I was getting some flickering when getting close to full power. The light is driven remotely via an XBee, and I was also losing data coming from the XBee sender.

So I created the following test code to:

  • Reduce the number of interrupts used to manage the PowerSSR tail. The following code uses one interrupt callback per zero-cross to drive the PowerSSR instead of multiple callbacks.
  • Remove the flicker when close to full power.
  • Use a dimming scale that was more logical to me.

I also changed the timer library, to make it easier to switch over to a new interrupt timer if needed. As for the loss of serial data, that was finally solved by moving the XBee handling from SoftwareSerial to AltSoftSerial.

Anyway, here's some sample code in the hopes that the next newbie that gets a PowerSSR Tail gets it running faster than I did. Now that's it's running, I'm pretty happy with the PowerSSR. Now I just need to solder up a final solution and enclose it.

I'm new to the hardware side of things, so any suggestions are appreciated.

/*
 Dim_PSSR_ZC_Tail_2
 
 This sketch is a sample sketch using the ZeroCross Tail(ZCT)to generate a sync
 pulse to drive a PowerSSR Tail(PSSRT) for dimming ac lights.
 
 Connections to an Arduino Duemilanove:
 1. Connect the C terminal of the ZeroCross Tail to digital pin 2 with a 10K ohm pull up to Arduino 5V.
   (or whatever pin is used for interrupt 0 on your Arduino. For the MICRO it's pin 3.)
 2. Connect the E terminal of the ZeroCross Tail to Arduino Gnd.
 3. Connect the PowerSSR Tail +in terminal to digital pin 4 and the -in terminal to Gnd.
 
This sketch differs from the original Dim_PSSR_ZC_Tail by:
- Setting the timer interrupt to fire when the PowerSSR should be fired, instead of looping repeatedly.
  The main goal was to reduce interactions with other code that may disable interrupts.
- Uses a different scale, with 0 = off and 100 = full power.
- Avoids firing the PowerSSR too close to the zero-cross.  Firing the PowerSSR at the zero-cross gives smooth light.
  But flickering occurred with LED lights when the PowerSSR was set to fire between ~600us from the zero-cross events.
  So dim values of 1 through 99 fire between 600us and 7600us from the zero cross.
- Uses Timer1.h instead of TimerOne.h
 
*/


#include <Timer1.h>                    

const int PSSR1 = 4;                  // PowerSSR Tail connected to digital pin 4

int dim = 0;                    // Default dimming level (0-100)  0 = off, 100 = on

// For 60 Hz mains, zero-crosses occur twice per cycle. Or at 120Hz.
// In microseconds (best Arduino timing), that equates to a zero-cross every 8333 microseconds (1,000,000 / 120).
// Empirically, if the PowerSSR is fired too close to the zero-cross it doens't always take, causing the lights to flicker.
// The sweet spot seems to be between 500us and 7700us. To be safe, we'll fire the PowerSSR between 600us and 7600us.
// That gives us a range of 7000us, or 70us for each step of dimming.

const int minTimerDelay = 600;
const int timerDelayStep = 70;


void setup()
{
 Serial.begin(9600);
 
 pinMode(PSSR1, OUTPUT);                // Set SSR1 pin as output
 attachInterrupt(0, zero_cross_detect, RISING);   // Attach an Interupt to digital pin 2 (interupt 0),
}

void printDimLevel() {
  Serial.print("dim: ");
  Serial.print(dim);
  Serial.println();
}


void loop()                        // Main loop
{  

  for (dim = 0; dim <= 100; dim++) {
    printDimLevel();  
    delay(100);
  }  
}

// Functions

void zero_cross_detect() 
{      
   pauseTimer1();   // In case the timer did not fire yet (other interrupts), skip it.
   
   if (dim == 100) {
      // Full power: no delay
      //Fire the PSSR Tail.
      delayMicroseconds(100);       
      digitalWrite(PSSR1, HIGH);
      delayMicroseconds(50);
      digitalWrite(PSSR1, LOW); 
   }
   else if (dim > 0) {
       // Calls timer1Event when it's time to fire the PowerSSR.
       // The longer we wait, the less power will be delivered to the light until the PowerSSR turns off at the next zero-cross,
       // and the dimmer the light will be.
       startTimer1(minTimerDelay + (timerDelayStep * (100 - dim)));
   }
   // Dim level 0 (off): don't fire PowerSSR
} 

ISR(timer1Event)
{
  // Don't need to pauseTimer1().  Timer is stopped after the interrupt fires until explicitly reset.

  // Fire the PSSR Tail.
  // Initial delay taken into account by the timer's min delay.
  digitalWrite(PSSR1, HIGH);
  delayMicroseconds(50);
  digitalWrite(PSSR1, LOW); 
}

Hi Glenn,

Thank you for sharing this. I'm a complete newbie to Arduino and I've read a lot of threads already about building an automated light dimmer. I considered buying a PowerSSR Tail and a ZeroCross Tail to make my project. I have an Arduino Duemilanove.

My purpose is to create an automated loop that would dimm from full light to no light in about 3 to 5 seconds, stay to no light for around 10-15 minutes and then dimm back to full light in 3 to 5 seconds and stay at full light for 15 seconds and repeat this on/off pattern in loop. The idea is too simulate the light dimming in a cinema.

Do you think I can use your code and set-up to do this or is it too different?

Thank you very much in advance.

Ziuthre

I forgot one question in my previous post.

Is it easier to do such project with high-power LEDs instead of traditional light bulbs? Do I need the PowerSSR Tail with a system using LEDs ?

Thank you very much.

Hi Glenn (or anyone listening),

Your sketch is working great! Only question is that I have 2 PowerSSR tails connected to 1 ZeroCross tail and am trying to dim the PowerSSRs independently. I'm struggling to modify your code to accommodate that. Do you have any ideas?

Thanks
Matt

I keep getting the error message:

Arduino: 1.6.5 (Mac OS X), Board: "Arduino Duemilanove or Diecimila, ATmega328"

Dim_PSSR_ZC_Tail-ForumModSketch.ino:26:40: fatal error: Timer1.h: No such file or directory
compilation terminated.
Error compiling.

TimerOne Library is installed so I am confused. Any guidance would be appreciated.

Hi,
thanks for sharing.

Is there a link for the timer1.h library?
It seems I need that library to run the code and I couldn't fine anywhere.

Thanks.

Which version of the Arduino IDE are you using?