IR sensor к Arduino
- Войдите на сайт для отправки комментариев
Вс, 19/05/2013 - 12:35
int irPin = 4; //Sensor pin 1 wired to Arduino's pin D4 int start_bit = 4500; //Start bit threshold (Microseconds) int bin_1 = 1600; //Binary 1 threshold (Microseconds) int bin_0 = 560; //Binary 0 threshold (Microseconds) void setup() { pinMode(irPin, INPUT); Serial.begin(9600); Serial.println("IR/Serial Initialized: "); } void loop() { int key = getIRKey(); //Fetch the key Serial.println( key ); } int getIRKey() { int data[33]; int i; while(pulseIn(irPin, LOW) < start_bit); //Wait for a start bit for(i = 0 ; i < 32 ; i++) data[i] = pulseIn(irPin, HIGH); //Start measuring bits, I only want low pulses for(i = 0 ; i < 32 ; i++) { //Parse them //Serial.println( data[i] ); // debug if(data[i] > bin_1) //is it a 1? data[i] = 1; else if(data[i] > bin_0) //is it a 0? data[i] = 0; //else //return -1; //Flag the data as invalid; I don't know what it is! Return -1 on invalid data } int result = 0; for(i = 0 ; i < 32 ; i++) //Convert data bits to integer if(data[i] == 1) result |= (1<<i); return result; //Return key number }
Задача такая: Нужно получать команды с пульта ДУ. Пульт компании NEC.
Да, я знаю существую библиотеки например IRremote, но дело приобретает другой характер, цель программы перенести на Attiny85 - которая с этой библиотекой выдает кучу ошибок. Ниже код который без проблем выполняется на Attiny85, но вот декодирование не правильное. В интернете нашел протокол расшифровки сигнала NEC пультов(http://www.sbprojects.com/knowledge/ir/nec.php) но никак не могу разобраться..
Нашел старенький неудаленный скейтч, в котором делал так:
Так же рекомендую отказаться от pulseIn() и перейти на прерывание и micros(). Да и еще вспомнил у этого пульта была приамбула 8 нулей, 8 единиц а только потом 16 бит данных.
как я понял это у вас отправка через МК, а мне получать надо..
Вы плохо поняли. А еще раз и на всегда запомните - все выводы МК по умолчанию настроены на вход (с дуинами есть исключения).
maksim, извиняюсь, уже все в голове перемешалось, уже сутки как не сплю, наверно мне поспать нажно пойти..
На вашем месте я бы сделал как-то так:
спасибо maksim за код, что то как то работает, но какие то большущие задержки в реагировании... буду дальше голову ломать над своим кодом.. если изменить
это протокол Sony (http://www.sbprojects.com/knowledge/ir/sirc.php) - то мой код куда быстрее на кнопки пульта реагирует..
maksim, ваш последний код вообще не срабатывает....
А должен? ... как-то так ... это означает что вот вам пример как реализовать прием на прерываниях, вы ведь даже не знаете какие на самом деле интервалы времени у вашего пульта и не знает длинну пакета.
пакет найти то я нашел..
619212
8960
4468
588
264
868
256
868
264
820
256
880
864
832
876
268
852
564
165
224
272
538
852
902
610
39796
8980
2236
596
276
412
428
252
420
вот он от 4468 до 39796, и написан фильтрацию чтобы я только работал именно с этим диаппазоном. вот что у меня получилось
но никак понять не могу, хочу сделать вывод переменной i - он выводит бред!!! до 22 норм ально нумерует а потом 25, 28 и далее хаотично. пробовал переменную i засунуть в ОЗУ (volatile) - такой же результат...............
Вы инициализировали последовательный порт со скоростью 9600 бит/с - то есть около 1000 символов/сек.
если состояние отслеживаемого сигнала меняется со скоростью не более 1000 фронтов в секунду, то вы будете более-менее успевать пропихивать всю генерируемую информацию через com-порт, да и то при условии, что при каждом вызове Serial.print отправляется один символ.
А если фронтов больше, чем 1000 в секунду?
А если отправляется чуть больше одного символа (например Serial.println() отправит как минимум три символа - собственно символ и еще байты CR и LF)?
И в том и в другом случае постепенно буфер COM-порта переполнится и начнутся пропуски в передаче. И вы получите то, что получили.
Так что попробуйте поднять скорость передачи - ну хотя бы до 19200.
step962, спасибо за подробные разьяснения, поднял до 57600 чтобы наверняка и правда ведь, а я совсем что то на это внимания и не обратил..
скетч написал, на самой ардуине отлично работает!!!!!!!! теперь буду переносить на Attiny85, вчера правда перенес но понял что с 8Mhz - не катит, не все данные в порт выводит хоть даже и со скоростью 115200, буду добавлять кварцевый резонатор в схему на 16 или 20 Mhz, как все сделаю отпишусь с примерами...
Итак...
Скетч написал, как и обещал размещаю... Работает он отлично только с дополнительным кварцевым резонатором на 20Mhz, т.к. 8Mhz встроенный - выводил каждый раз новые результаты, по всей видимости не успевал принимать столь крутейший поток данных. Опять хочу сказать, в этом деле я не профи и вообще я только месяца 3 с ардуино в руках, вообще в целом электроника это как хобби у меня, в детстве игрался и вот сейчас решил поиграться после 12 лет спустя...
для подключния квацевого вот схема:
С1 и С2 = 22pF. Оказывается без них о вообще ведет себя как хочет.. XTAL2 - PB3(2 ножка), XTAL1 - PB4(3 ножка)
н и сам скетч, вставляю самую последнюю свою рабочую версию
SoftwareSerial - оставил чтобы кто-нибудь не тратил время на писалки, раскомментировал и продебаггил.
Еще хотелось бы всем сказать спасибо кто принял участие в этой теме - без вас я бы сидел и дальше собирал, особенно maksim'у!!!
Хорошая темка. У меня пара вопросов. Первый к автору. Какой размер скетча получается для тиньки и SoftwareSerial поделешься?
P.S. Все тиньку по умолчанию прошиты на максимальные 8 МГц от внутреннего кварца и при этом его работа действительно получается нестабильной. Можно уменьшить до 4 или даже 1 если этого достаточно, но на 4МГц тоже бывает подлагивает. При установке внешнего на 20 МГЦ резко снижается диапазон рабочих напряжений о чём говорится и в даташите и МК становится ужасно капризный. Ставил на машину, тинька жила своей жизнью. Правда простейший фильтр (диод и ёмкость) решил проблему, но я решил не рисковать и остановился на 12 МГц истессно от внешнего кварца. Проблем не было больше.
Ещё есть такой вопрос:
Есть ИК-приёмник, пульт ДУ, МК, светодиод. Через дуинку посылаю в порт код кнопки пульта, затем этот код вписываю в скетчь, нажимаю кнопку пульта - диод включается, нажимаю ещё раз - выключается. Всё великолепно. Вопрос такой - как сделать чтоб можно было обучить контроллер не зная кода кнопок пульта, чтоб МК читал код и вносил его в память и в последствии реагировал на этод код. Желательно чтоб при снятии питания с МК не нужно было его переобучать.
Разглядывал скетч, посылающий код в порт, не могу в свой скетч применить.
Вот скетч для имеющегося кода :
Я лишнее выкинул за ненадобностью, понять как с диодом работает, а дальше я сам.
SoftwareSerial я использовал стандартный который идет вместе в библиотеке к Attiny85 (http://code.google.com/p/arduino-tiny/downloads/list)
The following Arduino commands should be supported:
pinMode()
digitalWrite()
digitalRead()
analogRead()
analogWrite()
shiftOut()
pulseIn()
millis()
micros()
delay()
delayMicroseconds()
SoftwareSerial (has been updated in Arduino 1.0)
"Все тиньку по умолчанию прошиты на максимальные 8 МГц" - мне изначально пришли все 10 штук на 1Mhz.. Определил по стандартному скетчу Blink - светодиод мигал на других частотах очень долго мигал, а на 1Mhz нормально.
По поводу уменьшений я не знаю, но на 1Mhz - SoftwareSerial точно не работает! пишет надо минимум 8Mhz.
На 12Mhz я не пробовал, у меня библиотеки только на 1Mhz, 8Mhz и 20Mhz - с фьюзами у меня нет опыта пока еще.. так что не рискую ))
А IRremote.h - у меня почему не работает, там куча ошибок вылазит, поэтому и решил писать свою, благо maksim в этом очень помог! А с диодом аналогичная работа, вы должны не код передавать а именно формат протокола пульта, т.е. импульсы. Чтобы их увидеть, надо расскоментировать //comand = time; в 38 строке моего последнего кода и ты увидишь их через SoftwareSerial при приеме с пульта. первое число не обращай внимания, должно начаться с 9000, затем 4000 и далее до >3000 идут как раз данные, но тебе надо все передавать (кроме первого показания как уже сказал). смотри вобщем протокол (http://www.sbprojects.com/knowledge/ir/nec.php)
есть такой младший бит CKDIV8. Я не помню чтоб на тиньке его устанавливал (активировал) но когда считал из контроллера, был нолик. Он делит тактовую частоту на 8, т.е. МК работает на 8 Мгц, а фактически получается что 1. есть вероятность что CKDIV8 по умолчанию тоже активен.
CKDIV8 насколько я понял когда читал форумы про AtTiny85 - это когда вы програмно меняете частоту, а не изначальную делаете фьюзами через "Записать загрузчик"
Плохо читали это именно фьюз-бит, предназначен для деления на 8 тактовой частоты. По умолчанию включен.