#208 Using an ESP32 Task for my Web Radio - using the Arduino IDE

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
and welcome back yes now today although you're looking at my workbench with that web radio still on there today we're actually going to be talking about tasks or multitasking in a practical sense on the esp-32 amongst other things indeed now if you remember i said that um the web radio design is such that you've got to keep stuff pumped out to this little vs 1053 otherwise the music can stop basically so putting that into a main loop is not best idea because the main loop is doing well everything else as well you know whether it's looking to see whether you've pressed any of these buttons on here or you know muting or whatever it is you're doing it's it's doing everything in sequence all right no matter how fast your processor is and believe me the esp32 is a fast processor even the single core s2 one is fast but even so if you're doing something else it cannot possibly be pumping data out to the vs1053 so what i noticed was having played about these buttons on the screen i've got it connected at the moment and in fact i'll just demo that if i hit this minus button you should see if the camera doesn't automatically now let's see it's getting dimmer and then it gets brighter again there we are but today we really want to talk about tasks in the esp32 just before we do that though let's have a quick message i want to have a quick shout out to jlc pcb manufacturers of high quality pcbs and let's not forget their special offer going until the 25th of december 2020 that's two dollars for four layer pcb and it's so much easier to root stuff when you've got four layers you can have a ground plane in the middle or a vcc plane in the middle and leave the outer two layers for tracks of your choice now there's something else that jlc pcb brought to my attention if you've got more than one pcb to manufacturer don't put them in as separate orders all the shipping costs associated with that do what i did here once you've added your first order to the jail pcb order page let that go through the normal process and add it to your cart here's one i'm just doing as a demo if we save this to the cart and you think yeah that's fine but i've got another pcb to make and i don't want to add the extra shipping on all you have to do on this one go back into it so here's the file we've just uploaded that you just saw instead of creating a new order and incurring extra shipping costs click the add new item button up the top there and you can add a further gerber file zip file to that order all as one big order here we go so you just add more let me show you one that i did earlier so here you can see an order of mine where i've got three pcbs all attached to a single order and one shipping charge which makes life a lot cheaper doesn't it yeah funny what you can find out anyway don't forget then their special order at jlc pcb two dollars for four layer pcb only valid until december the 25th why not try them out now right and thank you very much for jlc pzb indeed because they're making the pcb for this possible and that will be part of a future video as well and hopefully we'll get rid of this rat's nest here of wires and it's just it's out of this world in it but it is hanging together and the other thing is this particular version now running that you can see here was not programmed using platform i o and it was not programmed using eclipse what was it programmed using yes the arduino ide foolishly i agreed to port the code from platform i o into arduino land much against my better judgment and believe me halfway through i thought why did i ever even try this let's just switch over to the code window right here we are so this is the arduino ide it's got a standard esp type board allocated i think i might have chosen the rover one there's a standard sort of generic esp rover and the only difference between that and the w room remember is the additional ps ram which some people have soldered directly onto the esp32 and turned it into a rover well if you've got a steady hand and good eyesight neither of which applies to me that's a good solution but i'm using a rover board in fact i'm using the ttgov 1.71 version of that board and it's working really well and that's what the pcb is going to be designed for because after all at the end of the day i'm designing the pcb for me to use and to share with you potentially all right let's see how it goes first back to the arduino ide then so as you can see this was all uploaded uh last night and it's all been running i can't handle heart i can't say it all wren smoother i mean when it was built and uploaded and everything else and yes this does use ps ram but i had to hack that again in a different way i'm a bit crossed with the arduino ide yeah i know again yes and because the ps ram just i could not get it to work because the underlying esp32 arduino core from espressif just would not recompile on here i made a change to one of the core cpp programs in a similar way to what i did the platform i o version and it would not pick it up it just would not pick it up no matter what so i'm well i don't know if i'm going to investigate that or not the trouble at the moment of course is if there's a new esp32 core from espressif as there will be of course going forward it's going to splatter the top of my hacks and indeed yours if you decide to do the same so it's not ideal by any means i might have to go into the espressif forum and say look we need ps ram to be usable in the circular buffer without me doing all these hacks what do you think can we do this this and this and we'll see what they say but as you know that's going to take weeks and months okay no but it looks all okay right up until i came in this morning and it was playing quite happily uh yeah and there is and it's been playing quite happily ever since we'll just leave it there but at least at the moment this is running now on an arduino build tasks we're going to talk about a task now let me draw on the whiteboard exactly how this really works so why do we need a task of this particular web radio when it puts the stuff out to the vs 1053 well this is your loop right now that is running on core one on the esp32 now each task and this is a task in itself is single threaded it can only do one thing at a time so if it's doing something at this point here it does it then comes back and does the next thing and comes back so on and then it hits the end of the loop goes back to the calling routine which you don't see normally and comes back in again and starts the whole process again now this can happen thousands if not tens of thousands of times a second on a fast processor so if one of these routines here say was to play the actual music and that was connected to the vs 1053 mp3 decoder why do we need a task to do that when this is already in a task well the long and short of it is if this is also doing things like button control and i know potentially screen updates and indeed anything else you might want to think of these will take time so let's come down here it's played that come down here now it's looking at the buttons or you've pressed the brightness button or the volume button you'll do that all now the titles change i've got to update that all right now i finished i'll come back down but time it gets to this point here again on the next iteration this has run out of music to play it goes ha nothing to play glitch now the time taking to get from here back down here doing whatever it's going to do here before it gets back down into the play thing might only be a millisecond or half a millisecond or tenth of a millisecond but believe me you will hear that so what we want to do is not have this here at all we want to create another task this is our own little task running in its own little loop here and of course we will have to say do forever because the task itself otherwise will start here run to here and stop that with the end of it it doesn't run again nothing's going to tell this to run again so we say do forever and move whatever was in here over to here so we say in here play that's it that's all this task is doing it's not looking at buttons on the screen it's not trying to update the titles it's it's totally independent okay and this one is running literally in parallel so i think that gives you an idea of why we need to have an independent task that does its thing all by itself and is not subject to the vagaries of what's happening in the loop right the loop can do its own thing fine but your task that you need to run that critical process and i do consider this a critical process putting stuff across the wire to the vs 1053 to ensure that seamless uh stream of music because your ears are very sensitive to even the tiniest glitch all right now we did talk about tasks on the esp32 before and in fact well if you look in the pdf i always put a link to in my well github and the video description down there it's a pdf that mike does for me every single week thank you mike by the way i know we have communication but i mean i find it an absolute godsend to search my own videos to find out where i did stuff in fact for this very reason so what we have here is i said go and find me esp32 and in fact this one here dual core programming so number 149 was one of them and then we said 151 how to pass values between tasks we're not doing here that's you know using cues and semaphores it's a little bit more in depth but certainly how to create a task that one there is basically what we're doing today but this time it's actually doing something for real if you like ron just i don't know i don't know what i did in that video anymore was it flashing led probably was wasn't it so let's have a look it's very very simple anybody can do this we'll have a look right now now i'm going to be using the arduino ide to show you this because there's something you need to take note of you'll notice that the main sketch the ino file eno file is the one highlighted in the tab up there but you can see these other tabs just about i don't think the color scheme is very good here blue on blue but anyway these are all the what i call helper files they're in h header files and one of them is the task helper file this is where we create the task that is invoked from the setup of the main system here so in the setup we say i want you to execute this task please so if we look at the taskhelper.h which is in the same folder as your sketch the eno file as are all these other helpers i might add wi-fi helper tft helper because they're just basically join joined on to this eno file but they're too big they i try to follow the single responsibility principle which is basically say this bit of code does this and that bit of code does that and if you join them all together hello who's ringing and if you join all these bits of code together in one big eno file you can't see the wood for the trees and you're scrolling up and down thinking where'd i put this and of course the arduino ide is not very friendly when it comes to programming anything larger than the blinx sketch really when i ported this over it was so awful because i don't use the arduino ide to program anymore i really don't i occasionally put stuff in there for the purpose of these videos to prove they run on the arduino ide but that's about it but whichever platform you use you shouldn't be putting all your code into one file it just makes it unwieldy you can't tell what's what you're getting the total mess so anyway i've split it up here okay so the the task helper is all in this file and it's included in the head of the main one let's have a look what we need to do these are the forward declarations that means functions that we're going to be using but are probably elsewhere so the compiler would normally get upset with that or do we know let you get away with it but it's bad practice right so the first thing we do is create a handle this task handle here to well a name of your choice now i've called it play music task handle because my task is called play music task so the handle for that makes it obvious that's what i'm going to call it okay and here is the task itself play music task and it has to take a parameter of void type of void star parameter which means any type of parameters go in there it doesn't have to be an int or a string or you into or anything what it means is it's an undefined type of parameter you can put anything in there it's just the way tasks are set up so this bit of code has been taken on mass from the original code so i've said okay the bit of code that i did originally in the loop to play the music i'm now going to put in here and what i'll put right at the top though i've added in this to say i want you to do this forever i don't want you to do this task once and then exit and that's it and that's not gonna that's gonna give us one milliseconds worth of music thereabouts okay so we want this to whiz round round and round and round and round forever as fast as it can do it yeah because that means the buffer is always going to be red and stuff down the wire to the vs1053 great now the task setup is pretty simple we say x task create pinned to core which means we want it to run on the core that we're telling it which is in our case core one do not pin things to core zero core zero is where wi-fi is running bluetooth is running and goodness what knows what else is running on core zero you do not really want to interfere with that so we're saying this is the the function that i want you to run as we define that play music task well up here we said play music task that's the name of the function we're going to run we give it a name although frankly i've never had cause use the name it's only when you display what tasks are running i think that'll become useful the stack size well as you can see i've chosen 1700 why did i choose that well i'll tell you how in a second uh input parameters well we've got no parameters for this one so there's nothing the priority of the task must be one not zero zero means idle when everything is not doing anything then you can run this well i said go on then try it go and try running that on zero and see how well it doesn't work yeah it's gotta be one okay you can put it as two but i wouldn't keep things at the same level as normal user tasks i'm running all at one that's the handle so if you ever want to talk to this task to say tell this task to stop or restart or do something that's what you'd have to use the handle and the core this is the pinned to core bit which core did we want to run on you at the back yes core one that's correct all right and that's it that's the end there is there is no more code after that now beware the instant you do this the minute that is actually executed in my case from the startup it starts running instantly right there's no set it up and now run it no no it's set up and run all in one go so the instant this is running if we go back to the actual task itself is going to go to the the buffer and go can i play music from the buffer and of course the default values no you can't you just hang on a bit i haven't even put anything in the buffer yet because this is going to run in you know a nanosecond isn't it given the speed of the call of the esp32 so eventually the can play music from buffer is going to be set by another bit of code in the main loop to say okay the buffer is full enough now off i'll set that flag this reads that flag and it starts playing the music right brilliant i'm thinking we really need two tasks don't we going back to the whiteboard we have one task that dumps all the data to here from the circular buffer but what about the reading from the internet stream and putting into the circular buffer in the first place i think that could probably be in a separate tasks so basically a little task does all the dumping out to here but a separate task at the same priority says go and get me data from the internet stream and stuff it in the buffer if there's room so we have two tasks all running independently and then the main loop to do things like all this button handling and screen updating with titles and stuff like that yeah oh by the way that's a mute symbol that is if i hit that they are muted now look at that cool so there's still things we can explore with this particular application and certainly i want to and i've even got a book to do it all about esp32 multitasking and the free rtos and all this kind of stuff so that will form a video or two in the future okay there's something else i need to tell you as well now remember last week i said there was noise and that was a couple of weeks ago now so there's noise on the line because of the ground loop situation where the output from here was being fed into my pc which is connected to the amplifier and we had a ground here and the ground on the usb side here and possibly the power as well and it was all you know one big circular thing and a couple of you said it's not just the ground loop potentially is that actually at ground the ground on here or the central connection is that really at ground as well or not and uh i said well i've got a couple of these little mini audio transformers oh there's the picture look a couple of those little miniature ones i thought do i really have to put those on the pcb they're so fiddly and then i just disconnected the ground so i had left them right out connected that to my pc and it all seemed to work okay very good quality except you know just that hint of noise at the back and it wasn't quite right i thought right i don't want to use those transformers i know they're cheap they were probably two or three quid or something whatever it was from ebay how do i know that an audio isolating transform is going to work anyway so i looked at amazon and i bought this and i thought well i'm going to get this and just try it out so this is a an audio isolating transformer from upside down or key you see that now this was not cheap it was i think about 999 british pounds and you put basically the output so the output from here this one here is in one side and this side it's all 3.5 millimeter jacks just goes into the computer or audio amplifier whatever it is you've got now hand on heart i can say that this is absolutely 100 the answer and i'm thinking i'm going to keep this instead of trying to put transformers on any kind of pcb there because they're just so fiddly and i'm not convinced they're going to work anyway whereas this most definitely does work now i did say i was going to show you about the heap memory on that task so let's have a quick very quick look at that so in the taskhelper.h file the helper file we have this this comment here um every minute we say go and get me uh the stack high watermark so a bit like they espresso explain it like when you get a riven you get the high water mark coming up and then the river drops back down again but you can see where the higher mortar water mark was so what this gives you effectively is the free memory of the stack that you gave it so here i'm saying free stack this is the remaining stack all right yeah all right yeah it is a little bit confusing people think it's the memory used but it's not the free memory and over on the um call term window you'll see that i'm printing it out once every minute now it starts because i give it i've originally gave it ten thousand just as something to give it so it wouldn't crash all right and i said how much have i got three and it says you've got nine thousand four hundred free or something ridiculous so eight thousand one free so i go okay let's bring it down to two thousand okay so in the task itself when we create the task here i kept changing that you know from ten thousand down to two thousand letting it display over here how much it got left and espresso say anything between two and 400 is okay and so i thought okay well i can still bring it down a little bit further no point in squandering the memory just because we have a lot of it here and eventually 1700 seems to work well however the free memory given that it's running the same task thousands of times a second the free memory changes over time and i've got a little snapshot of that to show you right so this is um the snapshot of a few days back when i was doing all this task stuff and this is where it's rebooting and showing you how much ps ram and heap and all that i've got and i've said right the free stack as the task started was a thousand and forty four bytes left right that's the free stack then it started the setup routine all the rest of it and it goes oh now your free stacks dropped to 324 still fine and well within the realms of what we we want right it's probably actually started to read the buffer at this point and play the stuff and then after a while it goes no three stacks now down to one three two so it's dropped quite a bit no particular reason nothing's gone wrong it just dropped and then it stays at 132 for a long long time and then suddenly says oh look you're now at 100 100 bytes free stack all within i don't know half an hour or something and then the next day though i let this run from that time so 15 56 on one day right until the next day and it says you're still on that 100 bytes free memory in that task all right imagine the task a little miniature tiny micro computer and it's just running that one task the memory it's using it doesn't seem to expand it just shrinks and contracts but it doesn't go beyond that it leaves it um at 100. i think hmm i wonder why what what have i got a memory leak or has espressif got a memory leak something to do with the circular buffer or is there something wrong with my code i haven't quite done something right and it's leaking memory creating variables on and on am i using the string variable with a capital s that's a bad thing to do because that does fragment he remembering use it and doesn't clean up after itself knows the answer i'm not not in this bit anyway so while that why why that free stack memory reduces down to a minimum and then sits there forever i have no idea so when you create your tasks first of all create it with a big thing first right you know five thousand ten thousand just to see what you get and then reduce it a little bit but let it run for a long long time all day if necessary just see how far it goes down to before you decide upon the final value now 100 bytes it's a little bit low to be quite honest so i might increase the stack value for that task to 2000 just to give it a bit of headroom given that we've got it it's only another 300 bytes isn't it and it'll be interesting then to see if it still reduces or not one final thing on here i can show you finally enough as we're here when this reads the streaming data and reads the metadata every so often let me find where it says metadata there we are look metadata block 96 bytes remember the value coming down is multiplied by four and the metadata here is this entire line here so it says stream data blah blah blah including the stream url and everything else and i extract the track title yes oh but look what happened here look waiting for metadata and it's found it here and it was huge um i seem to have deleted the um the actual value but it's something like 1500 bytes which is a ridiculous amount but you see all this stuff i thought it had corrupted it and all this is corruption no it wasn't and the clue was here where it says insertion type pre-roll because here i switched to this particular radio station i don't know which one it was it might have been greatest hits and i immediately got an advert even though i know at the time it was in the middle of playing a song but i switched to it i immediately got an advert and then it switched to playing joining the mainstream and that i think this ad whiz content all this is a an mp3 or something that's been compressed and it will play first clever stuff eh very clever embedded adverts as part of your metadata who would have thought just a nice to know i think okay that's it for this week i've realized this there's far too much and we could talk about this for hours and hours but the task thing i think was important to talk about the buttons i'll show you the code for that um some other time but it's it's fairly straightforward it's all part of that tft espi tft library well it's from bodmer but it's been forked and upgraded a little bit the version i'm using um it's not difficult but you know how to do these images and all that probably needs a little bit of explanation and we'll talk about that some other time and when i get the pcbs through for any of this you'll be the first to know until then thanks for watching i look forward to comments below see you in the next video i hope you're finding these videos useful and interesting there are plenty more videos to choose and a couple are shown below and if you'd like to subscribe to this channel just click on my picture below and enjoy the rest of the videos thanks for watching
Info
Channel: Ralph S Bacon
Views: 8,424
Rating: undefined out of 5
Keywords: Arduino, Beginners, electronics, C++, microcontrollers, programming, gadgets, ardiuno
Id: aMS4XwEr8s0
Channel Id: undefined
Length: 26min 46sec (1606 seconds)
Published: Fri Dec 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.