Точный контроль включения/выключения ИК-светодиода
Моя цель — иметь возможность отправлять/получать IR-сообщения в моем собственном формате и отправлять сообщения длиной ~10 байт. Мой объект сообщения будет сериализован до отдельных битов, которые передаются путем включения/выключения ИК-светодиода в определенные моменты времени по моему выбору для представления логических единиц и нулей. Судя по тому, что я видел, ИК-светодиод можно включать/выключать либо в цикле while, либо в качестве сигнала ШИМ для передачи сообщения. Я предполагаю, что единственное, что можно получить при использовании ШИМ-сигнала, это то, что работа там выполняется по обратному вызову таймера и позволяет другому коду выполняться одновременно. Для простоты я выбрал подход цикла while .
Проблема, которую я вижу, — одна из двух. Либо приемник неправильно считывает тайминги, либо передатчик не включает/выключает светодиод так быстро, как я ожидал.
В приведенном ниже примере кода ИК-светодиод включается на 600 микросекунд и выключается на 300 микросекунд. (В конечном итоге мои пользовательские сообщения будут построены с использованием чего-то подобного.) Однако, как вы можете видеть в примере Выходы ниже приемника не видят ИК-сигнал включенным или выключенным в течение какого-либо периода времени.
Не уверен, проблема ли это в настройке или в чем-то другом. Две платы Arduino, которые я использую, являются платами Arduino Pro ATmega328p. Для платы, отправляющей ИК-сигнал, контакт 6 подключается к резистору сопротивлением 330 Ом, затем к светодиоду, а затем к земле. ИК-приемник на другой плате не имеет резисторов, только прямое подключение к контактам. При считывании ИК-сигналов я держу приёмник на расстоянии нескольких сантиметров от светодиода.
Мои вопросы:
- Это жизнеспособная установка? Должно ли это работать? Или я ошибаюсь в своих предположениях и нужно искать другой способ сделать это?
- Правильно ли мое предположение о включении/выключении светодиода с помощью цикла while по сравнению с сигналом ШИМ? Или мне следует отказаться от концепции контура и использовать только ШИМ-сигнал.
Код ИК-передачи:
#define IRpin 6
void setup() {
pinMode(IRpin, OUTPUT);
}
void loop() {
//Светодиод включен
PORTD |= (1 << IRpin);
delayMicroseconds(600);
//Светодиод выключен
PORTD &= ~(1 << IRpin);
delayMicroseconds(300);
}
Код IR-приема (взято из онлайн-примера, внесены только изменения для вывода текста):
#define IRpin_PIN PIND
#define IRpin 2
// максимальный импульс, который мы будем слушать - 65 миллисекунд - это большой срок
#define MAXPULSE 65000
#define RESOLUTION 20
uint16_t pulses[300][2]; // пара — высокий и низкий импульс
uint8_t currentpulse = 0; // индекс импульсов, которые мы сохраняем
void setup(void) {
Serial.begin(9600);
Serial.println("Ready to decode IR!");
}
void loop(void) {
uint16_t highpulse, lowpulse; // время временного хранения
highpulse = lowpulse = 0; // начинаем без длины импульса
while (IRpin_PIN & (1 << IRpin)) {
// отсчитываем еще несколько микросекунд
highpulse++;
delayMicroseconds(RESOLUTION);
// Если импульс слишком длинный, у нас «тайм-аут» — либо ничего
// был получен или код завершен, поэтому выведите то, что
// мы уже захватили, а затем сбросили
if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
printpulses();
currentpulse = 0;
return;
}
}
// время ожидания не истекло, поэтому давайте сохраним показания
pulses[currentpulse][0] = highpulse;
// то же, что и выше
while (! (IRpin_PIN & _BV(IRpin))) {
// вывод все еще НИЗКИЙ
lowpulse++;
delayMicroseconds(RESOLUTION);
if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
Serial.println("Breaking - Hit max Pulse Low");
printpulses();
currentpulse = 0;
return;
}
}
pulses[currentpulse][1] = lowpulse;
// мы успешно читаем один высокий-низкий импульс, продолжаем!
currentpulse++;
}
void printpulses(void) {
uint32_t totalMicroseconds = 0;
for (uint8_t i = 0; i < currentpulse - 1; i++) {
Serial.print("On(");
Serial.print(pulses[i][1] * RESOLUTION , DEC);
Serial.print(");");
Serial.println("");
Serial.print(" Off(");
Serial.print(pulses[i + 1][0] * RESOLUTION , DEC);
Serial.println(");");
totalMicroseconds += pulses[i][1] * RESOLUTION;
totalMicroseconds += pulses[i + 1][0] * RESOLUTION;
if (i % 8 == 0) {
Serial.println("");
}
}
Serial.print("On(");
Serial.print(pulses[currentpulse - 1][1] * RESOLUTION, DEC);
Serial.print(");");
totalMicroseconds += pulses[currentpulse - 1][1] * RESOLUTION;
Serial.println("");
Serial.print("Total Microseconds: ");
Serial.println(totalMicroseconds, DEC);
}
Примеры результатов:
Ready to decode IR!
On(20);
Off(62064);
On(0);
Off(12060);
On(360);
Off(1860);
On(440);
Off(8940);
On(20);
Off(15460);
On(80);
Off(25672);
On(40);
Total Microseconds: 127016
On(40);
Off(6740);
On(300);
Off(6740);
On(20);
Off(8520);
On(40);
Off(6740);
On(1540);
Off(15720);
On(40);
Off(34860);
On(20);
Total Microseconds: 81320
On(3000);
Off(35384);
On(40);
Off(14180);
On(1220);
Off(54440);
On(980);
Total Microseconds: 109244
On(200);
Total Microseconds: 200
On(20);
Off(29160);
On(60);
Off(26700);
On(60);
Off(22880);
On(20);
Off(2928);
On(20);
Total Microseconds: 81848
@ProgrammerAl, 👍0
Обсуждение1 ответ
В конечном итоге я также задал этот вопрос на сайтеelectronics.stackexchange.com. Я знаю, что это не одобряется, но эта тема действительно находится на грани между темой Arduino и электроникой.
Подводя итог принятому ответу, никакие IR-сообщения не могут быть отправлены/получены так, как я думал. ИК-светодиод должен включаться/выключаться на частоте, соответствующей настройке приемника. В общем 38х. Итак, включено на 13 микросекунд, затем выключено на 13 микросекунд. Затем повторите.
https://electronics.stackexchange.com/questions /417387/точное управление включением-выключением для ИК-светодиода/417391
- Использование VS1838B с Arduino
- Как выбрать вывод передачи в библиотеке IRremote для Arduino Uno?
- Как увеличить расстояние обнаружения на датчике обхода препятствий Arduino KY-032?
- Ошибка "collect2.exe: error: ld returned 1 exit status"
- Как подключить ИК-передатчик и модуль приемника?
- Tone() конфликтует с библиотекой IRremote (множественное определение `__vector_7')
- Как остановить вращение сервопривода?
- ESP32 ИК-пульт
Я не знаю наверняка, но я предполагаю, что, хотя 65 миллисекунд — это большой срок для микропроцессора, для светодиодного освещения и приема это может быть не так уж много. Например, светодиоду может потребоваться больше времени, чем вы или я думаем, чтобы излучать его на читаемом уровне - я не знаю. Я бы, по крайней мере, подумал о том, чтобы замедлить процесс на несколько секунд - например, на несколько секунд - и посмотреть, получите ли вы надежную передачу и прием на очень-очень медленных скоростях. Возможно, вам также придется учитывать влияние внешнего света, движение руки и т. д., @mikeY
@mikeY - См. [Какова задержка светодиода?](https://electronics.stackexchange.com/q/86717/64015). В зависимости от типа светодиода: от 2 нс до 1,2 мкс, @Greenonline