Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async in Recv mode #475

Closed
tarzan115 opened this issue Jun 26, 2018 · 26 comments
Closed

Async in Recv mode #475

tarzan115 opened this issue Jun 26, 2018 · 26 comments
Assignees
Labels

Comments

@tarzan115
Copy link

tarzan115 commented Jun 26, 2018

Version/revison of the library used

_ 2.4.2

Expected behavior

_ run Recv mode in Async like Send mode

Actual behavior

_ I tried to use Recv mode with library TaskScheduler but I got Exception 28 with decode:


Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
Decoding 27 results
0x40106949: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 150
0x40106cb8: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 34
0x40106cb8: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 34
0x40106d00: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 41
0x402294b2: __ieee754_rem_pio2 at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libm/math/../../../.././newlib/libm/math/e_rem_pio2.c line 129
0x40106cb8: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 34
0x40106cb8: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 34
0x40106d00: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 41
0x401068fe: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 138
0x40106cb8: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 34
0x40106cb8: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 34
0x40106cb8: timer1_isr_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 34
0x401068c4: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 132
0x40208fc5: Scheduler::execute() at D:\WiFi-AP-UDP.ino line 59
0x4021f540: loop_wrapper at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 117
0x4020ebac: _receiverIR at D:\WiFi-AP-UDP.ino line 59
0x40106784: millis at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring.c line 183
0x4021f58e: __yield at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 100
0x40209044: Scheduler::execute() at D:\WiFi-AP-UDP.ino line 59
0x40208fee: Scheduler::execute() at D:\WiFi-AP-UDP.ino line 59
0x40209070: loop at D:\WiFi-AP-UDP.ino line 59
0x4021f560: loop_wrapper at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 125
0x40100739: cont_wrapper at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 81

Has this library/code previously worked as expected for you?

_ Yes, in sync, not use TaskScheduler

Thank you so much for greatest library!

@crankyoldgit
Copy link
Owner

crankyoldgit commented Jun 26, 2018 via email

@crankyoldgit
Copy link
Owner

Had a quick glance over TaskScheduler. It might be the case that both libraries are using the same timer. But without seeing how you are using our library, I really can't help.

@tarzan115
Copy link
Author

Hi, I'm sorry for the delay response!
here is my small of code

#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>

#include <TaskScheduler.h>


#define RECV_PIN 12
#define CAPTURE_BUFFER_SIZE 1500
#define TIMEOUT_DECODE_IR 50U

IRrecv irrecv(RECV_PIN, CAPTURE_BUFFER_SIZE, TIMEOUT_DECODE_IR);
decode_results results;

void recv_Cb();
Scheduler schedulerTask;
Task recv_Task(TASK_IMMEDIATE, TASK_FOREVER, &recv_Cb, &schedulerTask, true);

void recv_Cb()
{
    if (irrecv.decode(&results))
    {
        // Display a crude timestamp.
        uint32_t now = millis();
        Serial.printf("Timestamp : %06u.%03u\n", now / 1000, now % 1000);
        if (results.overflow)
            Serial.printf("WARNING: IR code is too big for buffer (>= %d). "
                          "This result shouldn't be trusted until this is resolved. "
                          "Edit & increase CAPTURE_BUFFER_SIZE.\n",
                          CAPTURE_BUFFER_SIZE);
        // Display the basic output of what we found.
        Serial.print(resultToHumanReadableBasic(&results));

        // Display the library version the message was captured with.
        Serial.print("Library   : v");
        Serial.println(_IRREMOTEESP8266_VERSION_);
        Serial.println();

        // Output RAW timing info of the result.
        Serial.println(resultToTimingInfo(&results));

        // Output the results as source code
        Serial.println(resultToSourceCode(&results));
        Serial.println(""); // Blank line between entries
    }
    return;
}

void setup()
{
    Serial.begin(115200);
    irrecv.enableIRIn();
    Serial.println("setup done");
    return;
}

void loop()
{
    schedulerTask.execute();
    return;
}

and here is decode log:


Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
Decoding 63 results
0x401067d9: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 150
0x40101c3d: trc_NeedRTS at ?? line ?
0x40101e0e: trc_NeedRTS at ?? line ?
0x40102167: wDev_ProcessFiq at ?? line ?
0x4010224e: wDev_ProcessFiq at ?? line ?
0x4010678e: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 138
0x40104bfd: ets_timer_disarm at ?? line ?
0x40101fe8: wDev_ProcessFiq at ?? line ?
0x40106754: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 132
0x4020f938: cyclic_timer at /local/users/gauchard/arduino/arduino_esp8266/origin/tools/sdk/lwip2/builder/lwip2-src/src/core/timeouts.c line 165
0x4020f7fc: sys_timeout_LWIP2 at /local/users/gauchard/arduino/arduino_esp8266/origin/tools/sdk/lwip2/builder/lwip2-src/src/core/timeouts.c line 217
0x4020f938: cyclic_timer at /local/users/gauchard/arduino/arduino_esp8266/origin/tools/sdk/lwip2/builder/lwip2-src/src/core/timeouts.c line 165
0x4020f938: cyclic_timer at /local/users/gauchard/arduino/arduino_esp8266/origin/tools/sdk/lwip2/builder/lwip2-src/src/core/timeouts.c line 165
0x4020f950: cyclic_timer at /local/users/gauchard/arduino/arduino_esp8266/origin/tools/sdk/lwip2/builder/lwip2-src/src/core/timeouts.c line 172
0x4020f9fc: sys_check_timeouts at /local/users/gauchard/arduino/arduino_esp8266/origin/tools/sdk/lwip2/builder/lwip2-src/src/core/timeouts.c line 351
0x40104ab2: wdt_feed at ?? line ?
0x4022dd04: ets_timer_handler_isr at ?? line ?
0x4022dd2a: ets_timer_handler_isr at ?? line ?
0x40207e0f: loop_task at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 133
0x40104424: call_user_start_local at ?? line ?
0x4010442a: call_user_start_local at ?? line ?
0x4010000d: call_user_start at ?? line ?
0x40100120: cont_ret at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 142
0x401000cd: cont_continue at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 51
0x40103125: lmacIsIdle at ?? line ?
0x4010426a: lmacTxFrame at ?? line ?
0x40100f22: pp_post at ?? line ?
0x4010431f: lmacRxDone at ?? line ?
0x40100f22: pp_post at ?? line ?
0x4010431f: lmacRxDone at ?? line ?
0x40101e0e: trc_NeedRTS at ?? line ?
0x40101c3d: trc_NeedRTS at ?? line ?
0x40100f22: pp_post at ?? line ?
0x40104304: lmacTxFrame at ?? line ?
0x40103523: lmacRecycleMPDU at ?? line ?
0x40103986: lmacRecycleMPDU at ?? line ?
0x40101e0e: trc_NeedRTS at ?? line ?
0x40103269: lmacProcessTXStartData at ?? line ?
0x4010346a: lmacProcessTxSuccess at ?? line ?
0x40102192: wDev_ProcessFiq at ?? line ?
0x401022eb: wDev_ProcessFiq at ?? line ?
0x40101fe8: wDev_ProcessFiq at ?? line ?
0x40104bfd: ets_timer_disarm at ?? line ?
0x40207fde: run_scheduled_functions() at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/Schedule.cpp line 70
0x40207ee3: loop_wrapper at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 126
0x401000cd: cont_continue at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 51
0x401000e5: cont_wrapper at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 81
0x40106af6: timer1_isr_init at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 47
0x40106614: millis at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring.c line 183
0x40207e54: esp_yield at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 91
0x40207f0e: __yield at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 100
0x40202940: Scheduler::execute() at D:\Documents\Arduino\libraries\TaskScheduler\src/TaskScheduler.h line 606
0x402029a4: loop at D:\Documents\Arduino\libraries\TaskScheduler\src/TaskScheduler.h line 606

@crankyoldgit
Copy link
Owner

crankyoldgit commented Jun 27, 2018 via email

@tarzan115
Copy link
Author

only when received a signal.
thank you very much! I really appreciate that.

@crankyoldgit
Copy link
Owner

crankyoldgit commented Jun 28, 2018

Some background info:

Fatal exception No.    Description         Possible Causes
27/28                  Invalid address     1. Access to Cache after it is turned off
                                           2. Wild pointers

So something is probably screwing with pointers/memory allocation etc.

@crankyoldgit
Copy link
Owner

More reading points to:
http://arduino-esp8266.readthedocs.io/en/latest/faq/a02-my-esp-crashes.html#other-causes-for-crashes

Asynchronous Callbacks
Asynchronous CBs, such as for the Ticker or ESPAsync* libs, have looser restrictions than ISRs, but some restrictions still apply. It is not possible to execute delay() or yield() from an asynchronous callback. Timing is not as tight as an ISR, but it should remain below a few milliseconds. This is a guideline. The hard timing requirements depend on the WiFi configuration and amount of traffic. In general, the CPU must not be hogged by the user code, as the longer it is away from servicing the WiFi stack, the more likely that memory corruption can happen.

The current recv_Cb() routine as it stands will take more than "a few milliseconds".

I suggest cutting it down (dropping the most of the serial printing) to a minimum to see if it works.

e.g.

void recv_Cb() {
    if (irrecv.decode(&results)) {
        Serial.println("Successfully got an IR message!");
    }
    return;
}

@tarzan115
Copy link
Author

I think TaskScheduler is not fully Async. It just a Task Manager. I think the error in something else in interrupt_handler.
I tried to cut down in recv_Cb() like you suggest but Exception still valid.

Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
Decoding 24 results
0x401067d9: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 150
0x40101c3d: trc_NeedRTS at ?? line ?
0x40100f22: pp_post at ?? line ?
0x4010431f: lmacRxDone at ?? line ?
0x40100f22: pp_post at ?? line ?
0x40101c3d: trc_NeedRTS at ?? line ?
0x4010224e: wDev_ProcessFiq at ?? line ?
0x40101e0e: trc_NeedRTS at ?? line ?
0x4010678e: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 138
0x40104bfd: ets_timer_disarm at ?? line ?
0x4010224e: wDev_ProcessFiq at ?? line ?
0x40106754: interrupt_handler at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 132
0x4020736d: esp_schedule at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 95
0x40106af6: timer1_isr_init at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_timer.c line 47
0x40106614: millis at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring.c line 183
0x4020734c: esp_yield at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 91
0x40202862: Scheduler::execute() at D:\Documents\Arduino\libraries\TaskScheduler\src/TaskScheduler.h line 606
0x4020291c: loop at D:\Documents\Arduino\libraries\TaskScheduler\src/TaskScheduler.h line 606
0x402073d8: loop_wrapper at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 125
0x401000e5: cont_wrapper at D:\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 81

@crankyoldgit
Copy link
Owner

crankyoldgit commented Jun 30, 2018

@tarzan115 It's the weekend so I've finally got time to look at this. I'm not sure what results you are getting, but when I ran your original sketch (only changed RECV_PIN to 14 to match my hardware) I get it constantly reporting signals. That's NOT what is expected.

(FYI, using 2.6.1 of TaskScheduler.)

It wasn't producing the exception you reported.

There is a small bug in your sketch however, which I didn't notice originally.
You're missing the appropriate irrecv.resume(); call which you need to do when you've created the IRrecv object that way. i.e. without the extra buffer to save the decode result.
e.g. You're sketch is using it the same way as the old method as per IRrecvDemo.ino, verses the newer faster (as in less capture down time) method as in IRrecvDumpV2.ino, which supplies the extra buffer.

Here is the updated sketch I used:

#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>

#include <TaskScheduler.h>


#define RECV_PIN 14
#define CAPTURE_BUFFER_SIZE 1500
#define TIMEOUT_DECODE_IR 50U

IRrecv irrecv(RECV_PIN, CAPTURE_BUFFER_SIZE, TIMEOUT_DECODE_IR);
decode_results results;

void recv_Cb();
Scheduler schedulerTask;
Task recv_Task(TASK_IMMEDIATE, TASK_FOREVER, &recv_Cb, &schedulerTask, true);

void recv_Cb()
{
    if (irrecv.decode(&results))
    {
        // Display a crude timestamp.
        uint32_t now = millis();
        Serial.printf("Timestamp : %06u.%03u\n", now / 1000, now % 1000);
        if (results.overflow)
            Serial.printf("WARNING: IR code is too big for buffer (>= %d). "
                          "This result shouldn't be trusted until this is resolved. "
                          "Edit & increase CAPTURE_BUFFER_SIZE.\n",
                          CAPTURE_BUFFER_SIZE);
        // Display the basic output of what we found.
        Serial.print(resultToHumanReadableBasic(&results));

        // Display the library version the message was captured with.
        Serial.print("Library   : v");
        Serial.println(_IRREMOTEESP8266_VERSION_);
        Serial.println();

        // Output RAW timing info of the result.
        Serial.println(resultToTimingInfo(&results));

        // Output the results as source code
        Serial.println(resultToSourceCode(&results));
        Serial.println(""); // Blank line between entries
        irrecv.resume();  // You need to call resume() if you don't supply a second buffer.
    }
    return;
}

void setup()
{
    Serial.begin(115200);
    irrecv.enableIRIn();
    Serial.println("setup done");
    return;
}

void loop()
{
    schedulerTask.execute();
    return;
}

Here is the serial out I get from running the modified sketch:

4, room 16 
tail 8
chksum 0x2d
csum 0x2d
v4ceabea9
~ld
setup done
Timestamp : 000019.985
Encoding  : UNKNOWN
Code      : CBC6E24C (6 bits)
Library   : v2.4.2

Raw Timing[11]:
   +   226, -   452,    +   332, -  7742,    +   334, -  7516,    +   230, -  3054, 
   +   224, - 12264,    +   322

uint16_t rawData[11] = {226, 452,  332, 7742,  334, 7516,  230, 3054,  224, 12264,  322};  // UNKNOWN CBC6E24C


Timestamp : 000030.870
Encoding  : SAMSUNG
Code      : E0E0E01F (32 bits)
Library   : v2.4.2

Raw Timing[67]:
   +  4538, -  4488,    +   570, -  1672,    +   572, -  1670,    +   574, -  1670, 
   +   574, -   548,    +   570, -   550,    +   576, -   546,    +   570, -   552, 
   +   574, -   544,    +   572, -  1670,    +   574, -  1668,    +   574, -  1668, 
   +   576, -   546,    +   570, -   550,    +   578, -   544,    +   572, -   548, 
   +   578, -   544,    +   574, -  1668,    +   574, -  1668,    +   576, -  1666, 
   +   578, -   544,    +   572, -   548,    +   568, -   554,    +   572, -   548, 
   +   570, -   552,    +   574, -   546,    +   570, -   550,    +   576, -   546, 
   +   570, -  1670,    +   574, -  1670,    +   574, -  1668,    +   576, -  1666, 
   +   576, -  1666,    +   568

uint16_t rawData[67] = {4538, 4488,  570, 1672,  572, 1670,  574, 1670,  574, 548,  570, 550,  576, 546,  570, 552,  574, 544,  572, 1670,  574, 1668,  574, 1668,  576, 546,  570, 550,  578, 544,  572, 548,  578, 544,  574, 1668,  574, 1668,  576, 1666,  578, 544,  572, 548,  568, 554,  572, 548,  570, 552,  574, 546,  570, 550,  576, 546,  570, 1670,  574, 1670,  574, 1668,  576, 1666,  576, 1666,  568};  // SAMSUNG E0E0E01F
uint32_t address = 0x7;
uint32_t command = 0x7;
uint64_t data = 0xE0E0E01F;

TL;DR: It isn't crashing/causing the exception for me.

@crankyoldgit
Copy link
Owner

Alternatively, use the extra save buffer and NOT use the resume() method.
e.g.
IRrecv irrecv(RECV_PIN, CAPTURE_BUFFER_SIZE, TIMEOUT_DECODE_IR, true);

@crankyoldgit
Copy link
Owner

crankyoldgit commented Jun 30, 2018

FWIW, I built it with ESP8266 core 2.4.0 & 2.4.1, IRremoteESP8266 2.4.2, TaskScheduler 2.6.1, and Arduino IDE v1.8.1 (running under linux) and tested on a NodeMCU board.

@tarzan115
Copy link
Author

I tried all as you said but it still errors. I build with ESP8266 core in git version. please try with git version of ESP8266 core.
Thank you.

@crankyoldgit
Copy link
Owner

Have you modified the IRremoteESP8266 library in any way at all? i.e. Turn on any debugging etc. If so, try clearing/removing the library and git re-clone or download from Library Manager again etc.

I assume you mean the master branch of ESP8266 core. I'll try it shortly. In the meantime, why not try using the 2.4.0 or 2.4.1 release images to see if it happens for you?

@tarzan115
Copy link
Author

I modified the define ALLOW_DELAY_CALLS to false

#define ALLOW_DELAY_CALLS false

I will try with ESP8266 core 2.4.1

@tarzan115
Copy link
Author

please take a look in this PR esp8266/Arduino#4609

@crankyoldgit
Copy link
Owner

That (ALLOW_DENY_CALLS) shouldn't affect anything though, but it isn't needed for your example sketch, as that only effects sending.

I'm not willing to overwrite my "Arduino IDE" env with the master version of the esp core at this stage. I want/need to keep it "typical" for normal user issues.

Re: The core PR. I've had a skim of it, I don't fully understand most of it, but I don't think it is relevant to this situation. It could be, but it's beyond my skill level to be sure. Our ISR will be invoked in the order of milliseconds during a brief window of around 100ms. e.g. about 70-ish times in that 100ms window. The run-time of the each ISR would be in the order of 5-6 usecs. So I don't think we'll be causing an issue. But hey, I'm no ESP8266 core expert. There would be plenty of other libraries that operate at this speed & ISR frequency so we would not be unique in this case.

i.e. I think the problem is elsewhere.

@crankyoldgit
Copy link
Owner

Oh, and the ISR is pretty much independent of the irrecv.decode() call.

@tarzan115
Copy link
Author

Okay, thank you for helping me. I will try another way to receive IR signal.
Thank you and have a good day.

@crankyoldgit
Copy link
Owner

How did it go with the 2.4.1 core? If it worked, then there is something broken & needs to change if their master is going to be released.

If it didn't work, then I suspect something else is different in your build env/setup etc. e.g. Your modified example is working as expected for me.

@crankyoldgit
Copy link
Owner

FWIW, I tried to use the esp core master branch, and it "broke" my Arduino IDE. I had to revert to a backup I made just prior. i.e. I wasn't able to convince the IDE to even think of compiling against it.

@tarzan115
Copy link
Author

with 2.4.1 core. It's run perfectly without exceptions.
I think if they release version 2.4.2. we have to fix it A.S.A.P.

@tarzan115
Copy link
Author

I don't want to use 2.4.1 core because in git version they fixed some bugs for my project

@crankyoldgit
Copy link
Owner

crankyoldgit commented Jun 30, 2018 via email

@tarzan115
Copy link
Author

okay. I will create a new issue in ESP8266 repo. thank you.

@tarzan115
Copy link
Author

it's working now with this PR esp8266/Arduino#4873
Thank you in advance.

@crankyoldgit
Copy link
Owner

Excellent news.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants