ИК ретранслятор

anton.tramp
Offline
Зарегистрирован: 11.01.2021

Есть ИК приемник и ИК передатчик. Задача: принять с приемника сигнал, запомнить его, а потом в нужный момент отправить этот сигнал через передатчик.

Проблема: вначале решил для этого использовать библиотеку IRremote, но он не может декодировать сигнал с моего пульта (с другого может, а с моего - Unknown protocol). Вначале хотел поискать альтернативные библиотеки, а потом подумал: а зачем? По идее можно просто запомнить последовательность сигналов с временными интервалами, которые пришли с пина, а потом просто отправить эту последовательность на другой пин.

Если идея жизнеспособная, то может кто показать, как это делается? Или не взлетит и нужно искать библиотеку с поддержкой моего протокола?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Как для ретранслятора идея жизнеспособна, но суть ее в чем? За стеной телевизором управлять?

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

Трамп, так в чем проблема?

Сначала принимаете сигнал,

затем его запоминаете,

потом - воспроизводите.

Начните с начала - что у Вас получается?

nik182
Offline
Зарегистрирован: 04.05.2015

В своё время снял с брелка моей хонды ИК сигнал открывания дверей и загнал его в телефон с ИК портом. А то пару раз сигналка закрывала двери с ключами в салоне. Снимал на блюпиле. Поставил в режим АЦП, что бы с приёмного ИК диода снять напряжение c равными интервалами времени, которое было совсем не TTL и снял длинную реализацию, загнал в комп, превратил в цифру по времени, нашёл минимальный квант, по нему восстановил цифровую последовательность нулей и единичек. Её отправил обратно - дверь открылась.  

maksmkv
Offline
Зарегистрирован: 07.04.2013

anton.tramp пишет:

Есть ИК приемник и ИК передатчик. Задача: принять с приемника сигнал, запомнить его, а потом в нужный момент отправить этот сигнал через передатчик.

Проблема: вначале решил для этого использовать библиотеку IRremote, но он не может декодировать сигнал с моего пульта (с другого может, а с моего - Unknown protocol). Вначале хотел поискать альтернативные библиотеки, а потом подумал: а зачем? По идее можно просто запомнить последовательность сигналов с временными интервалами, которые пришли с пина, а потом просто отправить эту последовательность на другой пин.

Если идея жизнеспособная, то может кто показать, как это делается? Или не взлетит и нужно искать библиотеку с поддержкой моего протокола?

 

А если считать код таким методом:

int pin = 7;
unsigned long duration;

void setup()
{
  Serial.begin(115200);
  pinMode(pin, INPUT);
}

void loop()
{
  duration = pulseIn(pin, LOW);
  if(duration)
  Serial.println(duration); 
}

В консоли будут какие-то  цифры, потом еще  раз запустить - цифры  будут совпадать??? Если да- тогда можно попробовать  их отправить дальше. 

 

nik182
Offline
Зарегистрирован: 04.05.2015

Идея так себе. PulseIn ждёт фронта, а потом начинает считать следующий. Т.е. есть промежуток времени, который таким образом ни как не получить, пока ждёт фронт. Если уж получать интервалы - то подать на вход таймера, у которого по разным фронтам разные прерывания и снимать счетчик в прерывании. Получим точные интервалы нулей и единичек. Но надо сигнал ИК к TTL подогнать. 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

BOOM пишет:

За стеной телевизором управлять?

Можно не только за стеной. Если соединить 2 модуля радиоканалом, хоть той же LoRа, можно оооочень сильно удлинить радиус действия пульта от зомбоящика)))

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

А смысл? Превратить "визор" в обычное "радио"?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Rumata пишет:

BOOM пишет:

За стеной телевизором управлять?

Можно не только за стеной. Если соединить 2 модуля радиоканалом, хоть той же LoRа, можно оооочень сильно удлинить радиус действия пульта от зомбоящика)))

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

anton.tramp
Offline
Зарегистрирован: 11.01.2021

Извините, пропал на неделю

BOOM пишет:
Как для ретранслятора идея жизнеспособна, но суть ее в чем?
Суть - управлять кондиционером по событиям. Вначале родным пультом программируем команды, а потом, при наступлении события, посылаем команду кондиционеру

andriano пишет:
так в чем проблема?

Сначала принимаете сигнал,

Проблема в принятии сигнала. Я правильно понимаю, что прием должен быть каскадом digitalRead() + micros(), а отправка digitalWrite() + delayMicroseconds() с вычисленными задержками?

anton.tramp
Offline
Зарегистрирован: 11.01.2021

Вот, например, такой код

#include <Arduino.h>

#define IR_PIN 12  // pins: SGV

#define WAIT_TIMEOUT ((unsigned long)-1)
#define TIMES_COUNT 100

void setup() {
    Serial.begin(9600);
    Serial.println("Test");
    pinMode(IR_PIN, INPUT);
}

unsigned long waitPin(uint8_t pin, uint8_t value, unsigned long timeout) {
    unsigned long startPhase = micros();
    uint8_t waitIdx = 0;
    unsigned long res = 0;
    while (true) {
        while (digitalRead(pin) == value && ++waitIdx != 0);
        unsigned long endPhase = micros();
        res += endPhase - startPhase;
        if (waitIdx == 0) {
            if (res >= timeout)
                return WAIT_TIMEOUT;
            startPhase = endPhase;
        } else
            return res;
    }
}

void readIR(uint8_t pin, uint8_t baseVal) {
    unsigned long times[TIMES_COUNT];
    uint8_t curVal = baseVal;
    uint8_t timeIdx = 0;
    do {
        times[timeIdx] = waitPin(pin, curVal, 100000);
        curVal = !curVal & 1u;
    } while (timeIdx < TIMES_COUNT && times[timeIdx++] != WAIT_TIMEOUT);
    curVal = baseVal;
    for (uint8_t i = 0; i < timeIdx; i++) {
        Serial.print('[');
        Serial.print(i);
        Serial.print("] ");
        Serial.print(curVal);
        Serial.print(": ");
        Serial.println(times[i]);
        curVal = !curVal & 1u;
    }
}

void loop() {
    if (digitalRead(IR_PIN) == LOW)
        readIR(IR_PIN, LOW);
}

При активации пультом выводит 96 элементов массива, а потом отправляет Ардуину в перезагрузку. Если TIMES_COUNT поставить 200, тогда выводится 195 элементов и перезагрузка

anton.tramp
Offline
Зарегистрирован: 11.01.2021

Нашел ошибку. Вместо

} while (timeIdx < TIMES_COUNT && times[timeIdx++] != WAIT_TIMEOUT);

нужно было писать

} while (times[timeIdx++] != WAIT_TIMEOUT && timeIdx < TIMES_COUNT);

Но теперь вопрос когда останавливать чтение? 250 элементов массива (т.е 125 переходов LOW-HIGH-LOW) считываются. Числа получаются такие

[0] 0: 8964
[1] 1: 4396
[2] 0: 636
[3] 1: 1616
[4] 0: 636
[5] 1: 1616
[6] 0: 632
[7] 1: 460
[8] 0: 664
[9] 1: 456
[10] 0: 640
[11] 1: 456
[12] 0: 636
[13] 1: 488
[14] 0: 636
[15] 1: 1616
[16] 0: 640
[17] 1: 1644
[18] 0: 640
[19] 1: 1616
[20] 0: 636
[21] 1: 1620
[22] 0: 640
[23] 1: 1612
[24] 0: 636
[25] 1: 456
[26] 0: 664
[27] 1: 456
[28] 0: 636
[29] 1: 456
[30] 0: 664
[31] 1: 1592
[32] 0: 664
[33] 1: 1616
[34] 0: 668
[35] 1: 456
[36] 0: 632
[37] 1: 456
[38] 0: 660
[39] 1: 456
[40] 0: 636
[41] 1: 1620
[42] 0: 640
[43] 1: 456
[44] 0: 660
[45] 1: 452
[46] 0: 636
[47] 1: 460
[48] 0: 664
[49] 1: 456
[50] 0: 664
[51] 1: 1592
[52] 0: 668
[53] 1: 1592
[54] 0: 640
[55] 1: 1644
[56] 0: 640
[57] 1: 456
[58] 0: 636
[59] 1: 460
[60] 0: 660
[61] 1: 1620
[62] 0: 612
[63] 1: 480
[64] 0: 664
[65] 1: 456
[66] 0: 656
[67] 1: 460
[68] 0: 636
[69] 1: 456
[70] 0: 660
[71] 1: 456
[72] 0: 632
[73] 1: 456
[74] 0: 664
[75] 1: 456
[76] 0: 636
[77] 1: 460
[78] 0: 632
[79] 1: 1624
[80] 0: 660
[81] 1: 456
[82] 0: 664
[83] 1: 452
[84] 0: 640
[85] 1: 456
[86] 0: 664
[87] 1: 460
[88] 0: 636
[89] 1: 456
[90] 0: 664
[91] 1: 432
[92] 0: 664
[93] 1: 456
[94] 0: 636
[95] 1: 452
[96] 0: 660
[97] 1: 488
[98] 0: 636
[99] 1: 456
[100] 0: 632
[101] 1: 460
[102] 0: 664
[103] 1: 464
[104] 0: 620
[105] 1: 460
[106] 0: 664
[107] 1: 452
[108] 0: 636
[109] 1: 464
[110] 0: 660
[111] 1: 1596
[112] 0: 660
[113] 1: 460
[114] 0: 660
[115] 1: 456
[116] 0: 632
[117] 1: 460
[118] 0: 664
[119] 1: 456
[120] 0: 636
[121] 1: 464
[122] 0: 660
[123] 1: 456
[124] 0: 636
[125] 1: 460
[126] 0: 664
[127] 1: 456
[128] 0: 640
[129] 1: 484
[130] 0: 632
[131] 1: 460
[132] 0: 660
[133] 1: 456
[134] 0: 640
[135] 1: 456
[136] 0: 668
[137] 1: 456
[138] 0: 636
[139] 1: 452
[140] 0: 660
[141] 1: 456
[142] 0: 636
[143] 1: 460
[144] 0: 660
[145] 1: 456
[146] 0: 636
[147] 1: 484
[148] 0: 636
[149] 1: 452
[150] 0: 668
[151] 1: 456
[152] 0: 640
[153] 1: 456
[154] 0: 660
[155] 1: 456
[156] 0: 636
[157] 1: 1624
[158] 0: 636
[159] 1: 456
[160] 0: 664
[161] 1: 460
[162] 0: 660
[163] 1: 460
[164] 0: 640
[165] 1: 452
[166] 0: 668
[167] 1: 456
[168] 0: 636
[169] 1: 460
[170] 0: 664
[171] 1: 456
[172] 0: 612
[173] 1: 480
[174] 0: 632
[175] 1: 460
[176] 0: 664
[177] 1: 460
[178] 0: 636
[179] 1: 1648
[180] 0: 636
[181] 1: 456
[182] 0: 664
[183] 1: 1592
[184] 0: 664
[185] 1: 452
[186] 0: 636
[187] 1: 456
[188] 0: 664
[189] 1: 456
[190] 0: 640
[191] 1: 456
[192] 0: 664
[193] 1: 460
[194] 0: 664
[195] 1: 456
[196] 0: 636
[197] 1: 1620
[198] 0: 640
[199] 1: 1616
[200] 0: 636
[201] 1: 1624
[202] 0: 664
[203] 1: 1592
[204] 0: 636
[205] 1: 484
[206] 0: 640
[207] 1: 1620
[208] 0: 636
[209] 1: 484
[210] 0: 636
[211] 1: 22392
[212] 0: 9056
[213] 1: 4392
[214] 0: 636
[215] 1: 1620
[216] 0: 612
[217] 1: 1648
[218] 0: 640
[219] 1: 456
[220] 0: 636
[221] 1: 484
[222] 0: 636
[223] 1: 456
[224] 0: 668
[225] 1: 456
[226] 0: 640
[227] 1: 1620
[228] 0: 636
[229] 1: 1620
[230] 0: 664
[231] 1: 1620
[232] 0: 612
[233] 1: 1644
[234] 0: 640
[235] 1: 1620
[236] 0: 632
[237] 1: 460
[238] 0: 664
[239] 1: 452
[240] 0: 632
[241] 1: 456
[242] 0: 664
[243] 1: 1592
[244] 0: 640
[245] 1: 1640
[246] 0: 664
[247] 1: 452
[248] 0: 636
[249] 1: 456

Что-то я не то делаю

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

anton.tramp пишет:

Числа получаются такие

[0] 0: 8964
[1] 1: 4396
...
[248] 0: 636
[249] 1: 456

Что-то я не то делаю

А почему Вы решили, что Вы что-то не так делаете?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Лог очень похож на посылки, которые вполне себе даже можно расшифровать.

У кондеев есть одна особенность: посылка, как правило, содержит всю информацию о настройках. Это как бы слепок настроек. А вот у телевизора, например, посылка это всего лишь код кнопки. Это нужно учитывать при расшифровке сообщения. Если хотите не просто скопирастить посылку, а готовитесь отправить ее "со смыслом".

Green
Offline
Зарегистрирован: 01.10.2015

brokly пишет:

У кондеев есть одна особенность: посылка, как правило, содержит всю информацию о настройках. Это как бы слепок настроек.


Именно так. По другому не встречалось.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Green пишет:

brokly пишет:

У кондеев есть одна особенность: посылка, как правило, содержит всю информацию о настройках. Это как бы слепок настроек.


Именно так. По другому не встречалось.

по видимо да, стоит притащить пульт от другого кондея и все настройки улетают

anton.tramp
Offline
Зарегистрирован: 11.01.2021

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

brokly пишет:
Если хотите не просто скопирастить посылку, а готовитесь отправить ее "со смыслом".
Мне не нужен смысл. У меня две команды включить и выключить. Я эти две команды хочу считать с родного пульта и потом их посылать

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

anton.tramp пишет:
Мне не нужен смысл. У меня две команды включить и выключить. Я эти две команды хочу считать с родного пульта и потом их посылать

Прикалываетесь ? Или подумать лень ? Не у кондея посылки ВКЛ. Есть например посылка "Вкл в режим охладения до целевой температуры 25, с медленным вращением вентилятора, махая опахалом". 

anton.tramp
Offline
Зарегистрирован: 11.01.2021

brokly пишет:
Прикалываетесь ? Или подумать лень ? Не у кондея посылки ВКЛ. Есть например посылка "Вкл в режим охладения до целевой температуры 25, с медленным вращением вентилятора, махая опахалом".
Пускай. И что это меняет в вопросе записи команды?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

anton.tramp пишет:
Пускай. И что это меняет в вопросе записи команды?

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

Кстати, IRremote может принимать  и воспроизводить и неизвестный ему протокол, это называется в RAW формате.

anton.tramp
Offline
Зарегистрирован: 11.01.2021

brokly пишет:
Если вам похрену в каком режиме будет кондиционер, тогда это не имеет значения.... Действительно какая разница.
Вариант, что я буду записывать именно ту команду, которая переводит кондиционер в нужный мне режим не рассматривается?

brokly пишет:
Кстати, IRremote может принимать  и воспроизводить и неизвестный ему протокол, это называется в RAW формате.
Можно пример или ссылку на документацию?

 

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020
anton.tramp
Offline
Зарегистрирован: 11.01.2021

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