Считывание посылок от брелка сигнализации
- Войдите на сайт для отправки комментариев
Пт, 02/03/2012 - 08:06
Имеется код, просьба ГУРУ - подсказать где ошибка.
// (c) 2012 tahion #define rxd 3 // rx data pin #define rxe 4 // rx enable pin #define delta 100 // max time delta #define mintime 100 // min time pulse unsigned int time,oldtime,count,log0,log1; byte data[8]; void setup(){ pinMode(rxd,INPUT); pinMode(rxe,OUTPUT); digitalWrite(rxe,LOW); attachInterrupt(rxd,pinint,CHANGE); Serial.begin(115200); Serial.println("Starline 64 bit receiver started"); interrupts(); } void pinint(){ if(digitalRead(rxd)==HIGH)oldtime=micros(); else{ time=micros()-oldtime; if(time<mintime)return; if(constrain(time,log0-delta,log0+delta)==time)savebit(false); else if(constrain(time,log1-delta,log1+delta)==time)savebit(true); else{ log0=time/2; log1=time/4; count=0; } } } void savebit(boolean val){ for(int i=1;i<=8;i++){ data[i]=data[i]<<1; if(i<8)if(bitRead(data[i+1],7))bitSet(data[i],0); } if(val)bitSet(data[8],0); count++; if(count==64){ Serial.print("STARLINE "); for(int i=1;i<=8;i++)printhex(data[i]); Serial.println(""); } } void printhex(byte val){ if(val<=0x0F)Serial.print("0"); Serial.print(val,HEX); } void loop(){}
Имеется код, просьба ГУРУ - подсказать где ошибка.
А с чего вы взяли, что здесь ошибка?
Она себя как-то проявила?
Ну так расскажите обществу - какие симптомы наблюдаются.
Да дело тут вот в чем. Не я автор кода. Автор в шапке некий tahion. Устройство предназначено для анализа пакетов отправляемых брелками сигнализации. Вот ссылка на более подробную информацию
http://phreakerclub.com/forum/showthread.php?t=377&highlight=%D0%B0%D1%8...
Автор выкладывает код и говорит что прога рабочая но есть ошибка (сделанная специально), при этом ошибка оч простая и элементарная, нужно только прочесть мануал по программированию ардуины.
Я вот долго всматривался и разбирал код. По мне так он написан в безобразной стилистике, ну это простимо. Устройства у меня нет чтоб все проверить на деле, но с первого взгляда мне не понятно (исходя из мануала) следущее.
В "attachInterrupt(rxd,pinint,CHANGE);" где rxd задает номер прерывания присваевается номер 3, что соответствует как я понимаю 20 пину на "ардуиноМЕГА", в проекте используется не "мега", это раз. Второе что мне совсем не понятно - переменные объявлены как "unsigned", а исходя из мануала должны быть "volatile". Возможно я просто не вкуриваю. И если не в этом ошибка то в чем она еще может быть.
А, так это квест! ;)
Уже интересно... Бум посмотреть.
присваевается номер 3
=Слушаем поступающую информацию, используя внешнее прерывание INT1.
А есть образчик этой самой поступающей информации? Может там просто-напросто ширина импульса другая?
Ну да ))) можно и так сказать)) Я вот сам случайно наткнулся, уже второй день пытаюсь понять. Придется наверно мастерить само устройство чтоб наглядно видеть что происходит.
Ну да ))) можно и так сказать))
У девайсов с ATmega328 - это пин 3, у тех, что 1280/2560 - пин 20. Тут все по-честному
хмм значит не в этом проблема, а что с volatile. Хотя нет стоп. В мануале написано что если interupt в функции "attachInterrupt(interrupt, function, mode)" имеет номер 1 то соответственно прерывание будет по пину 3, но тут судя по коду, номер прерывания стоит 3 что соответствует 20 пину в меге. Или все же не так.
Не обязательно, возможно один из if-ов в ISR с подковыркой.
Тут можно действовать методом исключения. Например, сразу исключить из рассмотрения функцию printhex() - все, что в ней делается, это добавляется ведущий 0 для значений<16.
Следующий кандидат на исключение - savebit.
Но тут главное не слишком увлекаться и не выплеснуть в запале такую подлость, как timing:
может быть время обработки отдельного события настолько велико, что вновь поступающие события начинают накладываться на обрабатываемые? Неплохо было бы знать, как часто меняется состояние на входе и сравнить с временем отработки одного бита. Плюс время отработки одного байта.
Не думаю что все настолько сложно как мне написал автор цитирую
"здесь именно ошибка, а не загадка, просто тупо ошибка. элементарная. тупая. ошибка.
что бы ее исправить не нужно задавать вопросов. нужно всего-лишь прочитать мануал.
внимательно. прочитать. мануал. "
хмм значит не в этом проблема, а что с volatile. Хотя нет стоп. В мануале написано что если interupt в функции "attachInterrupt(interrupt, function, mode)" имеет номер 1 то соответственно прерывание будет по пину 3, но тут судя по коду, номер прерывания стоит 3 что соответствует 20 пину в меге. Или все же не так.
attachInterrupt - "плохая" функция. На ATMega328 она способна настраивать лишь 2 вектора прерывания из 25 (у 1280/2560 этих векторов побольше и векторов INTx - тоже). Вектор 3 на ATMega328 она не настроит, да и смысла в этом нет, поскольку сигнал приходит на третью ногу, а это - в терминах AVR - пин PD2, отвечающий за внешнее прерывание INT0.
Поэтому для чтения с пина 3 необходимо активировать обработчик прерывания с номером 1.
Вполне приличный кандидат для проверки на ловушки (их таки может быть чуть больше одной).
ЗЫ: ну да, похоже, действительно, не одна: нога 3 Arduino - это PD3 AVR. или внешнее прерывание INT1, имеющее номер 2. Стало быть:
attachInterrupt(2,pinint,CHANGE);
Или все же 1 (потому что INT1)? Тут надо с обоими вариантами поэкспериментировать или английский вариант описания функции читать, а не русский. Т.е. выяснить, задают для функции в первом параметре номер вектора прерывания (от 1 до 25) или номер внешнего прерывания (0, 1)
Ну, а тройка в любом случае (для UNO/Duemilanove/Nano/...) не подходит.
ЗЫ: почитал английское описание (мутно - тоже говорится о номере прерывания, без акцента на то, вектор прерывания это или номер внешнего прерывания), посмотрел примеры. После примеров ясно/понятно:
нога 2 - прерывание 0 (таки внешнее), соответственно
нога 3 - прерывание 1
Значит можно счтитать присвоение прерывания 3 по значению переменной rxd неверно, нужно соответственно заменить в строчке attachInterrupt(rxd,pinint,CHANGE); rxd на цифру 1. Так ведь.
Значит можно счтитать присвоение прерывания 3 по значению переменной rxd
константы
неверно, нужно соответственно заменить в строчке attachInterrupt(rxd,pinint,CHANGE); rxd на цифру 1. Так ведь.
Похоже, так.
Да, извиняюсь, константы. Ладно попробую опубликовать эту версию.
Он там писал что дальше будет загадка помощнее. Итак - наше предположение оказалось верным, программа работает но данные не выводятся, в чем может быть проблема?
Ну во первых, не совсем понятно какой-же мануал читать нужно. Вы уверены что именно на ардуину? Как минимум может подразумеватся "на приемник" и "на передачик", на протокол.
Во вторых, на совсем понятно зачем фнукцаия interrupts(); вызывается (сторка 15).
в мануале про нее написанно "Re-enables interrupts (after they've been disabled by noInterrupts()).", то есть разрешает прерывания ранее запрещенные с помощью noInterrupts(). А его мы выше не видим. Скорее всего "обыкновенная перестраховка" и ни на что это не влияет, но....
мммнда.... мыслители всё просто void Loop пустой нет цикла я вроде не спец но видно сразу
loop здесь не нужен, всё делает pinint()