Giter Site home page Giter Site logo

esp-ir's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp-ir's Issues

Request: separate ir_mark and ir_space functions

Hi!

Really great solution for sending IR codes, but I'm really missing the separate IR.mark and ir.Space functions. My AC sends 8 bits splitted in two parts and its hard to implement because I need these functions like in ir-esp-uart. The only problem with this lib, it uses GPIO2 for TX and this is also the built-in LED's GPIO.

Is it possible to implement these two functions using I2S?

Suggestion: Disable GPIO 14 pull up on init

TL;DR

I find that esp8266 GPIO14(D5) although it's not high on boot/after boot, it is "pull-up" by default on boot and even after boot. So I suggest disable pull-up at user_init() to prevent IR led from burning.

void user_init(void) {
    uart_set_baud(0, 115200);
    gpio_set_pullup(14, false, false); // or gpio_write(14, false);
    //....
    //....
    ir_tx_init(); // or put inside this function, but I call this after homekit is paried. Maybe too late.
}

Experiment

You may do some experiments yourself. I want to add a technical reference to prove my result but I can't find it because most people care only about HIGH/LOW during boot state. You can find conclusion elsewhere: only D1(GPIO4) D2(GPIO5) are the safe pins to use. They are always low. However, i2s WS pin can't use these pins.

Just replace your IR led with visible light led and proper resistor. You can find the LED light "slightly" even after boot. This is because GPIO 14 is pulled up by default and has small voltage. This doesn't matter if you connect IR led to GPIO14/GND because the current is far too small.
P_20190917_091247

However, If GPIO14 this is connected to NPN transistor base to switch on/off the IR led, then the IR led will be ON state whole time until you send any IR signal at least one time! (because clr_carrier() explicitly write that pin to low). I use 1k ohms resistor for my 2N2222 base and this GPIO 14 pull-up voltage is still high enough to switch on the IR led. (I replace IR led with Red LED for demostration)

P_20190917_083007

My Story behind this suggestion

I use very low resistor (10 ohm, not 220 ohms for RED LED I demonstrated above) for my IR led because my esp8266 board is far away from my AC. It works totally fine because IR led should only turn on for short pulse during signal transmission. And it's 50% duty cycle hence reduce effective current by half.

Yesterday I find I broke my IR LED. I moved my board to another place, hence the power to my NodeMCU board was temperately down and back thus the system reboot. Actually I had done this several times without any issues. The only difference is that: this time I don't test if it still works after boot so it doesn't send at least one IR led signal ( no carrier_clr() write GPIO14 to low). And about one day later, I find it no longer works. I think the reason is that the IR led stay on with high current > 24 hours so IR led burn. I want to share this result and suggestion. Thanks for reading this far.

Tested and reproducible on hardware:

  • NodeMCU 1.0, ( with CP2102 Serial Chip) (3 boards)

Tested and reproducible on firmware:

  • esp-open-rtos
  • ESP8266_RTOS_SDK v3.2

GPIO 14 is not HIGH, but pull up with small voltage by default during flash/boot/after boot.

Latest fix for esp8266 bug seems to introduce a new bug with sending RAW

Here is the code I tried:

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

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



static int16_t command1[] = {3375 , -1771 ,   359 , -1378 ,   353 ,  -530 ,   352 ,  -531 ,   382 ,  -531 ,   382 , -1381 ,   361 ,  -522 ,   359 ,  -524 ,
357 ,  -526 ,   387 ,  -526 ,   387 , -1376 ,   356 ,  -527 ,   354 , -1379 ,   352 , -1381 ,   351 ,  -532 ,   360 , -1373 ,
358 , -1375 ,   356 , -1377 ,   355 , -1378 ,   353 , -1380 ,   351 ,  -532 ,   360 ,  -523 ,   359 , -1374 ,   389 ,  -524 ,
389 ,  -524 ,   357 ,  -526 ,   355 ,  -528 ,   417 ,  -467 ,   351 ,  -531 ,   382 ,  -531 ,   445 ,  -469 ,   360 ,  -522 ,
360 ,  -523 ,   358 , -1375 ,   388 ,  -525 ,   388 , -1375 ,   356 ,  -527 ,   355 ,  -528 ,   353 ,  -530 ,   351 , -1382 ,
360 , -1373 ,   359 ,  -524 ,   357 ,  -526 ,   356 ,  -527 ,   354 ,  -529 ,   352 ,  -531 ,   351 ,  -532 ,   360 ,  -523 ,
358 ,  -526 ,   387 ,  -526 ,   356 ,  -527 ,   354 ,  -529 ,   352 ,  -531 ,   351 ,  -532 ,   360 ,  -523 ,   358 ,  -525 ,
357 ,  -526 ,   387 , -1376 ,   355 , -1378 ,   353 , -1380 ,   352 ,  -531 ,   361 , -1372 ,   359 ,  -524 ,   357 , -1376 ,
356 , -1377 ,   354 , -32029 ,  3373 , -1773 ,   357 , -1380 ,   383 ,  -530 ,   352 ,  -531 ,   350 ,  -533 ,   359 , -1374 ,
358 ,  -525 ,   356 ,  -527 ,   355 ,  -528 ,   384 ,  -529 ,   353 , -1380 ,   351 ,  -532 ,   360 , -1373 ,   359 , -1374 ,
357 ,  -526 ,   356 , -1377 ,   354 , -1379 ,   352 , -1381 ,   351 , -1382 ,   359 , -1374 ,   358 ,  -525 ,   356 ,  -527 ,
355 , -1378 ,   385 ,  -528 ,   353 ,  -530 ,   351 ,  -532 ,   361 ,  -522 ,   359 ,  -524 ,   357 ,  -526 ,   356 ,  -527 ,
386 ,  -527 ,   386 ,  -527 ,   354 ,  -529 ,   353 ,  -530 ,   351 , -1382 ,   381 ,  -532 ,   381 ,  -532 ,   360 ,  -523 ,
358 ,  -525 ,   357 , -1376 ,   355 ,  -528 ,   385 , -1378 ,   353 ,  -530 ,   352 ,  -531 ,   361 , -1372 ,   359 ,  -524 ,
357 ,  -526 ,   356 , -1377 ,   354 ,  -529 ,   353 , -1380 ,   351 ,  -532 ,   360 , -1373 ,   358 ,  -525 ,   356 ,  -527 ,
355 ,  -528 ,   353 ,  -530 ,   352 ,  -532 ,   360 ,  -523 ,   358 , -1375 ,   357 ,  -526 ,   355 ,  -528 ,   353 ,  -529 ,
353 , -1380 ,   351 ,  -532 ,   360 , -1373 ,   359 , -32024 ,  3378 , -1772 ,   358 , -1379 ,   352 ,  -531 ,   351 ,  -532 ,
381 ,  -532 ,   381 , -1381 ,   360 ,  -523 ,   359 ,  -524 ,   357 ,  -527 ,   386 ,  -527 ,   386 , -1377 ,   354 ,  -529 ,
353 , -1379 ,   352 , -1381 ,   361 ,  -522 ,   359 , -1374 ,   358 , -1376 ,   355 , -1378 ,   353 , -1380 ,   352 , -1381 ,
360 ,  -523 ,   359 ,  -524 ,   357 , -1375 ,   388 ,  -525 ,   388 ,  -526 ,   355 ,  -528 ,   354 ,  -529 ,   352 ,  -531 ,
351 ,  -532 ,   360 ,  -523 ,   358 ,  -525 ,   389 ,  -524 ,   388 ,  -525 ,   357 ,  -526 ,   355 ,  -528 ,   353 ,  -530 ,
352 ,  -531 ,   361 ,  -522 ,   391 ,  -522 ,   391 ,  -522 ,   359 ,  -524 ,   358 , -1375 ,   356 ,  -527 ,   386 ,  -527 ,
386 ,  -527 ,   354 ,  -529 ,   353 ,  -530 ,   351 , -1382 ,   360 ,  -523 ,   390 ,  -523 ,   390 ,  -523 ,   358 ,  -525 ,
357 ,  -526 ,   355 , -1378 ,   353 , -1380 ,   352 ,  -531 ,   361 ,  -522 ,   359 ,  -524 ,   357 ,  -526 ,   356 ,  -527 ,
354 ,  -529 ,   353 ,  -530 ,   351 ,  -532 ,   360 ,  -523 ,   358 ,  -526 ,   387 ,  -526 ,   356 ,  -527 ,   354 ,  -529 ,
353 ,  -530 ,   351 ,  -532 ,   360 ,  -523 ,   411 , -1323 ,   356 ,  -526 ,   355 ,  -528 ,   354 ,  -529 ,   352 ,  -531 ,
351 ,  -532 ,   360 ,  -523 ,   358 ,  -525 ,   356 ,  -527 ,   355 ,  -528 ,   385 ,  -528 ,   353 ,  -530 ,   352 ,  -531 ,
361 ,  -522 ,   359 ,  -524 ,   358 ,  -525 ,   356 ,  -527 ,   354 ,  -529 ,   384 ,  -529 ,   353 , -1380 ,   351 , -1382 ,
360 ,  -523 ,   358 ,  -525 ,   357 ,  -526 ,   355 ,  -528 ,   354 ,  -530 ,   351 ,  -532 ,   360 ,  -523 ,   359 ,  -524 ,
357 ,  -526 ,   355 ,  -528 ,   354 , -1378 ,   353 , -1380 ,   351 ,  -533 ,   359 ,  -524 ,   358 ,  -525 ,   356 ,  -527 ,
355 ,  -528 ,   353 ,  -530 ,   352 ,  -531 ,   361 ,  -522 ,   359 ,  -525 ,   356 ,  -526 ,   356 ,  -527 ,   354 ,  -529 ,
352 ,  -531 ,   351 ,  -532 ,   360 ,  -523 ,   358 ,  -525 ,   357 ,  -526 ,   387 ,  -526 ,   355 ,  -528 ,   354 ,  -529 ,
352 ,  -531 ,   361 ,  -522 ,   359 ,  -524 ,   358 , -1375 ,   356 , -1378 ,   353 ,  -530 ,   352 ,  -531 ,   350 ,  -533 ,
359 ,  -524 ,   358 ,  -525 ,   356 ,  -527 ,   355 ,  -528 ,   353 ,  -530 ,   383 ,  -530 ,   352 ,  -531 ,   360 ,  -523 ,
359 ,  -524 ,   357 ,  -526 ,   356 ,  -527 ,   354 ,  -529 ,   353 ,  -530 ,   383 , -1380 ,   351 ,  -532 ,   360 ,  -523 ,
358 , -1375 ,   357 ,  -526 ,   355 , -1378 ,   353 , -1380 ,   353 , -1380 ,   361}; 
void user_init(void) {
    uart_set_baud(0, 115200);
	
	 printf("Starting \n");
	ir_tx_init();
	
	while(1)
	{
	 printf("Sending \n");
	ir_raw_send(command1, sizeof(command1) / sizeof(*command1));
	
	vTaskDelay( 4000 / portTICK_PERIOD_MS );
	}


}

Doubt: about sending raw values

Hello Max,

I was looking at the demo, I noticed that my compiler refuses to compile with your example and decided to change it to:
static int16_t command1[] = {}
After that it compiles, anyhow, I dumped a ir remote with your library and gives me this:
Decoded packet (size = 67): 8954 -4567 490 -617 514 -595 486 -619 512 -1754 461 -645 486 -621 463 -617 489 -618 488 -1778 461 -1750 489 -1749 513 -620 486 -1727 513 -1751 486 -1727 488 -1751 487 -1751 512 -1752 462 -617 514 -619 462 -619 512 -594 512 -594 513 -1751 487 -619 488 -592 514 -1727 512 -1727 512 -1728 511 -1728 512 -1727 512 -619 488

I also dumped with the IRRemoteESP8266, just to compare reasons and gave me this:
{8946, 4544, 538, 566, 542, 592, 512, 566, 538, 1724, 512, 568, 512, 594, 512, 594, 512, 594, 536, 1700, 538, 1700, 512, 1726, 512, 594, 510, 1726, 536, 1726, 486, 1724, 512, 1750, 542, 1670, 510, 1724, 514, 592, 512, 618, 486, 594, 512, 594, 510, 594, 512, 1752, 486, 594, 510, 568, 538, 1726, 510, 1722, 512, 1726, 510, 1724, 512, 1724, 510, 620, 460, 40564, 8946, 2326, 460}; // NEC 10EFC13E

According to the example I should leave the - negatives? or should I remove them?, with the negatives like this:

static int16_t command1[67] = {8954, -4567, 490,-617, 514,-595, 486,-619, 512 -1754, 461,-645, 486,-621, 463,-617,
489,-618, 488 -1778, 461 -1750, 489 -1749, 513,-620, 486 -1727, 513 -1751, 486 -1727,
488 -1751, 487 -1751, 512 -1752, 462,-617, 514,-619, 462,-619, 512,-594, 512,-594,
513 -1751, 487,-619, 488,-592, 514 -1727, 512 -1727, 512 -1728, 511 -1728, 512 -1727,512,-619, 488};

void ir_dump_task(void *arg) {
while(1){
ir_raw_send(command1, sizeof(command1) / sizeof(*command1));
vTaskDelay(5000 / portTICK_PERIOD_MS);
}

}

I cannot get it to transmit (it does blink the led) and my other doubt is:
ir_raw_send(command1, sizeof(command1) / sizeof(*command1)); should it be only the sizeof(command1)?

Some questions about carrier frequency and duty cycle

I used to work with high level raspberry pi with LIRC. I find it sometimes unstable. Even if there's hardware 38KHz pwm support, however, the IR space delay using usleep() is too inaccurate under linux to guarantee a successful IR signal. (my AC fails to get my generated IR signal about 3~5% even if it's very close to the AC and with a transistor/5V support)

Q1: I'm very new to esp-8266 and RTOS. I think it's possible to make this much more accurate to use NodeMCU (ESP-8266) compared to raspberry pi, right? I just ordered NodeMCU v3 so I can't test right now. I'm just trying to build esp-homekit-demo and investigate the code.

Q2: How can I adjust carrier frequency and duty cycle when sending IR signal? For example, I want to emit 36khz / 30% duty cycle or 40khz (for Sony), is it possible?

I investigate other libraries, it seems most of them generate pulse manually by using
1 / 38KHz delay and gpio_wrtie high or low on any GPIO output. I think this is very inaccurate because the result are rounded to 26 us (from 26.315789474us). The actual generated carrier frequency is 38461Hz. It seems that your library use very different mechanism to generate the pulse. I can't figure out how to change carrier frequency and duty cycle.

I think this is the key part but I can't figure out why it's 62 and 2 here.

    // Set i2s clk freq 
    I2S.CONF = SET_FIELD(I2S.CONF, I2S_CONF_BCK_DIV, 62);
    I2S.CONF = SET_FIELD(I2S.CONF, I2S_CONF_CLKM_DIV, 2);
    I2S.CONF = SET_FIELD(I2S.CONF, I2S_CONF_BITS_MOD, 0);

homekit and ir combination

Hi,

I'm having an intermittent issue with the following code. At random times, the IR sending part is no longer generating the proper signal to send the remote codes - sometimes are not recognised at all by the TV, sometimes are sent with minor variations and it is received as a different button press. I have tried to reinitialise the TX part by also changing the ir_tx_init function to delete the event group if defined, but I had absolutely no luck. Sometimes, the IR sending part comes back to proper behaviour, sometimes I loose my patience and I reset the ESP. Also, as you can see, I'm using ir_generic_send() and ir_raw_send(). Once sending is starting to randomly fail, the same applies to codes sent by the both functions. Can the timer be affected by the homekit part? As you can see from the code, the channel (input source) name is editable from the iPhone, so if you define an input source '51 Viasat History HD', the ESP will send the codes for 5, 1, OK to the TV when this input source is selected. Once the failure starts, I get random combinations of just 5 send, just 1 sent, just 5 and 1 sent, random button press sent - I even managed to turn off the TV several times :)

Here's the complete code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <esp/uart.h>
#include <esp/gpio.h>
#include <espressif/esp_common.h>
#include <sysparam.h>
#include <FreeRTOS.h>
#include <task.h>
#include <homekit/characteristics.h>
#include <homekit/homekit.h>
#include <wifi_config.h>
#include <ir/ir.h>
#include <ir/generic.h>
#include <ir/raw.h>

homekit_server_config_t config;

#define CHANNELS 10

uint8_t ch_data[10][4] = 
{
    {0x20, 0x08, 0x47, 0xB8},
    {0x20, 0x08, 0x1C, 0xE3},
    {0x20, 0x08, 0x1D, 0xE2},
    {0x20, 0x08, 0x1E, 0xE1},
    {0x20, 0x08, 0x40, 0xBF},
    {0x20, 0x08, 0x41, 0xBE},
    {0x20, 0x08, 0x42, 0xBD},
    {0x20, 0x08, 0x44, 0xBB},
    {0x20, 0x08, 0x45, 0xBA},
    {0x20, 0x08, 0x46, 0xB9},
};

ir_generic_config_t protocol = {
    .header_mark = 9000,
    .header_space = -4500,

    .bit1_mark = 560,
    .bit1_space = -1690,

    .bit0_mark = 560,
    .bit0_space = -560,

    .footer_mark = 560,
    .footer_space = -9000,

    .tolerance = 20,
};

void ir_send(uint8_t *data, uint8_t size)
{
    ir_tx_init();

    ir_generic_send(&protocol, data, size);
}

struct
{
    uint8_t active;
    uint32_t active_identifier;
    char configured_name[1024];
    uint8_t sleep_discovery_mode;
} device_state;

void device_identify(homekit_value_t value)
{
    printf("device_identify: %d\n", value.bool_value);
}

homekit_value_t device_active_get()
{
    printf("device_active_get: %d\n", device_state.active);

    return HOMEKIT_UINT8(device_state.active);
}

void device_active_set(homekit_value_t value)
{
    if (device_state.active != value.uint8_value)
    {
        int16_t data[] = {8934, -4534, 525, -630, 503, -630, 503, -1713, 527, -601, 532, -630, 503, -630, 503, -630, 502, -631, 503, -1714, 525, -1738, 502, -630, 503, -1716, 524, -1738, 501, -1714, 526, -1716, 524, -1737, 502, -631, 502, -631, 502, -631, 502, -1715, 525, -631, 502, -631, 502, -602, 531, -631, 502, -1738, 502, -1716, 523, -1716, 525, -630, 502, -1714, 526, -1709, 531, -1715, 524, -1710, 530};

        ir_tx_init();

        ir_raw_send(data, sizeof(data)/sizeof(*data));
    }

    device_state.active = value.uint8_value;

    printf("device_active_set: %d\n", device_state.active);
}

homekit_value_t device_active_identifier_get()
{
    printf("device_active_identifier_get: %u\n", device_state.active_identifier);

    return HOMEKIT_UINT32(device_state.active_identifier);
}

void device_active_identifier_set(homekit_value_t value)
{
    if (device_state.active_identifier != value.uint32_value)
    {
        char *ch_name_value = NULL;

        homekit_service_t **srv = config.accessories[0]->services + 3;

        while (*srv)
        {
            if (value.uint32_value == (*srv)->characteristics[1]->value.uint32_value)
            {
                ch_name_value = (*srv)->characteristics[2]->value.string_value;

                break;
            }

            srv++;
        }

        if (ch_name_value)
        {
            printf("device_active_identifier_set: channel name value: %s\n", ch_name_value);

            bool sent = false;

            for (uint8_t i = 0; i < strlen(ch_name_value); i++)
            {
                if (ch_name_value[i] >= '0' && ch_name_value[i] <= '9')
                {
                    sent = true;

                    ir_send(ch_data[ch_name_value[i] - '0'], 4);

                    vTaskDelay(500 / portTICK_PERIOD_MS);

                    printf("device_active_identifier_set: sending code for %d\n", (int16_t)(ch_name_value[i] - '0'));
                }
                else
                {
                    break;
                }
            }

            if (sent)
            {
                uint8_t data[] = {0x20, 0x08, 0x15, 0xEA};

                ir_send(data, 4);
            }
        } else {
            printf("device_active_identifier_set: channel not found: %u\n", value.uint32_value);
        }
    }

    device_state.active_identifier = value.uint32_value;

    printf("device_active_identifier_set: %u\n", device_state.active_identifier);
}

homekit_value_t device_configured_name_get()
{
    printf("device_configured_name_get: %s\n", device_state.configured_name);

    return HOMEKIT_STRING(strdup(device_state.configured_name), .is_static = 0);
}

void device_configured_name_set(homekit_value_t value)
{
    strncpy(device_state.configured_name, value.string_value, 1024);

    sysparam_set_string("device_state_configured_name", device_state.configured_name);

    printf("device_configured_name_set: %s\n", device_state.configured_name);
}

homekit_value_t device_sleep_discovery_mode_get()
{
    printf("device_sleep_discovery_mode_get: %d\n", device_state.sleep_discovery_mode);

    return HOMEKIT_UINT8(device_state.sleep_discovery_mode);
}

void device_sleep_discovery_mode_set(homekit_value_t value)
{
    device_state.sleep_discovery_mode = value.uint8_value;

    printf("device_sleep_discovery_mode_set: %d\n", device_state.sleep_discovery_mode);
}

void device_remote_key_set(homekit_value_t value)
{
    switch (value.uint8_value)
    {
        case HOMEKIT_REMOTE_KEY_ARROW_UP:
        {
            uint8_t data[] = {0x20, 0x08, 0x12, 0xED};

            ir_send(data, 4);
        }
        break;

        case HOMEKIT_REMOTE_KEY_ARROW_DOWN:
        {
            uint8_t data[] = {0x20, 0x08, 0x13, 0xEC};

            ir_send(data, 4);
        }
        break;

        case HOMEKIT_REMOTE_KEY_ARROW_LEFT:
        {
            uint8_t data[] = {0x20, 0x08, 0x14, 0xEB};

            ir_send(data, 4);
        }
        break;

        case HOMEKIT_REMOTE_KEY_ARROW_RIGHT:
        {
            uint8_t data[] = {0x20, 0x08, 0x16, 0xE9};

            ir_send(data, 4);
        }
        break;

        case HOMEKIT_REMOTE_KEY_SELECT:
        {
            uint8_t data[] = {0x20, 0x08, 0x15, 0xEA};

            ir_send(data, 4);
        }
        break;

        case HOMEKIT_REMOTE_KEY_BACK:
        {
            uint8_t data[] = {0x20, 0x08, 0x0C, 0xF3};

            ir_send(data, 4);
        }
        break;

        case HOMEKIT_REMOTE_KEY_INFORMATION:
        {
            uint8_t data[] = {0x20, 0x08, 0x0D, 0xF2};

            ir_send(data, 4);
        }
        break;

        default:
        break;
    }

    printf("device_remote_key_set: %d\n", value.uint8_value);
}

void speaker_mute_set(homekit_value_t value)
{
    printf("speaker_mute_set: %d\n", value.bool_value);
}

void speaker_volume_selector_set(homekit_value_t value)
{
    switch (value.uint8_value)
    {
        case HOMEKIT_VOLUME_SELECTOR_INCREMENT:
        {
            uint8_t data[] = {0x20, 0x08, 0x02, 0xFD};

            ir_send(data, 4);
        }
        break;

        case HOMEKIT_VOLUME_SELECTOR_DECREMENT:
        {
            uint8_t data[] = {0x20, 0x08, 0x03, 0xFC};
            ir_send(data, 4);
        }
        break;

        default:
        break;
    }

    printf("speaker_volume_selector_set: %d\n", value.uint8_value);
}

void channel_on_configured_name(homekit_characteristic_t *ch, homekit_value_t value, void *arg)
{
    const char *ch_name = NULL;

    homekit_service_t **srv = config.accessories[0]->services + 3;

    while (*srv)
    {
        if (ch == (*srv)->characteristics[2])
        {
            ch_name = (*srv)->characteristics[0]->value.string_value;

            break;
        }

        srv++;
    }

    if (ch_name)
    {
        sysparam_set_string(ch_name, value.string_value);

        printf("channel_on_configured_name: set name %s for channel %s\n", value.string_value, ch_name);
    }
}

homekit_server_config_t config = {
    .accessories = (homekit_accessory_t *[]){
        HOMEKIT_ACCESSORY(
            .id = 1,
            .category = homekit_accessory_category_television,
            .services = (homekit_service_t*[1 + 1 + 1 + CHANNELS + 1])
            {
                HOMEKIT_SERVICE(
                    ACCESSORY_INFORMATION,
                    .characteristics = (homekit_characteristic_t*[])
                    {
                        HOMEKIT_CHARACTERISTIC(NAME, "IrTvRemote"),
                        HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Andrei Gavrila"),
                        HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "000000000000"),
                        HOMEKIT_CHARACTERISTIC(MODEL, "Infrared Television Remote"),
                        HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1"),
                        HOMEKIT_CHARACTERISTIC(IDENTIFY, device_identify),
                        NULL
                    }
                ),
                HOMEKIT_SERVICE(
                    TELEVISION,
                    .primary = true,
                    .characteristics = (homekit_characteristic_t*[])
                    {
                        HOMEKIT_CHARACTERISTIC(ACTIVE, 0, .getter = device_active_get, .setter = device_active_set),
                        HOMEKIT_CHARACTERISTIC(ACTIVE_IDENTIFIER, 1, .getter = device_active_identifier_get, .setter = device_active_identifier_set),
                        HOMEKIT_CHARACTERISTIC(CONFIGURED_NAME, "Television", .getter = device_configured_name_get, .setter = device_configured_name_set),
                        HOMEKIT_CHARACTERISTIC(SLEEP_DISCOVERY_MODE, HOMEKIT_SLEEP_DISCOVERY_MODE_ALWAYS_DISCOVERABLE, .getter = device_sleep_discovery_mode_get, .setter = device_sleep_discovery_mode_set),
                        HOMEKIT_CHARACTERISTIC(REMOTE_KEY, .setter = device_remote_key_set),
                        NULL
                    },
                    .linked = (homekit_service_t*[CHANNELS + 1]){}
                ),
                HOMEKIT_SERVICE(
                    TELEVISION_SPEAKER,
                    .characteristics = (homekit_characteristic_t*[])
                    {
                        HOMEKIT_CHARACTERISTIC(MUTE, 0, .setter = speaker_mute_set),
                        HOMEKIT_CHARACTERISTIC(ACTIVE, 1),
                        HOMEKIT_CHARACTERISTIC(VOLUME_CONTROL_TYPE, HOMEKIT_VOLUME_CONTROL_TYPE_RELATIVE),
                        HOMEKIT_CHARACTERISTIC(VOLUME_SELECTOR, .setter = speaker_volume_selector_set),
                        NULL
                    }
                )
            }
        ),
        NULL
    },
    .password = "111-11-111"
};

void on_wifi_ready()
{
    homekit_server_init(&config);
}

void user_init(void) {
    char *s = NULL;

    uart_set_baud(0, 115200);

    gpio_set_pullup(14, false, false);

    ir_tx_init();

    for (uint8_t i = 0; i < CHANNELS; i++)
    {
        int ch_name_len = snprintf(NULL, 0, "ch_name_%d", i);
        char *ch_name = (char *)malloc(sizeof(char)*(ch_name_len + 1));
        snprintf(ch_name, ch_name_len + 1, "ch_name_%d", i);

        int ch_name_value_len = snprintf(NULL, 0, "Channel %d", i);
        char *ch_name_value = (char *)malloc(sizeof(char)*(ch_name_value_len + 1));
        snprintf(ch_name_value, ch_name_value_len + 1, "Channel %d", i);

        homekit_service_t *srv = NEW_HOMEKIT_SERVICE(
            INPUT_SOURCE,
            .characteristics = (homekit_characteristic_t*[]) {
                NEW_HOMEKIT_CHARACTERISTIC(NAME, ch_name),
                NEW_HOMEKIT_CHARACTERISTIC(IDENTIFIER,  i + 1),
                NEW_HOMEKIT_CHARACTERISTIC(
                    CONFIGURED_NAME,
                    ch_name_value,
                    .callback = HOMEKIT_CHARACTERISTIC_CALLBACK(channel_on_configured_name)
                ),
                NEW_HOMEKIT_CHARACTERISTIC(INPUT_SOURCE_TYPE, HOMEKIT_INPUT_SOURCE_TYPE_TUNER),
                NEW_HOMEKIT_CHARACTERISTIC(IS_CONFIGURED, 1),
                NEW_HOMEKIT_CHARACTERISTIC(CURRENT_VISIBILITY_STATE, HOMEKIT_CURRENT_VISIBILITY_STATE_SHOWN),
                NULL
            }
        );

        config.accessories[0]->services[1]->linked[i] = srv;
        config.accessories[0]->services[1 + 1 + 1 + i] = srv;
    }

    config.accessories[0]->services[1]->linked[CHANNELS] = NULL;
    config.accessories[0]->services[1 + 1 + 1 + CHANNELS] = NULL;

    device_state.active = 0;
    device_state.active_identifier = 1;
    if (sysparam_get_string("device_state_configured_name", &s) == SYSPARAM_OK)
    {
        strncpy(device_state.configured_name, s, 1024);

        free(s);
    }
    else
    {
        strncpy(device_state.configured_name, "Television", 1024);
    }
    device_state.sleep_discovery_mode = HOMEKIT_SLEEP_DISCOVERY_MODE_ALWAYS_DISCOVERABLE;

    homekit_service_t **srv = config.accessories[0]->services + 3;

    while (*srv)
    {
        if (sysparam_get_string((*srv)->characteristics[0]->value.string_value, &s) == SYSPARAM_OK)
        {
            homekit_value_destruct(&((*srv)->characteristics[2]->value));
            (*srv)->characteristics[2]->value = HOMEKIT_STRING(s);

            printf("user_init: set name %s for channel %s\n", s, (*srv)->characteristics[0]->value.string_value);
        }

        srv++;
    }

    wifi_config_init("Infrared Television Remote", NULL, on_wifi_ready);
}

Schematic circuit diagram of the IR part

Hi Maxim,

I wanted to ask you about the circuit diagram. I'm using the following schematic in regards to the IR part.
IR Circuit

Are you using the same or anything similar? Do you see any room for improvements or corrections?

Thanks
Yiannis

esp32 compatibility

I was wondering, can I compile against an esp32? I noticed some of the includes are standard libs, or the timer registers are different?

Worked on Samsung TV Remote. Troubles with A/C

Hi Maxim,

today I found some time to test your library. The IR Dumper example worked out of the box.

The IR Send code found in the repo's start page needed a small modification:

static int16_t[] command1 =.... >> static int16_t command1[] =....

As mentioned, I was successful testing Samsung TV IR commands, but I wasn't successful testing A/C IR commands.
If you have any advice on how to troubleshoot or tinker it, it would be greatly appreciated.

Many Thanks!!!

IR raw_dumper example not reading data

While trying to use raw_dumper example, in the line ir_rx_init(IR_RX_GPIO, 1024) esp was waiting for initializing but not initializing hanging on that line not initializing and not reading ir signal.......please help me!!!

error raw_dumper

hi, im ring to build the example, but I get this error...

./build/program.a(raw_dumper.o):(.text.ir_dump_task+0x8): undefined reference to ir_rx_init'
./build/program.a(raw_dumper.o):(.text.ir_dump_task+0xc): undefined reference to ir_raw_make_decoder' ./build/program.a(raw_dumper.o):(.text.ir_dump_task+0x10): undefined reference to ir_recv'
./build/program.a(raw_dumper.o):(.text.ir_dump_task+0x26): undefined reference to ir_rx_init' ./build/program.a(raw_dumper.o):(.text.ir_dump_task+0x2c): undefined reference to ir_raw_make_decoder'
./build/program.a(raw_dumper.o): In function ir_dump_task': /home/user/esp-open-rtos/examples/esp-ir/raw_dumper.c:22: undefined reference to ir_recv'`

any help? thnx !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.