maximkulkin / esp-homekit-demo

Demo of Apple HomeKit accessory server library
MIT License
803 stars 233 forks source link

ir my protocol config #401

Closed Kristian8606 closed 3 years ago

Kristian8606 commented 3 years ago

Cheers! I'm having trouble getting commands from the example my_protocol_config. He manages to get one or sometimes two ir commands after which esp freezes, does not respond. How to deal with this problem? Here is the code

Updated Actually does not freeze, just does not process the received commands from ir.

#include <stdio.h>
#include <stdlib.h>
#include <esp/uart.h>
#include <FreeRTOS.h>
#include <espressif/esp_common.h>
#include <esp8266.h>
#include <task.h>

#include <etstimer.h>
#include <esplibs/libmain.h>
#include <sysparam.h>
#include <ir/ir.h>
#include <ir/generic.h>

#define IR_RX_GPIO 12

static ir_generic_config_t my_protocol_config = {
    .header_mark = 2665,
    .header_space = -860,

    .bit1_mark = 470,
    .bit1_space = -1300,

    .bit0_mark = 470,
    .bit0_space = -420,

    .footer_mark = 470,
    .footer_space = -1300,

    .tolerance = 20,
};

void ir_decode_task(void *arg) {
ir_rx_init(IR_RX_GPIO, 1024);
ir_decoder_t *generic_decoder = ir_generic_make_decoder(&my_protocol_config);

uint8_t buffer[32];
while (1) {
    uint16_t size = ir_recv(generic_decoder, 0, buffer, sizeof(buffer));
    if (size <= 0)
        continue;

    printf("Decoded packet (size = %d): ", size);
    for (int i=0; i < size; i++) {
        printf("0x%02x ", buffer[i]);
        if (i % 16 == 15)
            // newline after every 16 bytes of packet data
            printf("\n");
    }

    if (size % 16)
        // print final newline unless packet size is multiple of 16 and newline
        // was printed inside of loop
        printf("\n");
 }

}

void user_init(void) {
    uart_set_baud(0, 115200);
    xTaskCreate(ir_decode_task, "IR decode", 2048, NULL, tskIDLE_PRIORITY, NULL);
}
renandw commented 3 years ago

Try this one:

#include <stdio.h>
#include <stdlib.h>
#include <esp/uart.h>
#include <FreeRTOS.h>
#include <task.h>

#include <ir/ir.h>
#include <ir/generic.h>

#define IR_RX_GPIO 12

static ir_generic_config_t generic_config = {
    .header_mark = 2665,
    .header_space = -860,

    .bit1_mark = 470,
    .bit1_space = -1300,

    .bit0_mark = 470,
    .bit0_space = -420,

    .footer_mark = 470,
    .footer_space = -1300,

    .tolerance = 20,
};
void ir_dump_task(void *arg) {
ir_rx_init(IR_RX_GPIO, 1024);
ir_decoder_t *generic_decoder = ir_generic_make_decoder(&generic_config);

uint8_t buffer[48];
while (1) {
uint16_t size = sizeof(buffer);
if (ir_recv(generic_decoder, 0, buffer, &size) <= 0)
continue;

printf("Decoded packet (size = %d):\n", size);
for (int i=0; i < (size + 7) / 8; i++) {
    printf("0x%02x ", buffer[i]);
    if (i % 16 == 15)
        printf("\n");
}

if ((size + 7) % 128)
    printf("\n");
}
}

void user_init(void) {
uart_set_baud(0, 115200);

xTaskCreate(ir_dump_task, "IR dump", 2048, NULL, tskIDLE_PRIORITY, NULL);
}

It works for me (changed to your values)

Kristian8606 commented 3 years ago

Thanks! Looks like the problem was different. I copied all the files of the ir library to the working directory and now it works. Thanks for responding.

maximkulkin commented 3 years ago

@renandw looks like you have a bug in your code: ir_recv takes size of the receive buffer as last argument, not a pointer. That potentially can lead to buffer overflow problems.

Kristian8606 commented 3 years ago

Excuse me for the stupid question, but as far as I understand, this library decodes signals from remotes that work only with a protocol? I have a Philips remote that probably doesn't use a protocol and its times look like 900, -830, 840, -802, 890, -844 ... packets(21) can you help me set it up?

maximkulkin commented 3 years ago

Depends on what you mean by "work only with a protocol". Every remote uses some kind of "a protocol". This library though only deals with On-off keying which is common for IR remotes. You can build decoder for any OOK protocols.

A quick web search showed that Philips have their own protocol for IR remotes - RC-5. Here is more information on it. Yes, you can build a decoder for that protocol with esp-ir library.

Kristian8606 commented 3 years ago

This is the raw data

Decoded packet (size = 41):
2689  -863   475  -868   476  -422   475  -422   476  -875   895  -429   476  -422   475  -423
475  -422   476  -421   476  -421   477  -421   476  -421   476  -426   476  -423   476  -421
476  -421   919  -430   477  -870   473  -423   476

do I create the protocol correctly I do not understand why I get such a result. Can you give me a hand?

static ir_generic_config_t my_protocol_config = {
   .header_mark = 2690,
    .header_space = -860,

    .bit1_mark = 470,
    .bit1_space = -860,

    .bit0_mark = 470,
    .bit0_space = -470,

    .footer_mark = 470,
    .footer_space = -1700,

    .tolerance = 20,
};

Decoded packet (size = 1): 0x09 Decoded packet (size = 1): 0x01 Decoded packet (size = 1): 0x09 Decoded packet (size = 1): 0x01 Decoded packet (size = 1): 0x01 Decoded packet (size = 1): 0x09 Decoded packet (size = 1): 0x01

maximkulkin commented 3 years ago

Ok, as I said, this is not a NEC protocol, so the code you're using won't help. You need to write a new decoder, that will handle that new protocol. Which turns out to be RC-6. I decoded address and command on that sample you have provided and according to address and command tables from RC-5 protocol this has to be power/standby button on a Philips TV remote. Am I right?

Kristian8606 commented 3 years ago

Yes this is a power button. I'm not sure I'll be able to write a new decoder. I will try and as a last resort I will use raw data. Thanks for helping me.

peros550 commented 3 years ago

@maximkulkin these days I'm also trying to use the encoder method as the RAW wasn't successful and in case it consumes more resources. There is one open issue in regards to longer timings (>9999) . In RAW , we have a workaround. What about the ir_generic_config_t object, f I set .footer_space = -20000, would that work as intended?

maximkulkin commented 3 years ago

@peros550 set it to -9999. Or even less. I bet your mark and space timings are less than 2000us anyways, so anything longer than that will be considered to be an end of transmission.

peros550 commented 3 years ago

I believe most remotes used in A/Cs split units (very commonly used here in Europe) have longer codes than typical remotes found in TVs etc. I am working on a unit that came by Daikin. In the past I have successfully used your IR library with other brands (i.e. Toyotomi, Midea) using the RAW workaround timing. All these had longer delays around 20000uS.

Here is a screenshot from the signals I captured using a program called AnalysIR for Daikin AC remote. If you pay close attention to the signal's form, it has a first long delay (~20000uS) in the beginning, then it transmits a few bits, then another delay of around 35000uS then it goes on. In total the signal has 3 long spaces.

AnalysIR-Daikin

I have tried to send RAW commands using your IR library with no good results. First the raw_dumber did not capture the full signal (probably the long delays (3 in count) ) made it stop. But I even used the data from AnalysIR with the workaround without success.

Then a fellow github user proposed a library which I tested and have found to reproduce the IR code sucesfully. Sadly the Arduino code is not RTOS ready and needs porting.

I have seen your comment about the incompatibility of the transmit start/stop logic to your library. But I would still like to try porting the code. I believe I can use the other library to make it calculate each A/C command in binary data, define a proper protocol and then give it to your IR library for sending.

To my understanding, the challenge is to create a new protocol.

Having said that (and sorry for my long message) do you thing longer (>9999) spaces defined in the encoder will work?

Thanks

maximkulkin commented 3 years ago

@peros550 I have pushed an update to workaround 9999 issue.

peros550 commented 3 years ago

many thanks maxim! I'll test and let you know :)