Zero cross and timer for SCR control Problem ..(SOLVED)

raceautoelectro
Sun Jul 02, 2017 8:36 pm
Hi , i have a little problem with timers ; the timer is changing , i am shure is something simple but i don’t find it …
https://www.youtube.com/watch?v=i-nWHMr … e=youtu.be my code is #define SERIAL_ENABLED 1
#define LCD_ENABLED 1

#if LCD_ENABLED
#include <LiquidCrystal.h>
LiquidCrystal lcd(PB15, PB14, PB13, PB12, PB11, PB10);
#endif
volatile int state = LOW;

const int ZCD_Pin = PB1;
int led_Pin = PB0; // PWM-capable pin

void setup() {
pinMode(led_Pin, OUTPUT); // setup the pin as PWM
attachInterrupt(ZCD_Pin, zcd, FALLING);
Timer1.setPeriod(5 * 1000);
Timer1.setChannel1Mode(TIMER_OUTPUT_COMPARE);
Timer1.setCompare(TIMER_CH1, 1);
Timer1.attachCompare1Interrupt(handler_led);
Timer1.refresh();
}

void loop() {

}

void zcd() {
digitalWrite(led_Pin, LOW);
Timer1.resume();
}

void handler_led() {
digitalWrite(led_Pin, HIGH);
Timer1.refresh();


stevestrong
Mon Jul 03, 2017 12:46 pm
Would you understand the problem from your description?
Because I don’t.

raceautoelectro
Mon Jul 03, 2017 6:40 pm
stevestrong , Timer1.setPeriod(5 * 1000); is not acting like it should … the period is changing , in the movie you can see the signal versus the zero cross . Sorry for my bad english , hope you understand this time .

raceautoelectro
Mon Jul 03, 2017 6:54 pm
I also try #define SERIAL_ENABLED 1
#define LCD_ENABLED 1

#if LCD_ENABLED
#include <LiquidCrystal.h>
LiquidCrystal lcd(PB15, PB14, PB13, PB12, PB11, PB10);
#endif
volatile int state = LOW;
const int ZCD_Pin = PB1;
int led_Pin = PB0; // PWM-capable pin

void setup() {
pinMode(led_Pin, OUTPUT); // setup the pin as PWM

// turn the LED on (HIGH is the voltage level)
#endif
attachInterrupt(ZCD_Pin, zcd, FALLING);
lcd.setCursor(0, 0);
Timer1.pause();
Timer1.setPrescaleFactor(7200);
Timer1.setOverflow(1000);
Timer1.setChannel1Mode(TIMER_OUTPUT_COMPARE);
Timer1.setCompare(TIMER_CH1, 1);
Timer1.attachCompare1Interrupt(handler_led);
Timer1.refresh();

}

void loop() {

}

void zcd() {

digitalWrite(led_Pin, LOW);
Timer1.resume();
}

void handler_led() {

digitalWrite(led_Pin, HIGH);
Timer1.pause();
Timer1.refresh();
}


Pito
Mon Jul 03, 2017 7:36 pm
So the yellow signal is the ZCD (zero crossing detector) output, and on the Falling edge of the ZCD signal (PB1 ZCD_Pin, input) you want to trigger the Timer1 such it produces an active Low signal (PB0 led_pin, output) of length xx microsecs (the blue signal).
But the blue_signal’s (led_pin) active Low duration is changing (it is growing with time) – that is the issue?

raceautoelectro
Mon Jul 03, 2017 7:58 pm
Pito , Exacly :| , and after growing it goes on lower value and start grow with time again .

Pito
Mon Jul 03, 2017 8:21 pm
What when you add before setup()

HardwareTimer timer1(1);


raceautoelectro
Mon Jul 03, 2017 8:37 pm
Pito , not working eeeuk:13: error: ‘Timer1’ does not name a type

Timer1.setCompare(TIMER_CH1, 1);

^

‘Timer1’ does not name a type


zmemw16
Mon Jul 03, 2017 8:58 pm
same error
stephen

Pito
Mon Jul 03, 2017 9:06 pm
Guys,
HardwareTimer Timer1(1);

raceautoelectro
Mon Jul 03, 2017 9:17 pm
I have try all combination my mind is curently capable :))) ( still havea lot to learn ) . i try also try HardwareTimer Timer1(1); but it will not compile (C:\Users\RACEAUTOELECTRO\Documents\Arduino\hardware\Arduino_STM32\STM32F1\cores\maple/HardwareTimer.cpp:48: multiple definition of `Timer1′) … i have also try to remove , move what i think it conflicts … but no luck .

Pito
Mon Jul 03, 2017 9:25 pm
Be creative :)
This compiles here:
// ZERO CROSSING DETECTOR AND TIMER EXAMPLE

HardwareTimer myTimer(1); // We use the TIMER1

const int ZCD_Pin = PB1; // Input from Zero Crossing Detector's output
int led_Pin = PB0; // LED driven by zcd() and handler_led()

void zcd() {
digitalWrite(led_Pin, LOW);
myTimer.resume();
}

void handler_led() {
digitalWrite(led_Pin, HIGH);
myTimer.refresh();
}

void setup() {
pinMode(led_Pin, OUTPUT); // setup the pin as output
pinMode(ZCD_Pin, INPUT); // ZCD signal input
attachInterrupt(ZCD_Pin, zcd, FALLING);
myTimer.pause();
myTimer.setPeriod(5 * 1000);
myTimer.setChannel1Mode(TIMER_OUTPUT_COMPARE);
myTimer.setCompare(TIMER_CH1, 1);
myTimer.attachCompare1Interrupt(handler_led);
myTimer.refresh();
myTimer.resume();
}

void loop() {
}


raceautoelectro
Mon Jul 03, 2017 9:40 pm
Pito , with you code is acting like my code , full problem view : https://www.youtube.com/watch?v=e5mkB-G … e=youtu.be

Pito
Mon Jul 03, 2017 9:44 pm
So when it reaches 5ms (based on your video) it resets to zero.

raceautoelectro
Mon Jul 03, 2017 9:50 pm
Pito , yes and want to stay at 5 ms all the time

Pito
Mon Jul 03, 2017 9:51 pm
Try with this:
void handler_led() {
digitalWrite(led_Pin, HIGH);
//myTimer.refresh();
}

raceautoelectro
Mon Jul 03, 2017 9:59 pm
no change on scope :| edit : the time is decreasing … freo 5 ms to 0 …. then 5 again

Pito
Mon Jul 03, 2017 10:11 pm
I’ve updated the source, try it, plz.
Not sure how the
timer.setCompare(TIMER_CH1, 1);
works.
Try to comment it out.

raceautoelectro
Mon Jul 03, 2017 10:18 pm
Same problem time is growing ( 0 to 5 s then resets ) , with line comented the growing time is smaller ( it takes less than before from 0 to 5 ms )

Pito
Mon Jul 03, 2017 10:23 pm
And try what happens with
timer.setCompare(TIMER_CH1, 0);

Also try
void zcd() {
digitalWrite(led_Pin, LOW);
myTimer.refresh(); // here we reset count to 0 (?)
myTimer.resume(); // here we starting the counting from zero
}

void handler_led() {
digitalWrite(led_Pin, HIGH);
myTimer.pause(); // here we finished at 5000 so we can pause
}


raceautoelectro
Mon Jul 03, 2017 10:37 pm
timer.setCompare(TIMER_CH1, 0); doesen’t change anything , and with void zcd() {
digitalWrite(led_Pin, LOW);
myTimer.refresh(); // here we reset count to 0 (?)
myTimer.resume(); // here we starting the counting
}

void handler_led() {
digitalWrite(led_Pin, HIGH);
myTimer.pause(); // here we finished at 5000 so we can pause
}


raceautoelectro
Mon Jul 03, 2017 10:47 pm
This code works , Thanks a lot Pito ! // ZERO CROSSING DETECTOR AND TIMER EXAMPLE

HardwareTimer myTimer(1); // We use the TIMER1

const int ZCD_Pin = PB1; // Input from Zero Crossing Detector's output
int led_Pin = PB0; // LED driven by zcd() and handler_led()

void zcd() {
digitalWrite(led_Pin, LOW);
myTimer.resume(); // here we starting the counting from zero
}

void handler_led() {
digitalWrite(led_Pin, HIGH);
myTimer.refresh(); // here we finished at 5000 thus we reset count to 0 (?)
myTimer.pause(); // here we can pause
}

void setup() {
pinMode(led_Pin, OUTPUT); // setup the pin as output
pinMode(ZCD_Pin, INPUT); // ZCD signal input
attachInterrupt(ZCD_Pin, zcd, FALLING);
myTimer.pause();
myTimer.setPeriod(5 * 1000);
myTimer.setChannel1Mode(TIMER_OUTPUT_COMPARE);
myTimer.setCompare(TIMER_CH1, 1);
myTimer.attachCompare1Interrupt(handler_led);
myTimer.refresh();
myTimer.resume();
}

void loop() {
}


Pito
Tue Jul 04, 2017 7:32 am
Great!!
:)

dannyf
Tue Jul 04, 2017 5:13 pm
it seems to me that for something this simple, the code is overly complex.

your task can be broken down to two pieces:

1) once a zero crossing is detected, restart the timer and reset the output pins;
2) once the timer overflows, flip the output pin. No point in operating on the timer at all here.

this is a piece of code that I wrote for a dimmer (cosine mode commutation for linear light output). I reproduced the relevant portion here for demonstration.

//isr
void interrupt isr(void) {
//tmr1 isr
TMR1IF = 0; //clear the flag
IO_FLP(sOUT_PORT, OUTP | OUTN); //flip outp/outn
OUT(sOUT_PORT);
}

int main(void) {

mcu_init(); //initialize the mcu
com_init(TMR1_PS8x); //reset cosine comm
ei(); //enable global interrupts

while (1) {
if (GPIF) { //AC_IN has changed state
AC_PORT; //read the port - necessary to clear the flag
GPIF = 0; //clear the gpif
//initialize the timer
TMR1 = -phase; //reset timer
//reset outp/outn
IO_CLR(sOUT_PORT, OUTP); IO_SET(sOUT_PORT, OUTN);
OUT(sOUT_PORT);
}
}
}


RogerClark
Tue Jul 04, 2017 9:56 pm
This is really interesting..

Thanks for posting.

I think I wrote something similar but had some small issues with ten timer initially calling the ISR when the code started.

I wonder what hardware you use to do the zero detection. I found problems with the simple hardware e.g. Just an optocouple, as it can exoerience interference if you have a noisy electrical load on the same input mains circuit.

I also did some work to map the proportion of power to the proportion of delay, so that I could, for example, select a specific percentage of power.
Because 25 % time delay does not result in 75% power, because of the shape of the sine wave.

But in the end, I didn’t use the project, and I am not entirely sure where I put the code


dannyf
Wed Jul 05, 2017 3:36 pm
I used a resistor. It was originally for a dimmer and then an adjustable power supply.

The circuit is substantially the same as one used by ST in an application note to caliberate hsi. The code follows largely a microchip application note on dimmers.

The code is simple. The only thing interesting is the offline calculation of a look up table.

Hope it helps.


Leave a Reply

Your email address will not be published. Required fields are marked *