#151

  Переглядів 48,793

Ralph S Bacon

Ralph S Bacon

4 роки тому

A deep dive into ESP32 Queues and Global Variables for passing variables and values between tasks, regardless of the core they are running on.
LCSC Electronics (Love Components? Save Cost!)
More Asian Brands, Lower Prices, 4 Hours Ready for Shipping
Shop: lcsc.com/?href=arduinoelectro...
All this and more (eg sketches) in my GitHub:
github.com/RalphBacon/ESP32-V...
It's not Rocket Science!
Here's all you need to know on how Queues work in RTOS and the ESP32 to pass values from one task to another in a safe manner. Just a couple of statements and it's done.
But this is a Deep Dive so we do cover the subject in depth!
As if that is not enough we also cover an alternative way of passing values between tasks - but is it any better? I'll leave that for you to decide.
As an extra (as if this video is not already long enough) we investigate how the Prime Number calculator suddenly increases its processing time from around 60 milliseconds to 1.7 seconds. What is going on?
====================
LINKS LINKS LINKS
====================
(Some links are affiliate links which may financially help my channel. As an Amazon Associate I earn from qualifying purchases.)
Arduino-sized ESP32 board (Wemos):
WeMos® TTgo ESP32 WiFi + Bluetooth Board 4MB Flash UNO D1 R32
eu.banggood.com/Wholesale-War...
Wemos D1 Mini ESP32 240Mhz Dual Core(as used in the demo) on offer $6 until end June 2019:
Wemos® D1 Mini ESP32 ESP-32 WiFi+bluetooth Internet Of Things Development Board Based ESP8266 Fully Functional
www.banggood.com/Wemos-D1-Min...
Hobby Components USBASP AVR Programmer and Adapter (Amazon UK):
amzn.to/2ZK5S3I
If you like this video please give it a thumbs up, share it and if you're not already subscribed please consider doing so and joining me on my Arduinite journey
My channel and blog are here:
------------------------------------------------------------------
/ ralphbacon
ralphbacon.blog
------------------------------------------------------------------

КОМЕНТАРІ: 300
@OsoPolarClone
@OsoPolarClone 4 роки тому
Ralph: I have seen lots of ESP32 videos. Yours is the FIRST to talk about the queue and how to use it. Until yours I did not know it existed. The same goes for semaphores. WELL DONE (AS ALWAYS). Thanks for another GREAT VIDEO!
@RalphBacon
@RalphBacon 4 роки тому
Thanks for that, Bruce, nice to hear from you.
@rjinnh3933
@rjinnh3933 4 роки тому
As always, outstanding video production quality. I simply marvel at the quality of each of your vids. Absolutely the best on YT! The content was pretty good also. Actually, the content was excellent begining with your 13 minute explanation of param passing and then diving into your code. Brings back memories. As a Hardware Designer, In 1978, I was writing my own diags and using semaphores in a Z80/Z8 design and having random crashes. A really sharp Software Engineer took pitty on me and showed me what you just showed us all. Saved my BACON. HAHA.... It's amazing how much I've forgotten during the last 45+ yrs, but you've again re-awakened those little grey cells with this vid. A really big TankYou! Russ in NH
@RalphBacon
@RalphBacon 4 роки тому
Well, the good news, Russ, is that although you might think you have forgotten things they will quickly resurface once prompted. So you are ahead of the game!
@michaelmcnaughton1535
@michaelmcnaughton1535 Рік тому
I like your videos. 1. Minimum blabby content. 2. Clear explanation with just the right degree of complexity. 3. Excellent downloadable examples. Your work is much appreciated, on a par with Andreas Spiess "the guy with the Swiss Accent".
@RalphBacon
@RalphBacon Рік тому
Awesome, thank you! I can't believe Andreas even knows I exist but I do occasionally watch his excellent content too.
@gpTeacher
@gpTeacher 4 роки тому
You hit it out of the park yet again Ralph! This is a FANTASTIC demo of queues for my Grade 12 CompSci course! Very approachable. I’ll be having the students work through it. Thanks!
@RalphBacon
@RalphBacon 4 роки тому
Thanks Gord, if your students understand this then my work is complete!
@maoku7435
@maoku7435 9 місяців тому
I just came here looking for copper and found gold. I learned a lot from this. you explain really well! Thanks for your video.
@RalphBacon
@RalphBacon 8 місяців тому
Awesome! Thank you!
@secraiskille
@secraiskille 4 роки тому
Because of the COVID, my teacher simply sent us here. Great video!
@RalphBacon
@RalphBacon 4 роки тому
Awesome! Thank you! And thank your teacher for pointing you in this direction!
@stompreaper
@stompreaper 4 роки тому
I really like how you are exploring these topics. Thanks for sharing!
@RalphBacon
@RalphBacon 4 роки тому
Thank you for your feedback, Stephen Thompson, noted and appreciated!
@robinharris4706
@robinharris4706 4 роки тому
Another excellent video, thanks Ralph. I get a lot of help and value from your videos and this one is a particularly good example - it goes into a deep technical topic in a clear and informative way. I like your style and that there are no distractions (poor audio, annoying habits etc.!). It is much more useful to me to watch this style of video than a 5 minute overview of something basic or well covered by others. Please keep producing the deep dive style video and I'll keep on watching and supporting! Thanks.
@RalphBacon
@RalphBacon 4 роки тому
Glad you liked this one, Robin, that ESP32 is a most powerful device indeed and it makes sense to know how to program it properly. Thanks for posting.
@jamescullins2709
@jamescullins2709 4 роки тому
Well done Ralph. I Love your explanations.
@RalphBacon
@RalphBacon 4 роки тому
Glad you liked it James!
@george12121979
@george12121979 4 роки тому
thank you for continuing the videos about ESP32
@RalphBacon
@RalphBacon 4 роки тому
You are most welcome george kon, I'm glad you like the video. Nice to hear from you.
@vince_martyn
@vince_martyn 3 роки тому
Hi Ralph, Just discovered your channel and have subscribed. The quality of your explanations and presentation style are excellent and I will be watching more as I plan to port an audio project from the ATMEGA328 to ESP32.
@RalphBacon
@RalphBacon 3 роки тому
Welcome aboard! I'm looking at doing more ESP32 stuff, Vince, as it happens. Such a powerful chip. Keep tuned!
@anispinner
@anispinner 4 роки тому
Thanks for the huge work on this board, again!
@RalphBacon
@RalphBacon 4 роки тому
You are most welcome NLab ™, I'm glad you like the video. Nice to hear from you.
@davidharms3562
@davidharms3562 Рік тому
Thanks Ralph! I thoroughly enjoy the detailed explanation in your videos. Having developed with arduino for a while now, the magic of the ESP32 is truly fascinating. 👍🏻
@RalphBacon
@RalphBacon Рік тому
Glad it was helpful! I tend to use the ESP32 for most projects unless it's trivial and doesn't ever need Wi-Fi connectivity.
@Tony770jr
@Tony770jr 2 роки тому
Hi Ralph, excellent video. Keep it up my friend!
@RalphBacon
@RalphBacon 2 роки тому
Thanks, will do!
@annacermed4468
@annacermed4468 4 роки тому
What a beautiful diving into the deep blue of multitasking. That's simply awesome. Thanks a lot (from Algeria).
@RalphBacon
@RalphBacon 4 роки тому
Glad you liked it Annacer Med, great to hear from someone in Algeria, warmer than the UK, that's for sure.
@davidlambert8368
@davidlambert8368 4 роки тому
Wonderfully succinct and so appreciated! Thanks Ralph.
@RalphBacon
@RalphBacon 4 роки тому
Thank you for your feedback, David Lambert, noted and appreciated!
@mikelopez9893
@mikelopez9893 4 роки тому
Great video Ralph and a good explanation of queues as a sync mechanism.
@RalphBacon
@RalphBacon 4 роки тому
Thanks for that, Mike Lopez, nice to hear from you.
@nexuzinnovation-com
@nexuzinnovation-com 3 роки тому
hi Ralph, I really like the way you teach software programming such as the explanation "volatile" and the LGT8F328P clock_prescale_set() in layman terms, very easy to understand. Thank you, keep up the passion, good works and stays healthy.
@RalphBacon
@RalphBacon 3 роки тому
I'm glad it helped, and thank you for your good wishes. There will be a pause in my videos soon as I move house. After Christmas, in early 2021.
@jackyli6716
@jackyli6716 2 роки тому
best tutorial that i have never seen before! well done ! good job! i love it!
@RalphBacon
@RalphBacon 2 роки тому
Wow, thanks!
@dnarobo
@dnarobo 2 роки тому
Your videos are an essential "library", I never needed Tasking before...but when I ran into a blocking conundrum today...RSB was my first and last stop to learn exactly what I needed.
@RalphBacon
@RalphBacon 2 роки тому
Excellent! I am so glad this video helped you. I can never cover all aspects of a topic but enough to get you going in the right direction. Thanks for the feedback, David.
@TheRooster276
@TheRooster276 7 місяців тому
Great job in explaining details like what "volatile" etc. does. I have purchased books on C++ and they often don't explain well what is going on in the code. Your videos are making all the difference. Thanks a bunch.
@RalphBacon
@RalphBacon 7 місяців тому
Glad it was helpful!
@readmoreon2390
@readmoreon2390 2 роки тому
Just found your channel, absolutely love it thanks for great content as well as being very informational. Well deserved sub and like!
@RalphBacon
@RalphBacon 2 роки тому
Welcome aboard! You only have around 233 more videos to watch, then! Oh, and the quiz to take (latest video). Good luck!
@readmoreon2390
@readmoreon2390 2 роки тому
@@RalphBacon Ahahhahahah will do
@sirrcharles1869
@sirrcharles1869 Рік тому
Thank you for.this content! Fantastic explanation! Was using global variabeles now I will think twice :)
@RalphBacon
@RalphBacon Рік тому
Glad it was helpful!
@kenasuea3617
@kenasuea3617 4 роки тому
I like your enthusiasm. Good Job !
@RalphBacon
@RalphBacon 4 роки тому
I probably had too many coffees before this video, but inside I'm always enthusiastic! Good to hear from you, thanks for posting.
@SameerKhanna-zh7iq
@SameerKhanna-zh7iq Рік тому
Thanks for this great toturial.
@RalphBacon
@RalphBacon Рік тому
You're very welcome!
@daniegar
@daniegar 2 роки тому
awesome content! Thanks a lot Ralph.
@RalphBacon
@RalphBacon 2 роки тому
Glad you liked it!
@iandrake4683
@iandrake4683 3 роки тому
I'm a c# dev and just wanted to say I really appreciate your content. It's perfect for me, even if I already understand most concepts like queues and mutexes. Having them explained in the context of rtos is super helpful. Also, this is the first I've heard that delay on an esp32 releases the CPU! I'm used to the arduino uno. That tidbit helped a bunch.
@RalphBacon
@RalphBacon 3 роки тому
Great to hear! From one C# developer to another it's all quite different in the embedded C++ world without the .NET safety net!
@dalewolver8739
@dalewolver8739 4 роки тому
Great explanation.
@RalphBacon
@RalphBacon 4 роки тому
I'm very glad you think so, Dale, you're very welcome.
@andymouse
@andymouse 4 роки тому
Interesting stuff Ralph, but I'm definitely gonna need to watch a few times!
@RalphBacon
@RalphBacon 4 роки тому
That's fine, Andy, repeat views are apparently a Good Thing as far as UKposts go! But it is worth understanding this correctly to avoid problems down the line.
@andymouse
@andymouse 4 роки тому
@@RalphBacon ​ Nice one Ralph and Happy Birthday! may you have many more and keep your tutorials coming ...I love 'em!
@tomwatzek3500
@tomwatzek3500 4 роки тому
Nice Video, well explained, I'm happy with that! Go on that way, thanks!
@RalphBacon
@RalphBacon 4 роки тому
You are most welcome Tom Watzek, I'm glad you like the video. Nice to hear from you.
@robertmurton7373
@robertmurton7373 2 роки тому
A interesting video, I am new to the ESP32 so this help me understand it better.
@RalphBacon
@RalphBacon 2 роки тому
Glad it was helpful!
@avejst
@avejst 4 роки тому
Impressive multi processor programming design Thanks for sharing👍😀
@RalphBacon
@RalphBacon 4 роки тому
Thanks for your post, Asger Vestbjerg, good to hear from you.
@chriskosik663
@chriskosik663 4 роки тому
Very solid video. Thank you so much!
@RalphBacon
@RalphBacon 4 роки тому
Thanks Chris!
@bharadwajtke
@bharadwajtke 3 роки тому
thank u for the video..done a great work...I appreciate ur genorous nature
@bharadwajtke
@bharadwajtke 3 роки тому
I wasn't subscribed now i subscribed...Thank u
@RalphBacon
@RalphBacon 3 роки тому
And thank you back, welcome to my channel!
@dafydds
@dafydds 2 роки тому
Another excellent video... Passing variables, and the bain of everyone's lives, global variables... I can't lie, I've been hellishly lazy in my recent project; it has global stuff all over the place along with threads. But as per usual, I've forgotten more than I remember from programming, so this video is great at just showing "here's a start, an idea, think and play, the don't cry over your cereal if you're using global variables" 😁🤣 Thanks for a great video 👍
@RalphBacon
@RalphBacon 2 роки тому
Well said! I'm using a task and a global variable in my ESP32 Web Radio project and it works very well.
@normcaissie5598
@normcaissie5598 4 роки тому
Keep up the good videos
@RalphBacon
@RalphBacon 4 роки тому
Thanks for your post, Norm Caissie, good to hear from you.
@jackflash6377
@jackflash6377 Рік тому
The first computer I bought had 64K of RAM and a 1mhz CPU (Apple IIe bought new with 2 disk drives and a DOT matrix printer.. $2500 in 1979ish) The first computer I built was a 386 30mhz, 4mb RAM with a 40mb HD running DOS or Windows3.11 depending on what game I was playing at the time. The ESP32 is more powerful and has more onboard RAM than my full size PC had in that time.
@RalphBacon
@RalphBacon Рік тому
$2,500 in 1979 is worth about $11,356 today! Wow! Expensive computer. See: www.in2013dollars.com/us/inflation/1978?amount=2500 Yes, the ESP32 is a powerful beast for sure. One reason why I like it!
@Kosmonooit
@Kosmonooit 4 роки тому
Good work, thanks.
@RalphBacon
@RalphBacon 4 роки тому
Thanks for the supportive feedback, good to hear from you, thanks for posting.
@TheSimRacers
@TheSimRacers 14 днів тому
FYI: WROOM: WROOM stands for "Wireless Room" and refers to a compact module that integrates Espressif's Wi-Fi and Bluetooth SoC. These modules are designed to provide wireless connectivity capabilities to various IoT devices. They typically come in small form factors, making them suitable for applications where space is limited. WROVER: WROVER stands for "Wireless Room with RAM Overlay." Similar to WROOM, it includes Wi-Fi and Bluetooth functionality. However, WROVER modules also feature additional external RAM, which provides expanded memory capabilities compared to WROOM modules. This extra RAM allows for more complex applications or larger data storage requirements.
@RalphBacon
@RalphBacon 14 днів тому
That's very interesting, and plausible; if you can give me a citation where this info can be found, it would be even better. I searched high and low and could not find it). But for now, I'll use your explanation!
@VictorianMaid99
@VictorianMaid99 8 місяців тому
This is so useful, I am playing a project with multiple Arduinos talking back and forth.
@RalphBacon
@RalphBacon 8 місяців тому
Sounds like you have an interesting project ahead.
@niekbeijloos8355
@niekbeijloos8355 4 роки тому
Very nice thank you!
@RalphBacon
@RalphBacon 4 роки тому
I'm glad you found it useful, thanks for posting.
@ArjanvanVught
@ArjanvanVught 4 роки тому
Yeah! Using a proper developement environment -> Eclipse Thank you!
@RalphBacon
@RalphBacon 4 роки тому
Ha Ha! You're being cruel to the Arduino IDE now, Arjan! But, would you believe it, I'm also running *Visual Studio Code* and *Platformio* at the moment, mainly for ESP32 development but it also works for the Arduino and supports hundreds of other boards too. So maybe, that might become my IDE of choice in the future, you never know. Thanks for your enthusiasm for a 'proper' development IDE, keep tuned.
@W--ko9ms
@W--ko9ms 3 роки тому
@@RalphBacon I've also found myself using vs code with platformio for the esp32. Had been a wonderful experience thus far. Thank for this explanation, cleared some things up for me.
@rayztech7384
@rayztech7384 3 роки тому
Great video full of info! Would it be possible to a video like this where you can control several servos?
@RalphBacon
@RalphBacon 3 роки тому
If you write one function to control one servo you could run that function many times (once per servo) in different tasks. Just pass in the parameter which servo it is that you are wishing to control from your main sketch and Bob's your uncle.
@asagk
@asagk 3 роки тому
Hey Ralph! "loop(){...}" might also work very well for asynchronous stuff like writing aggregated log files (error messages, etc) and else from time to time. So not using loop() at all might not be the case for most projects, but instead be used for low priority asynchronous stuff to do, like waiting for logging buffers to fill up, to be written somewhere when ever a buffer is filled to some amount, like page/block size in a flash device (e.g. some 64/128mbit spi flash).
@RalphBacon
@RalphBacon 3 роки тому
Great tip! Sounds like it would be a good use for the loop.
@tomforrester377
@tomforrester377 4 роки тому
Thanks Ralph. I find the format of your videos really easy to follow. One question - what causes loop0 and loop1 to be started? Something special about that naming convention?
@RalphBacon
@RalphBacon 4 роки тому
Nothing special about loop0 and loop1 at all; these are arbitrary names and, as I mentioned, I would call them something very different in a real program. They are started the instant the setup() creates them. Which means that if you have several tasks to start the first one will be running long before the last one gets scheduled. Thanks for posting Tom, always good to hear from you.
@tomforrester377
@tomforrester377 4 роки тому
Ah okay, so xTaskCreatePinnedToCore() doesn’t only define the properties of the task, it also runs it. Thanks again Ralph!
@bipolarchemist
@bipolarchemist 4 роки тому
Instead of Serial.println("..." + String("...")); at least on the ESP32 and maybe the ESP8266, you can use Serial.printf("%d %f %0.2f... ", varInt, varFloat, varFormattedFloat); to save yourself some typing. You can also get printf to work on the SAMD line as well, but it requires a few lines of code to 'turn on', but much easier than achieving the same thing for the AVR platform. Benefit, you can toss in as many variables as you want, format them to your hearts content and you don't have to use String. And thanks for another great addition to your ESP32 videos.
@RalphBacon
@RalphBacon 4 роки тому
Yes, you can indeed, hmx, and that is indeed the way to do it, but I knew if I did that I would confuse my audience. I tend to use sprintf on my ESP8266 for my HomeAlone project as it's easy to use and is "proper" C! I mentioned in the previous video that users can continue to use Arduino-friendly speak or slowly migrate to the underlying language constructs; maybe I need to expand on this?
@RalphBacon
@RalphBacon 4 роки тому
Oh, and I _never_ use String (capital S) as it can fragment the Heap space, so std::string it is, but then we have to convert that back... the list goes on!
@bipolarchemist
@bipolarchemist 4 роки тому
Glad to hear that you are aware of sprintf. I go crosseyed every time I see example code and there are 5+ Serial.print() statements in a row just to output a single line of text. I am enjoying that you are encouraging people to use more standard functions. Can't wait to see what you have for us next.
@chrisandersson3428
@chrisandersson3428 Рік тому
Hi. Thank you very much for taking the time to explain concurrent computing by examples. For me, a beginner, to follow an example saves a lot of time in learning. I'm using an Arduino Due and could not see same behaviour as on your video. Then I read the "FreeRTOS Reference Manual" and realized that " vTaskStartScheduler()" has to be added to get the RTOS "started". One differens is that your board has the RTOS "built in"? whatever that means. is that it? Can you say a few words about a set of FreeRTOS functions to master to make advanced projects.
@RalphBacon
@RalphBacon Рік тому
To really master FreeRTOS (especially in ESP32 terms and perhaps Due too) you need to work through the book "Free-RTOS for ESP32 Arduino" by Warren Gay. If you learn 1/10th of what's in there you will be head and shoulders above everyone else. Well, except me, of course 😉
@taobot8
@taobot8 2 роки тому
This was incredibly useful! I'd been thinking about how to break away from the Arduino's delay() function to achieve a 250Hz sampling of an IMU and also how to move to a more easily tested codebase. This video really crystalized things for me and helped me appreciate that it's time for me to ditch the Arduino framework and just jump straight to tasks and queues in RTOS. Thankyou so much!
@RalphBacon
@RalphBacon 2 роки тому
I'm glad it's opened your eyes to new possibilities, Stuart! But when you say "ditch the Arduino framework", just hold your horses! When you program for the ESP32, you still use what is effectively an Arduino-like framework (ported from Espressif's IDF development system). Whilst there will be new syntax to learn for the ESP32, you can still use just _most_ of the Arduino-speak you currently use which should speed up development. If you really want to embrace a better way of working (and cut the apron strings of Arduino) think about using PlatformIO (built on top of Visual Studio Code). It is far less hand-holding but ultimately leads to a better programming experience. I now use it all the time unless I'm doing a video! It still uses an Arduino-like framework (supports Arduino-speak C++) but gives you much greater freedom and control when developing. Just a thought!
@taobot8
@taobot8 2 роки тому
@@RalphBacon I've been using PlatformIO since I started down this path back in November last year. I normally develop on non-embedded systems using TDD, so the opportunity to use an IDE that integrated with the Unity test framework swung it for me to use PlatformIO over the Arduino IDE. My understanding was that the ESP32 port of the Arduino framework was a wrapper layer on top of the Espressif IDF, am I correct in that? I'm wondering if that's why the String implementation you'd mentioned wasn't stable hadn't given you any problems on your ESP32.
@RalphBacon
@RalphBacon 2 роки тому
The PlatformIO (and Arduino) implementation of the Espressif ESP32 platform are not wrappers for the IDF (which we would only use if we were developing software professionally, I guess). Espressif release these platforms (port them) regularly and although Arduino and PlatformIO might be at different versions I think they are basically the same thing. That allows the use of Arduino-speak C++ for all the millions of users out there. I haven't had any issues with string handling in the PlatformIO environment but maybe Espressif's implementation of String (capital S) doesn't turn your heap memory into Swiss cheese. That said, I tend to use std::string as a more standard way of using strings in C++.
@MrAshrot
@MrAshrot 3 місяці тому
Brilliant vid, loaded with info! I have a question! A simple setup. task on one core reads temperature off a sensor, and the task on the other core sends that temperature to an IoT cloud. It seems its safe to use a global variable, unless the sending task tries to read the variable at the same time reading task tries to update it. For such a setup, would a queue be more suitable or a semaphore?
@RalphBacon
@RalphBacon 2 місяці тому
Using shared (volatile) global variables is always tricky; using a semaphore before reading a shared variable will be much safer. BTW I would not put the two tasks on different cores; run them at the same priority on Core 1 and it will be safer for all the Espressif stuff (BT/WiFI etc) running on Core 0.
@jorgerive7335
@jorgerive7335 4 місяці тому
Excellent video…much appreciated. I just found you while I was looking for tutorials on the ESP32 (WROOM) and FreeRTos- I’m new to these processors and in programming with OS’s ( I’m an embedded HW guy, knowing enough programming to be dangerous, ;-) and your videos are very helpful. What IDE do you use?
@RalphBacon
@RalphBacon 3 місяці тому
I currently use Visual Studio Code (free) with the PlatformIO add-in. After an initial learning curve (plenty of helpful videos out there, but not by me!) it was bliss (as I have used Visual Studio for decades in my day job!)
@johnhoeppner1569
@johnhoeppner1569 3 роки тому
Good video on the enigmatic ESP32. FYI: I encountered the issue with running a task on core 0 and getting a 'panic' message saying that the watchdog timer had timed out. Following this the CPU reset itself. This occurs if the new task loops forever. When a task is started using the xTaskCreatePinnedToCore, the watchdog for core 0 is started and needs to be reset periodically by the task running in core 0. One solution is to place a call to vTaskDelay(1) inside the infinite loop which restarts the watchdog. There are probably other methods but this worked for me.
@RalphBacon
@RalphBacon 3 роки тому
Yes, putting small delay in the loop is one way to prevent the panic message, but what I do is delete the unwanted task as a first step, then the OS doesn't expect it to run. I demo this somewhere in my code, search my GitHubs for all things ESP32 and you will doubtless find it.
@johnhoeppner1569
@johnhoeppner1569 3 роки тому
@@RalphBacon Hi Ralph, in my particular app I needed core 0 to continuously monitor time sensitive sensors while core 1 handled other asynchronous stuff. There is no issue with using either core in an infinite loop as long as the watchdog is refreshed periodically or disabled. The vTaskDelay() refreshes the watchdog kinda like time.sleep() does in Python but there may be more elegant ways to do this.
@rafaelhenrique7998
@rafaelhenrique7998 3 роки тому
​@@johnhoeppner1569 Hey john, i have the same error as you, can you please help me fix it?
@chrisgibbons2304
@chrisgibbons2304 2 роки тому
Great video, just started using the ESP32 and I'm finding it difficult to find these sorts of indepth explanations, keep up the good work. Regarding core 0, if you're are not using bluetooth/wireless would it be safe to use it?
@RalphBacon
@RalphBacon 2 роки тому
Thanks Chris for your kind words. Now, if you're not using Wi-Fi or BT there is still the OS running on Core 0 but I would use it, with caution. If you upset it you will soon find out with a PANIC or similar on Core 0. Don't forget to yield tasks when there is no more work to do and to keep the priority of _your_ tasks to the default of 1 so that others in Core 0 continue to run.
@emmanuelsheshi1553
@emmanuelsheshi1553 Рік тому
the LOCK method does the same thing in python Threading module. awesome tutorials sir.
@RalphBacon
@RalphBacon Рік тому
Thank you Emmanuel, glad you found it interesting.
@scroogemcducklovers
@scroogemcducklovers 2 роки тому
Whew, ESP-32 and 8266 has been my first and go-to MCU until now (well alongside arduino Nano). I never touched the RTOS part insofar i dabbled with prototyping devices, only with the Arduino-world. Now with multitasking like these, ESP-32 seems more OP than i've imagined. How could i missed such unlimited power & possibilities lol
@RalphBacon
@RalphBacon 2 роки тому
RTOS is pretty well hidden from users of the ESP32; but now you have discovered a whole new world of possibilities! Keep away from Core 0, that is for WiFi, BT and RTOS. Use tasks on Core 1.
@-highvoltage4685
@-highvoltage4685 9 місяців тому
thank you a lot!
@RalphBacon
@RalphBacon 9 місяців тому
You're welcome!
@LimbaZero
@LimbaZero 4 роки тому
One note: If you are planning to do custom board for application that uses ESP32 then recommend to check directly these modules. Just noticed they were from 2e to 5e without vat (in Mouser). Only downside is shipping cost but I usually order that much that I get free shipping.
@RalphBacon
@RalphBacon 4 роки тому
I'll have a look to see how the prices compare to Chinese outlets, thanks for letting me know.
@unglaubichuberlieber8048
@unglaubichuberlieber8048 4 роки тому
you have explained this rtos, multitasking very well, what i like to know, is the ram on the board you have used, or tell me where to find that info, thanks in advance
@RalphBacon
@RalphBacon 4 роки тому
I'm glad you found this useful. Regarding your question, I'm not totally clear what you mean by "is the ram on the board you have used". The ESP32 has 4Mb of SRAM built into the chip, shared by both processors and is used just like any other memory would be. You know this. so what was your question, exactly?
@akasickform
@akasickform 4 роки тому
This is great! I was refreshing my memory as to how queue and semaphores work etc. I forgot that you can change the processing speed. Does this mean you can do this per core? Also, would be interesting to see how much energy per cycle is used when the clock rate is lowered. IE. If using a battery system for a non-time critical application, is it more energy efficient to lower the clock cycle, and if so, how much benefit is this? (I'd imagine the results would not be linear. Also, it would generate less heat due to lower clock speeds, but how much does this actually save?)
@RalphBacon
@RalphBacon 4 роки тому
It's pretty much a fallacy, IMHO, to think that you will save power by reducing the clock rate. If your microController is mostly asleep then that is where your power savings come from. Then, upon waking, you want to get things done pretty much as quickly as possible so you can get back to sleep as quickly as possible. Whilst slightly less power is consumed whilst on a lower clock frequency it does not make up for the fact that you will be awake for longer. That's my take on it, anyway. Of course, if you are dependent on a reliable clock (eg serial transmissions) then a slower internal one _may_ be better regulated but then you should really use a crystal anyway!
@timblack4123
@timblack4123 2 роки тому
Hi Ralph, about the static keyword. Not sure if it’s different in the Arduino world but in C a static “modifier” would make the variable or function local to the module, eg the compiler doesn’t export it and make it available to other modules. This could be useful if you want to make sure the mutex is protecting the variable in all cases. In C++ the static modifier WITHIN A CLASS makes it a class level variable, eg the variable is available to all instances of the class. The variable isn’t instantiated. So what you could do is instantiate an object of type x in each task and either one could access the variable. Of course the mutex would also need to be static. To reduce code and complexity you could simply have a function or method that would increment the variable with the mutex protection and return the new value. This is kind of implementing a design pattern called a Singleton. Of course for this simple example you could just just use a completely static class that wouldn’t need to be instantiated.
@RalphBacon
@RalphBacon 2 роки тому
I use 'static' variables mainly to reduce the scope; that is, ensure they are not global. Within a function they are removed from the function by the compiler (so they are not re-initialised on each loop) but are not visible to other functions. Even so-called global variables (within a sketch) would benefit from being static to prevent the compiler exporting the name and potentially clashing with a name in another library (happened to me, only once or twice). I'd be very wary of declaring variables as static within a class as they are, as you say, shared between instances of the class. Might be what you want but probably not! I don't expect they are thread-safe on an ESP32 either, but I'm just guessing. Yes, we could protect the variable with semaphores, but that's beyond most beginner coding ability (although I did do a video on that, which everyone seemed to understand) 😜 Thanks for the feedback, Tim, some good points you raise there 👍
@marianofranceschetti7847
@marianofranceschetti7847 3 роки тому
Hello Ralph, thanks a lot for your videos. Do you have one of an introduction to ESP32 telling your prefered IDE and what to know about freeRTOS? Something like the correct way to work with ESP32. I'm currently using Arduino and should upgrade.
@RalphBacon
@RalphBacon 3 роки тому
Espressif, the designers of the ESP32, have taken note of the popularity of the Arduino IDE, Mariano, and you can continue programming right there if you wish. Just install the ESP32 boards from the Tools, Boards Manager, ESP32 once you have added in the following entry into your Tools, Preferences, Additional Boards URL Manager: dl.espressif.com/dl/package_esp32_index.json That said, I would take the plunge and either use the new Arduino PRO IDE that is still in alpha (based on Eclipse) or use the open source and well-respected PlatformIO with Visual Studio Code (which I am currently using). Anything new will require a degree of familiarisation (aka a steep initial learning curve) but the PlatformIO community is mature with a wealth of documentation and videos. I decided to build my ESP32 Web Radio project using Platformio & VS Code (so I became familiar with it) and whilst at times it was quite frustrating, it eventually became a joy to use. No turning back for me now although I will keep trying the Arduino PRO IDE (it didn't compile my ESP32 project though!)
@marianofranceschetti7847
@marianofranceschetti7847 3 роки тому
@@RalphBacon Great, thanks a lot. I'll study PlatformIO. So far Arduino has shown to be sufficient, but sometimes I fill it's not enough, specielly when debuging. Have a nice week-end : )
@ardespmaker
@ardespmaker 4 роки тому
Just came across this - I was really confused before. What a great presentation, thanks. Could you tell me - in the xQueueCreate would it be possible to send a structure with different data types. Also could you send an array? One thing I found - - (I only use Arduino IDE) using the serial print code within the tasks in the format with String caused the fatal error situation. Once I split it into 3 statements no problems at all. Interesting that the String format style does not cause problem when used in the standard loop section.
@RalphBacon
@RalphBacon 4 роки тому
The _vparameters_ parameter type is just a void pointer (to a variable), so I guess you could point it to a struct or even a class instance (object)! I have some faint bells ringing but no definitive answer, this time. Strange about Serial.print but maybe a native C++ call might work better. Or output a char array rather than a String (with capital S).
@ardespmaker
@ardespmaker 4 роки тому
@@RalphBacon Thanks Ralph. I've been able to pass both arrays and structs with no issues. Interesting was that the number of arrays or structs put on the queue works just like a normal variable in the xQueueCreate statement, as the sizeof () is just set to the array or struct variable. If you set to 1 then task0 just waits until it can put the next whole set of array data to the queue.
@BerndFelsche
@BerndFelsche 4 роки тому
My recollection could be wrong but writing and reading to/from FreeRTOS queues is atomic. If several tasks are waiting for a queue, then only the first found with highest priority is woken when something is sent into the queue. Similarly at writing. One uses queue-driven tasks for e.g. ensuring that data written to a serial port doesn't get scrambled, which could happen if two or more tasks are writing to the same port "at the same time".
@RalphBacon
@RalphBacon 4 роки тому
I haven't even covered task priority yet (except in passing) but you are correct that the serial port most certainly does get corrupted (well, interleaved) with data from more than one task if the data is written in different statements. Perhaps the Serial library uses secret mutexes to ensure atomic operation?
@treefrogclassics
@treefrogclassics 2 роки тому
Thanks for producing this and #150. It greatly demystified multi-core programming for me. I have a project That I think might benefit from this. I have a ESP32 based controller that centralizes control of lights, thermostat, and air compressor in my shop. The thermostat is controlled via wifi and the lights and compressor are controlled via relays. The user interface is via a touchscreen and a webserver. Occasionally, the touch screen is unresponsive. I suspect this is because the thermostat is being slow to respond over wifi and the request is blocking while waiting for an response. It appears to me that I could avoid this by using the second core. Core 0: - thermostat handling - web server Core 1: - touchscreen service - timer maintenance - relay control How does this approach sound? My thinking is that the Core 1 functions would work normally while Core 0 tasks were blocked while waiting on the thermostat to respond. The timer values are accessed by the web server, touchscreen, and timer maintenance functions. I don't see how a queue would serve this. So I guess I would use global variables with semaphores.
@RalphBacon
@RalphBacon 2 роки тому
I'm glad you found the video interesting, Leon. However... However, although I might have used Core 0 and Core 1 to make a point about moving values between tasks, you really should not use Core 0 at all; it's for the RTOS and Wi-Fi and BT... all the stuff Espressif have put in there. Core 1 is for us developers. So, the best approach is not to use Core 0, just to create a new task, at the same priority as all other tasks (=1) pinned to Core 1. That's what I do with my ESP32 Web Radio: a separate task to handle the transfer of data from an audio buffer to an audio module. Before I did this it was very jittery due to other functions in Core 1 blocking (mostly waiting for) some Wi-Fi procedure to return. Now it runs like a dream. Tasks get a time-slice of about 1mS unless they "yield" their time slot. If the task has run out of work to do, or is itself blocked, you yield the remainder of its 1mS time-slice to other tasks of the same priority (which, counter-intuitively then only can use the remaining time left in that 1mS slice) but it all works amazingly well. I do this with the above-mentioned Web Radio task; if it runs out of data I just "yield" - no point in hogging a time-slice to do nothing in! You've listed several functions that you feel need a dedicated time-slot; set up new tasks for each, but do this slowly. Keep everything in the loop initially, which, of course, must be non-blocking in any way (no delay(x) calls) and move each function to a new task, one by one, ensuring the whole thing functions. Ensure you have enough debugging (monitoring) in each task but remove that (or switch it off) as soon as you feel it's running, as Serial prints are slow. The other thing I do, is to call each of the functions from the main loop() every few milliseconds, rather than doing all tasks all the time. So, for example, I update the screen every X milliseconds (given that it's mostly static). This then gives more time to other functions in the main loop( ). You may find you need fewer tasks than you think! Anyway, this is not the work of a few hours, it will take some design and experimentation - good luck and go slow!
@paulyorke1437
@paulyorke1437 4 роки тому
So very very clear as always, thanks Ralph. Just a question about cores, I am planning to run three tasks and was thinking of task0 on core0 and the other two tasks on core1. If I'm not using the wifi, will this be faster / more efficient than running all three tasks on core1?
@RalphBacon
@RalphBacon 4 роки тому
Short answer: yes, Paul. Longer answer: Yes. If you use two independent cores then each core can support X tasks before you see a noticeable slow-down. But even if you do not use WiFi or BT you might have to take further steps to kill (suspend?) the tasks that _are_ running on Core 0 as otherwise you may get a Core Panic and the ESP32 will reboot. That said, if you code well, that is don't hog all the CPU cycles in a tight loop, for example, it will all work anyway (as my demo from the previous video showed). Good luck!
@paulyorke1437
@paulyorke1437 4 роки тому
@@RalphBacon Thanks Ralph. Just a supplementary (and probably unnecessary) question, your excellent demo showed tasks sharing data via queues but on one core only. Can I assume that this technique will work between tasks running on different cores? All the best.
@mumbaiverve2307
@mumbaiverve2307 3 роки тому
Hi Ralph, your comment about the String() function vis-a-vis the ESP32 was a tad inaudible. Is the String function safer in ESP32, I mean is there an error catch , if heap allocation is unsuccessful ? Thanks for your amazing videos !
@RalphBacon
@RalphBacon 3 роки тому
The use of the Arduino "String" with a capital S is known to cause heap fragmentation (and eventually a crash). However, heap management is allegedly better on the ESPxxxx processors and your heap space doesn't turn into Swiss cheese. That said, I've used std::string in my ESP8266 work and that runs 24x7 for months on end with no issues. Regarding a "catch" for heap fragmentation problems, I'm not sure you _can_ correct it - I mean what is your code going to do if your request for heap space fails?
@jedandecko5585
@jedandecko5585 4 роки тому
Glad you continue with esp32 series, Arduino is dying slowly even them are planing a lot of new boards. Still love nano for offline stuff. Thank you on your effort.
@RalphBacon
@RalphBacon 4 роки тому
Arduino boards (perhaps, as you say, Jedan, in Nano format) are useful in simple projects but even Arduino.cc have just released a whole new set of Nanos to get the interest back. But when you look at this chip, which is cheaper than the Nano (official version) there is no comparison in capabilities, it is true.
@thomasmcneil9598
@thomasmcneil9598 Рік тому
Thank you for this great tutorial, I am learning so much from the creators on UKposts it is fantastic. With som small exceptions, I am beginning to believe you could get a really great technical education just from what you can read/ follow along with on UKposts and the web. A couple of questions about the Semaphore. You define the volatile long count0, and that is what each task increments inside the code. Prior to incrementing, the task will take the semaphore, increment count0 and then give the semaphore back. Between the take and give it accesses the global variable count0.My question is: What associates this global variable count0 with the semaphore? In the semaphore declaration, the global variable is not mentioned. Does the compiler associate whatever variables are between TAKE-GIVE with the semaphore? Can the task access multiple global variables between the TAKE-GIVE and those variables are "protected " from the other task? Thanks Again
@RalphBacon
@RalphBacon Рік тому
In a word (or two) there is _no relationship_ between a semaphore and what you are then doing. The fact that we are updating a variable is just coincidence. The semaphore prevents _concurrent_ updating by two tasks that are otherwise unaware that another task is in the process of updating the variable. By using the semaphore, we are just saying to any other task, "Sorry, you will have to wait a while to get that semaphore and continue whatever it is you were doing." That's why we need to be quick about handing back semaphore when we have carried out the critical process.
@TOMTOM-nh3nl
@TOMTOM-nh3nl 2 роки тому
Thank You
@RalphBacon
@RalphBacon 2 роки тому
You're welcome!
@GoatZilla
@GoatZilla 5 місяців тому
This seems to apply to interrupt context as well, although I've rarely seen this mentioned in Arduino land. Even with a single core, your "main" loop seemingly can get interrupted wherever unless they run it with interrupts off...
@RalphBacon
@RalphBacon 5 місяців тому
Yes, the main flow of the code (the loop) will be interrupted by, well, an interrupt! In an ESP32 environment, each task gets a 1mS slice of time to do its thing. Very fair!
@henrikjensen3278
@henrikjensen3278 4 роки тому
Very interesting video. My favorite multitasking synchronizing is Javas synchronize and queues, with these two I can do a lot of safe multitasking. With semaphores you have to be careful, at least when using multiple levels. Deadlocks are a PITA to locate! This happens very easily when you need a couple of resources and each has it own semaphore and each task have to reserve stuff at different parts in the code. Reading and writing variable asynchronous is usual safe when using the native word size, but with anything else semaphores are needed. My ESP32 boards runs at 80MHz, but I am going to check if I can change frequency. I use some 30pins boards, they looks like nice ESP32 hardware, the 36 pins board add a couple of useless pins (The ones needed for internal program access).
@RalphBacon
@RalphBacon 4 роки тому
I showed you how to change the CPU frequency, Henrik, (assuming you watched to the end) so a quick 5-line sketch should prove it one way or the other. As for deadlocks, I sort of mentioned that if you cannot get a semaphore in the allotted time it will return a response indicating this. It's something I must expand upon as they are, as you say, somewhat problematic.
@henrikjensen3278
@henrikjensen3278 4 роки тому
I have tried that now, but I do not have the functions to get/set CPU frequency. Searching the library code I found this: uint8_t getCpuFreqMHz(){ return CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; } In the ESP class and it return 240 The timeout on semaphores are not always available and it is mostly meaningless in some content anyway.
@RalphBacon
@RalphBacon 4 роки тому
Yes, 240Mhz is the default speed (and that used by the Arduino IDE). But if you have installed the recent boards from Espressif then you should have access to those function I show, to set and get the speed of the chip.
@henrikjensen3278
@henrikjensen3278 4 роки тому
I have not really worried about updates, but hoped that the Arduino IDE handled that, but that may not be true. I use this link for ESP32 in the board manager: dl.espressif.com/dl/package_esp32_index.json I do not know how to force a update. Maybe remove the link and add it again after a restart.
@RalphBacon
@RalphBacon 4 роки тому
Now, Henrik, I did a detailed, step-by-step demo on how to add _or update_ the board definitions so you obviously skipped ahead! Go to Tools, Boards, Boards Manager then type in ESP32 in the search box and you will see ESP32 version 1.02 (or even later). Upgrade to the latest if you haven't already. That should give you all the (new) commands you seem to be missing. Let me know how it goes!
@noweare1
@noweare1 4 роки тому
Are these boards with the esp32 documented well. I know the chip is but are there schematics or pin out table. Also, a huge advantage of an Arduino is the number of libraries already written. Can these libs be used with the ESP32 ? Thanks Ralph, great video. Glad your getting into this chip.
@RalphBacon
@RalphBacon 4 роки тому
The ESP32 community is vibrant, Joey, as is the documentation and support (including the forums) from Espressif themselves, IMHO. You can use the Arduino libraries although I've only used a few so far. After all, if you're writing commands to the I2C bus then it makes no difference what hardware platform you're running on. For the sake of a few dollars it's well worthwhile just getting one and playing with it (also IMHO).
@noweare1
@noweare1 4 роки тому
@@RalphBacon Thanks Ralph
@ElieWar
@ElieWar 4 роки тому
Thank you
@RalphBacon
@RalphBacon 4 роки тому
You are most welcome Elie Wardini, I'm glad you like the video. Nice to hear from you.
@stephenborntrager6542
@stephenborntrager6542 3 роки тому
Threading is an incredibly complicated topic, and you are brave for even touching on it! (And you have done a remarkable job covering what to do, without scaring people away.) I assume the ESP32 does not do instruction re-ordering like an x86 would, so we hopefully do not need to worry about memory access semantics at a hardware level. Does the platform not support the std::atomic library? There are many constructs far more appropriate than "volatile" in general. The trouble with volatile is that it has inconsistent meaning on different compilers and different hardware! (This is actually a HUGE problem, from a standards perspective!) Typically, it is a "full fence" barrier, which prevents memory access re-ordering both ways across all occurrences of that variable. (Typically the entire cache line, not just that variable.) This can really hurt optimization to the point where a single core might be better. (Supposedly, this impacts RISC chips like ARM too, not just intel or amd!) What we really need is acquire/release semantics, like what a proper implementation of the standard atomics library should provide. Basically, acquire/release fences are a way of getting the same anti-corruption guarantee, but while also allowing the compiler to optimize around the variable. Most of this is implementations specific, and I don't know how good the compiler for this chip is able to optimize in the first place, so it's hard to say how big of an issue volatile is.
@RalphBacon
@RalphBacon 3 роки тому
Certainly having two tasks update the same variable, Stephen, is just asking for trouble - unless the developer has ensured the entire read/update operation is atomic, which you most certainly can do. Volatile alone may not do this (it's usually used to ensure register copies of memory values are not used). The question is why you might want the headache of doing this! Certainly not for beginners (which you show you are not, so you probably appreciate the coding complexity this would entail). You could use semaphores or queues, of course, but you always risk a deadlock. When using tasks I'd try and ensure the entire task was doing something independently (single responsibility principle) to avoid huge amounts of testing and debugging.
@stephenborntrager6542
@stephenborntrager6542 3 роки тому
@@RalphBacon I may have gotten a little carried away! You're right, it's definitely better to keep tasks independent when possible. After looking around, It appears that std::atomic is available, if we need it. I haven't even gotten one of these chips yet, so maybe it's too soon for me to be trying to push the things limits ;)
@RalphBacon
@RalphBacon 3 роки тому
Indeed, start slow and build on what you learn. Great chip the ESP32 and the RTOS is very good too, pity it's not a FULL implementation (ie certain functions are just not available).
@KSITREVS
@KSITREVS 4 роки тому
Second question, hello again, what ide do you use? Looks a lot better for developing with! :)
@RalphBacon
@RalphBacon 4 роки тому
This: eclipse.baeyens.it/ but don't forget Arduino is developing a new IDE based on the Eclipse Thea framework, probably for later this year, Trevor. But you can use that Sloeber version in the meantime to get familiar with the way it works (expect to devote several dozen hours to getting your head around it).
@efwilson
@efwilson 3 роки тому
@@RalphBacon Great video as always, thanks! How do you find the Arduino Pro IDE compares to it?
@stephenborntrager6542
@stephenborntrager6542 3 роки тому
@@RalphBacon That's the first I've heard of an alternative IDE from Arduino! That's really exiting! Another option I'd just put out there is visual studio code (free, lightweight, multi-OS), which has an unofficial but decently supported Arduino plugin. It relies on Arduino IDE for part of the toolchain though, so it has the same crippling problems. (Weirdness involving header files and multiple source files in a project.) It CAN parse the source though, and provide code completion and suggestions, etc. Overall it's a very nice editor, but it can't overcome the issues inherent in the underlying build process. I've never had a good time with Eclipse, though I know it has come a long way, and literally anything is better than the plain Arduino IDE! So both this Sloeber thing and that new Arduino IDE are hugely good news, to me! Thanks for sharing!
@TristanGomez
@TristanGomez 4 роки тому
I have one of those ESP32 with the Arduino UNO form factor and they're surprisingly compatible with many of the shields, with some caveats: those that require 5v for gpio won't work as the ESP32 only has 3v3 pins, and the older shields that have SDA and SCL on pins A4 and A5 (like the older non-R3 compliant data logger clones) won't work either, as those pins are input only for the ESP32. I'm maintaining my own wiki while doing research; some people might be interested so I'll link it here if you don't mind :) github.com/parasquid/mcu-iot-sensors/wiki/ESP32#espduino-32
@TristanGomez
@TristanGomez 4 роки тому
One other advantage of having the ESP32 in the same form factor as the Arduino UNO is ability to simply transfer the shields from one to the other. Just a couple of days ago I was doing a presentation to a javascript group about Espruino and part of it was a comparison of how code would look like if written for the Arduino. It really helped hammer home the fact that the hardware being controlled is the same, but the language being used to program is different. Just wanted to mention that one quickly :) The queueing discussion was really interesting and it's something I'd like to experiment on in the future.
@jimb032
@jimb032 4 роки тому
Normally it can work, but it depends on the shield. 3.3v is still seen as a logic high to a 5v input. And if you feed the shield only 3.3v it will return only 3.3v logic levels. You have to look at them case by case.
@RalphBacon
@RalphBacon 4 роки тому
So what we need, Tristan, is an ESP32-compatible shield format! Someone has probably created one already!
@RalphBacon
@RalphBacon 4 роки тому
Glad you like the queuing discussion; it can be a bit long-winded but once understood it's pretty straightforward.
@TristanGomez
@TristanGomez 4 роки тому
I think the most successful shields were the ones by Wemos (which you've covered quite thoroughly in the past) but that was for the ESP8266; and there were some that tried to ride on the form factor, but I haven't seen anything that really took off. One would think that it would be easy to design a pcb which would take the usual devkit-c boards and adapt it to the UNO form factor (much like the nano adapter boards you've also shown in the past) but again, I haven't seen anyone build that (yet).
@JeanDAVID
@JeanDAVID 3 роки тому
in maxprime process, there is a double loops computing float TEMP and long TEMP2 ? is this used to slow the process more ?
@RalphBacon
@RalphBacon 3 роки тому
Yes, I put a number of things in there that I new would be computationally hard work for all the processors (although the ESP32, being 32-bit with a floating point unit, found it no trouble at all).
@edgeeffect
@edgeeffect 4 роки тому
I've said this before but I'm still impressed... your little talking head at the bottom of the screen is a huge improvement on the popular format of "stuff on a green cutting mat". And you VHS-fast forward fade is great too... well done on bringing a bit of life to what's otherwise quite a boring video format. Having multiple cores and an RTOS would be great stuff... it's a pity I'm not that interested in WiFi and Bluetooth or I'd be going crazy for these here ESP32s. The kids who smoke cigs behind the bikesheds say that you could ditch that FOR( ; ; ) and replace it with a label and a GOTO. Wow... string concatenation with a "+" operator instead of strncat().... Blimey! At this rate, they might even pursuade me to start actually liking "C".
@RalphBacon
@RalphBacon 4 роки тому
Glad you like the format of the videos; and the content too! That "for{;;}" construct is just what has been always used. I don't think anyone would ever use a GOTO in C... would they? But the compiler probably compiles it to that anyway. Yes, C can be OK but C++ (object oriented) is better, of course.
@peut
@peut 4 роки тому
Hi, for some reason, your example worked well, but in a bigger project I got a kernel panic (.../freertos/queue.c:1442 (xQueueGenericReceive)- assert failed! ) when taking or giving the semaphore. I had to initialize the semaphoers with Semaphore = xSemaphoreCreateMutex(). after that ot worked fine. Ideas?
@RalphBacon
@RalphBacon 4 роки тому
Indeed you have to create the semaphore, as I show in my setup() routine. Did you miss it or I have misunderstood your question, Jose?
@peut
@peut 4 роки тому
@@RalphBacon Yes, I missed it :-). Sorry.
@antipainK
@antipainK 3 роки тому
But queues that are used by multiple threads also need a concurrency lock (ec semaphores). Any operation on shared resource can create an error if accessed at the same time.
@RalphBacon
@RalphBacon 3 роки тому
Indeed. I guess it depends on how atomic each operation is, but semaphores is what I would go with anyway if I decide to use a task to read the circular buffer.
@TheDiverJim
@TheDiverJim 3 роки тому
Great vid. I know it’s a nit, but probably shouldn’t have held the the mutex while printing. Longer block than required.
@RalphBacon
@RalphBacon 3 роки тому
Great point! Ok for this demo but in general you are spot on.
@jwcolby54
@jwcolby54 4 роки тому
The architecture is 32 bit which means 4 bytes of ram written and read at once. Even more importantly though is that higher math functions such as multiply and divide are software routines in an 8 bit processor whereas they are native instructions in a 32 bit processor. Often times hundreds of instructions on an 8 bit cpu.
@RalphBacon
@RalphBacon 4 роки тому
Often true, John, but it's lucky for us the AVR 8-bit chips do have hardware multiplication. According to the datasheet, it allows 8- and 16-bit implementations, signed and unsigned routines, and fractional signed and unsigned multiply. Here's some bedtime reading: ww1.microchip.com/downloads/en/AppNotes/Atmel-1631-Using-the-AVR-Hardware-Multiplier_ApplicationNote_AVR201.pdf
@4lnstudios833
@4lnstudios833 2 роки тому
I want to use 2 tasks, one for a keypad and lcd interface and the 2nd to drive a stepper motor. Is Semaphore a good way to pass the input of how much to move the motor? Or perhaps to interrupt it if it is mid movement? Will calling the Semaphore code in a loop that controls a stepper motor delay the movement because it has to keep getting the value?
@RalphBacon
@RalphBacon 2 роки тому
You sure you want to use two tasks for this? You could certainly use a separate, self-contained task to get input from the keyboard and display that on an LCD, but how about using the standard loop() to move the stepper motor? Why? I can hear you asking. Well, if the keyboard task updates a volatile, global variable then the main loop just reads that (you might get away with no semaphores if you ensure the read is atomic, that is, it reads the entire two-byte integer) and drives the motor the required amount. If you can use a single byte for the value then it will work without any semaphores or worrying about atomicity. And the stepper motor is only moved if that global variable changes value. Incidentally, the processor is so quick there will be no "delay" in the stepper motor just because you have to read a variable, whichever way you design your code.
@4lnstudios833
@4lnstudios833 2 роки тому
@@RalphBacon Thank you so much for your time in replying. I know you didn't have to but that is what makes you a great person. I appreciate the input and I would love to avoid having to do multiple tasks. I just didn't want having to take input from a keypad, update a display and run a stepper motor at the same time to stop the smooth flow of the stepper motor. Based on what you have said, maybe I should try and get it working the basic way first and then look at improving my code if it doesn't work rather than giving myself hurdles I haven't even encountered yet. Thanks again, you rock!
@MPElectronique
@MPElectronique 3 роки тому
Hello Ralph, Why vTaskDelete (NULL); in the main loop? THanks. Marc.
@RalphBacon
@RalphBacon 3 роки тому
Because we have our own task(s) running we don't need the "loop" any more so we can delete it in this manner; keeps things tidy and reduces resources.
@AndrewJones-tj6et
@AndrewJones-tj6et 4 роки тому
When setting CPU frequency below the default of 240MHz are there any implications on the WiFi/Bluetooth tasks and can the CPU frequency be changed on the fly within the loop not just setup?
@RalphBacon
@RalphBacon 4 роки тому
Others have asked the same, Andrew, and Espressif indicate that 80Mhz should be considered a safe, minimum frequency to use. But, yes, you can adjust the frequency on the fly, dynamically as my demo shows. Have a go!
@KSITREVS
@KSITREVS 4 роки тому
Why doesn’t serial.println need semaphores? Surely two tasks accessing this at the same time would cause a problem? Thank you very informative!!!
@RalphBacon
@RalphBacon 4 роки тому
Yes, it can cause issues with one message mixed up with another!
@KSITREVS
@KSITREVS 4 роки тому
@@RalphBacon interesting, ill remember this when i come to making something. Thank you!
@TamPham-oj4os
@TamPham-oj4os 2 роки тому
I want to save the raw array into non-volatile memory. Can I save the IRremtoe raw array by spiffs ? Which one is the best NVS, SPIFFS, EEPROM ? Thank you
@RalphBacon
@RalphBacon 2 роки тому
The best way (and now advocated by Espressif, the makers of the ESP32) is to use LittleFS instead of SPIFFS. I did an entire video on this, and used it in my ESP32 Web Radio project. ukposts.info/have/v-deo/bKJnjZCjg5x8x6s.html
@sevm7792
@sevm7792 Рік тому
"Bletooth" is the version the "based esp32" uses?
@RalphBacon
@RalphBacon Рік тому
ESP32 does indeed have Bluetooth (the more recent chips support Low Energy BT, BLE). So the ESP32 can act as server or client for BLE.
@yurkshirelad
@yurkshirelad 3 роки тому
What editor are you using in the video?
@RalphBacon
@RalphBacon 3 роки тому
I would be using the Eclipse Sloeber IDE, now deprecated, but remember that the new Arduino IDE is based on Eclipse too. See eclipse.baeyens.it/
@mohamedgendia4274
@mohamedgendia4274 Рік тому
Can the queue take more than one variable? Is it possible to pass variables like the functions ? If i want to give it the address to time struct or any thing complicated is that possible?
@RalphBacon
@RalphBacon Рік тому
Yes, the queue can take any number of variables (structs, objects etc).
@YordanYanakiev
@YordanYanakiev 3 роки тому
Hello Ralph, I have the follow issue - I need to share a record of a few Strings, and integers between 3 tasks on ESP32. What's the best way ?
@RalphBacon
@RalphBacon 3 роки тому
Firstly, don't share strings they take far too much space up. Use a value that means the same as a string. Eg 1=error, 2=too hot, 3= too cold... You get the idea. Push the value onto a queue as I described in this and other esp32 videos and the other task will detect the presence and continue.
@TYGAMatt
@TYGAMatt 3 роки тому
Hi Ralph. Quick question. When passing global variables between tasks, must they be 'volatile'? Im using ESP32. Running some code within the main loop, and also running a couple of tasks on core 1. One of the tasks runs fine, but the other crashes now and again. Also using semaphores but now wondering if I need to also use the volatile key word. The variables are being read and changed in both tasks, the main loop and also being sent over bluetooth. The data is from an MPU6050 (if it makes any difference). Oh, and I have two other i2c devices running, all on same bus, with plans to run another two as and when I can get the code running sweetly as it is now. Any help greatly appreciated.
@RalphBacon
@RalphBacon 3 роки тому
The two cores should be treated as two independent chips; that said, steer clear of Core 0 as it's used by the WiFi and BT tasks. Tasks within the _same_ core probably don't need the _volatile_ keyword if you're passing variables back and forth, but you can try it out in a simple loop to see if it changes correctly. Adding in that keyword won't cause issues, though.
@TYGAMatt
@TYGAMatt 3 роки тому
@@RalphBacon thanks Ralph. I'll give it a bash. Chances are that I also missed a semaphore somewhere.
@TYGAMatt
@TYGAMatt 3 роки тому
So after getting depressed about not being able to run my MPU6050 as a separate task, went back to running it as a normal function in the main loop. Worked fine. But as I'm a very bad loser, tried again, but this time was very meticulous about the semaphore give and take, and declared all the necessary variables as volatile. It now appears to run perfectly. I'm updating the i2c device from within the task. At first this seemed to have issues. Then created a semaphore to sort of isolate each i2c device. No idea if that's how you're supposed to do it, but it worked :) I'm using xCreateSemaphoreMutex() for all cases. Again, no idea if that's the correct way. Anyway, just thought I'd let you know seeing as your video was my initial inspiration for trying tasks in the first place. More vids on the ESP32 and various RTOS magic certainly wouldn't be a bad thing. Good day to you Sir!
@RalphBacon
@RalphBacon 3 роки тому
Experience never comes cheap, does it? But I'm delighted that my video at least made you try this (and then refine it). Your knowledge has now increased. So I'm more than happy!
@TYGAMatt
@TYGAMatt 3 роки тому
Ralph, experience is a bit lacking on my side, but with guys like your good self sharing your vast experience with us incompetent fools makes learning these thing so much fun.
@PavolFilek
@PavolFilek Рік тому
Hi Ralph, I can not change freq. of ESP32 under 80 MHz, 240 OK, 160 OK, 80 OK, but if I set 40 MHz, ESP32 crashes.Why ?
@RalphBacon
@RalphBacon Рік тому
I suspect that the Wi-Fi, Bluetooth and other protocols/services are too delayed with a slow frequency. The question I'm asking myself is why you would want to reduce the frequency of an ESP32 _at all_ let along to below 80MHz? Let me know!
@bobp5776
@bobp5776 Місяць тому
Is it possible to run a i2c device in one of those Tasks? So far i haven't seen it anywhere. I.e. A simple AS5048 i2c Position Sensor running in one core , Making its Angle data available Globally to the other core . I cant get it to work.
@RalphBacon
@RalphBacon Місяць тому
I2C (and, indeed, any other hardware device) can be used in any task. You just have to be careful not to conflict their use from multiple tasks. However, back to your question. If you have initialised the I2C device, either in the "setup" of your sketch, or the task itself, you should be able to determine it is present (perhaps using the "standard" ESP32 GPIO pins 21/22 but you can actually assign most GPIO pins as you see fit). Look at the ubiquitous I2C "scanner" sketch to ensure you have discovered the device, it's only about 6 lines long! Then, in your task's infinite loop (tasks must never end, except by deleting them) just use the I2C functionality as you need. It all works just as you would expect. Tip: Keep all your task on Core 1, leaving Core 0 for the ESP32's system processes (such as Wi-Fi, BT and so on). You can expose the data the task reads on the I2C bus by updating a shared variable (if you want to consume the data in another task, you will probably need to use semaphores so each task doesn't fight over - and corrupt - the data values).
@thisnicklldo
@thisnicklldo 4 роки тому
Interesting - but I'm a bit perplexed. Taking the example using a global, it seems the ++count is not atomic - I see that ++count must take a few machine code instructions, and if you say so then I can see that the RTOS might choose the wrong moment to suspend the task doing ++count and start the other task that also wants to do ++count. But surely the underlying semaphore implementation must take several machine code instructions, so that is presumably treated as atomic, else it won't work. Is the position that the compiler only guarantees to create semaphores as atomic instructions and nothing else?
@RalphBacon
@RalphBacon 4 роки тому
Quite so. If the count is not atomic then the use of a semaphore is _essential_ but we can't be sure at which point the task handler switches contexts. But the semaphore ensures consistency.
@chevere3424
@chevere3424 5 місяців тому
I am trying to show a message on an LED screen that comes from a telegram message and at the same time if this message is "led1" the led fades in and fades out (using pwm), but the telegram bot needs 1 second to wait for a new message, then I thought "I could use a core to update the message on the screen and another core to manage the class that makes the LED fade" however I can't do it, I see that you use two different tasks in the same core, if you use a delay(1000) in one task and delay(50) in the other, do they add up or are they still independent?
@RalphBacon
@RalphBacon 4 місяці тому
If you are (still) using delays you need to learn how not to do that. Blocking code is wasteful in microcontroller cycles. At the very least you could YIELD that part of the timeslice it has been given, but better still is suspending the task for a particular period (either relative or absolute). Or just suspend the task until it is un-suspended (resumed) by another bit of code. Options, options! OK, enough wrist slapping! If you delay one task you will not affect the operation of other tasks (they all get an equal share of the time, usually 1mS each). (But if you do YIELD a task, the next task gets the remainder of its timeslice). BTW I've covered how not to use delay statements in more than video, good hunting (a searchable and linked pdf of all my videos in each video description).
@chevere3424
@chevere3424 4 місяці тому
@@RalphBacon I really appreciate your help, since I learned to use millis on class objects, I no longer use delay. I hope to show you the progress of my project. Thank you!!!
@pacsmile
@pacsmile 3 роки тому
Is there a limit of tasks we can execute on the esp32?
@RalphBacon
@RalphBacon 3 роки тому
Yes, when you run out of memory (each task requires a stack in memory). It's probably documented somewhere but it must also depend on what your task is doing, how many variables it uses, wifi, bluetooth etc.
@phillipneal8194
@phillipneal8194 Рік тому
can I throw an interrupt between cpus ?
@RalphBacon
@RalphBacon Рік тому
You cannot directly. Each processor is independent. But you could pass a value between tasks (running on different processors) that then generates an interrupt on that processor, I suppose.
@W122ard1
@W122ard1 2 роки тому
If i use volatile global variable will it be safe to use between threads?
@RalphBacon
@RalphBacon 2 роки тому
No, Alexander, volatile variables are not thread-safe. You would have to use semaphores or use another signalling system to ensure you did not stomp all over a variable as it was being updated by another thread. Remember that *volatile variables* are simply those flagged to the compiler that they are unsafe to be referenced by a register where the compiler might have put a _copy_ of the variable's value; it will _always_ be retrieved from its memory location. But that doesn't help across threads at all!
@W122ard1
@W122ard1 2 роки тому
@@RalphBacon Hm actually after some research and reading, looks like in some case i can use that. Depending on controller "bits" so in arduino it is safe to use byte size variables, and it case of ESP i could safely use up to 32bits variable. But if some structure to read is more than 32bits in this case could be problems
@RalphBacon
@RalphBacon 2 роки тому
Well, OK, a single byte is OK, because the operation is _atomic_ - that is, it completes in its entirety or not at all. But updating an integer (2-bytes) can go very wrong, as one task updates the low-byte then before it has a chance to update the high-byte the other task stomps all over the low-byte value (or reads a now corrupt value). Personally, I think it would be foolhardy to _hope_ it will work when semaphores are very easy to use and are designed to avoid this exact situation of clashes. Just sayin'! 😜
@sudedemmanuel2975
@sudedemmanuel2975 2 роки тому
Im trying to pass a dynamically changing variable to Task 1 (one task only) that is running like infinite loop, the variable has been defined in .h file and used by the software and dynamically changing, I want to keep track of its value I could pass a constant and it works, can you help please?
@RalphBacon
@RalphBacon 2 роки тому
You need to pass it as a (void *) &reference (pointer) and then de-reference it in the task back to the correct variable type. I'll post some very simple code tomorrow for you; I do this in my project. What are you passing to the task?
@sudedemmanuel2975
@sudedemmanuel2975 2 роки тому
@@RalphBacon can i send you my code so to show how i can modify please
@sudedemmanuel2975
@sudedemmanuel2975 2 роки тому
@@RalphBacon thanks Ralph much appreciated im passing a float variable that is being used elsewhere and changing i need to track its value it is declared in a structure in .h file and used by .c files i think 2 i passed a constant float variable and that worked but the varying one is not giving me the right values
@RalphBacon
@RalphBacon 2 роки тому
This is how I do it: 1. When you create the (pinned) task, I pass the parameter like this: (void *)&myVariable, /* Task input parameter */ 2. In the task I dereference it (to get to the actual value) likes this: int myVariable = *((int *)parameter); You need to do this action whenever you want to get to the new (updated) values. I was wondering whether there was another way I could do this but as I am using a struct in an array it's the best way for me. One word of warning: floats are not a good variable type to pass around as they get rounding errors very easily. Better to use an integer (2 bytes) or a long integer (4 bytes) and then divide down to the float when you need to _display_ it. It's what I do. Example: float value of 10.45 received from some sensor. Multiply by 100 to get 1045 as the _integer_ value that you can then use without worries of rounding errors. When you need to display the value just do (float) myInteger / 100.00
@sudedemmanuel2975
@sudedemmanuel2975 2 роки тому
@@RalphBacon Hi Ralph thanks for your reply this is my code in the task its running outside void loop() void task1(void *parameters){ //contl.LutOut=34.0f; //volatile control_output_t contl; digitalWrite(2,HIGH); delay(5000); digitalWrite(2,LOW); delay(5000); for(;;){ //volatile control_output_t contl; if(contl.LutOut>33.0f) {digitalWrite(2,HIGH); } else if (contl.LutOut
@gavinsmalley1513
@gavinsmalley1513 4 роки тому
I'm not sure of the origins of the names "WROOM" and "WROVER" but, as far as I understand it, essentially the two major differences are that the "WROOM" is a 3.3v core with no PSRAM and the "WROVER" uses a 1.8v core and has a PSRAM chip hiding under the can.
@RalphBacon
@RalphBacon 4 роки тому
Yes, that PSRAM caused them no end of problems, from I hear (and read)! You raise an important note there, Gavin, that these modules are NOT 5v tolerant (although some have experimented) but I would always use a level shifter). Thanks for posting, good to hear from you.
#149 ESP32 Dual Core Programming + Speed 💨Test vs Arduino UNO (fast!)
31:18
#224 🛑 STOP using Serial.print in your Arduino code! THIS is better.
26:39
Артем Пивоваров х Klavdia Petrivna - Барабан
03:16
Artem Pivovarov
Переглядів 1,7 млн
Гражданская оборона 2024 - 16 полный выпуск
1:04:15
Телеканал ICTV
Переглядів 664 тис.
Minimalist Microcontroller: Building a Bare-Bones Dev Board
9:15
atomic14
Переглядів 100 тис.
#149 ESP32 Deep Sleep, RTC Memory, "Secret" LoLin Pins
13:28
Andreas Spiess
Переглядів 145 тис.
#328 ESP32 Secrets: Interrupts, and Deep-Sleep under the Hood
18:57
Andreas Spiess
Переглядів 171 тис.
Verilog intro - Road to FPGAs #102
12:08
Electronoobs
Переглядів 104 тис.
Revolutionize Your ESP32 Projects with Live GPIO Pin Monitoring!
8:08
The Last Outpost Workshop
Переглядів 137 тис.
#332 ESP32  OTA tutorial with tricks (incl. OTA debugging)
10:17
Andreas Spiess
Переглядів 130 тис.
#BB11 Create an Arduino Library😨 - A Real World Example (Easy)
25:54
Ralph S Bacon
Переглядів 23 тис.
#363 Which ESP32 pins are safe to use?
11:53
Andreas Spiess
Переглядів 123 тис.