/* * switch4ch.c * ATtiny13 mit 1,25 MHz internal RC resonator * * This small program parses the signal of an RC receiver output and switches * 4 functions according to the input signal. The pcb will be connected * exactly like a standard servo. * The servo signal usually repeats every 20ms and has a high value of the * signal ranges from 0.5ms to 2.5ms maximum and 1ms to 2ms at a standard * RC control. * * Usage: * A 'click' your RC-sender pult channel to 100% a short time * (<0.5s) will toggle channel 1 * A click to -100% will toggle channel 2 * If you stay at 100% for more than a half second, channel 3 will be set * until you release the channel again. * The same happens to channel 4 if you stay at -100% for more than a half * second - currently this generates a funny 'morse code' signal for a * small tweeter. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND * This file is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 */ #include #include #include #include /** * The pin where we get the servo signal from the receiver */ #define PIN_PULSE_IN PB3 #define MAX_CLICK_TIME 25 /** * the ouputs */ #define OUT1 PB0 #define OUT2 PB1 #define OUT3 PB2 #define OUT4 PB4 /** * Higher byte of the timer. this will be incremented by the int SIG_OVERFLOW0 * This is needed since the TIMER0 is running without any prescaler. * This variable is defined as volatile to avoid that C is optimising it to a register * which cannot be shared between the interrupt service routine and the mail loop. */ volatile uint8_t timerHighByte; /** * counts the number of cycles the high value has been reached. * If this value is 0 then no high value has been detected previously. * If the value is > 50 (~1 second) then stop counting and switch on SW4. */ uint8_t highCounter; /** * counts the number of cycles the low value has been reached. * If this value is 0 then no low value has been detected previously. */ uint8_t lowCounter; /** * If this variable is > 0 then play a sound. If 0 then stop playing. * This is used as a ship horn which is output by SW2. */ uint8_t soundRunning; /** * This interrupt gets triggered if the timer0 is running and an overflow (from 0xff to 0x00) happens */ SIGNAL (SIG_OVERFLOW0) { timerHighByte++; // incrementing timerHighByte } /** * reset the timer value to 0x0000 and start the timer */ void restartTimer() { timerHighByte = 0; // higher Byte of the timer TCNT0 = 0; // lower Byte of the timer TCCR0B |= (1 << CS00); // set Prescaler to 1:1 (count with clkspeed of ~1MHz) } /** * stop the timer0 */ void stopTimer() { TCCR0B &= ~(1 << CS00); // set Prescaler to 0 will stop the timer } /** * This function is called if a valid servo pulse has been detected. * The timerValue is the pulse length in microseconds */ void performAction(uint16_t timerValue) { if (timerValue < 1500) { if (lowCounter >= MAX_CLICK_TIME) { // the button has been pressed for aprox 1 second -> switch on SW2 //X disabled. SW2 is now used for playing sound: PORTB |= (1< 2100) { if (highCounter >= MAX_CLICK_TIME) { // the button has been pressed for aprox 1 second -> switch on SW4 PORTB |= (1< 3 && highCounter < MAX_CLICK_TIME) { // single 'click' detected -> toggle switch SW3 PORTB ^= (1< 3 && lowCounter < MAX_CLICK_TIME) { // single 'click' detected -> toggle switch SW1 PORTB ^= (1< 0 && soundCounter & (1<<5)) { PORTB ^= (1< 800 && timerValue < 3000) { performAction(timerValue); } else { performActionOnInvalidPulse(); } } // end of main loop }