внешние прерывания attiny13
- Войдите на сайт для отправки комментариев
Вс, 02/07/2017 - 18:27
есть вот такой код, работающий на ардуино-
#define rxPin 2 //пин приемника void setup() { pinMode(rxPin, INPUT); Serial.begin(115200); Serial.println("Came started"); attachInterrupt(0, grab, CHANGE); interrupts(); } volatile static long lastCode = 0; void loop() { if (lastCode > 0) { Serial.println(lastCode); lastCode = 0; } } #define MAX_DELTA 200 boolean CheckValue(unsigned int base, unsigned int value) { return ((value == base) || ((value > base) && ((value - base) < MAX_DELTA)) || ((value < base) && ((base - value) < MAX_DELTA))); } volatile unsigned long prevtime; volatile unsigned int lolen, hilen, state; volatile static byte cameCounter = 0; // count of bits stored volatile static long cameCode = 0; // code itself void grab() { state = digitalRead(rxPin); if (state == HIGH) lolen = micros() - prevtime; else hilen = micros() - prevtime; prevtime = micros(); if (state == LOW) { // последовательность закончилась if (CheckValue(320, hilen) && CheckValue(640, lolen)) // valid 1 { cameCode = (cameCode << 1) | 1; cameCounter++; } else if (CheckValue(640, hilen) && CheckValue(320, lolen)) // valid 0 { cameCode = (cameCode << 1) | 0; cameCounter++; } else cameCounter = 0; } else if (lolen > 1000 && (cameCounter == 24) { lastCode = cameCode & 0xfff; cameCounter = 0; cameCode = 0; } if (lastCode == 432) { time1=millis()-time; if(time1>200) digitalWrite(13, !digitalRead(13)); time = millis(); } }
работает нормально. он при нажатии кнопки на пульте зажигает светодиод и при повторном нажатии гасит. все как мне надо. теперь стоит задача засунуть его в attiny13. но похоже я напутал что то-
#include <avr/io.h> #include <avr/interrupt.h> #define MAX_DELTA 200 volatile unsigned long prevtime; volatile unsigned int lolen, hilen, state; volatile static byte cameCounter = 0; volatile static long cameCode = 0; volatile static long lastCode = 0; static unsigned long time = 0; static unsigned long time1 = 0; boolean CheckValue(unsigned int base, unsigned int value) { return ((value == base) || ((value > base) && ((value - base) < MAX_DELTA)) || ((value < base) && ((base - value) < MAX_DELTA))); } void InitINT0() { MCUCR =_BV(ISC01) | _BV(ISC00); GIMSK = _BV(INT0); sei(); } void setup() { DDRB |= (1 << PB1); //pinMode(1, OUTPUT); PORTB |= (1 << PB1); //digitalWrite(1,HIGH); PORTB |= (1 << PB0); //digitalWrite(0, HIGH); InitINT0(); } void loop() { } ISR(PCINT0_vect) // прерывание по вектору PCINT0(ножка РВ0), тоесть по изменению состояния вывода { if (PINB & (1 << PINB0) == HIGH) lolen = micros() - prevtime; else hilen = micros() - prevtime; prevtime = micros(); if (PINB & (1 << PINB0) == LOW) { if (CheckValue(320, hilen) && CheckValue(640, lolen)) // valid 1 { cameCode = (cameCode << 1) | 1; cameCounter++; } else if (CheckValue(640, hilen) && CheckValue(320, lolen)) // valid 0 { cameCode = (cameCode << 1) | 0; cameCounter++; } else cameCounter = 0; } else if (lolen > 1000 && (cameCounter == 24) ) { lastCode = cameCode & 0xfff; cameCounter = 0; cameCode = 0; } if (lastCode == 432) { time1=millis()-time; if(time1>200) digitalWrite(1, !PINB & (1 << PINB1)); time = millis(); } }
подскажите как вот тут-
избавиться от digitalWrite?
подскажите как вот тут- избавиться от digitalWrite?
Только у Attiny13a ножка PB5 она же ножка Reset. Чтобы её использовать как порт ввода-вывода, нужно во фьюзах отключить Reset. Но тогда вы не сможете прошивать тиньку ISP программатором.
спасибо. у меня получился вот такой код, работающий на ардуино-
и занимающий 1176 байт. что то он пожирел вместо уменьшения. я в комментариях написал что на что планирую заменить для attiny13. насколько это корректно?
добился 990 байт при частоте 600 кгц. подскажите должно ли работать?
нашел ошибки но не работает-
строка 20 задает прерывание по Росту!!!!!!
а тебе нужно по чейнджу, то есть так:
дальше не смотрел. читай даташит и все проверяй.
строка 20 задает прерывание по Росту!!!!!!
а тебе нужно по чейнджу, то есть так:
дальше не смотрел. читай даташит и все проверяй.
да у меня трудности как раз в паре мест. на PB0 у меня выход, а на PB1 вход.
значит-
верно же? и насколько корректна частота 600 кгц ? (если ставить выше - код не влезает)
верно же? и насколько корректна частота 600 кгц ? (если ставить выше - код не влезает)
твоя программа, тебе виднее. А бред про 600КГц я не коментирую, уж прости. Ты понимаешь какого размера micros() будет на 600КГц? Микрос будет считать с точностью 427 микросекунд. Гы! работать у тебя все это будет забавно.
верно же? и насколько корректна частота 600 кгц ? (если ставить выше - код не влезает)
твоя программа, тебе виднее. А бред про 600КГц я не коментирую, уж прости. Ты понимаешь какого размера micros() будет на 600КГц? Микрос будет считать с точностью 427 микросекунд. Гы! работать у тебя все это будет забавно.
пока она вообще никак не работает. какую частоту надо и как можно еще уменьшить размер кода?
Вот тебе, навскидку, оптимизация с выбрасыванием ненужных статиков и волатилей.
Еще поменял. 1018 - все у тебя помещается.
ваш код работает на ардуино а на тини13 нет. частоту установил в 9,6 мгц. сейчас хаотично мигает светодиод
1. Это не мой код, это твой код, немноого причесан.
2. Чушь. смотри на свою схему, где-то накосячил. Уж хаотичного мигания точно не можетт быть. Читай свой код и схему.
хотя я за тобой не проверил, чорт возми! INT0 на PB1!!!!!
=========================================
5-я нога - диод, 6-ая нога вход от приемника!
==========================================
тогда диод цепляешь к PB0 код меняешь на такой: (9600 - это ты правильно угадал ;) )
хаотичное мигание пропало но и не работает
раз уж я ввязался - пиши что ты делаешь подробно, а то что ты за коды и откуда берешь - нихера не понятно.
Схему, описание и что хочешь получить. ОК?
Посмотрю, если будет время. Откуда у тебя эти значения для 0 и 1? Что означает "на ардуино работает"? - на какой? - при какой схеме? - короче пиши все подробно, форум терпит, а я завтра посмотрю.
Все.... чакры промыл, пора спать....
начало тут http://arduino.ru/forum/programmirovanie/prochitat-kod-pulta-arduino
схема из ардуино нано, трех проводков и приемника 433,92 мгц выглядит так-
в ней записан этот код-
да тут ничего, кроме неточного времени, быть не может, если на нанке работает.
1. Убедись, что ты программируешь для тиньки на максимальной частоте 9.6 МГц.
2. напиши чистый скетч, используя микрос, чтобы мигать диодом каждые 30 сек и проверь с секундомером.
вот так:
3. по результатам откорректируй свои константы длительности низкого и высокого уровней. Думаю - заработает.
если не получится - ничего страшного! что-нить придумаем.
4. ты не разместил фотографию с тинькой. Ты уверен, что не накосячил с пайкой там?
скетч что то не мигает. даже в протеусе
на тинни мигает с частотой 1 раз в 30 сек
Я настаиваю на том, чтобы не использовать при общении со мной ссылки на тестирование в Протеусе. и даже наименовние не использовать.
Только нормальное железо.
=============================
Этот скетч был ТОЛЬКО для тиньки!
Проверь на точность 30 сек. с секундомером, в каждой мобиле есть секундомер.
понял.
в железе на тинни13 мигает с вашим скетчем 1 раз в 30 сек.
еще раз записал код-
частота 9,6 мгц. фотография-
не работает
а вариант для нано работает? так?
Буду думать... прости, может ты на форуме новый чел, но я много пью... поэтому ничего не обещаю... может стоит вообще весь алгоритм приема перелопатить.
по таймингам из другой темы посчитай ТОЧНО среднее для хай и лоу. Я, все-таки, полагаю, что нужно поменять константы в твоем алгоритме.... для нанки с 16 МГц прокатывает, а для тиньки с 9.6Мгц - уже грубо получается.... попробуй подобрать:. сделай 600 и 300 для начала.
Вообще, пока я думать буду, поиграй с константами. Возможно все само решится.
для нано работает как часы- с первого нажатия. попробую уменьшить константы. попробую ваш код записать в нано и тинни и сравню мигания
записал и получил одинаковый результат. но убрав по одному нулю получил что нано стала мигать чаще тини...
вместо 1000-100 и вместо 30000-3000
примерно в 2 раза чаще мигает нано
ну попробуй на тиньке 300 тысяч раз по 100 мкс. Посмотри, что выйдет.
ну попробуй на тиньке 300 тысяч раз по 100 мкс. Посмотри, что выйдет.
не совсем понял
ну попробуй на тиньке 300 тысяч раз по 100 мкс. Посмотри, что выйдет.
не совсем понял
1 минута
1 минута
это время горения?
тогда давай пробовать характерные времена твоего протокола:
100000 раз по 300 мкс и 50000 раз по 600 мкс.
и кинь ссылку на то ядро тиньки 13, которое ты используешь. Их много в сети. Я погляжу.
1 минута
это время горения?
тогда давай пробовать характерные времена твоего протокола:
100000 раз по 300 мкс и 50000 раз по 600 мкс.
и кинь ссылку на то ядро тиньки 13, которое ты используешь. Их много в сети. Я погляжу.
горит минуту, потом не горит минуту. ядро скачал и переустановил отсюда последнее https://sourceforge.net/projects/ard-core13/files/
ладно. снова давай до завтра, и скажи, что вышло с 300 и 100000, и с 600 и 50000? Потому, как не может на нанке работать, а на тиньке нет!
На тиньке 9600 точность микрос - 27 мкс, много, но не страшно. Если что-то упирается в это - будем думать.
Да! если я втянулся, то давай код передатчика, чтобы посмотреть.
Если с утра "здоров" буду, то до мастерской добреду... с Б..жей помощью.
Чет меня заело, почему у тебя на нанке работает, а на тиньке нет.
И код тебе, ессно, нужно перелопатить, тат как не дело на сраный приемник весь килобайт расходовать.
....ладно - все умное - на завтра. бай.
cameCode == 432
и почему тогда if (cameCode == 1234) для тиньки
я игрался в библиотеке RCSwitch длиной импульса 300->310->320->330->340, прием стабильный
300-100000 - 28 сек
600-50000 - 28 сек
кода передатчика у меня нет- это же не мое устройство. но имитатор выглядит так-
cameCode == 432
и почему тогда if (cameCode == 1234) для тиньки
я игрался в библиотеке RCSwitch длиной импульса 300->310->320->330->340, прием стабильный
да я эмулятором посылаю что бы за пультом не бегать туда сюда и отправляю 1234
что-то ты темнишь. в прошлой теме ты показуешь устройство. снимаешь с него осциллограмы, логическический анализ, сам выкладываешь скетч, который имитирует работу пульта. дальше расказываешь, что хочешь в одном экземплиаре сделать девайс. а так как 328 жирная для проэкта, использую тиньку. для пятидневного головогемороя разница в цене 1$ для единичного экземплиара. габариты я не учитываю, коммутация лампы все равно требует стационарной установки - место можно легко найти в подрозетнике....
зачем в начале темы давать один код, потом другой. что подразумевается под словом эмулятор.?
или я что-то не пойму. как ты отправляешь 1234 - покажи..
смысл не в 1$, не в размере и даже не в функциональности устройства а в программировании микроконтроллера. я на практике изучаю. эмулятор это та штука с предыдущей темы которой я проверял работоспособность кода открывания. что бы ключи с пультом не таскать на стол и не забывать их на нем.
и есть рациональность- смысл в 328 меге если используется всего 2 пина? в конце концов никто же не кипятит 100 литров воды что бы выпить кружку чая
значит ты изменил старый бинарный код на новый с учетом инверсии в строке
и как он выглядит
значит ты изменил старый бинарный код на новый с учетом инверсии в строке
и как он выглядит
Я написал sendcame(1234);
1234 -10011010010 твой последний 0 программа воспринимает как начало задержки
про обработку этой строки явообще молчу
1234 -10011010010 твой последний 0 программа воспринимает как начало задержки
про обработку этой строки явообще молчу
что то не пойму - дело сейчас в пульте а не в тини? Странно но ведь я проверял - писал sendcame(432); и в порт приходило 432
сейчас все перепроверил-
вот этот код выбрасывает именно 432 и никак иначе. а так - SendCame(1234); выбрасывается именно 1234
я проверял пульт на меге 328
код передатчика
и код приемника на меге 328 из этого сообщения
с дописаным выводом в монитор значением , получилось 432
просто верни старые значения кода .....которые в конце прошлой темы и в начале этой
Вы не поверите но на 328 меге и у меня работают оба пульта (естественно меняю условия ). На Тини работать не хочет ни один пульт. Кстати попробую записать в Тини код передатчика. Интересно что получится
там кнопка на 7pin ардуины или 13 нога контроллера повешена , притянута к + через 10к и замыкает на землю
нажата - код идет, отпущена - вечный
анализатором Logic 1.2.10 паказавает практически тоже из Вашего сообщения
+ - 50 милисекунд
анализатором Logic 1.2.10 паказавает практически тоже из Вашего сообщения
+ - 50 милисекунд
а у вас тини13 нет случайно? Может у вас заработает?
нет у меня тиньки я вообще железячник. когда-то паял спектрумы. там нужно было знание Алгебры Буля и пару кодов ассемблера
и мои познания далеко не ушли
я думаю, может не стоит оперировать с & 0xfff, мне не ясно, куда денется старшая единичка после сложения. может кто подскажет...? просто получается
так как на выходе и я и ты получили 432
День добрый, твой приемник работает, просто немного внимательности нужно было. биты портов мы с тобой путали.
1. Видео, как оно работает.
2. скетч для тиньки.
3. код для передатчика на леонарде. это твой код, я не вмешивался, думая, что ты адекватно воспроизвел свой пульт.
Добрый вечер. это работает. спасибо. а что же у нас неправильно было? я заметил вы добавили пару констант?
Не ломай голову. Разберешься -хорошо, нет так нет. Это же не твоя профессия.
разобраться я дожен- в этом и есть основной смысл. и код как то сильно похудел.
Это потому, что я микрос и миллис заменил на внешнюю переменную - счетчик циклов таймера ovrf. Поэтому линкер выкинул математику - умножение и деление.
Стало понятнее? Я с телефона из машины. Неудобно. Позже или завтра. Ты все вопросы собери в кучу. Я отвечу.
Ну что? Утро красит нежным светом...? ;) Всем бобра!
Отвечаю:
1. F_CPU это константа, задаваемая компилятору. Нет, к фьюзам не имеет прямого отношения. И фьюзы и эта константа задаются средой.
2. 256000000 это 256 миллионов ;), цикл таймера - 256 циклов тактовой частоты процессора. "tous" читается как "в микросекунды" = сколько микросекунд в единице ovrf. по простому это 256тактов / 9.6МГц = 27 мкс. "toms" - в миллисекунды и равна 37 тикам на миллисекунду.
3. ovrf - это счетчик полных оборотов таймера конкретно и только в тиньке! Подробности смотри в файле wiring.c в своем ядре.
-----
микрос и миллис используют ovrf * 27 для микрос и ovrf / 37 для миллис. Отсюда нужда в длинной математике.
Я не использовал в программе делений и умножений, только НА ЭТАПЕ КОМПИЛЯЦИИ, для числовых констант, то есть в программе нет нужды добавлять функции для умножения и деления, вот код и похудел.
я перейду потом к другому компу, если не лень будет, и покажу тебе ассемблер твоего кода.