Hi,
I'm trying to implement upy-rtttl (https://github.com/dhylands/upy-rtttl) in my project in a non-blocking way.
My current solution is to use '_thread'.
The orignial example of upy-rtttl is shown as below: (https://github.com/dhylands/upy-rtttl/b ... yb_test.py)
```
def play_song(search):
play(RTTTL(songs.find(search)))
```
My implementation with _thread is:
```
def play_song(self, search):
_thread.start_new_thread(self.play, (RTTTL(songs.find(search)),))
```
It worked when run alone (without other major tasks), however when running with other tasks, the sound showed obvious delay (jagged), and very often I got: RuntimeError: maximum recursion depth exceeded
The trackback points to the "parse_defaults" method in class RTTTL (https://github.com/dhylands/upy-rtttl/b ... r/rtttl.py)
My questions:
1. Is there a better way to do it in a non-blocking way?
2. What could be the possible cause of the RuntimeError: maximum recursion depth exceeded? The stack size of the thread was too little?
Thanks in advance!
Kaiyuan
solutions for non-blocking rtttl ringtones?
Re: solutions for non-blocking rtttl ringtones?
That is indeed a possibility. This error is thrown when the stack overflows, and that usually happens when there is a runaway recursion. According to the current source, the default stack size is 5kB.2. What could be the possible cause of the RuntimeError: maximum recursion depth exceeded? The stack size of the thread was too little?
Re: solutions for non-blocking rtttl ringtones?
If you want to increase the thread stack size, you can set
Note the default on ESP32 is 5kiB, the minimum is 4kiB.
The probably better solution to your problem is to use (u)asyncio, but that will likely require a significant re-writing of the rtttl library and your application. (But it might be worth it!) Note that https://github.com/micropython/micropython/pull/5332 is about to be merged and may be of interest.
Code: Select all
_thread.stack_size = 8192
The probably better solution to your problem is to use (u)asyncio, but that will likely require a significant re-writing of the rtttl library and your application. (But it might be worth it!) Note that https://github.com/micropython/micropython/pull/5332 is about to be merged and may be of interest.
Re: solutions for non-blocking rtttl ringtones?
I'm not sure that any changes need to be made to upy-rtttl to support asyncio. The library was designed as a generator which returns a tuples. Each tuple contains the note to play and how long to play it for. Each time you call the generator it returns the next tuple.
upy-rtttl doesn't have any internal delays or other blocking operations. That's all left to the calling code.
upy-rtttl also doesn't use any recursion.
upy-rtttl doesn't have any internal delays or other blocking operations. That's all left to the calling code.
upy-rtttl also doesn't use any recursion.
Re: solutions for non-blocking rtttl ringtones?
Thanks for creating and sharing the upy-rtttl library @dhylands.dhylands wrote: ↑Mon Jan 27, 2020 4:06 amI'm not sure that any changes need to be made to upy-rtttl to support asyncio. The library was designed as a generator which returns a tuples. Each tuple contains the note to play and how long to play it for. Each time you call the generator it returns the next tuple.
upy-rtttl doesn't have any internal delays or other blocking operations. That's all left to the calling code.
upy-rtttl also doesn't use any recursion.
I guess it may not be appropriate to call it blocking - what I tried to say was that when using rtttl with another task, say a timer, the timer can still work properly when the loop is generating tones.
Thanks for the advise @jimmo @fstengel. I will try increasing the stack size to see if it will solve the issue.
Thanks again.
Kaiyuan