Hello all, this is the first time I am doing something writing to registers so I don't even know if what I want is possible.
I made abit of a mix with two codes I found. One is to measure mains grid frequency using a optocoupler and an external interrupt. The second code is to create a PWM on pin 9 with a frequency of 1Hz.
I am interested in doing a code that can read the grid frequency and change the duty cycle of the 1Hz PWM that is controlling a SSR so I can control power going to a heating element. Duty cycle should be 0% at 50.5Hz and 100% at 51Hz
Each part of the code works ok. If I measure frequency it will measure ok. And changing duty cycle of 1Hz pwm works ok too. But when I try to do both together arduino will stop generating PWM signal on pin 9. I think this might be due to the external interrupt on pin 2
This is my code
unsigned int outputvalue;
void setup() {
pinMode(9, OUTPUT); // Set digital pin 9 (D9) to an output
TCCR1A = _BV(COM1A1) | _BV(WGM11); // Enable the PWM output OC1A on digital pins 9
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS12); // Set fast PWM and prescaler of 256 on timer 1
ICR1 = 62499; // Set the PWM frequency to 1Hz: 16MHz/(256 * 1Hz) - 1 = 62499
OCR1A = 6249; // Set the duty-cycle to 10%: 62499 / 10 = 6249
TCNT1 = 0; // Set Timer1 preload value to 0 (reset)
TIMSK1 = 1; // enable Timer1 overflow interrupt
EIFR |= 1; // clear INT0 flag
attachInterrupt(0, timer1_get, FALLING); // enable external interrupt (INT0)
Serial.begin(9600);
}
uint16_t tmr1 = 0;
float period, frequency;
void timer1_get() {
tmr1 = TCNT1;
TCNT1 = 0; // reset Timer1
}
ISR(TIMER1_OVF_vect) { // Timer1 interrupt service routine (ISR)
tmr1 = 0;
}
void loop(){
// save current Timer1 value
uint16_t value = tmr1;
// calculate signal frequency which is = 1/period ; or = MCU_CLK/(Prescaler * Timer_Value)
// since using full bridge rectifier we measure half period, so f=1/2*p
if(value == 0)
frequency = 0; // aviod division by zero
else
frequency = 16000000.0/(2*(256UL*value));
if (frequency>50.49 && frequency<51){
outputvalue= 2*62499*(frequency-50.5);
}
if (frequency>51){
outputvalue=62499;
}
if (frequency<50.5){
outputvalue=0;
}
OCR1A = outputvalue;
Serial.println(frequency);
}
I am just starting with using external interrupts and also writing to registers. But I think it might be that I am setting TCNT1 to cero after each cero crossing of ac, so this "resets" the counter for PWM?
Any recomendation in how I could to this?
Thank you in advanced