Управление светом от хлопков в ладоши.
- Войдите на сайт для отправки комментариев
Пт, 16/12/2011 - 12:38
Задача заключается в том чтобы управлять светом от двух хлопков в ладоши.Хочу все это сделать на ардуино но испытываю трудности в написании программы.Сам новичок в программировании.Два хлопка должны включать диод, а два выключать.Вот код программы не судите строго.
void setup(){
pinMode(2,INPUT);
pinMode(13,OUTPUT);
analogReference(EXTERNAL);
}
void loop(){
label:
unsigned long time;
int var = analogRead(2);
if(var < x || var > a){ //x и a будут заменены на точные значения.
time = millis(); // начать отсчет времени.
do{
if(var < x || var > a){
digitalWrite(13,HIGH);
}
}while(time < 1000); //после получения на входе значений ждать второе значение пока не пройдет секунда.
else if(time > 1000){
goto label;
}
if(var < x || var > a){
time = 0;
do{
if(var < x || var > a){
digitalWrite(13,LOW);
}
}while(time < 1000);
}
Попробуй так и посмотри что пишет когда хлопаешь и когда не хлопаешь:)
void setup() { Serial.begin(9600); } void loop() { int sensorValue = analogRead(2); Serial.println(sensorValue, DEC); }int analogData=0; //тут будут храниться данные с АЦП пин 0 int ledstate=0; //переменная состояния вкл-выкл void setup() { pinMode(13,OUTPUT); } void loop() { analogData=analogRead(0); //читаем значение if(analogData>120){ //в моём случае аудио сенсор имеет жутко малую чувствительность и выдаёт значение до 130 из 1024 возможных delay(200); //ожидаем 200милисекунд для повторного хлопка - можно не делать но в моём случае это добавило удобства for(int t=0;t<=500;t++) //цикл на проверку второго хлопка по идее на пол секунды но ардуино делает его дольше { delay(1); //для цикла analogData=analogRead(0);//считываем данные if(analogData>120){ //сверяем данные для второго хлопка, если он был то меняем состояние лампы с вкл на выкл и наоборот ledstate=!ledstate; //меняем состояние analogData=0;//обнуляем данные break;//выходим из цикла после второго хлопка delay(200);//для удобства } } analogData=0; } digitalWrite(13,ledstate); //включаем выключаем светодиод на 13м пине }Мой рогатый код, заинтересовали меня, сделать сразу влёт как думал не вышло. Есть видео - работает. Главное после включения ждать секунду и можно снова 2 раза хлопать.
У меня мега1280 и есть куча всяких шилдов и сенсоров, вот и решил помочь. Итого что в моём случае это мега1280 + DFrobot audio sensor + IO Expansion Shield
Спасибо.Как у вас все получилось просто.
Остается только дописать программу чтобы также 2-ух хлопков выключался.И вопрос зачем вы в конце обнулили данные?
analogData=0//обнуляем данные
ТАк оно и включается и выключается после двух хлопков
В конце можно было бы не обнулять. В ходе экспериментов пробовал разные варианты - это остатки предыдущих вариантов.
Понятно.И еще один вопрос не по теме.Как вы так редактируете код, когда вставляете его на форум я понимаю что есть кнопка "code", но как ею пользоваться?
нажимаете на кнопку код и в пустом поле вставляете весь свой код и всё
int analogData=0; //тут будут храниться данные с АЦП пин 0 int ledstate=0; //переменная состояния вкл-выкл void setup() { pinMode(13,OUTPUT); analogReference(EXTERNAL); } void loop() { analogData=analogRead(0); //читаем значение if(analogData > a && analogData < x){ //x и a будут заменены на точные значения delay(200); //ожидаем 200милисекунд для повторного хлопка - можно не делать но в моём случае это добавило удобства for(int t=0;t<=500;t++){ //цикл на проверку второго хлопка по идее на пол секунды но ардуино делает его дольше delay(1); //для цикла analogData=analogRead(0);//считываем данные if(analogData > a && analogData < x){ //сверяем данные для второго хлопка, если он был то меняем состояние лампы с вкл на выкл и наоборот ledstate=!ledstate; //меняем состояние break;//выходим из цикла после второго хлопка delay(200);//для удобства } } } digitalWrite(13,ledstate); } Вот законченный код.Не прокатит.
Во первых вместо || (логического ИЛИ) должно быть логическое И. Потому что ИЛИ - Истина, если хотя бы один операнд истина - у вас получится постоянная истина на выходе проверки, потому что если хлопка нет, analogData=0 и попадает под условие analogData < x - итого истина.
А если поставить логическое И - Истина, если оба операнда истина (true) То получится сравнение, тоесть если analogData попадает между а и х
Во вторых у вас в коде нет конечного элемента, который будет управлять вкл/выкл тоесть digitalWrite(pin,ledstate)
я хотел написать &, но перепутал с ||.
Теперь все исправлено
if(ledstate == 0){
22 digitalWrite(13,LOW)
23 }
24 else if(ledstate == 1){
25 digitalWrite(13,HIGH)
Эти проверки лишние, переменная принимает значения или 0 или 1, соответственно необходимо писать лишь
digitalWrite(13,ledstate)
&& вот так правильно, а не одна &
Я хотел бы задать вопрос о выводе AREF.Мне не совсем понятно, как его использовать.Просто к выводу AREF подключить напряжение например +3в и все?
Его можно вообще не использовать в данной задаче.
Все собрано.Уррраааа.Вот здесь нашел схему микрофонного усилителя : www.cxem.net/sound/soundpred/soundpred5.php
>>Я хотел бы задать вопрос о выводе AREF.Мне не совсем понятно, как его использовать.Просто к выводу AREF подключить напряжение например +3в и все?<<
На ареф подается опорное напряжение АЦП , по умолчанию (когда ареф не подключен) там 5в.
АЦП сравнивает опорное напряжение с поступающим и делает соответствующие выводы.
Если вы хотите подключить к ареф 3в то : эту функцию нужно включить программно , напруга ,
подаваемая на ареф , должна быть супер стабильной иначе получите ложные данные.
Потратил несколько часов на написание кода.
При старте происходит автодетект уровня тишины. После определённого времени есть возможность автоматического отключения нагрузки, также с опцией мигания в конце.
Подключение по этой схеме:
upload.wikimedia.org/wikipedia/commons/4/49/Electret_condenser_microphone_schematic..svg
Полярность микрофона имеет значение!
Вообщем, попробуйте залить этот код:
unsigned int silence_val = 0; //если 0, то будет autodetect уровня тишины unsigned int detect_delta = 10; //считается что есть звук, если значение звука различается на эту дельту относительно тишины unsigned int detect_count = 2; //количество замеров в цикле и выборка среднего за операцию unsigned int pin_in = 5; //аналоговый вход pin unsigned int pin_out = 2; //упраление нагрузкой на этот pin unsigned int silence_between = 500; //после первого срабатывание столько длится тишина unsigned int second_detect = 2000; //после тишины столько проверяется на второе срабатывание unsigned int pin_out_max_on1 = 5 * 1000; //msec идёт на выходной pin (0 - мониторится не будет) unsigned int pin_out_max_on2 = 15 * 1000; //msec идёт мигание (0 - мигания не будет) unsigned int pin_out_max_on2_skip = 50; //столько длится фаза одного мигания unsigned int pin_led_debug = 13; //debug led unsigned int detect1; unsigned int detect2; unsigned int pin_out_status = 0; unsigned long tm = 0; unsigned long tm_delta; unsigned int i; unsigned int count; unsigned int tmp; unsigned int silence; unsigned int cur_val; unsigned int cur_pin_out_max_on2_skip = 0; unsigned int tmp_pin_out_status; void setup() { Serial.begin(9600); pinMode(pin_out, OUTPUT); pinMode(pin_led_debug, OUTPUT); } unsigned int analogReadCount(unsigned int pin_in, unsigned int count) { unsigned int i; unsigned long ul; ul = 0; for(i = 0; i < count; i++) ul += analogRead(pin_in); return (ul / i); } void loop() { //silence if(silence_val == 0) { silence_val = analogReadCount(pin_in, 1000); Serial.print("Silence val: "); Serial.println(silence_val); } //end while(1) { cur_val = analogReadCount(pin_in, detect_count); if((cur_val + detect_delta) < silence_val) { Serial.print("Detect 1: "); Serial.println(cur_val); //задержка, чтобы последующие щелки пропустились digitalWrite(pin_led_debug, HIGH); delay(50); digitalWrite(pin_led_debug, LOW); //end detect1 = 1; } else { detect1 = 0; } if(detect1 == 1) { //тишина silence = 1; for(i = 0; i < silence_between; i++) { cur_val = analogReadCount(pin_in, detect_count); if((cur_val + detect_delta) < silence_val) { silence = 0; break; } } //end Serial.print("Silence: "); Serial.println(silence); } //первый был, тишина была if((detect1 == 1) && (silence == 1)) { digitalWrite(pin_led_debug, HIGH); //второй щелчок Serial.println("detect2 start"); for(i = 0; i < second_detect; i++) { cur_val = analogReadCount(pin_in, detect_count); if((cur_val + detect_delta) < silence_val) { Serial.print("Detect 2: "); Serial.println(cur_val); pin_out_status = !pin_out_status; digitalWrite(pin_out, pin_out_status); if(pin_out_status == 1) { tm = millis(); tmp_pin_out_status = pin_out_status; } else { tm = 0; } //задержка, чтобы последующие щелки пропустились digitalWrite(pin_led_debug, HIGH); delay(20); digitalWrite(pin_led_debug, LOW); delay(20); digitalWrite(pin_led_debug, HIGH); delay(20); digitalWrite(pin_led_debug, LOW); //end break; } } Serial.println("detect2 finish"); //end } //end //max on if(tm != 0) { tm_delta = millis() - tm; if(tm_delta > pin_out_max_on1) { if(pin_out_max_on2 == 0) { Serial.println("Max on 1 - off"); digitalWrite(pin_out, LOW); pin_out_status = 0; tm = 0; } else { if(tm_delta < pin_out_max_on2) { pin_out_status = 0; //(для decect2) пусть основной цикл думает что led не горит, тогда если щёлкнуть led включится Serial.println("Max on 2"); if(cur_pin_out_max_on2_skip > pin_out_max_on2_skip) { tmp_pin_out_status = !tmp_pin_out_status; digitalWrite(pin_out, tmp_pin_out_status); cur_pin_out_max_on2_skip = 0; } else { cur_pin_out_max_on2_skip++; } } else { Serial.println("Max on 2 - off"); digitalWrite(pin_out, LOW); pin_out_status = 0; tm = 0; } } } } //end } }ДОброго! скажи пожалуйста, что необходимо для того чтобы работала система 2хлопкового вкл выкл..
сам не программер..так что..)
обязателен ли комп включенный при этом? вообще можно ли ардуину как то скрыть от глаз допустим поместить в стену (проштробить и зашпоклевать)?
буду признателен+)
управление хлопком в ладоши (инфракрасным) ИК сигналом
Clap Switch, management claps infrared IR signal
Version 0.1 2013/06/12
Перед тем как начать управление хлопками, нужно ввести звуковой логин и звуковой пароль.
Для защиты от случайного срабатывания - посторонних шумов
1. Вводим звуковой логин в моем примере это три хлопка
Если логин введен правильно Загорается желтый светодиод у нас есть три секунды для ввода звукового пароля
2. Вводим звуковой пароль, в моем примере это два хлопка, если звуковой пароль введен правильно загорается зеленый светодиод, у нас есть пять секунд Для ввода звуковой команды
3. Например хлопаем два раза у нас включается второй pin на ардуино,
или отправляется (инфракрасный) ИК сигнал на телевизор включая второй телеканал.
Нужно заранее прописать в sketch, код кнопки пульта от вашего телевизора
У меня модуль микрофона на LM 393 при подключении выдаёт одни и те же значения, меняется максимум на единичку, если только чем нибудь по самому микрофону постучать, то значения меняются, а так хлопай, кричи и все одно и то же, в чем может быть проблема?