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();
Because I don’t.
#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();
}
But the blue_signal’s (led_pin) active Low duration is changing (it is growing with time) – that is the issue?
HardwareTimer timer1(1);
Timer1.setCompare(TIMER_CH1, 1);
^
‘Timer1’ does not name a type
stephen
HardwareTimer Timer1(1);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() {
}
void handler_led() {
digitalWrite(led_Pin, HIGH);
//myTimer.refresh();
}Not sure how the
timer.setCompare(TIMER_CH1, 1);
works.
Try to comment it out.
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
}
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
}
// 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() {
}
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);
}
}
}
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
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.

