solutions for non-blocking rtttl ringtones?

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
dukeduck
Posts: 22
Joined: Thu Aug 29, 2019 2:06 pm

solutions for non-blocking rtttl ringtones?

Post by dukeduck » Sun Jan 26, 2020 5:28 pm

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

fstengel
Posts: 55
Joined: Tue Apr 17, 2018 4:37 pm

Re: solutions for non-blocking rtttl ringtones?

Post by fstengel » Sun Jan 26, 2020 8:53 pm

2. What could be the possible cause of the RuntimeError: maximum recursion depth exceeded? The stack size of the thread was too little?
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.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: solutions for non-blocking rtttl ringtones?

Post by jimmo » Mon Jan 27, 2020 3:53 am

If you want to increase the thread stack size, you can set

Code: Select all

_thread.stack_size = 8192
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.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: solutions for non-blocking rtttl ringtones?

Post by dhylands » Mon Jan 27, 2020 4:06 am

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.

dukeduck
Posts: 22
Joined: Thu Aug 29, 2019 2:06 pm

Re: solutions for non-blocking rtttl ringtones?

Post by dukeduck » Mon Jan 27, 2020 3:10 pm

dhylands wrote:
Mon Jan 27, 2020 4:06 am
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.
Thanks for creating and sharing the upy-rtttl library @dhylands.

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

Post Reply