Надежно дублируйте индивидуальный ИК-пульт дистанционного управления с помощью ATTiny85.

Это то, с чем я борюсь некоторое время и не могу найти надежного решения. Библиотека Arduino IR предоставляет метод для записи произвольного IR-кода и его повторной отправки. Это давало мне разные результаты каждый раз, когда я записывал ИК-пульт, поэтому я написал небольшой код, основанный на прерываниях, который пытается максимально точно записать подъем/спад ИК-сигнала. Я работаю с ATTiny85, работающим на частоте 8 МГц на внутреннем генераторе.

Вот код:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4,3);

const int dataSize = 40;
int data[dataSize];
int dataLength[dataSize];


void setup() {
  pinMode(0, OUTPUT); // 0 - контакт ИК-приемника
  mySerial.begin(9600);
  mySerial.println("Start");
  attachInterrupt(0,IR_ISR,CHANGE); 
  mySerial.println("Registered");
  sei();
}
volatile unsigned long prev = micros();
volatile unsigned long curr = -1;
volatile unsigned short index = 0;
volatile bool rising = true;
void IR_ISR()
{
  if (!rising)
  {
    dataLength[index] = micros() - curr;
    rising = !rising;
    return;
  }

  curr = micros();

  data[index++] = (int)curr-prev;

  prev = curr; 
  rising = !rising;
}

void loop() {

  delay(5000);
  for (int i=1; i<dataSize; i++)
  {
    mySerial.print(data[i]);
    mySerial.print("(");
    mySerial.print(dataLength[i]);
    mySerial.print(")");
    mySerial.print("; ");
  }
  mySerial.println();
  index = 0;
}

Проблема в том, что миллисекунды меняются на каждой записи пульта, вот пример вывода 3-х попыток нажатия на одну и ту же кнопку пульта (я вклеил только первые 5 ИК-модуляций, чтобы не было лишнего текст, всего около 39):

Начать
Зарегистрировано

14104(9496); 1184 (672); 1184 (616); 1160 (656); 1176 (672); ...

14096(9480); 1184 (664); 1208 (568); 1136 (616); 1184 (664); ...

14096(9384); 1216(576); 1136 (616); 1184 (664); 1208(560); ...

Формат: [микросекунды от предыдущего заднего фронта](микросекунды от нарастания до спада);

Как видите, результаты различаются. Согласно веб-сайту arduino.cc, функция micros() имеет разрешение 8 микросекунд на AVR 8 МГц, но разница между читает больше, чем это.

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

, 👍2

Обсуждение

Хотя AVR работает на частоте 8 МГц, существует задержка для обслуживания ISR. Отсюда ваши наблюдаемые различия., @mpflaga

Это правда, что ISR имеет некоторую задержку и не предоставляет значения в реальном времени, но если то, что вы говорите, верно, я должен был измерять одно и то же отклонение при каждой попытке, а этого не происходит., @Omer


2 ответа


Лучший ответ:

4

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

about 14000 (about 9400); about 1200 (about 600); about 1200 (about 600) etc.

Важно то, что нигде у вас нет импульсов около 900 : другими словами, если приемник обнаружит импульс 672, он будет знать, что это определенно 600, а не 1200.

Поэтому, если вы отправите именно эти значения, получатель распознает их.

,

Это интересное наблюдение; у вас есть эмпирическое правило округления?, @Omer

Я использую 412-712 для обнаружения «ноля» и 1187-2187 для обнаружения «единицы». 412-712 за разрыв между ними. Похоже, что пульт использует [протокол NEC](http://www.sbprojects.com/knowledge/ir/nec.php). На самом деле я использовал Excel, чтобы преобразовать необработанные данные в число и проверить, достаточны ли границы. На самом деле мне пришлось увеличить границы несколько раз, чтобы надежно поймать ИК-сигнал. Приведенные выше значения - это то, с чем я столкнулся., @Gerben

Я использовал удаленный NEC для поста, но я намерен надежно настроить любой пользовательский протокол. Поэтому я не уверен, что значения NEC меня устроят. Кроме того, моя конечная цель - сделать всю обработку динамически на самом AVR, сделав его настоящим регулируемым пультом дистанционного управления, поэтому excel здесь не вариант :) Я попытаюсь поиграть с округлением, используя код, посмотрим, поможет ли это (если это сработает, я приму ваш ответ)., @Omer

Просто сэмплируйте один и тот же код n раз и запишите средние значения длительности импульсов. Если вы отправите его повторно, вы будете уверены, что отправили тот же код. То, как этот код интерпретируется приемником (NEC, rc-6 и т. д.), не имеет значения., @Nicolas D

В конце концов я решил не использовать ATtiny85, поскольку даже при использовании PROGMEM он просто не подходит для работы в качестве «универсального пульта дистанционного управления» с точки зрения памяти. Но это действительно правильный ответ на мой вопрос., @Omer


0

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

,