Very Confusing PWM is not working when I attempt to change Timer 1
My desired mode (I Think) is:
**Mode ** |
**WGM13 ** |
**WGM12 ** |
**WGM11 ** |
**WGM10 ** |
Timer/Counter Mode of **Operation ** |
**Top ** |
Update of **OCR1x at ** |
TOV1 Flag **Set on ** |
---|---|---|---|---|---|---|---|---|
7 |
0 |
1 |
1 |
1 |
Fast PWM, 10-Bit |
0x3FF |
BOTTOM |
TOP |
Page 132 of the Datasheet
I am attempting to set PWM to handle a specific trigger I can not use mode 8 PWM, Phase and Frequency Corrected because the start time and end time of the Pulse width is relative to the center of the pulse.
My goal is to have a fixed known end time. I am not worried about phase and frequency being correct
I am using the timer1 library Google Code Archive - Long-term storage for Google Code Project Hosting.
Documentation for the timer1 library is Found at Arduino Playground - Timer1
My Attempted change in the library to switch to mode 7:
TimerOne & PWMTimerOne::initialize(long microseconds)
{
TCCR1A = 0; // clear control register A
// TCCR1B = _BV(WGM13); // set mode 8: phase and frequency correct pwm, stop the timer
TCCR1B = _BV(WGM10)|_BV(WGM11)|_BV(WGM12); //****** Changed to ******* set mode 7: Fast pwm, stop the timer
setPeriod(microseconds);
return *this;
}
The Basic code for testing:
#include <PWMTimerOne.h> // http://www.arduino.cc/playground/Code/Timer1
#include "Interrupts.h"
InterruptsClass Interrupt;
volatile int Duty = 1024 * .1;
volatile int ActualPeriod = 8333;
volatile unsigned long LastTime;
volatile unsigned long TimerValue;
void SetPWM() {
unsigned long Time = micros();
Timer1.setPwmDuty(9, Duty);
Timer1.setPeriod(constrain(Time - LastTime, 8300, 8400));
Timer1.start(); //and start it up with timer at zero
ActualPeriod = Time - LastTime;
LastTime = Time;
TimerValue = Timer1.read();
static unsigned long SpamTimer;
if ( (unsigned long)(millis() - SpamTimer) >= (100)) {
SpamTimer = millis();
sei(); // re enable other interrupts at this point, so Serial Print doesn't flop
Serial.print(ActualPeriod);
Serial.print("\t ");
Serial.println(TimerValue);
}
}
void setup() {
Serial.begin(115200);
Serial.println("AC Phase Control Test");
Timer1.initialize(ActualPeriod); //AC Frequency is 8.3333 milliseconds @ 60HZ,
//pick a period that gives you a little headroom.
Timer1.stop(); //stop the counter
Timer1.pwm(9, 0, ActualPeriod);//.InvertPwm(9);
attachInterrupt(0, SetPWM,FALLING); // PWM Calibration Pulse input
}
void loop() {
static unsigned long SpamTimer;
if ( (unsigned long)(millis() - SpamTimer) >= (100)) {
SpamTimer = millis();
Duty += 10; // Shift the Duty Cycle
if (Duty >= 1024) Duty = 10;
}
}
Note the code compiles:
I need the pulse to set the start of the next PWM Sequence
My operating frequency is 120HZ US AC power
Ideally I need to PWM to be inverted so the Pulse starts low then rises somewhere in the middle set by duty cycle and drops at an exact spot set by the calibration trigger (Zero crossing circuit input on Pin2)
Currently I can calibrate the PWM but it is referenced to the center of the pulse not the edge.
What am I missing, Nothing I try generates results and I haven't found the solution yet.
- Any documents better describing PWM Register Setup,
- Code examples using the Fast PWM 10-bit mode 7 (any level of complexity)
- Corrections / additions to my code if you would like
- Any Help
Anything Please
Thanks in advance
Z