• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ir-remote: библиотека для управления техникой по ИК каналу

DarkSide

New member
Исходный код доступен по адресу https://github.com/valkuc/esp8266-ir-remote
Библиотека позволяет отправлять ИК коды для протоколов NEC, Panasonic, Sony, Samsung. Тайминги были взяты из одноименной библиотеки для Arduino.

Идеи:
- было бы неплохо вместо TIMER ISR использовать SIGMA-DELTA для ШИМ, но запутался в конец с этими регистрами. Если есть желающие - welcome!
 

aIDAR

New member
Здравствуйте DarkSide, я недавно приобрел ЕСП-07, пытаюсь изучить но ничего толком не получается. Моя цель подключить IR передатчик и переключать каналы телевизора через WIFI.
На ардуине все сам сделал все работает только через блютуз. Не могли бы Вы мне подсказать что да как делать, как подключить передатчик к какому выходу на ЕСП, как залить программу и как отправлять запросы
 

DarkSide

New member
Здравствуйте. Я использовал ESP-01. Подключение ИК-диода и вспомогательных кнопок во вложении. Особенность данной схемы в том, что ИК-диод подтянут к VCC резистором. Это необходимо для старта ESP модуля, т.к. ИК-диод подключен к GPIO2.
 

Вложения

Creature

New member
@DarkSide прошу прощения за совсем уж ламерский вопрос... А нет ли где-нибудь более подробного описания вашего проекта? Я во всем этом новичок, начал собирать систему домашней автоматизации, есть BananaPi, которая посредством OpenHAB уже управляет устройствами на 433мГц, но категорически не хватает интерфейса ИК-управления и самым удобным было бы построить его на 8266. Но я, конечно же, вообще не имел с ней дело и не совсем понятно как именно собрать микропрограмму для нее. Был бы премного благодарен за HOWTO с примерами управляющих команд, отправляемых на 8266.
 

DarkSide

New member
@DarkSide прошу прощения за совсем уж ламерский вопрос... А нет ли где-нибудь более подробного описания вашего проекта? Я во всем этом новичок, начал собирать систему домашней автоматизации, есть BananaPi, которая посредством OpenHAB уже управляет устройствами на 433мГц, но категорически не хватает интерфейса ИК-управления и самым удобным было бы построить его на 8266. Но я, конечно же, вообще не имел с ней дело и не совсем понятно как именно собрать микропрограмму для нее. Был бы премного благодарен за HOWTO с примерами управляющих команд, отправляемых на 8266.
Пример отправки команды вы можете посмотреть в файле https://github.com/valkuc/esp8266-ir-remote/blob/master/user/user_main.c
Например, ir_remote_send_nec(0x5EA1F807, 32); - отправить 32 битны код 0x5EA1F807
Для ваших нужд одной отправки кодов будет мало, т.к. эти коды, я так понимаю, вы хотите отправлять по wifi с banana-pi. Для этого нужно написать TCP/UPD-сервер на стороне ESP, который будет принимать эти коды и отправлять в ИК-диод.

HOWTO по командам вам никто писать не будет - есть известные и стандартные протоколы от не менее известных брендов - это NEC, Panasonic, Samsung, Sony (ну может еще парочка найдется). Ищите даташит на протокол, изучаете команды. Либо более простой вариант: сканирование кода который отправляет пульт. Для этого нужен ИК приемник, руки и гугл (яндекс).

Сама библиотека ir-remote документирована - смотрите файл https://github.com/valkuc/esp8266-ir-remote/blob/master/include/ir_remote.h

Так же предоставляю вам кусок кода который создает слушающий UDP сервер и передает команды в ИК-либу:
Код:
void ICACHE_FLASH_ATTR udp_server_task(void *pvParameters)
{
    struct sockaddr_in server_addr, client_addr;
    int server_sock, client_sock;
    socklen_t sin_size = sizeof(client_addr);

    bzero(&server_addr, sizeof(struct sockaddr_in));
    server_addr.sin_family = AF_INET;
    server_addr.sin_len = sizeof(struct sockaddr_in);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(93);

    if (-1 == (server_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
    {
        return;
    }

    if (-1 == bind(server_sock, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)))
    {
        return;
    }

    printf("UDP server listening on port: %d\n", ntohs(server_addr.sin_port));

    int recbytes;
    uint32_t code;

    for (;;)
    {
        if ((recbytes = recvfrom(server_sock, &code, sizeof(code), 0, (struct sockaddr *)&client_addr, &sin_size)) != -1)
        {
            if (code > 0)
            {
                ir_remote_send_nec(code, 32);
                // 40ms after the pulse burst that signified the end of the message
                vTaskDelay(40 / portTICK_RATE_MS);
            }
        }
    }
}

void ICACHE_FLASH_ATTR user_init(void)
{
    uart_init();

    ir_remote_init(2, true);

    if (wifi_station_get_auto_connect() != 1)
        wifi_station_set_auto_connect(1);
    if (wifi_get_phy_mode() != PHY_MODE_11N)
        wifi_set_phy_mode(PHY_MODE_11N);
    if (wifi_get_sleep_type() != MODEM_SLEEP_T)
        wifi_set_sleep_type(MODEM_SLEEP_T);

    // connect to wifi here

    xTaskCreate(udp_server_task, "udp_server_task", 256, NULL, 1, NULL);
}
Код писался еще под версию rtos sdk < 1.0.0 (даже не помню точно версию).
 

tolyan23

New member
Так же предоставляю вам кусок кода который создает слушающий UDP сервер и передает команды в ИК-либу:
Код:
void ICACHE_FLASH_ATTR udp_server_task(void *pvParameters)
{
    struct sockaddr_in server_addr, client_addr;
    int server_sock, client_sock;
    socklen_t sin_size = sizeof(client_addr);

    bzero(&server_addr, sizeof(struct sockaddr_in));
    server_addr.sin_family = AF_INET;
    server_addr.sin_len = sizeof(struct sockaddr_in);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(93);

    if (-1 == (server_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
    {
        return;
    }

    if (-1 == bind(server_sock, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)))
    {
        return;
    }

    printf("UDP server listening on port: %d\n", ntohs(server_addr.sin_port));

    int recbytes;
    uint32_t code;

    for (;;)
    {
        if ((recbytes = recvfrom(server_sock, &code, sizeof(code), 0, (struct sockaddr *)&client_addr, &sin_size)) != -1)
        {
            if (code > 0)
            {
                ir_remote_send_nec(code, 32);
                // 40ms after the pulse burst that signified the end of the message
                vTaskDelay(40 / portTICK_RATE_MS);
            }
        }
    }
}

void ICACHE_FLASH_ATTR user_init(void)
{
    uart_init();

    ir_remote_init(2, true);

    if (wifi_station_get_auto_connect() != 1)
        wifi_station_set_auto_connect(1);
    if (wifi_get_phy_mode() != PHY_MODE_11N)
        wifi_set_phy_mode(PHY_MODE_11N);
    if (wifi_get_sleep_type() != MODEM_SLEEP_T)
        wifi_set_sleep_type(MODEM_SLEEP_T);

    // connect to wifi here

    xTaskCreate(udp_server_task, "udp_server_task", 256, NULL, 1, NULL);
}
for (;;) я так понимаю бесконечный цикл в котором все и слушается?
можно увидеть содержимое xTaskCreate(udp_server_task, "udp_server_task", 256, NULL, 1, NULL); или хотябы описание что это такое и что делает
recvfrom() какая то функция которая считывает новые данные полученные в запросе
что значит !=-1 не равно -1 а в каком случае функция возвращает -1?
 

CHERTS

Moderator
Команда форума
DarkSide, а нет ли у Вас желание переписать эту библиотеку на классический Espressif SDK?
 

chubuchnyi

New member
Подскажите пожалуйста, может кто сталкивался с таким. Настраиваю hw_timer на работу на определенной частоте, использую стандартные средства Espressif SDK:
Код:
hw_timer_init(FRC1_SOURCE,0);//timer use frc1 isr as isr source., 0 - not autoload
    hw_timer_set_func(pwm_tim1_intr_handler);
    hw_timer_arm(20);
при этом в прерывании сбрасываю таймер,
Код:
void pwm_tim1_intr_handler()
{
//мой код просто инвертируем состояние выхода
//.......
    hw_timer_arm(20);//сбрасываю таймер

}

При этом работает сервер, которые периодически отвечает на GET запросы.
Но мне необходимо в процессе работы устройства периодически менять ssid и пароль в SoftAP. При смене данных SoftAP меняется частота прерываний аппаратного таймера при этом она падает с 22кГц до 20кГц. Это происходит при первой смене настроек SoftAP, затем при смене настроек до перезагрузки модуля частота остается в пределах 20кГц.



Функция для смены настроек FiWi:
Код:
void ICACHE_FLASH_ATTR wifiInit(char *ssid, char *pass)
{

struct softap_config ap_config;

    wifi_set_opmode(SOFTAP_MODE);
    os_delay_us(10000);
    os_memset(&ap_config, 0, sizeof(ap_config));
    wifi_softap_get_config(&ap_config);

        int len = os_strlen(ssid);
            os_memcpy(ap_config.ssid, ssid, len);
            ap_config.ssid_len = len;


             len = os_strlen(pass);
            if(len > (sizeof(ap_config.password) - 1))
            {
                len = sizeof(ap_config.password) - 1;
             }
            os_memset(&ap_config.password, 0, sizeof(ap_config.password));
            os_memcpy(ap_config.password, pass, len);

        ap_config.channel = 1;
        ap_config.authmode = AUTH_WPA_WPA2_PSK;
        ap_config.ssid_hidden = 0;
        ap_config.max_connection = 4;
        //ap_config.beacon_interval = 100;
        wifi_set_phy_mode(1);
        wifi_softap_set_config(&ap_config);
        struct ip_info info;

        IP4_ADDR(&info.ip, 192, 168, 4, 1);
        IP4_ADDR(&info.gw, 192,168, 4, 1);
        IP4_ADDR(&info.netmask, 255, 255, 255, 0);
        wifi_set_ip_info(SOFTAP_IF, &info);
       
        wifi_softap_start();
        wifi_softap_dhcps_start();

}
Кто сталкивался с подобным, подскажите - мне очень важно, чтобы частота прерываний таймера была стабильной
 

pvvx

Активный участник сообщества
Кто сталкивался с подобным, подскажите - мне очень важно, чтобы частота прерываний таймера была стабильной
У WiFi есть режим sleep = light - он отключает все прерывания и тактирование аппаратуры проца на паузу между beacon. В принципе этот метод понижения потребления не работает, если модуль ещё и в режиме SOFTAP, но возможны зависимости. По умолчанию режим sleep у wifi = modem. Кроме того в режиме sleep = light таймеры обработки потока Lwip и прочие увеличены беспредельно в сотни раз (китай фича). Это не позволяет работать с потоком TCP более 1 пакета в десяток секунд. Возникают переполнения у Lwip, т.к. таймер счета закрытий и обработки стека (да вообще всего потока) увеличен с 25 ms до 6000.
 

RjLexx

New member
@DarkSide,а протокол RC6 не поддерживается случаем? Я ардуину с телеком Philips по этому протоколу дружил. Хотелось бы теперь ESP вместо ардуинки использовать
 

DarkSide

New member
@DarkSide,а протокол RC6 не поддерживается случаем? Я ардуину с телеком Philips по этому протоколу дружил. Хотелось бы теперь ESP вместо ардуинки использовать
RC6 я не добавлял, но поидее его добавить очень просто. Посмотрите Arduino-IRremote/ir_RC5_RC6.cpp at master · z3t0/Arduino-IRremote · GitHub - и добавьте по аналогии. У меня сейчас нет возможности этим заниматься.
 

DarkSide

New member
Обновил библиотеку. Изменения:
1) Теперь в репозитории на гитхабе 2 бранча - sdk и rtos_sdk; первый (он же основной) для обычной SDK, второй - для RTOS SDK
2) Код обоих версий обновлен и протестирован на SDK 1.5.2 и RTOS_SDK 1.3.0
3) Немного изменена логика генерации ШИМ
4) Добавлена поддержка протоколов RC5 и RC6 (не тестировалось ибо не на чем)
 

sega6549

New member
Приветствую, а нет ли случайно примерчика как передавать коды кнопок по протоколу mqtt, то есть, я сканирую кнопки с пульта, и передаю по mqtt на сервер, это я сделал в принципе, далее я пытался передать на esp данные коды кнопок но проблема в написании функции callback, нужно конвертировать из того что она получает в тот формат который понимает команда irsend, перепробовал кучу вариантов преобразования но в итоге либо пишет ошибку несовместимы типа типов либо на выходе ноль получаю, можете подсказать хотя бы как правильно преобразовывать
 
Сверху Снизу