Сделал себе в комнату бесконтактный выключатель . Срабатывает на расстоянии 10см от датчика (можно увеличить), для того что бы включить или выключить свет достаточно махнуть рукой рядом с выключателем. Выключатель сделан на базе Arduino nano
В качестве лампочки для тестирования в скетче используется светодиод на D13
Ик Светодиод взял от пульта управления телевизором. Фототранзистор любой
PHP код:
#include <TimerOne.h> #include <avr/delay.h> #include <avr/pgmspace.h> #include "fife.h" #include "hi.h" ////////переменные проигрывателя//////////////////////////////////// #define speakerPin 11 #define lamp 13 volatile uint16_t sample = 0 ; volatile uint8_t lastSample , FirstSample ; volatile byte new_data , future_data , old_data ; volatile byte stat = 0 ; unsigned char * wave ; unsigned int length ; ////////переменные выключателя//////////////////////////////////// uint8_t state = 0 ; volatile uint16_t timerCount , lengthImpuls ; volatile uint16_t Counter = 0 ; ////////////начальная предустановка/////////////////////////////// void setup () { pinMode ( speakerPin , OUTPUT ); //выход на динамик digitalWrite ( speakerPin , LOW ); // на всякий случай, что бы не спалить динамик pinMode ( 2 , INPUT ); // Вход, к фототранзистору // digitalWrite(2, HIGH); //Подключить подтягивающий резистор pinMode ( lamp , OUTPUT ); //Лампочка pinMode ( 5 , OUTPUT ); //выход ШИМ на ИК светодод TCCR0B = TCCR0B & 0b11111000 | 3 ; //частота ШИМ 1000Гц analogWrite ( 5 , 128 ); //запустить ШИМ attachInterrupt ( 0 , Ir_sens , RISING ); //внешнее прерывание по фронту Timer1 . initialize ( 10 ); //инициализация таймера Timer1 . attachInterrupt ( callback ); //прерывание таймера } ////////////обработка прерывания по таймеру/////////////////////////////// void callback () { timerCount ++; } ////////////обработчик внешнего прерывания/////////////////////////////// void Ir_sens () { lengthImpuls = timerCount ; timerCount = 0 ; Counter ++; } ///////////////////////Обработчик прерывания по совпадению с OCR2/////////////////// ISR ( TIMER2_COMPA_vect ) { switch ( stat ) { case 0 :{ old_data = pgm_read_byte (& wave [ sample ]); OCR2A = old_data ; stat = 1 ; ++ sample ; if ( sample == length ) stat = 4 ; future_data = pgm_read_byte (& wave [ sample ]); new_data = ( old_data + future_data )/ 2 ; } break; case 1 : { OCR2A =( old_data + new_data )/ 2 ; stat = 2 ; } break; case 2 : { OCR2A = new_data ; stat = 3 ; } break; case 3 : { OCR2A =( new_data + future_data )/ 2 ; stat = 0 ; } break; case 4 : if( lastSample == 0 ) stat = 5 ; else {-- lastSample ; OCR2A = lastSample ;} break; case 5 : stopPlayback (); break; } } ////////////главный цикл приграммы/////////////////////////////// void loop () { if( lengthImpuls > 105 || lengthImpuls < 99 ) Counter = 0 ; if( lengthImpuls > 99 && lengthImpuls < 105 && Counter > 20 ) { state =~ state ; digitalWrite ( lamp , state ); if( state > 0 ) play_wave (( unsigned char *) hi , hi_length ); if( state == 0 ) play_wave (( unsigned char *) fife , fife_length ); _delay_ms ( 200 ); while( Counter > 10 ) { if( lengthImpuls > 105 || lengthImpuls < 99 ) Counter = 0 ; } lengthImpuls = 0 ; } } ////////////начать воспроизведение/////////////////////////////// void play_wave ( unsigned char * wave_data , unsigned int wave_length ) { wave = wave_data ; length = wave_length ; startPlayback (); } void startPlayback () { sample = 0 ; stat = 0 ; ASSR |=( 1 << AS2 ); TCCR2A |= (( 1 << COM2B1 )|( 0 << COM2B0 )|( 1 << COM2A1 )|( 0 << COM2A0 )|( 1 << WGM21 )|( 0 << WGM20 )); TCCR2B = (( 0 << CS22 ) | ( 0 << CS21 ) | ( 1 << CS20 ) | ( 0 << WGM22 ) | ( 1 << FOC2A ) | ( 1 << FOC2B )); lastSample = pgm_read_byte (& wave [ length - 1 ]); TCNT2 = 0 ; TIMSK2 |=( 1 << OCIE2A ); sei (); for ( int i = 0 ; i < 50 ; i ++) { new_data = i ; stat = 2 ; sample = 0 ; _delay_us ( 1 ); } stat = 0 ; } ////////////остановить воспроизведение/////////////////////////////// void stopPlayback () { TIMSK2 &=( 0 << OCIE2A ); TCCR2B &=( 0 << CS10 ); }