Добрый день!
В этом посте я хочу поделится с хабр сообществом о принципе работы сделанного мной
бесконтактного выключателя. Выключатель планируется использовать в системе умный дом.
Основой выключателя является недавно купленный мной улучшенный клон контроллера Arduino, продающегося под названием Carduino Nano V.7

Работает выключатель так:
Arduino с выхода D5 постоянно выдает ШИМ сигнал с частотой 976Гц и со скважностью 50%. К выходу
D5 через токограничивающий резистор подключен светодиод, излучающий световой сигнал в инфракрасном диапазоне. Фототранзистор подключенный к входу Arduino D2 детектирует
отраженный от руки ИК сигнал. Arduino получает ИК сигнал, проверяет его на достоверность и если сигнал из 20 идущих подряд импульсов соответствует частоте 976Гц, то тогда контроллер включает синий светодиод (L) на выходе D13 Arduino и начинает воспроизводить звуковой эффект через выход SPK контроллера. Все тоже самое происходит и при выключении светодиода (L).
Воспроизведение :
При воспроизведении звуковых эффектов используется звуковой фаил формата WAV без сжатия, с частотой 16000Гц и глубиной 8бит.
Для улучшения качества воспроизведения звука, используется линейная интерполяция. Для этого, выборка семплов происходит на частоте 96000Гц и между оригинальными семплами вставляются 4 промежуточных семпла рассчитанных методом линейной интерполяции. Таким образом снижается шум квантования, улучшеатся качество и для воспроизведения звуков не потребуются дополнительные фильтры.
Схема простая для ее ��борки я использовал
1-Carduino Nano V.7
2-IR светодиод из старого пульта ДУ от телевизора, светодиод нужно запаять в термоусадку, во избежании бокового излучения
3-Фототранзистор LTR-3208E
4-Динамическая головка из детской игрушки
5-Резисторы 10к и 68ом

Как работает схема собранная мной на макетной плате, можно посмотреть на видео.
Код для Arduino Nano:
Скачать исходники одним файлом
В следующей статье:
Arduino Nano будет заменен на контроллер Atmega328, вся схема с блоком питания будут собраны на отдельной плате и вмонтирована в коридорный выключатель.
В этом посте я хочу поделится с хабр сообществом о принципе работы сделанного мной
бесконтактного выключателя. Выключатель планируется использовать в системе умный дом.
Основой выключателя является недавно купленный мной улучшенный клон контроллера Arduino, продающегося под названием Carduino Nano V.7

Работает выключатель так:
Arduino с выхода D5 постоянно выдает ШИМ сигнал с частотой 976Гц и со скважностью 50%. К выходу
D5 через токограничивающий резистор подключен светодиод, излучающий световой сигнал в инфракрасном диапазоне. Фототранзистор подключенный к входу Arduino D2 детектирует
отраженный от руки ИК сигнал. Arduino получает ИК сигнал, проверяет его на достоверность и если сигнал из 20 идущих подряд импульсов соответствует частоте 976Гц, то тогда контроллер включает синий светодиод (L) на выходе D13 Arduino и начинает воспроизводить звуковой эффект через выход SPK контроллера. Все тоже самое происходит и при выключении светодиода (L).
Воспроизведение :
При воспроизведении звуковых эффектов используется звуковой фаил формата WAV без сжатия, с частотой 16000Гц и глубиной 8бит.
Для улучшения качества воспроизведения звука, используется линейная интерполяция. Для этого, выборка семплов происходит на частоте 96000Гц и между оригинальными семплами вставляются 4 промежуточных семпла рассчитанных методом линейной интерполяции. Таким образом снижается шум квантования, улучшеатся качество и для воспроизведения звуков не потребуются дополнительные фильтры.
Схема простая для ее ��борки я использовал
1-Carduino Nano V.7
2-IR светодиод из старого пульта ДУ от телевизора, светодиод нужно запаять в термоусадку, во избежании бокового излучения
3-Фототранзистор LTR-3208E
4-Динамическая головка из детской игрушки
5-Резисторы 10к и 68ом

Как работает схема собранная мной на макетной плате, можно посмотреть на видео.
Код для Arduino Nano:
#include <TimerOne.h> #include <avr/delay.h> #include <avr/pgmspace.h> #include "fife.h" #include "hi.h" ////////переменные проигрывателя//////////////////////////////////// #define speakerPin 11 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(13, OUTPUT); //Лампочка pinMode(5, OUTPUT); //выход ШИМ на ИК светодиод TCCR0B = TCCR0B & 0b11111000 | 3; //частота ШИМ 976Гц 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(13, 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); }
Скачать исходники одним файлом
В следующей статье:
Arduino Nano будет заменен на контроллер Atmega328, вся схема с блоком питания будут собраны на отдельной плате и вмонтирована в коридорный выключатель.
