No questions here, I though it might be useful for someone to look over.
Goal:
LED driver. I have 14 stairs where I am installing LED strips under the step overhang.
- The LED strips are so bright I have to reduce the dutycycle to < 1%.
- Don't want to see flicker so the base frequency > 200 Hz.
- To reduce power supply load I want to power two strips at a time.
- I want to use timer1 because I like to use the timers when I can.
- Reduced power of µP needed if run at 24Vdc input. I don't to use a buck converter.
Just an example where everything is performed in a interrupt where normally a good goal it to keep the interrupt as short as possible.
Graphically this is what I want (and this program does):
/*
Front Stairs (livingroom to Foyer) LED Driver
2022-07-12 v001
- control 7 strips (one on each step) independently (or 14 strips 2 at a time)
- On time is approx 1/2 %
- Frequency approx 230 Hz
- Strips are only on one at a time.
- undecided if one right after another or spread across the period.
Target:
Arduino Pro Mini 16Mhz 5V
the 5v output is needed to drive the output MosFet's (logic level)
Period controlled by Interrupt on timer1
*/
#include <avr/power.h>
#define period 0x0F0A //259.7
#define OnTime 20 // OnTime 20 meas 24µs with scope (at LED strip)
#define interPulseDelay 5
// ---------------------------------------------------------------------------------
void setup(){
cli(); //stop interrupts
DDRD = 0b11111110; // set PORTD (digital 7~0) to outputs
PORTD = 0;
TIMSK0 &= ~_BV(TOIE0); // disable timer0 overflow interrupt
//
//set timer1 interrupt period (freq)
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; //initialize counter value to 0
// set compare match register
OCR1A = period;
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS11 for ÷8 prescaler
TCCR1B |= (1 << CS11); // | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
// to save power disable unused functions in µP
ADCSRA = 0; // turn off the ADC converter
power_adc_disable(); // ADC converter (need the above and this line to fully disable the ADC)
power_spi_disable(); // SPI
power_usart0_disable(); // Serial (USART)
power_timer0_disable(); // Timer 0
//power_timer1_disable(); // Timer 1
power_timer2_disable(); // Timer 2
power_twi_disable(); // TWI (I2C)
sei(); //enable interrupts
} //end setup
// ---------------------------------------------------------------------------------
ISR(TIMER1_COMPA_vect){ //timer1 interrupt
// toggle LED is only used during development to trigger the logic analyzer.
asm ("sbi %0, %1 \n": : "I" (_SFR_IO_ADDR(PINB)), "I" (PINB5)); // Toggle LED
for (int i =1; i < 8; i++){
PORTD |= (1 << i);
delayMicroseconds(OnTime);
PORTD = 0x00;
delayMicroseconds(interPulseDelay);
}
}
// ---------------------------------------------------------------------------------
void loop(){}
// -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
/*
Output Pins: (Board markings)
Tx
2
3
4
5
6
7
*/