#151

Sdílet
Vložit
  • čas přidán 27. 08. 2024
  • 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...
    All this and more (eg sketches) in my GitHub:
    github.com/Ral...
    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.co...
    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.c...
    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
    ------------------------------------------------------------------

Komentáře • 308

  • @OsoPolarClone
    @OsoPolarClone Před 5 lety +9

    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  Před 5 lety +1

      Thanks for that, Bruce, nice to hear from you.

  • @rjinnh3933
    @rjinnh3933 Před 5 lety +3

    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  Před 5 lety

      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 Před rokem +1

    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  Před rokem

      Awesome, thank you! I can't believe Andreas even knows I exist but I do occasionally watch his excellent content too.

  • @gpTeacher
    @gpTeacher Před 5 lety +2

    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  Před 5 lety +1

      Thanks Gord, if your students understand this then my work is complete!

  • @secraiskille
    @secraiskille Před 4 lety +4

    Because of the COVID, my teacher simply sent us here. Great video!

    • @RalphBacon
      @RalphBacon  Před 4 lety

      Awesome! Thank you! And thank your teacher for pointing you in this direction!

  • @maoku7435
    @maoku7435 Před rokem +1

    I just came here looking for copper and found gold. I learned a lot from this. you explain really well! Thanks for your video.

  • @TheBionicbone
    @TheBionicbone Před měsícem

    Great video and excellent info, a good discussion at the end too about speed vs power consumption that I wasn't expecting from the title. It is defo a video to watch in full - Thank you, subscribed !!

  • @annacermed4468
    @annacermed4468 Před 4 lety +1

    What a beautiful diving into the deep blue of multitasking. That's simply awesome. Thanks a lot (from Algeria).

    • @RalphBacon
      @RalphBacon  Před 4 lety

      Glad you liked it Annacer Med, great to hear from someone in Algeria, warmer than the UK, that's for sure.

  • @davidharms3562
    @davidharms3562 Před rokem +1

    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  Před rokem

      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.

  • @nexuzinnovation-com
    @nexuzinnovation-com Před 3 lety +2

    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  Před 3 lety

      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.

  • @stompreaper
    @stompreaper Před 5 lety +1

    I really like how you are exploring these topics. Thanks for sharing!

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Thank you for your feedback, Stephen Thompson, noted and appreciated!

  • @TheRooster276
    @TheRooster276 Před 11 měsíci +1

    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.

  • @dnarobo
    @dnarobo Před 2 lety

    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  Před 2 lety

      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.

  • @george12121979
    @george12121979 Před 5 lety +1

    thank you for continuing the videos about ESP32

    • @RalphBacon
      @RalphBacon  Před 5 lety

      You are most welcome george kon, I'm glad you like the video. Nice to hear from you.

  • @anispinner
    @anispinner Před 5 lety +2

    Thanks for the huge work on this board, again!

    • @RalphBacon
      @RalphBacon  Před 5 lety +1

      You are most welcome NLab ™, I'm glad you like the video. Nice to hear from you.

  • @robinharris4706
    @robinharris4706 Před 4 lety

    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  Před 4 lety

      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.

  • @jackflash6377
    @jackflash6377 Před rokem +3

    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  Před rokem

      $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!

  • @iandrake4683
    @iandrake4683 Před 3 lety

    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  Před 3 lety

      Great to hear! From one C# developer to another it's all quite different in the embedded C++ world without the .NET safety net!

  • @jamescullins2709
    @jamescullins2709 Před 4 lety +1

    Well done Ralph. I Love your explanations.

  • @VictorianMaid99
    @VictorianMaid99 Před rokem

    This is so useful, I am playing a project with multiple Arduinos talking back and forth.

    • @RalphBacon
      @RalphBacon  Před rokem +1

      Sounds like you have an interesting project ahead.

  • @mikelopez9893
    @mikelopez9893 Před 5 lety

    Great video Ralph and a good explanation of queues as a sync mechanism.

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Thanks for that, Mike Lopez, nice to hear from you.

  • @bipolarchemist
    @bipolarchemist Před 5 lety +1

    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  Před 5 lety

      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  Před 5 lety +1

      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 Před 5 lety

      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.

  • @dafydds
    @dafydds Před 2 lety

    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  Před 2 lety +1

      Well said! I'm using a task and a global variable in my ESP32 Web Radio project and it works very well.

  • @readmoreon2390
    @readmoreon2390 Před 2 lety +1

    Just found your channel, absolutely love it thanks for great content as well as being very informational. Well deserved sub and like!

    • @RalphBacon
      @RalphBacon  Před 2 lety +1

      Welcome aboard! You only have around 233 more videos to watch, then! Oh, and the quiz to take (latest video). Good luck!

    • @readmoreon2390
      @readmoreon2390 Před 2 lety +1

      @@RalphBacon Ahahhahahah will do

  • @andymouse
    @andymouse Před 5 lety +1

    Interesting stuff Ralph, but I'm definitely gonna need to watch a few times!

    • @RalphBacon
      @RalphBacon  Před 5 lety +1

      That's fine, Andy, repeat views are apparently a Good Thing as far as CZcams go! But it is worth understanding this correctly to avoid problems down the line.

    • @andymouse
      @andymouse Před 5 lety +1

      @@RalphBacon ​ Nice one Ralph and Happy Birthday! may you have many more and keep your tutorials coming ...I love 'em!

  • @jackyli6716
    @jackyli6716 Před 2 lety

    best tutorial that i have never seen before! well done ! good job! i love it!

  • @TristanGomez
    @TristanGomez Před 5 lety +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 Před 5 lety

      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 Před 5 lety +1

      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  Před 5 lety

      So what we need, Tristan, is an ESP32-compatible shield format! Someone has probably created one already!

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Glad you like the queuing discussion; it can be a bit long-winded but once understood it's pretty straightforward.

    • @TristanGomez
      @TristanGomez Před 5 lety

      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).

  • @ArjanvanVught
    @ArjanvanVught Před 5 lety +1

    Yeah! Using a proper developement environment -> Eclipse Thank you!

    • @RalphBacon
      @RalphBacon  Před 5 lety +1

      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 Před 3 lety

      @@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.

  • @davidlambert8368
    @davidlambert8368 Před 5 lety

    Wonderfully succinct and so appreciated! Thanks Ralph.

    • @RalphBacon
      @RalphBacon  Před 5 lety +1

      Thank you for your feedback, David Lambert, noted and appreciated!

  • @vince_martyn
    @vince_martyn Před 4 lety

    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  Před 4 lety

      Welcome aboard! I'm looking at doing more ESP32 stuff, Vince, as it happens. Such a powerful chip. Keep tuned!

  • @johnhoeppner1569
    @johnhoeppner1569 Před 4 lety +1

    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  Před 4 lety +2

      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 Před 4 lety +2

      @@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 Před 4 lety

      ​@@johnhoeppner1569 Hey john, i have the same error as you, can you please help me fix it?

  • @Tony770jr
    @Tony770jr Před 2 lety

    Hi Ralph, excellent video. Keep it up my friend!

  • @sirrcharles1869
    @sirrcharles1869 Před rokem

    Thank you for.this content! Fantastic explanation! Was using global variabeles now I will think twice :)

  • @TheSimRacers
    @TheSimRacers Před 4 měsíci

    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  Před 4 měsíci

      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!

  • @SameerKhanna-zh7iq
    @SameerKhanna-zh7iq Před rokem +1

    Thanks for this great toturial.

  • @robertmurton7373
    @robertmurton7373 Před 2 lety

    A interesting video, I am new to the ESP32 so this help me understand it better.

  • @kenasuea3617
    @kenasuea3617 Před 5 lety

    I like your enthusiasm. Good Job !

    • @RalphBacon
      @RalphBacon  Před 5 lety

      I probably had too many coffees before this video, but inside I'm always enthusiastic! Good to hear from you, thanks for posting.

  • @avejst
    @avejst Před 5 lety

    Impressive multi processor programming design
    Thanks for sharing👍😀

    • @RalphBacon
      @RalphBacon  Před 5 lety +1

      Thanks for your post, Asger Vestbjerg, good to hear from you.

  • @dalewolver8739
    @dalewolver8739 Před 4 lety +1

    Great explanation.

    • @RalphBacon
      @RalphBacon  Před 4 lety

      I'm very glad you think so, Dale, you're very welcome.

  • @LimbaZero
    @LimbaZero Před 5 lety

    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  Před 5 lety

      I'll have a look to see how the prices compare to Chinese outlets, thanks for letting me know.

  • @edgeeffect
    @edgeeffect Před 5 lety +1

    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  Před 5 lety

      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.

  • @timblack4123
    @timblack4123 Před 2 lety

    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  Před 2 lety +1

      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 👍

  • @taobot8
    @taobot8 Před 2 lety

    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  Před 2 lety +1

      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 Před 2 lety

      @@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  Před 2 lety +1

      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++.

  • @scroogemcduckenjoyer
    @scroogemcduckenjoyer Před 2 lety

    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  Před 2 lety

      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.

  • @jwcolby54
    @jwcolby54 Před 4 lety +1

    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  Před 4 lety +1

      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

  • @jedandecko5585
    @jedandecko5585 Před 5 lety

    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  Před 5 lety +2

      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.

  • @treefrogclassics
    @treefrogclassics Před 2 lety

    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  Před 2 lety

      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!

  • @tomwatzek3500
    @tomwatzek3500 Před 5 lety

    Nice Video, well explained, I'm happy with that! Go on that way, thanks!

    • @RalphBacon
      @RalphBacon  Před 5 lety

      You are most welcome Tom Watzek, I'm glad you like the video. Nice to hear from you.

  • @stephenborntrager6542
    @stephenborntrager6542 Před 4 lety +1

    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  Před 4 lety

      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 Před 4 lety

      @@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  Před 4 lety

      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).

  • @asagk
    @asagk Před 3 lety

    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  Před 3 lety

      Great tip! Sounds like it would be a good use for the loop.

  • @chriskosik663
    @chriskosik663 Před 4 lety

    Very solid video. Thank you so much!

  • @normcaissie5598
    @normcaissie5598 Před 5 lety

    Keep up the good videos

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Thanks for your post, Norm Caissie, good to hear from you.

  • @emmanuelsheshi1553
    @emmanuelsheshi1553 Před 2 lety

    the LOCK method does the same thing in python Threading module. awesome tutorials sir.

    • @RalphBacon
      @RalphBacon  Před 2 lety

      Thank you Emmanuel, glad you found it interesting.

  • @antipainK
    @antipainK Před 3 lety +2

    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  Před 3 lety +1

      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.

  • @bharadwajtke
    @bharadwajtke Před 3 lety

    thank u for the video..done a great work...I appreciate ur genorous nature

    • @bharadwajtke
      @bharadwajtke Před 3 lety +1

      I wasn't subscribed now i subscribed...Thank u

    • @RalphBacon
      @RalphBacon  Před 3 lety

      And thank you back, welcome to my channel!

  • @tomforrester377
    @tomforrester377 Před 5 lety +1

    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  Před 5 lety

      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 Před 5 lety +3

      Ah okay, so xTaskCreatePinnedToCore() doesn’t only define the properties of the task, it also runs it.
      Thanks again Ralph!

  • @niekbeijloos8355
    @niekbeijloos8355 Před 4 lety +1

    Very nice thank you!

    • @RalphBacon
      @RalphBacon  Před 4 lety

      I'm glad you found it useful, thanks for posting.

  • @henrikjensen3278
    @henrikjensen3278 Před 5 lety

    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  Před 5 lety

      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 Před 5 lety

      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  Před 5 lety

      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 Před 5 lety

      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  Před 5 lety

      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!

  • @willofirony
    @willofirony Před 5 lety +1

    Static keyword: defines a variable that "lives" in the static data area i.e. not on the heap (dynamically created variable that lives until the memory is reallocated [deleted]) and not a temporary variable that lives on the stack and only lives until the end of the current scope. Now any variable that is declared outside a a function scope (including main()) is also designated space in the static data area. So, the static keyword is NOT essential. However it does make the code and intentions of the programmer easier to read. This is particularly the case when the static variable is declared outside but amongst a bunch of functions (either because the programmer just remembered it was needed by the following function or to indicate the close relationship between the variable and the following function). No matter were the variable is declared it lives until the program exits (when all the variables go to the variable cemetery - very sad).

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Indeed, Michael. So, given that the variable in question is declared within the scope of main() but outside of setup() and loop() it should exist for as long as main() runs (ie until the program exits). So with or without the static keyword the variable remains a Global Variable. I wonder why Espressif want it declared as static? Perhaps the SDK they use works a bit differently to the traditional Arduino setup?
      Thanks for the detailed response, very interesting, always good to hear from you.

  • @FaizanAhmad-mf5wq
    @FaizanAhmad-mf5wq Před měsícem

    Esp32 CAM
    Hii guys, i am stuck at designing a system.
    I want one task to continually check for touch sensor signal, if it comes, then save image and insert its name into queue.
    For second task i simply need to poll queue if there is a file name, send that file to email, pop the name and continue polling.
    I am unable to run both tasks concurrently on both cores, esp32cam resets itself when i run the program.
    Can someone help me how should i design my tasks so they can work concurrently?
    Please pardon me i am new to these things.

  • @PavolFilek
    @PavolFilek Před rokem +1

    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  Před rokem +1

      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!

  • @BerndFelsche
    @BerndFelsche Před 5 lety

    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  Před 5 lety

      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?

  • @gavinsmalley1513
    @gavinsmalley1513 Před 5 lety

    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  Před 5 lety

      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.

  • @rayztech7384
    @rayztech7384 Před 3 lety

    Great video full of info!
    Would it be possible to a video like this where you can control several servos?

    • @RalphBacon
      @RalphBacon  Před 3 lety +1

      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.

  • @chrisandersson3428
    @chrisandersson3428 Před 2 lety

    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  Před 2 lety

      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 😉

  • @fabiovsroque
    @fabiovsroque Před měsícem

    I am not hundred per cent sure, but I think Arduino IDE handles global variables for ESP32 internally...

  • @chriskosik663
    @chriskosik663 Před 4 lety +2

    wroom vs wrover has to do with sram differences!

    • @RalphBacon
      @RalphBacon  Před 4 lety +1

      Good to know, Chris, pity Espressif didn't make it plain.

  • @Kosmonooit
    @Kosmonooit Před 5 lety

    Good work, thanks.

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Thanks for the supportive feedback, good to hear from you, thanks for posting.

  • @TheDiverJim
    @TheDiverJim Před 3 lety

    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  Před 3 lety +1

      Great point! Ok for this demo but in general you are spot on.

  • @thomasmcneil9598
    @thomasmcneil9598 Před rokem

    Thank you for this great tutorial, I am learning so much from the creators on CZcams 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 CZcams 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  Před rokem

      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.

  • @jorgerive7335
    @jorgerive7335 Před 8 měsíci

    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  Před 7 měsíci

      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!)

  • @GoatZilla
    @GoatZilla Před 9 měsíci

    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  Před 9 měsíci +1

      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!

  • @noweare1
    @noweare1 Před 5 lety +1

    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  Před 5 lety

      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 Před 5 lety +1

      @@RalphBacon Thanks Ralph

  • @KSITREVS
    @KSITREVS Před 4 lety +2

    Second question, hello again, what ide do you use? Looks a lot better for developing with! :)

    • @RalphBacon
      @RalphBacon  Před 4 lety +2

      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 Před 4 lety

      @@RalphBacon Great video as always, thanks! How do you find the Arduino Pro IDE compares to it?

    • @stephenborntrager6542
      @stephenborntrager6542 Před 4 lety +1

      @@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!

  • @michaelhyde9971
    @michaelhyde9971 Před 5 lety +2

    Hi Ralph dose the clock speed upset the wifi .

    • @jimb032
      @jimb032 Před 5 lety +1

      It's not supposed to...it's managed in the background by the RTOS. ESP8266 yes- you can seriously piss it off.

    • @michaelhyde9971
      @michaelhyde9971 Před 5 lety

      @@jimb032 thanks

    • @RalphBacon
      @RalphBacon  Před 5 lety +1

      Espressif seem to say that 80Mhz is the slowest, reliable speed for any ESP32 variant (when running wifi). But the only way to know is to try it at lower speeds and see what happens.

    • @michaelhyde9971
      @michaelhyde9971 Před 5 lety

      @@RalphBacon thanks for letting me know. I try when I have fixed my usb port after a little mishap. Lol.
      Great videos as usual.

    • @RalphBacon
      @RalphBacon  Před 5 lety +1

      "A little mishap" = "totally destroyed the motherboard"? Yes, I've had a few like that! I've heard anecdotally that the wifi signal gets "corrupted" at too low CPU Speed, but an identical ESP32 with the same speed can communicate with it no problem. Secret network!

  • @chrisgibbons2304
    @chrisgibbons2304 Před 2 lety

    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  Před 2 lety

      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.

  • @MrAshrot
    @MrAshrot Před 7 měsíci

    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  Před 7 měsíci

      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.

  • @JeanDAVID
    @JeanDAVID Před 3 lety

    in maxprime process, there is a double loops computing float TEMP and long TEMP2 ? is this used to slow the process more ?

    • @RalphBacon
      @RalphBacon  Před 3 lety

      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).

  • @TamPham-oj4os
    @TamPham-oj4os Před 3 lety

    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  Před 3 lety +1

      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.
      czcams.com/video/4r6YZlLfKfw/video.html

  • @bobp5776
    @bobp5776 Před 5 měsíci

    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  Před 5 měsíci

      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).

  • @AndrewJones-tj6et
    @AndrewJones-tj6et Před 5 lety

    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  Před 5 lety +2

      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!

  • @YordanYanakiev
    @YordanYanakiev Před 3 lety

    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  Před 3 lety

      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.

  • @AKKJ420
    @AKKJ420 Před 2 lety

    I am not sure what I am doing wrong but I am getting the following error. I think when I comment out vTaskDelete(Null) it stops rebooting but nothing appears on the serial monitor.
    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0030,len:1240
    load:0x40078000,len:13012
    load:0x40080400,len:3648
    entry 0x400805f8

    • @RalphBacon
      @RalphBacon  Před 2 lety +1

      Why did you delete that task? It is the loop( ) task which must either contain a single "delay(1)" or it must be removed by the line you commented out. Reinstate the line (or put in the delay) and see whether your device boots again. Don't forget to set the Debug Level to VERBOSE (level 5) as part of the Tools / Settings.

  • @-highvoltage4685
    @-highvoltage4685 Před rokem

    thank you a lot!

  • @akasickform
    @akasickform Před 4 lety

    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  Před 4 lety +1

      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!

  • @automation_jeff
    @automation_jeff Před 5 lety

    Ralph, you do know that you can pass a global variable in your create task setup? It's has to be a void pointer, so instead of actually returning a variable, it places it in memory where it can be read?
    int count0 = 9;
    xTaskCreate(
    globalIntTask, /* Task function. */
    "globalIntTask", /* String with name of task. */
    10000, /* Stack size in words. */
    -->> (void*)&count0, /* Parameter passed as input of the task */
    1, /* Priority of the task. */
    NULL); /* Task handle. */
    //to retrieve it in the function
    void globalIntTask( void * parameter ){
    Serial.print("globalIntTask: ");
    Serial.println(*((int*)parameter));
    vTaskDelete( NULL );
    }

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Indeed I do, Jeff, but that 'just' passes a parameter at the time of initiating the task, of course. Now, if the variable we're passing is a global variable that might be OK to pass variables but IMHO not ideal. I'm guessing there's more to it otherwise it would not be offered. You'd still need to use mutexes to prevent updating at the time of reading, I'm assuming, so why this is better than queues is currently not known to me! Do have insider knowledge?

    • @automation_jeff
      @automation_jeff Před 5 lety

      @@RalphBacon The reason I mentioned this example is, in your video you are just declaring a global variable and using it in your function, not good programming practice - could become corrupted else where in the program. I am simply pointing out, if you want to safely pass a global variable into the function this is a way to do it at start up. You can then check it's validity.

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Ah, you mean pass the variable as a void pointer to multiple tasks but access it _as though_ it were a global variable but its scope is tightly controlled? That sounds much better, Jeff, I will bear this in mind for any future video on ESP32 variables/tasks videos. We can only pass a single variable though, right? Could we pass a struct, I wonder, containing all the variables required. Or an instance of a class object? Thanks for clarifying.

    • @automation_jeff
      @automation_jeff Před 5 lety

      @@RalphBacon Ralph - I guess you can, the variable has to be stored on the heap not on the stack( temporary memory), apparently using word size memory not bytes, let me draw your attention to these URL's: www.freertos.org/a00125.html and www.esp32.com/viewtopic.php?t=1892, try it out - I think this would be a good topic for your next video, interesting concept.

    • @RalphBacon
      @RalphBacon  Před 5 lety

      Yes, it is interesting, I shall have a read, thanks for the heads up, Jeff.

  • @mohamedgendia4274
    @mohamedgendia4274 Před rokem

    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  Před rokem

      Yes, the queue can take any number of variables (structs, objects etc).

  • @mumbaiverve2307
    @mumbaiverve2307 Před 4 lety

    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  Před 4 lety

      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?

  • @thisnicklldo
    @thisnicklldo Před 5 lety

    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  Před 5 lety

      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.

  • @unglaubichuberlieber8048

    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  Před 4 lety

      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?

  • @peut
    @peut Před 5 lety

    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  Před 5 lety

      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 Před 5 lety +1

      @@RalphBacon Yes, I missed it :-).
      Sorry.

  • @GBRiLFLRNTiN
    @GBRiLFLRNTiN Před 3 měsíci

    29:00 you set task0 with priority 10 and task1 with priority 1 ( is that why task0 runs many more times than task1? and, besides that, isnt task priorities limited to 1-5?)

    • @RalphBacon
      @RalphBacon  Před 3 měsíci +2

      That looks like a typo, edited from a priority 0 (idle) to a standard priority 1. The thing is, if a higher priority task is ready to run (or continue to run) then it _will_ continue to run, starving any lower priority tasks from any cpu time at all.
      I'm sort of surprised this worked at all.
      TL;DR they should both be at priority 1 to give them an equal share of the processing time.

    • @GBRiLFLRNTiN
      @GBRiLFLRNTiN Před 3 měsíci +1

      @@RalphBacon thanks, man. Your video helped me a lot

  • @ElieWar
    @ElieWar Před 5 lety

    Thank you

    • @RalphBacon
      @RalphBacon  Před 5 lety

      You are most welcome Elie Wardini, I'm glad you like the video. Nice to hear from you.

  • @TOMTOM-nh3nl
    @TOMTOM-nh3nl Před 2 lety

    Thank You

  • @marianofranceschetti7847

    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  Před 3 lety +2

      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 Před 3 lety +1

      @@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 : )

  • @paulyorke1437
    @paulyorke1437 Před 5 lety

    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  Před 5 lety +1

      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 Před 5 lety

      @@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.

  • @4lnstudios833
    @4lnstudios833 Před 3 lety

    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  Před 3 lety +1

      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 Před 3 lety +1

      @@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!

  • @ardespmaker
    @ardespmaker Před 4 lety

    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  Před 4 lety

      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 Před 4 lety +1

      @@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.

  • @edwinov
    @edwinov Před 2 měsíci

    23:40 vTaskDelay takes ticks, not milliseconds

    • @RalphBacon
      @RalphBacon  Před 2 měsíci

      Luckily, the ticks are the same as milliseconds here. I didn't want to confuse things!

  • @chevere3424
    @chevere3424 Před 9 měsíci

    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  Před 9 měsíci +1

      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 Před 9 měsíci +1

      @@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!!!