Надежно дублируйте индивидуальный ИК-пульт дистанционного управления с помощью 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 батарейка разряжена наполовину).
@Omer, 👍2
Обсуждение2 ответа
Лучший ответ:
Точная продолжительность импульсов не имеет большого значения. В вашем примере вы видите, что во всех трех записанных образцах это
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
Я часто вижу, что у людей время от времени возникают проблемы с декодированием ИК-сигналов, но очень немногие говорят, как они пытаются это сделать? Первое, что вам действительно нужно знать, это то, что такое несущая частота? если вы используете TSOP IR DEMODULATOR, они бывают нескольких видов, и если вы ошиблись, ваши результаты могут быть не такими надежными. Есть один или два способа определить это. иметь цифровую область памяти и быстрый фотодиод (фототранзисторы медленные), который не выполняет демодуляцию, а просто дает необработанный ИК. Как только вы определите свою несущую частоту, купите ИК-демодулятор TSOP, наиболее близкий к вашей несущей частоте, и ваши результаты, несомненно, будут более стабильными.
- Генерация сигнала частотой 38 кГц без таймеров
- При использовании Arduino Uno в качестве ISP: "Yikes! Invalid device signature" - плохое соединение, неверную конфигурацию или неверную версию avrdude?
- Использование VS1838B с Arduino
- Связь ATtiny85 с компьютером через USB
- Получить доступ к EEPROM ATtiny с помощью кода Arduino?
- avrdude: ошибка проверки, первое несоответствие в байте 0x0000 : 0x00 != 0x16 с использованием USBasp
- Радиочастотное дистанционное управление с использованием VirtualWire на ATtiny85, работающем на частоте 8 МГц на внутреннем генераторе
- Как выбрать вывод передачи в библиотеке IRremote для Arduino Uno?
Хотя AVR работает на частоте 8 МГц, существует задержка для обслуживания ISR. Отсюда ваши наблюдаемые различия., @mpflaga
Это правда, что ISR имеет некоторую задержку и не предоставляет значения в реальном времени, но если то, что вы говорите, верно, я должен был измерять одно и то же отклонение при каждой попытке, а этого не происходит., @Omer