maximkulkin / esp-ir Goto Github PK
View Code? Open in Web Editor NEWLibrary for ESP-OPEN-RTOS to send IR commands.
License: MIT License
Library for ESP-OPEN-RTOS to send IR commands.
License: MIT License
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);
}
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 !
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!!!
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)?
What does I2S_CONF_RX_START do in the gen_carrier() and clr_carrier()
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 );
}
}
I was wondering, can I compile against an esp32? I noticed some of the includes are standard libs, or the timer registers are different?
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?
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!!!
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.
}
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.
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)
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:
Tested and reproducible on firmware:
GPIO 14 is not HIGH, but pull up with small voltage by default during flash/boot/after boot.
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);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.