I'm Finally getting the time to play with many of these Microcoller Modules "Pi's / Arduino's / ESP32's".. I appreciate all the Tips and Tricks Videos like these.. (For Newbies like ME) 👍👍😊
It would be interesting to compare the maximum frame rates of each method to determine how much more efficient each was compared to using only one core. There must be some overhead involved in switching cores that could be quite significant.
Hi. I did do some work on that in making this little RP2040 console - th-cam.com/users/shortsQusjn49OLL4. I do plan a video based around it but work has been quite hectic for the past few months. The core switching isn't such an issue. Once you get your threads up and running they really do work in parallel. The key is in dividing up the tasks and making sure that one doesn't block the other when accessing resources etc.
Liked your tutorial, with a stream of examples from understanding the basics to a real case usage. I was searching threading related info for Raspberry Pi Pico, and this tutorial nicely appeared: I'm sure I'll give it a try. Thank you very much. Andrea
Great thorough explanation, thanks for that. One point of critique, I'm not a big fan of the 'live drawing' animation style found at the beginning of the video. It adds a lot of visual noise and especially distracts from your speaking. This however is a personal preference but imo worth mentioning
Thank you for the time and insight you provide with your channel. If each thread waits for the other one to finish its access to the frame buffer, what is the advantage of using two cores? The renderer can only do a little work (some Trig maybe) before its main job of accessing the frame buffer. The two cores would indeed run in parallel if the frame buffer were double-buffered, but of course this is not possible with the small Pico RAM size.
You're right about the double buffering but this setup can still work well. The idea here is that you split your code into an update phase and a render phase. The update phase is the parallel part so you try to put as much of the processing load into that. The bouncing box demo doesn't really have any update processing but the Asteroids game (I hope that's shown in the video!) performs all the polygon rotations, collision detection, etc. leaving only the actual drawing of lines into the buffer for the render phase. You can actually make some great multi thread savings this way.
@@BytesNBits today I was able to output some sound with a buzzer and some animation in the oled screen both at the same time thanks to your video. Im not sure if there is other way to do it but at least is working with threads.
I’m not sure about the fact that the second thread is running on the second core. I’ve already used threads in my projects but with an ESP32-C3, so a single core microcontroller and it runs without problems.
The Pico handles threads differently to the ESP32 in MicroPython. On the ESP32 MicroPython code can only run on one of the cores so your threads are running as tasks on the same core. The Pico allows you to run MicroPython on both cores (mostly) but can also use the asyncio package to get multiple tasks per core.
I was having the same crashes where my rpi got frozen using the second core... The way I fixed it was using a "return 0" at the end of the function instead of the GC.
even if makes the example understandable, you should mention that it's never a good idea to do a sleep() while you hold a lock, which another thread may be waiting on
If you check the Micropython docs it's still listed as experimental - docs.micropython.org/en/latest/library/_thread.html. I'd be wary of using it in anything where a system crash would be bad.
Hi. I use PyCharm for my coding. There is a free community version that does everything you need. Make sure you install the MicroPython plugin so it can talk to the Pico. MicroPython is an interpreted language so is much slower than C++. It is aware of time and you can use this to make sure things happen at the correct time. If you are trying to get very tight timing e.g. some sort of signal timing, then I'd probably go with C, or have a play with the PIO system.
Wondering if you have any more info on how to use the REPL tool in PyCharm - for example, flashing a program to it causes it to run immediately, but when opening REPL the keyboard interrupt ends it. Using the soft reboot is enough to reset it, but it's an issue using the socket library for my web sever as I get the EADDRINUSE OSError, essentially that the static IP address I want to bind to is already being used, but by the instance that was interrupted. You seem to be able to just upload and start it in a few examples here? Plus the terminal window you use just says 'Local', mine has a path to "...\venv\Scripts\python.exe". And obviously I can't flash a new version of the file unless I close the instance of REPL terminal as the COM port is in use... If you know of any sources online about how to use REPL to debug beyond the official documentation (which is not great) I would appreciate it a ton :)
Hi. Make sure you're using the latest version of PyCharm. They fixed a number of REPL bugs a few months ago. After that make sure you've got the project set up and the extra Micropython add ons installed. If you upload a file called main.py it will auto execute, or if one already exists that will execute. Try saving the main entry point for your code as something different , e.g mycode.py, and delete any main.py. Once you upload you'll be able to REPL onto the device and start the code manually, import mycode.
then theres the PIO stuff. they basically function as 'event computers' that generate CPU interrupts based on the interaction between a state machine and the input stream. This makes it easy for drivers to be efficient because there is no impedance gap to cross converting from a raw data stream to contextually meaningful IO events. While the PIO is figuring out what events it should tell the CPU about happening on the IO pins, the CPU is free to do whatever it likes, and is not occupied doing this work itself like it would be in many other computing environments.
Will there be any issue when apply the same method to all the other cores available ? Assumming earch cores handle one box redenering around the LCD and running around. The use case is appilcable for max. 8 application running concuerrently or different input running curently ?
Hi. The RP2040 only has 2 cores for you to use. You can only run 1 thread per core. If you are using a processor with more cores then the same method would apply.
i am trying to program a clock (micropython, raspberry pi pico). my goal is to be able to set the time while the clock is ticking. is this possible or is it a contradiction.
Hello, wanna try your example, but only got a 1.8 tft spi (128x260) (the red one with sd card reader) and no MISO nor MISI but only A0 and SDA ... how can i adapt teh code?
@@V1P3RSlab I think A0 is the DC pin. SDA is MOSI. There is no MISO as this isn't really needed for the TFT panel. The other pins should match the video. I hope this helps.
Hi. Basically yes - 75KB of single byte integers / characters. There's not enough memory for 2 buffers so the processes have to share the one memory block. Double buffering would be great but not really an option without more RAM.
@@jyvben1520 Hi. For the LCD panel I was using it's 16bits per pixel. You can store the colour info in memory in any way you want but you have to expand it out to the full 16 bits to send to the LCD. Pure Python isn't fast enough to do this on the Pico.
Where did you got the idea that multithreading is implemented using the 2 cores ? There is nothing in the documentation that can lead to this conclusion Please explain why you think so. Also explain what happens if you declare 3 threads...
Hi. The Micropython threading package assumes one thread per core. I know in more powerful processors you can run multiple threads per cores but that doesn't seem to be implimented in MicroPython.
@@BytesNBits Again, there is no such thing in the documentation The Micropython documentation points to CPython documentation and CPython does not know about multicore. Beside, MicroPython runs also on the ESP32 which has only one core... Please post the web page adress where you found this info Thanks
@@BytesNBits Finaly, I checked the core assumption using a simple script which reads the CPUID register from the RP2040 and you're right, the first thread runs on core 1 Adding a second thread as you mentioned leads to an error Here is the script for those who are interested : ----------------------------------------------------------- import time, _thread from machine import mem32,Pin led = machine.Pin(25, machine.Pin.OUT) def Core0(): while True: led.on() time.sleep(5) #read CPUID print("Core0 = ",mem32[0xd0000000])
def Core1(): while True: led.off() time.sleep(5) #read CPUID print("Core1 = ",mem32[0xd0000000]) _thread.start_new_thread(Core1, ( )) time.sleep(1) Core0() ----------------------------------------------- Core0 output is 0 and Core1 output is 1 Regards
I'm Finally getting the time to play with many of these Microcoller Modules "Pi's / Arduino's / ESP32's".. I appreciate all the Tips and Tricks Videos like these.. (For Newbies like ME) 👍👍😊
Glad you like them!
It would be interesting to compare the maximum frame rates of each method to determine how much more efficient each was compared to using only one core. There must be some overhead involved in switching cores that could be quite significant.
Hi. I did do some work on that in making this little RP2040 console - th-cam.com/users/shortsQusjn49OLL4.
I do plan a video based around it but work has been quite hectic for the past few months.
The core switching isn't such an issue. Once you get your threads up and running they really do work in parallel. The key is in dividing up the tasks and making sure that one doesn't block the other when accessing resources etc.
Really useful, going to use it to control two independent motors, one steering, one driving... Nice
Glad it helped
Liked your tutorial, with a stream of examples from understanding the basics to a real case usage.
I was searching threading related info for Raspberry Pi Pico, and this tutorial nicely appeared: I'm sure I'll give it a try.
Thank you very much. Andrea
Great. Definitely put multi core into your programming toolbox.
Excellent explanation and great video. Thank you for helping us to better understand threading on Python.
Hi. No problem. I hope you're found it useful!
Have followed your tutorials with great interest; excellent work, very well explained. Thank you very much for sharing your insights. Rob
Great to hear you're enjoying them.
Thanks a lot, really good explanation. My automatic plants watering system soon will be working
Glad it helped
Great thorough explanation, thanks for that. One point of critique, I'm not a big fan of the 'live drawing' animation style found at the beginning of the video. It adds a lot of visual noise and especially distracts from your speaking. This however is a personal preference but imo worth mentioning
Glad you enjoyed the video. Sorry the whiteboard animations are not your cup of tea.
THANK YOU SIR FOR THIS DETAILED EXPLANATION :))))))))))))))
Greetings from Morocco
Glad it was helpful!
Great explanation for beginners. Really loved the video.
Glad you liked it
You're awesome. Thank you for what you do
You're very welcome.
a 40 min vid,let me get the snacks!
Great. Hope you enjoy it! Some popcorn and a coke for me!
Thank you for the time and insight you provide with your channel.
If each thread waits for the other one to finish its access to the frame buffer, what is the advantage of using two cores? The renderer can only do a little work (some Trig maybe) before its main job of accessing the frame buffer. The two cores would indeed run in parallel if the frame buffer were double-buffered, but of course this is not possible with the small Pico RAM size.
You're right about the double buffering but this setup can still work well. The idea here is that you split your code into an update phase and a render phase. The update phase is the parallel part so you try to put as much of the processing load into that. The bouncing box demo doesn't really have any update processing but the Asteroids game (I hope that's shown in the video!) performs all the polygon rotations, collision detection, etc. leaving only the actual drawing of lines into the buffer for the render phase. You can actually make some great multi thread savings this way.
@@BytesNBits Great answer, thanks.
This was on point! Thanks so much. Worth every second of it!!
Glad it was helpful!
@@BytesNBits today I was able to output some sound with a buzzer and some animation in the oled screen both at the same time thanks to your video. Im not sure if there is other way to do it but at least is working with threads.
@@1Geek4Ever1 Great! There are a number of ways to solve any issue. Go with the one that works for you.
great explanation. tnx.
Glad it was helpful!
Very useful tutorial.
Glad it was helpful!
Thanks for the great video. 👍
Thanks for watching!
I’m not sure about the fact that the second thread is running on the second core. I’ve already used threads in my projects but with an ESP32-C3, so a single core microcontroller and it runs without problems.
The Pico handles threads differently to the ESP32 in MicroPython. On the ESP32 MicroPython code can only run on one of the cores so your threads are running as tasks on the same core. The Pico allows you to run MicroPython on both cores (mostly) but can also use the asyncio package to get multiple tasks per core.
FreeRTOS and Multicore.
Thanks for the tip. I haven't played around with RTOS yet.
Thank you!
Hope you're finding these useful.
I was having the same crashes where my rpi got frozen using the second core... The way I fixed it was using a "return 0" at the end of the function instead of the GC.
I hadn't considered that. I'll give it a go. Thanks for the tip.
Great video
Glad you enjoyed it
even if makes the example understandable, you should mention that it's never a good idea to do a sleep() while you hold a lock, which another thread may be waiting on
Thanks for the tip.
thanks! what micropython fw version do you use? so main question is does _thread module can be used in production code?
If you check the Micropython docs it's still listed as experimental - docs.micropython.org/en/latest/library/_thread.html.
I'd be wary of using it in anything where a system crash would be bad.
What is that IDE that you are using?
As well could this MicroPython setup you are using guarantee timing precision during execution?
Hi. I use PyCharm for my coding. There is a free community version that does everything you need. Make sure you install the MicroPython plugin so it can talk to the Pico.
MicroPython is an interpreted language so is much slower than C++. It is aware of time and you can use this to make sure things happen at the correct time. If you are trying to get very tight timing e.g. some sort of signal timing, then I'd probably go with C, or have a play with the PIO system.
_thread has been worked on since the official 1.18 version. Try using a recent nightly build, it appears much more robust.
Hi. Thanks for the tip. I'll give that a go.
Wondering if you have any more info on how to use the REPL tool in PyCharm - for example, flashing a program to it causes it to run immediately, but when opening REPL the keyboard interrupt ends it. Using the soft reboot is enough to reset it, but it's an issue using the socket library for my web sever as I get the EADDRINUSE OSError, essentially that the static IP address I want to bind to is already being used, but by the instance that was interrupted.
You seem to be able to just upload and start it in a few examples here? Plus the terminal window you use just says 'Local', mine has a path to "...\venv\Scripts\python.exe". And obviously I can't flash a new version of the file unless I close the instance of REPL terminal as the COM port is in use...
If you know of any sources online about how to use REPL to debug beyond the official documentation (which is not great) I would appreciate it a ton :)
Hi. Make sure you're using the latest version of PyCharm. They fixed a number of REPL bugs a few months ago. After that make sure you've got the project set up and the extra Micropython add ons installed. If you upload a file called main.py it will auto execute, or if one already exists that will execute. Try saving the main entry point for your code as something different , e.g mycode.py, and delete any main.py. Once you upload you'll be able to REPL onto the device and start the code manually, import mycode.
then theres the PIO stuff. they basically function as 'event computers' that generate CPU interrupts based on the interaction between a state machine and the input stream. This makes it easy for drivers to be efficient because there is no impedance gap to cross converting from a raw data stream to contextually meaningful IO events. While the PIO is figuring out what events it should tell the CPU about happening on the IO pins, the CPU is free to do whatever it likes, and is not occupied doing this work itself like it would be in many other computing environments.
Thanks for the info. PIO is something I intend to look at in some upcoming videos.
Will there be any issue when apply the same method to all the other cores available ? Assumming earch cores handle one box redenering around the LCD and running around. The use case is appilcable for max. 8 application running concuerrently or different input running curently ?
Hi. The RP2040 only has 2 cores for you to use. You can only run 1 thread per core. If you are using a processor with more cores then the same method would apply.
i am trying to program a clock (micropython, raspberry pi pico). my goal is to be able to set the time while the clock is ticking. is this possible or is it a contradiction.
That should be fine. Your code will need to take account of the time reset in the way it tracks time. I'll leave that to you to work out!
Hello, wanna try your example, but only got a 1.8 tft spi (128x260) (the red one with sd card reader) and no MISO nor MISI but only A0 and SDA ... how can i adapt teh code?
Hi. Are you sure this is an SPI lcd? Those connections sound more like part of an I2C interface.
@@BytesNBits they sell like "AZDelivery Display SPI TFT 128 x 160 Pixel" :-(
@@V1P3RSlab I think A0 is the DC pin. SDA is MOSI. There is no MISO as this isn't really needed for the TFT panel. The other pins should match the video. I hope this helps.
@@BytesNBits trying, i let you know :D
@@BytesNBits no way. Using pycharm i got some compile errors on library versions, using thonny, i adapt the code but receive the "unsupported display"
Is the buffer a string of 75KB ? are 2 buffers used ?
Hi. Basically yes - 75KB of single byte integers / characters. There's not enough memory for 2 buffers so the processes have to share the one memory block. Double buffering would be great but not really an option without more RAM.
@@BytesNBits how many colours are used ? could 4 bits be enough ?
@@jyvben1520 Hi. For the LCD panel I was using it's 16bits per pixel. You can store the colour info in memory in any way you want but you have to expand it out to the full 16 bits to send to the LCD. Pure Python isn't fast enough to do this on the Pico.
Where did you got the idea that multithreading is implemented using the 2 cores ?
There is nothing in the documentation that can lead to this conclusion
Please explain why you think so. Also explain what happens if you declare 3 threads...
Hi. The Micropython threading package assumes one thread per core. I know in more powerful processors you can run multiple threads per cores but that doesn't seem to be implimented in MicroPython.
@@BytesNBits Again, there is no such thing in the documentation
The Micropython documentation points to CPython documentation and CPython does not know about multicore.
Beside, MicroPython runs also on the ESP32 which has only one core...
Please post the web page adress where you found this info
Thanks
@@Новости-з3й Thanks for your comments and tips.
@@BytesNBits Finaly, I checked the core assumption using a simple script which reads the CPUID register from the RP2040 and you're right, the first thread runs on core 1
Adding a second thread as you mentioned leads to an error
Here is the script for those who are interested :
-----------------------------------------------------------
import time, _thread
from machine import mem32,Pin
led = machine.Pin(25, machine.Pin.OUT)
def Core0():
while True:
led.on()
time.sleep(5)
#read CPUID
print("Core0 = ",mem32[0xd0000000])
def Core1():
while True:
led.off()
time.sleep(5)
#read CPUID
print("Core1 = ",mem32[0xd0000000])
_thread.start_new_thread(Core1, ( ))
time.sleep(1)
Core0()
-----------------------------------------------
Core0 output is 0 and Core1 output is 1
Regards
No thanks. I’ve no tolerance for garbage collection.
The package is still in development. Hopefully this is just a work around until the bugs get ironed out.
Python 🤦
MicroPython is the microcontroller version of Python. Pretty much the same.
Lol ... Couldn't get a harder way to complicate a basic example??? 😂😂😂😂