TimerOne.h alternative using micros() function to work with POWERSSR Tail

I’m working on a sparkcore controlled light dimmer with using the PowerSSR tail and PowerZeroCross tail from powerswitchtail. I’m trying to modify the example arduino sketch they post on their website to work with the sparkcore. The sketch uses TimerOne.h to attach timer interupts but I don’t think there’s a library just yet for the sparkcore so I am using the alternative method of counting time in the main loop. This is the work in progress code I have but unfortunately it does not work.

unsigned long oldTime;

int i=0;               // Variable to use as a counter
boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int PSSR = D5;                  // PowerSSR Tail connected to digital pin 4
int dim = 0;                   // Default dimming level (0-128)  0 = on, 128 = off
int freqStep = 60;              // Set to 60hz mains
int LED = D7;                    // LED on Arduino board on digital pin 13

void setup()
{
 pinMode(LED, OUTPUT);
 pinMode(PSSR, OUTPUT);                // Set SSR1 pin as output
 attachInterrupt(D1, zero_cross_detect, RISING);   // Attach an Interupt to digital pin 2 (interupt 0),
//  Timer1.initialize(freqStep);
//  Timer1.attachInterrupt(dim_check,freqStep);
oldTime = micros();
}


void loop()                        // Main loop
{
    
    dim = 120;
    fire_dim_check();
    delay(500);
    dim = 100;
    fire_dim_check();
    delay(500);
    dim = 80;
    fire_dim_check();
    delay(500);
    dim = 60;
    fire_dim_check();
    delay(500);
    dim = 40;
    fire_dim_check();
    delay(500);
    dim = 20;
    fire_dim_check();
    delay(500);
    dim = 0;
    fire_dim_check();
    delay(500);
}

// Functions

void fire_dim_check() {
   if((micros() - oldTime) >= freqStep) {
        dim_check();
        oldTime = micros();
    } 
}

void dim_check() {                  // This function will fire the triac at the proper time
 if(zero_cross == 1) {              // First check to make sure the zero-cross has happened else do nothing
   if(i>=dim) {
    delayMicroseconds(100);        //These values will fire the PSSR Tail.
    digitalWrite(PSSR, HIGH);
    digitalWrite(LED, HIGH);
    delayMicroseconds(50);
    digitalWrite(PSSR, LOW);
    digitalWrite(LED, LOW);
     i = 0;                         // Reset the accumulator
     zero_cross = 0;                // Reset the zero_cross so it may be turned on again at the next zero_cross_detect    
   } else {
     i++;                           // If the dimming value has not been reached, increment the counter
   }                                // End dim check
 }                                  // End zero_cross check
}

void zero_cross_detect() 
{
   zero_cross = 1;
   // set the boolean to true to tell our dimming function that a zero cross has occured
}

I’m sure I’m missing something but I was using the water sensor example code posted by peekay​123 in the Flow sensor library thread.

edgji, can you post the original code? I am trying to figure out what the original intent was versus what you are doing so I can better guide you. :smile:

@peekay123 I also have a library I’m pulling functions from that is using TimerOne.h

The libarary is built for Arduino so I’m wondering how much trouble I’m going to have getting the TimerOne Functions to be replaced or working on the Spark Core.

Here is the library for a power meter that I’m going to pull some functions from, let me know what you think about TimerOne.h

https://github.com/FriedCircuits/FC-USB-Tester-OLED-Backpack/blob/master/USB_Tester_v2/USB_Tester_OLED_128x64/USB_Tester_OLED_128x64.ino

RWB, timer1 cannot be used as it is dedicated to systicks, the lowest level system timer. I have been discussing with the Spark Team and Elites the need for a timer “pool” and have started working on it. The pool would give access to timer2, 3 and 4 when they are not used by servos or pwm output. In the meantime, I’ll see if your specific need can be done without a timer. I’ll be getting back to you this evening. :smile:

1 Like

Here’s the original sketch unrevised. I believe this worked but I did make a few changes to the sketch when I tried it on an arduino. Mainly changing pinMode(4, OUTPUT); to pinMode(PSSR1, OUTPUT);

/*
 Dim_PSSR_ZC_Tail
 
 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.
 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.
 
 
*/


#include <TimerOne.h>                    

volatile int i=0;               // Variable to use as a counter
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int PSSR1 = 4;                  // PowerSSR Tail connected to digital pin 4
int dim = 32;                   // Default dimming level (0-128)  0 = on, 128 = off
int freqStep = 60;              // Set to 60hz mains
int LED = 0;                    // LED on Arduino board on digital pin 13

void setup()
{
 pinMode(LED, OUTPUT);
 pinMode(4, OUTPUT);                // Set SSR1 pin as output
 attachInterrupt(0, zero_cross_detect, RISING);   // Attach an Interupt to digital pin 2 (interupt 0),
 Timer1.initialize(freqStep);
 Timer1.attachInterrupt(dim_check,freqStep);
}


void loop()                        // Main loop
{
dim = 120;
delay(500);
dim = 100;
delay(500);
dim = 80;
delay(500);
dim = 60;
delay(500);
dim = 40;
delay(500);
dim = 20;
delay(500);
dim = 0;
delay(500);
}

// Functions

void dim_check() {                  // This function will fire the triac at the proper time
 if(zero_cross == 1) {              // First check to make sure the zero-cross has happened else do nothing
   if(i>=dim) {
    delayMicroseconds(100);        //These values will fire the PSSR Tail.
    digitalWrite(PSSR1, HIGH);
    delayMicroseconds(50);
    digitalWrite(PSSR1, LOW); 
     i = 0;                         // Reset the accumulator
     zero_cross = 0;                // Reset the zero_cross so it may be turned on again at the next zero_cross_detect    
   } else {
     i++;                           // If the dimming value has not been reached, increment the counter
   }                                // End dim check
 }                                  // End zero_cross check
}

void zero_cross_detect() 
{
   zero_cross = 1;
   // set the boolean to true to tell our dimming function that a zero cross has occured
} 

edgji, I see what their doing. I have a good idea how to get around using timer1 and I will post something later this evening. It’s March break here and I have “obligations”.,wink:

Ok, I have a few minutes. Try this:

unsigned long oldTime, waitTime;
const unsigned long chkTime = 16667L;		//60Hz is approx 16667 microseconds
const usigned long dimWait = 500L			// wait 0.5sec between dims


int i=0;               // Variable to use as a counter
boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int PSSR = D5;                  // PowerSSR Tail connected to digital pin 4
int dim = 0;                   // Default dimming level (0-128)  0 = on, 128 = off
int freqStep = 60;              // Set to 60hz mains
int LED = D7;                    // LED on Arduino board on digital pin 13

int dimPattern[] = {120, 100, 80, 60, 40, 20, 0};

void setup()
{
	pinMode(LED, OUTPUT);
	pinMode(PSSR, OUTPUT);                // Set SSR1 pin as output
	attachInterrupt(D1, zero_cross_detect, RISING);   // Attach an Interupt to digital pin 2 (interupt 0),
	//  Timer1.initialize(freqStep);
	//  Timer1.attachInterrupt(dim_check,freqStep);
	oldTime = micros();
	dimWait = millis();

	dim = dimPattern[0];
}


void loop()                        // Main loop
{
	int dimIndex = 0;
	
	//timing loop to simulate timer1... this needs to run constantly like it does in the interrupt
	if((micros() - oldTime) >= chkTime) {
		dim_check();
        oldTime = micros();
    }

	//Wait .5 seconds between setting new dim values
	if((millis() - waitTime) >= dimWait) {
		if (dimIndex++ > 6)			//reset the pointer when it overflows
			dimIndex = 0;

		dim = dimPattern[dimIndex];	//change the dim to the next value
       dimWait = millis();
    }

}

// Functions

void dim_check() {                  // This function will fire the triac at the proper time
 if(zero_cross == 1) {              // First check to make sure the zero-cross has happened else do nothing
   if(i>=dim) {
    delayMicroseconds(100);        //These values will fire the PSSR Tail.
    digitalWrite(PSSR, HIGH);
    digitalWrite(LED, HIGH);
    delayMicroseconds(50);
    digitalWrite(PSSR, LOW);
    digitalWrite(LED, LOW);
     i = 0;                         // Reset the accumulator
     zero_cross = 0;                // Reset the zero_cross so it may be turned on again at the next zero_cross_detect    
   } else {
     i++;                           // If the dimming value has not been reached, increment the counter
   }                                // End dim check
 }                                  // End zero_cross check
}

void zero_cross_detect() 
{
   zero_cross = 1;
   // set the boolean to true to tell our dimming function that a zero cross has occured
}
1 Like

Thanks peekay​123 but that didn’t do it. I used the code your provided with minor changes to get it to verify.
fixed the line third line: const unsigned long dimWait = 500L;
and changed dimWait = millis(); to waitTime = millis();
in both places
still no dimming sequence and just a dead (off) light

I really appreciate your help.

Also the interrupt on D1 calls for a 10k ohm resistor on 5v mains in the original sketch. Since the sparkcore is 3v I’m running it straight with no resistor. Just want to double check this is not a problem.

edgji, sorry I didn’t have time to actually compile it so good catch on those errors! First, I realize you need to actually make pin D1 an input with internal pull-up by adding:

pinMode(D1, INPUT_PULLUP;

after your other pinMode statements. Hopefully, that will remove the need for an external one. This is needed because the powertail is open-collector and pulls its output pin LOW (to GND) only. So you need something to pull it back up!

Try that and see if that works. :smile:

I made the change you suggested but it didn’t seem to make a difference. By accident I removed the 3v reference I had on the breadboard to the D1 pin and I started to get a flicker. It’s like a quick dim flash of the light every 5 or 6 seconds. We’re getting somewhere. :smiley:

edgji, 3v reference? Can you explain what that was? It sounds like D1 is either a) not getting proper LOW to HIGH transitions or b) the code is fighting us. Is there a way (scope) for you to check the signal on D1?

UPDATE: Can you please change zero_cross to an “int” instead of boolean.

baah well I don’t know if reference is the term per say but I was referring to the following comment in the original code "Connect the C terminal of the ZeroCross Tail to digital pin 2 with a 10K ohm pull up to Arduino 5V."
I mentioned previously that I had tried dropping the 10k resistor for a wire. My C terminal for the ZeroCross tail is connected to D1 just so we’re clear.

Oh crap! edgji, if you connected a wire from the Spark 3.3v to the terminal C of the zerocross tail you may have damaged the output transistor of the tail by passing 3.3v and no current limit through it.

You can test the output by connecting the cathode of an LED (the negative side, usually the shorter lead) to the C terminal and the anode to a 180 to 200 ohm resistor with the other end connected to the Spark 3.3v. If the LED lights that is a start. If it is “blinking” at 60Hz and appears somewhat dim, that is very good. If it is bright and does not seem to be blinking then the transistor in the zerocross tail is shorted out.