I'm using a 6ms pulse to power two IR LED's using 1 ohm resistors at 5VDC. The circuit is drawing about 140 ma average based on my power supply current reading.
The 6ms pulses are applied with two timers, timer 0 is a 100 ms timer and timer 1 is the 6ms timer so On time is 6ms and off time is 100ms
As I was testing, I made a programming error where the pulse stayed on drawing 400 ma current for a few seconds.
What kind of protection can I use to solve a potential AVR malfunction or mosfet malfunction or development software error that would protect those led's from burning up?
I am familiar with PTC fuses but is there any other method using capacitors or something?
Code so far
#include <tiny45.h> volatile unsigned char WheelTenMSTimer = 10; // Decrements once per Millisecond resets to 10 when WheelPin state is read. volatile unsigned char WheelState = 2; // 2 = Unknown State initially volatile unsigned char PreviousWheelState = 2; // 2= Unknown State initially Valid 1 = High, 0 = Low volatile unsigned char IRLedOutputFlag = 0; volatile unsigned char RollerSenseCount = 50; // Valid 0 = Sensor Low, 100 = Sensor High volatile unsigned char WheelPulseCounter = 0; // alarm #define AlarmPin PINB4 #define AlarmPort PORTB #define AlarmDDR DDRB #define AlarmOn AlarmPort |=(1 <<AlarmPin) #define AlarmOff AlarmPort &=~(1 << AlarmPin) // RollerSensor INPUT #define WheelPin PINB1 #define WheelPort PORTB #define WheelDDR DDRB #define WheelPinHigh ( (PINB & (1 << WheelPin)) == (1 << WheelPin) ) // Roller sensor IR Led OUTPUT #define RollerPin PINB3 #define RollerPinPort PORTB #define RollerPinDDR DDRB #define RollerPinOn RollerPinPort |=(1 << RollerPin) #define RollerPinOff RollerPinPort &=~(1 << RollerPin) //ScreenFrame Sensor INPUT #define FrameInputSensorPin PINB0 #define FrameInputSensorPort PORTB #define FrameInputSensorDDR DDRB #define FrameInputSensorPinHigh ( (PINB & (1 << FrameInputSensorPin)) == (1 << FrameInputSensorPin) ) // ScreenFrame Sensor OUTPUT #define FrameOutputSensorPin PINB2 #define FrameOutputSensorPort PORTB #define FrameOutputSensorDDR DDRB #define FrameOutputLedON FrameOutputSensorPort |=(1 << FrameOutputSensorPin) #define FrameOutputLedOFF FrameOutputSensorPort &=~(1 << FrameOutputSensorPin) interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // 1MS interrupts TCNT0 = 131; if (WheelTenMSTimer > 0) { WheelTenMSTimer--; // Decrement 10 ms timer } } interrupt [TIM1_COMPA] void timer1_compa_isr(void) { // compare OCR1A = 200 // Clock /256 // 6.4MS timer interrupt if (WheelTenMSTimer == 0) //Turn the IR Led Flags on and reset ten MS timer { WheelTenMSTimer = 100; // 100 MS until next on cycle IRLedOutputFlag = 2; // Set to turn IRE led ON } if (IRLedOutputFlag == 1) // Turn off IR LED { FrameOutputLedOFF; RollerPinOff; IRLedOutputFlag = 0; } if (IRLedOutputFlag == 2) { FrameOutputLedON; RollerPinOn; IRLedOutputFlag = 1; // Set so next time this interrupts 6.4MS turn off IR LED } } void TestValidWheelPulse(); void TestAlarmConditions(); void main(void) { // Setup timers TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00); TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00); TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; TIMSK=(1<<OCIE1A) | (0<<OCIE1B) | (0<<OCIE0A) | (0<<OCIE0B) | (0<<TOIE1) | (1<<TOIE0); // clock / 256 TCCR1 =(1<<CTC1)|(0<< PWM1A )| (0<<COM1A1) |(0<< COM1A0) |(1<<CS13) |(0<<CS12) |(0<<CS11) |(1<<CS10); OCR1A = 200; OCR1C = 200; WheelDDR &=~(1 << WheelPin); // Input WheelPort |= (1 << WheelPin); // Pull up FrameInputSensorDDR &=~(1 <<FrameInputSensorPin); // Input FrameInputSensorPort |= (1 <<FrameInputSensorPin); // Pull up AlarmDDR |=(1 << AlarmPin); RollerPinDDR |=(1 << RollerPin); FrameOutputSensorDDR |=(1 << FrameOutputSensorPin); #asm("sei") // Turn on interrupts while (1) { while (IRLedOutputFlag == 1) // When Timer1 Interrupt turns IR LED on Read status IR Receiver until IR Led turns off { if (!FrameInputSensorPinHigh) // Reset all counters if no frame in sensor beam { AlarmOff; WheelState = 2; // 2 = Unknown State initially PreviousWheelState = 2; // 2= Unknown State initially Valid 1 = High, 0 = Low RollerSenseCount = 50; // Valid 0 = Sensor Low, 100 = Sensor High WheelPulseCounter = 0; // Flag for alarm when counts up to 16 , ten inches have passed } if (WheelPinHigh) { if (RollerSenseCount < 100) { RollerSenseCount++; // Increase counter if IR sensor is receiving } } else // WheelPin is LOW { if (RollerSenseCount > 0) { RollerSenseCount--; // Decrease counter if IR sensor is not receiving } } } if (IRLedOutputFlag == 0) // When Timer1 interrupt turns IR led off Reset the counter { if (RollerSenseCount == 100) // Test if Roller Sensor valid Receive { RollerSenseCount = 50; // Reset to neutral WheelState = 1; } else { if (RollerSenseCount == 0) // Test if Roller Sensor valid Receive { RollerSenseCount = 50; // Reset to neutral WheelState = 0; } } } if (WheelState != 2) { TestValidWheelPulse(); TestAlarmConditions(); } } } void TestValidWheelPulse() { if (PreviousWheelState == 2) { PreviousWheelState = WheelState; } if( WheelState == 0) { if (PreviousWheelState == 1) // Record a valid pulse { WheelPulseCounter++; PreviousWheelState = WheelState; WheelState = 2; } } else // WheelState = 1 { if (PreviousWheelState == 0) // Record a valid pulse { WheelPulseCounter++; PreviousWheelState = WheelState; WheelState = 2; } } } void TestAlarmConditions() { if (WheelPulseCounter == 2) { AlarmOn; } }