ESP32: не работают вместе IRemote и NVS

Тема в разделе "ESP8266, ESP32", создана пользователем nsv2018, 5 сен 2018.

  1. nsv2018

    nsv2018 Нерд

    При совместной работе IRremote и NVS Esp32 вываливается в перезагрузку с вот таким сообщением:


    Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed)
    Register dump:
    PC : 0x400d0c90 PS : 0x00060034 A0 : 0x400822b4 A1 : 0x3ffc0bf0
    A2 : 0x00000001 A3 : 0x00000002 A4 : 0x000000ff A5 : 0x40085b54
    A6 : 0x00000000 A7 : 0x3ffcf000 A8 : 0x80081140 A9 : 0x3ff5f024
    A10 : 0x3ffc1038 A11 : 0x20000000 A12 : 0x00000400 A13 : 0x00000002
    A14 : 0x00000003 A15 : 0x00060d23 SAR : 0x00000013 EXCCAUSE: 0x00000007
    EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff

    Backtrace: 0x400d0c90:0x3ffc0bf0 0x400822b1:0x3ffc0c10 0x40087b97:0x00000000

    Rebooting...
    ets Jun 8 2016 00:22:57

    rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0010,len:4
    load:0x3fff0014,len:716
    load:0x40078000,len:0
    load:0x40078000,len:11572
    entry 0x40078a14


    Использую простейший скетч (см ниже) - получаю код с пульта - записываю и читаю байт из NVS

    По отдельности все работает. Вместе - не хочет.
    Перепробовал кучу разных библиотек - не работает.
    На форумах ничего полезного не нашел.
    Неужели никто не сталкивался? Или я не то делаю? Но все же элементарно....

    Тема для многих может быть актуальной.
    Прошу помощи!
    Заранее благодарен всем откликнувшимся.


    вот сам скетч:

    /////////////////////////////////////////////////////////////////////////////////
    #include <Preferences.h>
    #include <IRremote.h>

    byte RECV_PIN = 26; //IR приемник
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void setup() {
    Serial.begin(115200); // устанавливаем скорость Com порта
    delay(100);
    irrecv.enableIRIn(); // Start the IR receiver
    } // setup

    void loop() {
    if (irrecv.decode(&results)) //если в IR Port поступили данные
    {
    IRComHandler(&results); // читаем результат
    irrecv.resume();
    }
    } // loop
    /////////////////////////////////////////////////////////////////////////////////
    // Обработчик команд от IR датчика
    void IRComHandler(decode_results *results)
    {
    int irp=results->value;
    Serial.println("ir=" + String(irp));
    // NVS_RW(); // пишу-читаю в NVS
    }

    void NVS_RW()
    {
    byte b;
    Preferences prefs; // создаем объект
    // Инициализируем хранилище с идентификатором «nvs».
    // false относится в выбору режима чтение/запись, в данном случае и чтение и запись.
    prefs.begin("nvs1", false);
    prefs.putInt("p1", 65); //Сохраняем байт под именем «p1r»
    b = prefs.getInt("p1", 0); // Читаем сохранённый байт из p1
    prefs.remove("nvs1"); // Удаляем хранилище.

    Serial.println("p1"="+String(b));
    }
     
  2. ИгорьК

    ИгорьК Гуру

    Оформи код правильно, а я потом тебя расстрою.
     
  3. ИгорьК

    ИгорьК Гуру

  4. nsv2018

    nsv2018 Нерд

    Прошу прощения за неправильно оформленный код - исправился
    Код (C++):
    #include <Preferences.h>
    #include <IRremote.h>

    byte RECV_PIN = 26; //IR приемник
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void setup() {
    Serial.begin(115200); // устанавливаем скорость Com порта
    delay(100);
    irrecv.enableIRIn(); // Start the IR receiver
    } // setup

    void loop() {
    if (irrecv.decode(&results)) //если в IR Port поступили данные
    {
    IRComHandler(&results); // читаем результат
    irrecv.resume();
    }
    } // loop
    /////////////////////////////////////////////////////////////////////////////////
    // Обработчик команд от IR датчика
    void IRComHandler(decode_results *results)
    {
    int irp=results->value;
    Serial.println("ir=" + String(irp));
    // NVS_RW(); // пишу-читаю в NVS
    }

    void NVS_RW()
    {
    byte b;
    Preferences prefs; // создаем объект
    // Инициализируем хранилище с идентификатором «nvs».
    // false относится в выбору режима чтение/запись, в данном случае и чтение и запись.
    prefs.begin("nvs1", false);
    prefs.putInt("p1", 65); //Сохраняем байт под именем «p1r»
    b = prefs.getInt("p1", 0); // Читаем сохранённый байт из p1
    prefs.remove("nvs1"); // Удаляем хранилище.

    Serial.println("p1"="+String(b));
    }
     
  5. ИгорьК

    ИгорьК Гуру

    Спасибо!
    upload_2018-9-5_16-25-39.png

    Теперь о плохом. Так обозначаются системные ошибки. Они возникают вследствие багов SDK, а не ошибок вашего кода.

    Не скажу, что их нельзя обойти, но в проблему надо лезть очень глубоко.
     
  6. ZAZ-965

    ZAZ-965 Гуру

    @nsv2018, возможно нужно закрывать preferences
    Код (C++):
    prefs.begin("nvs1", false);
    ...................
    prefs.end();
     
  7. nsv2018

    nsv2018 Нерд

    Пробовал. Не помогает!
    Да,уж!! Очень неожиданно!
    В любом случае Большая благодарность всем откликнувшимся.
    Но очень Странно.
    Для подобных модулей классическая ситуация, когда с пульта управляется, а в NVS запоминаются параметы.
    И еше, в интернете об этом ничего не нашел!
    Неужели никто не решал подобной задачи?
    Ведь она типовая!

    Завис красивый проект.
    Очень прошу - если хоть какая то информация имеется - сообщите пож-ста.
    Заранее благодарен.
     
  8. Mitrandir

    Mitrandir Гуру

    А если перед доступом к хранилищ глушить приёмик ИК?
    Что то типа irrecv.disableIRIn();//
     
  9. nsv2018

    nsv2018 Нерд

    ОНО это irrecv.disableIRIn(); не понимает
    Заметил - если prefs.begin("nvs1", false); (см скетч выше) , то все нормально - но не записывет.
    т.е. ошибка возникает только при записи данных
     
  10. ИгорьК

    ИгорьК Гуру

    Я бы одно проверил - чтобы ничего за пределы массивов не вылетало если они есть в библиотеках.
     
  11. ИгорьК

    ИгорьК Гуру

    Там наверняка идет прием, разбор сигнала и запись его в массив или в строку по указателю. Если места под него в библиотеке выделено недостаточно и нет контроля длины записи - может быть такая фигня.
     
  12. ZAZ-965

    ZAZ-965 Гуру

    Посмотрел на гитхабе код Arduino-IRremote. В IRremote.cpp вызывается в прерывании функция IRTimer() без атрибута IRAM_ATTR, по моему обязательного для прерываний.Функция дергается каждые 50мкс, в итоге при использовании библиотеки Preferences (небыстрое сохранение данных во флэш-память) валится в панику. Да и функциям NVS_RW() и IRComHandle() можно добавить этот атрибут.
    Код (C++):
    //Interrupt Service Routine - Fires every 50uS
    #ifdef IR_TIMER_USE_ESP32
    void IRAM_ATTR IRTimer() //я бы добавил для проверки
    #else
    ISR (TIMER_INTR_NAME)
    #endif
     
    ИгорьК, DIYMan и Mitrandir нравится это.
  13. nsv2018

    nsv2018 Нерд

    Как это сделать?
    Функция disableIRIn() в библиотеке отсутствует.
    нашел в Гугле - https://github.com/markszabo/IRremoteESP8266/issues/57
    но добавить функции в библиотеку не получилось.
    До Гуру мне пока далековато, рано еще лезть в библиотеки
     
  14. Mitrandir

    Mitrandir Гуру

    Это я так, на вскидку написал. как идею. Наверняка есть функции отключающие ик
     
  15. nsv2018

    nsv2018 Нерд

    На мой взляд предложение от Mitrandir разумное - на момент передачи останавливать IRremote.
    Но вот как это сделать - пока не знаю, подобная функция в библиотеке IRremote отсутствует
    Проверил - не помогло!
     
  16. nsv2018

    nsv2018 Нерд

    В библиотеке нет.
     
  17. Mitrandir

    Mitrandir Гуру

    По ссылке что вы дали на гитхаб есть такая фуНкция.
    Код (C++):
    // main class for receiving IR
    class IRrecv {
    public:
      explicit IRrecv(uint16_t recvpin, uint16_t bufsize = RAWBUF,
                      uint8_t timeout = TIMEOUT_MS,
                      bool save_buffer = false);  // Constructor
      ~IRrecv();  // Destructor
      bool decode(decode_results *results, irparams_t *save = NULL);
      void enableIRIn();
      void disableIRIn();
     
  18. ИгорьК

    ИгорьК Гуру

    ох уж эта динамическая загрузка-выгрузка на сях...
     
  19. Mitrandir

    Mitrandir Гуру

    попробуйте воспользоваться библиотекой марга что вы нашли
     
  20. nsv2018

    nsv2018 Нерд

    1. Воспользоваться этой библиотекой ее удается - ругается на отсутствие модуля gpio.h.
    Она, похоже, для 8266 с соотв набором модулей в библиотеках.
    2. Попытался в библиотеку добавить функцию void disableIRIn ().
    Для этого:

    1. В модуль IRremote.h добавил void disableIRIn ();

    Код (C++):
    // Main class for receiving IR
    //
    class IRrecv
    {
        public:
            IRrecv (int recvpin) ;
            IRrecv (int recvpin, int blinkpin);

            void  blink13    (int blinkflag) ;
            int   decode     (decode_results *results) ;
            void  enableIRIn ( ) ;
            [B]void  disableIRIn ();[/B]
            bool  isIdle     ( ) ;
            void  resume     ( ) ;
    2. В модуль irRecv.cpp добавил опимание функции void disableIRIn()
    Код (C++):
     
    Код (C++):
    ///////////////////////////////////////////////////////////////////////////////
    void IRrecv::disableIRIn()
      {
              //  irReadTimer.Stop();
              //   os_timer_disarm(&irReadYimer);
              ETS_INTR_LOCK();
            ETS_GPIO_INTR_DISABLE();
      }
    Теперь ругается что не понимает
    ETS_INTR_LOCK();
    ETS_GPIO_INTR_DISABLE();
    Где они описывется пока не нашел.
    Куда двигаться дальше.

    Или, альтернативный вариант останова IRremote.
    В сети ничего не нашел