Будет ли работать IRRemote со включенным Fast PWM на Atmega328?

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

subj.

Не трогаю таймер T0, т. к. мне нужно millis()

Трогаю таймеры T1, T2 - т. к. мне плевать на servo(), tone() (я ими не пользуюсь). Но в системных требованиях IRRemote написано что она использует на m328 таймер T2, моя усматривать в этом некоторое противоречие.

Нужно три PWM на 7.8 кГц и управление с ПДУ.

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Вообще мне бы хорошо писок системных требований по библиотекам, перечисленным на playground, как можно собрать такую информацию? Я тогда сделаю удобную панель для новичков с чекбоксами, чтобы можно было выбирать библиотеки и там красным/зелёным подсвечивалась совместимость. Если честно, этот бесячий знатоков вопрос возникает регулярно.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Voodoo Doll пишет:

subj.

Не трогаю таймер T0, т. к. мне нужно millis()

Трогаю таймеры T1, T2 - т. к. мне плевать на servo(), tone() (я ими не пользуюсь). Но в системных требованиях IRRemote написано что она использует на m328 таймер T2, моя усматривать в этом некоторое противоречие.

Нужно три PWM на 7.8 кГц и управление с ПДУ.

Да, IRRemote использует Timer2 и система декодирования работает при условии, что прерывание TIMER2_COMPA_vect срабатывает каждые 50микросекунд (20KHz). В качестве решения проблемы совместимости в лоб могу преложить взять еще одну нану\мини и использовать ее как приемник ИК, а декодированные команды передавать в основную ардуину, например, через компорт.

Logik
Онлайн
Зарегистрирован: 05.08.2014

А в качестве решения не в лоб - пишем сами обработчик прерывания для декодирования ИК (можно подсматривать в код библиотеки ;) в котором период вызова задаем некоторой константой. И вешаем его на имеющееся прерывание, например  "PWM на 7.8 кГц". Задаем константу как 1/7800=0,128мс и наслаждаемся жизнью. 

ПС. Игра случая не исповедима, посмотрел свой код для ИК приема, а там как раз

byte IK_REMOVE_CONTROL::Process(word t)

{
  byte InpPin;

     
  if(IK_Status != IK_STATUS_FINISH)
  {
    t =t &  0xff80;   //с дискретность 128мкс обрабатываем ввод с ИК датчика

Так что, проверено на периоде 128мкс. Причем это вызываю не с прерывания, а с почти пустого лупа , t - время с микроса.

-NMi-
Offline
Зарегистрирован: 20.08.2018

Logik пишет:

пишем сами обработчик прерывания  и наслаждаемся жизнью. 

Это самое классное сообщение, которое я прочитал в этом году. Смею добавить к нему ещё -> и ниукого ничего не просим!!!

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

А в качестве решения не в лоб - пишем сами обработчик прерывания для декодирования ИК (можно подсматривать в код библиотеки ;) в котором период вызова задаем некоторой константой.

Если делать единичный проект, то при стоимости ардуины микро на atmega168 в 100р дешевле будет ее подключить и не заморачиваться с переписыванием обработчика. Особенно если учесть что используемый в библиотеке метод постоянного опроса ИК приемника жрет дофига рессуров. И ладно бы в момент приема/декодирования, так нет, постоянно.

-NMi-
Offline
Зарегистрирован: 20.08.2018

asam пишет:

Особенно если учесть что используемый в библиотеке метод постоянного опроса ИК приемника жрет дофига рессуров. И ладно бы в момент приема/декодирования, так нет, постоянно.

Это просто лох какой-то пейсанул библу такую кривую. Давай расскажу способ проще и не такой прожорливый: берёшь первый таймер в любом виде, берёшь INTx (не PCINT!) и по изменению фронтов считаешь длительность пачек. Весь фикус в том, что нет ИК-посылки - проц не напрягаеццо... ну и так далее...            )))))))))))))

Проверено лет 6 назад.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

-NMi- пишет:

Это просто лох какой-то пейсанул библу такую кривую. Давай расскажу способ проще и не такой прожорливый: берёшь первый таймер в любом виде, берёшь INTx (не PCINT!) и по изменению фронтов считаешь длительность пачек. Весь фикус в том, что нет ИК-посылки - проц не напрягаеццо... ну и так далее...            ))))))))))))

Так оцифровать сигнал с ИК датчика это элементарно. И даже библиотека работающая по прерываниям есть - IRRemoteControl

Главное потом декодировать. И вот в этом лучше всех как раз IRremote. Можно, конечно, ее переделать на работы по прерываниям от датчика, но лень.

Logik
Онлайн
Зарегистрирован: 05.08.2014

Не надо переделывать её на прерывания от датчика! Датчик может стока шума выдать, что положит прогу в обработку прерываний навечно. Дело в том что в ИК обмене модулируют излучение на 30-40КГц. И в разных пультах свое, где 30, а где и 40. И вот если чужой пульт засветит, да еще и при неудачных стечениях обстоятельств (уровень излучения, засветка, помехи и т.д.) то на выходе своего приемника получите частые смены уровней что даст загрузку прерываниями по полной с печальным для проги финалом. Лучше уж пусть отъедает пол проца стабильно, чем временами весь проц. А отжераемый % процессорного времени можно улучшить опрашивая реже 50мксек, у меня 128 вполне работает. Хотя наверно от подробностей ИК протокола зависит, их до чертиков, этих протоколов, может кому токо 50мксек нужно.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

LOGIK!  взял на заметку, но как еще одно решение вопроса 328PB или WAVGAT (таймер3) , но там (PB) с потерей сериала0, но есть сериал1, в WAVGAT не помню, надо смотреть )))

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

Не надо переделывать её на прерывания от датчика! Датчик может стока шума выдать, что положит прогу в обработку прерываний навечно. Дело в том что в ИК обмене модулируют излучение на 30-40КГц. И в разных пультах свое, где 30, а где и 40. И вот если чужой пульт засветит, да еще и при неудачных стечениях обстоятельств (уровень излучения, засветка, помехи и т.д.) то на выходе своего приемника получите частые смены уровней что даст загрузку прерываниями по полной с печальным для проги финалом. Лучше уж пусть отъедает пол проца стабильно, чем временами весь проц.

Да какой там весь проц? 30-40КГц это частота модуляции, а ИК приемник выдает демодулированный сигнал, а там частоты в районе 500Гц всего. Если обработчик прерываний сделан правильно, то пусть даже если от двух пультов мы получим 1Кгц прерываний то это займет меньше 1% CPU 

Logik
Онлайн
Зарегистрирован: 05.08.2014

Еще раз. Теперь внимательно. Если на приемник приходит сигнал, модулированый не той частотой  на которую он рассчитан то проблема. Их селективность не достаточна чтоб вообще не принимать такой сигнал, а различия частот приводят к коротким и частым импульсам.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

Еще раз. Теперь внимательно. Если на приемник приходит сигнал, модулированый не той частотой  на которую он рассчитан то проблема. Их селективность не достаточна чтоб вообще не принимать такой сигнал, а различия частот приводят к коротким и частым импульсам.

С какой частотой конкретно? Наблюдал лично на скопе или програмно?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Кстати замерял, тут, сколько конкретно жрет библиотека IRreceiver на атмеге328 получилось около 30% процессорного времени.

Logik
Онлайн
Зарегистрирован: 05.08.2014

asam пишет:

Logik пишет:

Еще раз. Теперь внимательно. Если на приемник приходит сигнал, модулированый не той частотой  на которую он рассчитан то проблема. Их селективность не достаточна чтоб вообще не принимать такой сигнал, а различия частот приводят к коротким и частым импульсам.

С какой частотой конкретно? Наблюдал лично на скопе или програмно?

Наблюдал програмно. Проявляется очень неприятно, как подвисания и глюки иногда при пользовании посторонних пультов. Разбор показывает что скорость выполнения лупа при этом резко снижается. Пришлось переписывать все на прерывания по таймеру.

Logik
Онлайн
Зарегистрирован: 05.08.2014

asam пишет:
Кстати замерял, тут, сколько конкретно жрет библиотека IRreceiver на атмеге328 получилось около 30% процессорного времени.

Да. Что-то типа такого. Даже простое прерывание занимает порядка 10мксек обработки т.е. при вызове каждые 50 имеем 20%. А при вызове каждые 128 всего 8%, что уже не проблема. Столб нельзя перепрыгнуть, но можно обойти )))

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:
Наблюдал програмно. Проявляется очень неприятно, как подвисания и глюки иногда при пользовании посторонних пультов. Разбор показывает что скорость выполнения лупа при этом резко снижается. Пришлось переписывать все на прерывания по таймеру.

Все же, мне, как-то, сильно сомнительно, что там получится что-нибудь существенно выще 20КГц, ну а глюки не показатель. Не намекаю на ваш случай, но доводидлось мне наблюдать, как система с гораздо более мощным процессором ложилась от прерываний в районе единиц килогерц из-за криво написанного драйвера.

Посмотрю дома на скопе что там датчик выдает если на него несколькими пультами светить.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

По какой методе CPU Load вычисляете, если не секрет?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

Еще раз. Теперь внимательно. Если на приемник приходит сигнал, модулированый не той частотой  на которую он рассчитан то проблема. Их селективность не достаточна чтоб вообще не принимать такой сигнал, а различия частот приводят к коротким и частым импульсам.

Посмотрел осциллографом что дает на выходе ИК приемник если светить на него 2мя или даже 3-мя пультами. Перепробовал все пульты, что есть дома - 9 штук. Никакого особенного криминала не заметил, да иногда проскакивают импульсы порядка 100uS. Но этого явно недостаточно чтобы поломать систему. В основном картина типа такой.

Один пульт -

 

2 пульта

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

sadman41 пишет:

По какой методе CPU Load вычисляете, если не секрет?

Да по простейшей. Запускаю  математические вычисления (операции с float) и засекаю время. Потом добавляю IRremote и засекаю время вычислений опять. Во время вычислений к каким либо функциям IRremote не обращаюсь, пультом не свечу. Засекаю с помощью миллис, время вычислений порядка секунды. По разнице определяю сколько отъел IRremote.

 

Logik
Онлайн
Зарегистрирован: 05.08.2014

asam пишет:

 Никакого особенного криминала не заметил, да иногда проскакивают импульсы порядка 100uS. Но этого явно недостаточно чтобы поломать систему. 

Ну вот это и есть проблема. Одиночный конечно не поломает, если проскакивают иногда, а иногда идут пачками, я  ж писал

"И вот если чужой пульт засветит, да еще и при неудачных стечениях обстоятельств (уровень излучения, засветка, помехи и т.д.) то на выходе своего приемника получите частые смены уровней что даст загрузку прерываниями"

Вот когда пачка, таких как Вы поймали одиночный, приходит - тогда и имеем.

Я удивлен что вам удалось его засечь осцилом. У меня оно воспроизводилось очень не часто, зато очень ярко. Возможно одиночные конечно и чаще бегали, но не проявлялись в сбоях. 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

asam пишет:

 Никакого особенного криминала не заметил, да иногда проскакивают импульсы порядка 100uS. Но этого явно недостаточно чтобы поломать систему. 

Ну вот это и есть проблема. Одиночный конечно не поломает, если проскакивают иногда, а иногда идут пачками, я  ж писал

"И вот если чужой пульт засветит, да еще и при неудачных стечениях обстоятельств (уровень излучения, засветка, помехи и т.д.) то на выходе своего приемника получите частые смены уровней что даст загрузку прерываниями"

Ну не знаю, пачек добиться не удалось, только одиночные и то редко

Да даже и пачка из 100 микросекундных импульсов процессор загрузит не больше чем IRremote у которой прерывания каждые 50 микросекунд.

Logik
Онлайн
Зарегистрирован: 05.08.2014

sadman41 пишет:

По какой методе CPU Load вычисляете, если не секрет?

Обычно в луп добавляю типа Cnt++ на каждом проходе. И изредка, например раз за секунду вывожу его и обнуляю. Так вижу среднее кол-во проходов лупа за секунду.

Иногда этого мало, тогда по серезному, гисторграмму строю.

#define SIZE_HISTOGRAMM_LOOP 16
word HistogrammaLoopTime[SIZE_HISTOGRAMM_LOOP]; //последний элемент - максимальная длительность

/* Формируем новое системное время для текущего цикла, 
   собираем статистику загрузки, 
   определяем короткий цикл для запуска */
boolean GetNewTime(word* Timer)
{
  word T=millis();
  word i=T-*Timer;
  {
   if(i>SIZE_HISTOGRAMM_LOOP-2) i=SIZE_HISTOGRAMM_LOOP-2; 
   HistogrammaLoopTime[i]++;
   if(i>HistogrammaLoopTime[SIZE_HISTOGRAMM_LOOP-1])
      HistogrammaLoopTime[SIZE_HISTOGRAMM_LOOP-1]=i;
   if(!HistogrammaLoopTime[i])
   {
     memset(HistogrammaLoopTime, 0, SIZE_HISTOGRAMM_LOOP*2);
   }
  }
  *Timer=T;
  return i==0;
}

И вижу, сколько циклов за сколько времени проходит.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Про скорость выполнения лупа я понял, не понял как из этого вычисляется загрузка в %. Процент вычисляется относительно чего?

Просто я привык, что для CPU Load % есть противоположная величина - Idle %. А тут CPU в idle не находится по определению - всегда какую-то херню мотает.

Logik
Онлайн
Зарегистрирован: 05.08.2014

asam пишет:

Да даже и пачка из 100 микросекундных импульсов процессор загрузит не больше чем IRremote у которой прерывания каждые 50 микросекунд.

Так а кто ж сказал что они все и всегда стабильно по 100мксек? Если аппаратно такая гадость в принципе появляется то жди беды.

Logik
Онлайн
Зарегистрирован: 05.08.2014

sadman41 пишет:

Про скорость выполнения лупа я понял, не понял как из этого вычисляется загрузка в %. Процент вычисляется относительно чего?

Просто я привык, что для CPU Load % есть противоположная величина - Idle %. А тут CPU в idle не находится по определению - всегда какую-то херню мотает.

Ну в контексте данного вопроса CPU Load % - это доля времени на прерывания от общего процессорного времени. Если из 100мсек в обработчиках прерывания висели 20мсек - то и говорим 20%. При этом луп за 100мсек посчитал (или просто прокрутился, не важно) столько же, сколько считает за 80мсек при запрещенных прерываниях.

Часто важен не сам % а максимальное время прохождения лупа, иногда 2-3 циклов подряд,  иногда важно среднее время. От задачи вобщем.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ага. Т.е. в идеале, по вашей методике, надо "от пустого лупа" считать. Пустой - 100% Idle, потом, при наращивании функционала, вычисляется падение Idle, и затем 100-Idle=Load.

Logik
Онлайн
Зарегистрирован: 05.08.2014

неее.. идла у нас нет вообще, вы же сами это заметили. И пустой луп тоже не бывает, даже если на каком проходе в лупе ничего не делается, то надо ж проверить, что именно сейчас ничего не делаем, а это уже не пусто)) Чисто академический интерес может конечно представлять накопление времени лупов в которых чтото делали. Накапливаем за некий интервал измерения. Потом делим это время на длительность интервала измерения. И вуаля -  CPU Load % , но без учета прерываний. Их тоже можно померить, хотяб по методике как выше и учесть. Но практической пользы от такого % я думаю не будет.

Logik
Онлайн
Зарегистрирован: 05.08.2014

Из интереса решил попробовать (всякую херню я делал, а вот такой  - еще нет )))) . Взял рабочий, достаточно сложный скетч - счетчик гейгера с програмной реализацией формирования высокого напряжения, прерывания от пина, от таймера, экран, сириал... И решил обмерить. В конец лупа дописал следующее (благо ретурнов в нем нет)

    static long TimeLoad;
  if(FlLoad)
  {
    
    TimeLoad+=word(micros()-t);
    FlLoad=false;
  }

    static long T1;
  if(TT-T1>1000)
  {
    Serial.print("TimeLoad =");
    Serial.println(TimeLoad);
    TimeLoad = 0;
    T1+=1000;
  }

ТТ - значение миллиса, там выше уже было при вхождении в луп получено, t - значение микроса при вхождении в луп. Везде где в лупе шото делалось добавил FlLoad=true. Получил вывод типа



12:19:41.821 -> TimeLoad =120588
12:19:42.834 -> TimeLoad =120828
12:19:43.810 -> TimeLoad =120612
12:19:44.818 -> TimeLoad =121164
12:19:45.829 -> TimeLoad =120584
12:19:45.895 -> Rf23.85
12:19:45.996 -> T279
12:19:46.798 -> TimeLoad =164172
12:19:47.803 -> TimeLoad =120580
12:19:48.781 -> Rf23.79
12:19:48.815 -> TimeLoad =142196
12:19:48.881 -> T271
12:19:49.724 -> Rf24.03
12:19:49.825 -> TimeLoad =168032
12:19:49.825 -> T271
12:19:50.801 -> TimeLoad =139508
12:19:51.812 -> TimeLoad =121796
 

Таким образом за 1секунду у меня обычно чегото работает 120мсек. 12% загрузки. Если прилетела частица (это когда Rfххх) +2% загрузки. Измерение температуры по внутреннему датчику - тоже +2%. Наверно на самом деле эти 2% это вывод в сириал. Максимальное что есть - 25% при ежеминутном обновлении совпавшем с прилетом.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sadman41 пишет:

Про скорость выполнения лупа я понял, не понял как из этого вычисляется загрузка в %. Процент вычисляется относительно чего?

Просто я привык, что для CPU Load % есть противоположная величина - Idle %. А тут CPU в idle не находится по определению - всегда какую-то херню мотает.

Идея измерения вполне верная, просто то, к чему мы привыкли, измеряется в многозадачных системах, где процессор обрабатывает все поступающие сообщения, а когда очередь сообщений заканчивается, останавливается командой halt. Соответственно, загрузка - это отношение полезной работы к сумме полезная_работа + простой_по_команде_halt. Например, в Винде прерывания по таймеру просходят через каждые 15-16 мс. Можно измерить время в начале прерывания, по завершении обработки очереди команд и поделить разницу на период (15-16 мс). это и будет загрузкой процессора.

У нас обычно (как в DOS) процессор не останавливается, а постоянно крутится в каком то цикле. И посчитать нужно не загрузку процессора вообще (она всегда 100%), а загрузку процессора выполнением прерывания. С этой точке зрения прерыванию безразлично, что делается за пределами самого прерывания - оно всегда возьмет свое. И при этом столько же отберет от фонового (для прерывания основной loop - это фоновый процесс). Соответственно, какой процент будет отобран у процесса в loop, настолько дольше он будет выполняться. Т.е. по увеличению времени работы вполне точно можно оценить процент времени, отъедаемого прерыванием (собственно, нас, с точки зрения конкретной задачи, именно этот процент и интересует, а не абстрактная "загрузка процессора").

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

asam пишет:

Да даже и пачка из 100 микросекундных импульсов процессор загрузит не больше чем IRremote у которой прерывания каждые 50 микросекунд.

Так а кто ж сказал что они все и всегда стабильно по 100мксек? Если аппаратно такая гадость в принципе появляется то жди беды.

Я же говорил, что импульсы короче чем 100 uS мне не удалось увидеть вовсе. И уж если пачка из 100uS импульсов не нанесет существенного вреда, то если часть из них будет длиннее чем 100uS то нагрузка только снизится. 

Logik
Онлайн
Зарегистрирован: 05.08.2014

Не удалось увидеть Вам не означает что они не возникнутвозникнут ни при каких условиях. Импульсов в 100мкс там тоже не предпологалось, но они обнаружились. О чем я и предупреждал, хотя в документации этот эффект не описан. Вы действительно хотите утверждать что импульсы короче там не возникнут на основании своих впечатлений от трёх домашних пультов? Если нет - давайте прекратим демогогию.Я личным опытом поделился, желающие восприймут, не желающие потом рефакторят. Вам спасибо что проверили и обнаружили импульсы осцилографом. Я этого даже не надеялся обнаружить т.к. смотреть осцилографом проблему возникающую раз в день не каждый день счел безнадежным. А получается что в лёгкой форме, не приводящей к глюкам, обнаруживается куда стабильней. Ну и славно.

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Короч ребятки, TL;DR

Куда нажать что написать чтоб поднять бабла чтобы в лупе успевать отработать сигнал с приёмника? Logik, если я правильно понимаю, предлагает воспринимать ИК датчик как оченьбыстронажимаемую кнопку. Впринципе логично, учитывая что алгоритм захвата я знаю (слушать до тех пор пока не найдётся нечто, отдалённо напоминающее преамбулу, затем дискретизировать).

Дамп кнопки например: rawData[67] = {9000,4400, 600,500, 600,550, 550,550, 600,500, 600,550, 550,550, 600,500, 550,600, 550,1650, 550,1700, 550,1650, 600,1650, 550,1650, 600,1650, 600,1650, 550,1650, 600,550, 550,550, 550,550, 600,500, 600,1650, 600,500, 600,550, 550,550, 600,1650, 550,1650, 550,1700, 550,1650, 600,500, 600,1650, 600,1650, 550,1650, 600}; // NEC FF08F7

как я это вижу:

и так далее (дальше рисовать было лень)

И отличия между 550, 600, 650, а также отличия 1650, 1700 - это проёбы при оцифровке (грубо говоря - тиринг либо фризы, как последствия наличия/отсутствия vsync при неравномерном фреймтайме в игрульках из-за дновидеокарты, ну в терминологии школьников). И этими отличиями можно пренебречь, без потери сути. Соответственно есть разумный предел огрубления разрешающей способности в темпоральных координатах (возможность использовать бОльшие цифры в условии).

Короче суть вопроса, возможно ли привязать оцифровку ИК не к таймеру, а к аппаратному прерыванию? (d2, d3)

И как аттачить прерывание? 1 (или отпускание линии) надо тоже ловить (концы розовых прямоугольников), как и нули (начала розовых). Как это сделать? Потому что attachInterrupt() вешает по-моему только на LOW, во всяком случае в режиме сна у меня работало только если написать там LOW.

Как же выбешивает автовпихивание <span> в разметку поста при правке, просто голову автору скрипта откусить хочется. Прямо как курице.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Если декодированием самому заниматься, то я бы попробовал библиотеку IRRemoteControl. Она маленькая и если работать только на прием, то не использует таймеры. Да она работает по прерываниям от ИК приемника, но ужасы которые описывает Logic если и случаются, то только, как он сам говорит "при неудачных стечениях обстоятельств".  И, при нормально написанном обработчике прерывания, самое худшее, что может произойти так это тормоза на тем моменты когда это неудачное стечение обстоятельств произошло. Мне, перепробовав десяток пультов в разных комбинациях, стечь обстоятельства не удалось.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

я использую так по CHANGE, для радиоканала
 

/****************** INT1 *******************/
void int1(){              // Interrupt service routine INT1
  static unsigned long ulStart;
  static unsigned long rch1;
  if(digitalRead(CH1))  {
    ulStart = micros();
  }
  else  {
    rch1 = (int)(micros() - ulStart);
    if(rch1<2200 && rch1>800) {
      sharedCh1=rch1;
      sharedFlag1 = 1;
        } else{
      sharedFlag1 = 0;  
    }
  }
} // END INT1 (пин 3)

 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

если ты тут условия местами поменяешь, то при <=800 выполняться будет быстрее

10    if(rch1<2200 && rch1>800) {

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

DetSimen пишет:

если ты тут условия местами поменяешь, то при <=800 выполняться будет быстрее

10    if(rch1<2200 && rch1>800) {

ок, поправлю, а почему, сразу выскочит не пробежав всё в скобках?

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

потомушта, в Си условия проверяются по короткому пути.  Если первое - ложь, то второе, в выражении AND проверять уже НЕ надо. А у тебя, если rch1 меньше 800, то будет проверяться и первое(ибо истина) и второе условия.  Паняна?

Век живи, и деду наливай за ликбес. :) 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Так-то, как мне кажется, средняя скорость выполнения if() больше зависит от того, какие rch1 встречаются чаще - <=800 или >=2200.

ВН
Offline
Зарегистрирован: 25.02.2016

Voodoo Doll пишет:

читывая что алгоритм захвата я знаю (слушать до тех пор пока не найдётся нечто, отдалённо напоминающее преамбулу, затем дискретизировать).

Дамп кнопки например: rawData[67] = {9000,4400, 600,500, 600,550, 550,550, 600,500, 600,550, 550,550, 600,500, 550,600, 550,1650, 550,1700, 550,1650, 600,1650, 550,1650, 600,1650, 600,1650, 550,1650, 600,550, 550,550, 550,550, 600,500, 600,1650, 600,500, 600,550, 550,550, 600,1650, 550,1650, 550,1700, 550,1650, 600,500, 600,1650, 600,1650, 550,1650, 600}; // NEC FF08F7

вообще-то дискретизации как таковой не требуется, это полезно для разбора работы неизвестного пульта, что же касается известного, то .... отбросив преамбулу суммируем пары чисел

 (600,500), (600,550), (550,550), (600,500), (600,550), (550,550),( 600,500),( 550,600),( 550,1650),( 550,1700),

и т.д.  .... 550,1650, 600,1650, 550,1650, 600,1650, 600,1650, 550,1650, 600,550, 550,550, 550,550, 600,500, 600,1650, 600,500, 600,550, 550,550, 600,1650, 550,1650, 550,1700, 550,1650, 600,500, 600,1650, 600,1650, 550,1650, 600}

получим длительности нулей -единиц, которые обычно отличаются не менее чем в 1,5-2 раза.

Первым после преамбулы приходит опорный импульс на основе длительности которого и декодируется вся последующая посылка. 

ну дальше все просто, по прерыванию запускаете счетчик микросекунд, читаете его по следующему прерыванию и перезапускаете, по величине насчитанного и величине опорного пишете, что приняли нолик или единичку.

Так же на счет обработки ошибок, если в код влезет преамбула другого пульта, как тут недавно рассматривали, то это повод прервать обработку полностью, а не заниматься ловлей блох. Количество принятых бит тоже может быть фактором контроля, если их число в посылках неизменно для разных команд.

В общем, ИК-пульты появились еще до массового применения МК и их протокол работы был изначально рассчитан  на кратковременную стабильность времен и простоту алгоритма обработки. 

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

sadman41 пишет:

Так-то, как мне кажется, средняя скорость выполнения if() больше зависит от того, какие rch1 встречаются чаще - <=800 или >=2200.

истину глаголешь, так как это радиоканал присутсвуют помехи двух видов, искровая и фоновая 50 герц, именно эта строка была заимствована у умного человека и, там было написано именно так, сам озадачился почему, так как для русского человека не логично ...
 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Ну, тогда не наливай.  Ничего не имею против умного человека, ему виднее. 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

DetSimen пишет:

Ну, тогда не наливай.  Ничего не имею против умного человека, ему виднее. 

можно и просто так налить )))

PS он просто в теме проводил натурные испытания

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

all, спасибо. Напишу о результатах. Пока что кручу энкодером, но это не очень удобно.