PWM with Timer 3 on Arduino Yun
Just a quick post with an example sketch for how to setup timer 3 on an Arduino Yun to control the brightness of an LED.
I had to go through figuring this out while experimenting with brightness and flash patterns.
Anyway….
- It’s just a simple sketch.
- I’m not really sure why a prescaler of 1 doesn’t work (I guess the LED switches on and off too quickly).
- I’m not going to explain the ins and outs of a PWM for LED control (there are lot of good examples on the web).
- The “brightness” value is really just the ratio of ON time to OFF time vs the rollover value (255).
- The actual perceived brightness for any LED will not be linear…you have to compensate for how the eye works and how the LED makes light (in a real product).
// Exmaple using PWM (Timer 3) for brightness control
enum {
RED_PIN = 13,
STEP = 5,
};
int dir = STEP;
int brightness = 0;
void setup() {
Serial.begin(9600);
pinMode(RED_PIN, OUTPUT);
noInterrupts(); // disable all interrupts
// Waveform Generation
// ===================
// Mode Mode of Operation TOP Update of OCRnx at TOVn Flag Set on
// 3 - Fast PWM, 8-bit 0x00FF TOP BOTTOM
// 14.10.2 Timer/Counter3 Control Register A – TCCR3A
// 7 6 5 4 3 2 1 0
// COM3A1 COM3A0 COM3B1 COM3B0 COM3C1 COM3C0 WGM31 WGM30
// 0 0 0 0 0 0 0 1
TCCR3A = 0x01;
// 14.10.4 Timer/Counter3 Control Register B – TCCR3B
// 7 6 5 4 3 2 1 0
// ICNC3 ICES3 – WGM33 WGM32 CS32 CS31 CS30
// 0 0 0 0 1 1 0 1
TCCR3B = 0x0D;
// Enable Overflow and Output Compare 1 interrupt
TIMSK3 |= (1 << TOIE3) | (1 << OCIE3A);
OCR3AH = 0;
OCR3AL = 0;
interrupts(); // enable all interrupts
}
// On the compare interrupt, set the pin low
ISR(TIMER3_COMPA_vect) {
digitalWrite(RED_PIN, LOW);
}
// On the timer rollover interrupt, set the pin high if the brightness is non-zero
ISR(TIMER3_OVF_vect) {
digitalWrite(RED_PIN, brightness > 0);
OCR3AL = brightness;
}
void loop() {
delay(500);
// Step up or down by STEP size
brightness += dir;
// Clip to the 0..255 range
brightness = min(brightness, 255);
brightness = max(brightness, 0);
// Change the step direction if at the limit
if (brightness == 255) {
dir = -STEP;
}
if (brightness == 0) {
dir = STEP;
}
Serial.print("Brightness:");
Serial.print(brightness);
Serial.println("");
}
Posted on
Nov 4, 2019 at 00:00