/*****************************************************************************
*
* Copyright (c) 2012 Johannes Hermen www.der-frickler.net
*
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*****************************************************************************
*
* ESC Light Module
* Uses an TowerPro MAG8 12A Brushless ESC as light switch.
* switches the different lights on dependent to the stick position .
*
* PINOUT: Servo Signal IN: INT0 (PD2)
* OUT_1 PD4 YELLOW strobe double flash
* OUT_2 PD5 RED tail single flash
* OUT_3 PD7 BLACK ACL single flash
*
* PD0, PD1, PD3 MUST be set to LOW to avoid short Circuit
*
*****************************************************************************/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define PORT PORTD
#define OUT_1 PD4
#define OUT_2 PD5
#define OUT_3 PD7
#define IN PD2
#define STICK_CENTER 22400
#define STICK_HIGH 28800
#define STICK_OVERFLOW 40000
#define STROBE_DIST 500
#define STROBE_TIME 20
#define STROBE_REPEAT 180
#define ACL_DIST 280
#define ACL_TIME 20
uint16_t value;
// on timer1 overflow
ISR (TIMER1_OVF_vect)
{
value = STICK_OVERFLOW;
}
// on INT0 / PD2 pinchange
ISR (INT0_vect)
{
if ((PIND & 4)==4) // check 3th bit of PORTD (pin 4) got HIGH
{
TCCR1B = 0; // stop timer1
TCNT1 = 0; // reset timer1
TCCR1B = 1; // start 16bit timer1 - no prescale
}
else if ((PIND & 4)==0 )
{ // check 3th bit of PORTD (pin 4) got LOW
TCCR1B = 0; // stop timer1
value = TCNT1; // get Timer Value
}
}
int main (void)
{
DDRB = 255; // portb as output
PORTB = 0; // portb to 0
DDRD = 251; // portd as output, int0 as input
PORTD = 0; // portd to 0
DDRC = 0; // portc as input
PORTC = 255; // portc to 0
MCUCR = 1; // External Interrupt on PinChange
GICR = 64; // enable Int0
TCNT1 = 0;
TIMSK = 4; // 16-Bit Timer Overflow-Interrupt an
TCCR1A = 0; // 16-Bit Normal Mode
TCCR1B = 0; // stop 16-Bit Timer
sei(); // Interrupts on.
TCCR1B = 1; // start timer1
while(1)
{
if (value > STICK_HIGH) {
//PORT |= (1 << OUT_3); // constant light on
} else {
//PORT &= ~(1 << OUT_3); // constant light off
}
if (value > STICK_CENTER) {
_delay_ms(STROBE_DIST);
PORT |= (1 << OUT_1); // flash strobe on
PORT |= (1 << OUT_2); // flash tail on
_delay_ms(STROBE_TIME);
PORT &= ~(1 << OUT_1); // flash strobe off
PORT &= ~(1 << OUT_2); // flash tail off
_delay_ms(STROBE_REPEAT);
PORT |= (1 << OUT_1); // flash strobe on
_delay_ms(STROBE_TIME);
PORT &= ~(1 << OUT_1); // flash strobe off
_delay_ms(ACL_DIST);
PORT |= (1 << OUT_3); // flash ACL on
_delay_ms(ACL_TIME);
PORT &= ~(1 << OUT_3); // flash ACL off
} else { // set port to 0
PORT = 0;
}
}
}