I've been playing around with Timer1 to produce a PWM signal and looking on my scope I can see that it's generating a 50KHZ signal. It's bits of code I've been studying and playing around with to get a better understanding. Looking on the scope I can see that the PWM produces a duty of 0-100% at 50KHZ with a rise and fall time of <600.0ns with a Width of 9.2us and -witdh 10.80us
The bit I'm struggling with is how to adjust the frequency correctly
here is the code
#include "TimerOne.h" // using Timer1 library from http://www.arduino.cc/playground/Code/Timer1
#include <LiquidCrystal_I2C.h> // I2C LCD display
#include <Wire.h>
#include <TimedAction.h>
LiquidCrystal_I2C lcd(0x027, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
#define PWM_PIN 9 // the output pin for the pwm
#define PWM_FULL 1023 // the actual value used by the Timer1 routines for 100% pwm duty cycle
#define PWM_MAX 100 // the value for pwm duty cyle 0-100%
#define PWM_MIN 1 // the value for pwm duty cyle 0-100%
#define PWM_START 1 // the value for pwm duty cyle 0-100%
#define PWM_INC 1 //the value the increment to the pwm value for the ppt algorithm
#define ONE_SECOND 50000 //count for number of interrupt in 1 second on interrupt period of 20us
int pwm = 0;
unsigned int seconds = 0; // seconds from timer routine
unsigned int prev_seconds = 0; // seconds value from previous pass
unsigned int interrupt_counter = 0; // counter for 20us interrrupt//pwm duty cycle 0-100%
void TimerService01();// This is for the read A/D and set pwm
TimedAction Timedact01 = TimedAction(200, TimerService01);// mS
//#####################################
//# Start up and set up #
//#####################################
void setup() {
lcd.begin (16, 2); // for 12 X 2 LCD module
lcd.setBacklightPin(3, POSITIVE); //set back light pin
lcd.setBacklight(HIGH); //Turn the back light on the LCD
Timer1.initialize(20); // initialize timer1, and set a 20uS period
Timer1.pwm(PWM_PIN, 0); // setup pwm on pin 9, 0% duty cycle
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
Serial.begin(9600); // open the serial port at 38400 bps:
pwm = PWM_START; //starting value for pwm
}
//#####################################
//# Main loop #
//#####################################
void loop() {
Timedact01.check();//Call to read and set pwm
}
//#####################################
//# TimerService01 every 200Ms #
//#####################################
void TimerService01() {// read pot and set pwm value
int sensorValue = analogRead(A0);//read chanel A0
pwm = map(sensorValue, 0, 1023, 0, 99); //map sensorvalue to pwm 0-100
set_pwm_duty(); // set pwm duty cycle to pwm value
// print out the value you read:
lcd.setCursor(0, 0);
lcd.print(sensorValue);
lcd.setCursor(0, 1);
lcd.print(pwm);
lcd.print(" ");
}
//#####################################
//# Set the PWM output #
//#####################################
void set_pwm_duty(void) {
if (pwm > PWM_MAX) { // check limits of PWM duty cyle and set to PWM_MAX
pwm = PWM_MAX;
}
else if (pwm < PWM_MIN) { // if pwm is less than PWM_MIN then set it to PWM_MIN
pwm = PWM_MIN;
}
if (pwm < PWM_MAX) {
Timer1.pwm(PWM_PIN, (PWM_FULL * (long)pwm / 100), 20); // use Timer1 routine to set pwm duty cycle at 20uS period
//Timer1.pwm(PWM_PIN,(PWM_FULL * (long)pwm / 100));
}
else if (pwm == PWM_MAX) { // if pwm set to 100% it will be on full but we have
Timer1.pwm(PWM_PIN, (PWM_FULL - 1), 1000); // keep switching so set duty cycle at 99.9% and slow down to 1000uS period
//Timer1.pwm(PWM_PIN,(PWM_FULL - 1));
}
}
//#####################################
//# interrupt routnie #
//#####################################
void callback()
{
if (interrupt_counter++ > ONE_SECOND) { //increment interrupt_counter until one second has passed
interrupt_counter = 0;
seconds++; //then increment seconds counter
}
}
I was wondering if some one with more knowledge of coding to have a quick look and explain how to work it out correctly.
I have altered these lines
#define ONE_SECOND 50000 //count for number of interrupt in 1 second on interrupt period of 20us
Timer1.initialize(20); // initialize timer1, and set a 20uS period
Timer1.pwm(PWM_PIN, (PWM_FULL * (long)pwm / 100), 20); // use Timer1 routine to set pwm duty cycle at 20uS period
and managed to change it to 25KHZ, But I'd rather get a better understanding of it.
Am I correct in saying I think it produces 16bit PWM ?