All right, good afternoon to everyone. Looks like I got sound at least going to OBS. We were good there. Let's get the rest of this stuff set up here. Chat windows, somewhere where we can see them. Let's turn off this preview. Let me switch over. Yeah, this one's caught up now. There we go. Okay, this one's... Honestly, I don't know what this one's doing. Show the current state it seems like. How's it going, Sea Grover? Good afternoon. There we go. So hello to everybody. My name is Tim. Happy Friday, first of all. Thanks for tuning in for everybody who's watching this. This is the CirclePython deep dive program, which is a weekly live stream program where we are working on various different aspects of CirclePython, sometimes down into the deepest layer, the C code in the CirclePython core, sometimes in the library layer, sometimes in the infrastructure like GitHub actions and documentation and things like that. Just depends from week to week what's going on. This week, we're going to start out in library land. We're going to look at the HT16K33 library, and then we'll see if there's any time after that. We may jump to something else, but we'll see how it goes with this first. So we'll be doing that. I will say, though, before we get too far down the road here, let's just take a quick step back for anybody that might be new. Didn't mean to refresh that. That's fine, though. For anybody that might be new, if you don't know what this stream is about, you can learn more at the main website right here for the project, circuitpython.org. CircuitPython is basically an implementation of Python that is designed to run on tiny computers called microcontrollers like this Adafruit Feather ESP32S3TFT Feather right here. This is one of the microcontrollers that can run CircuitPython. Basically, the idea behind this is that this device, when you plug it into your computer, it shows up like a thumb drive. On that thumb drive, there's a Python code file. You can edit the code in that file, and then the computer, which is in the main chip on this board, will actually execute your Python code for you. We'll interpret it and execute it for you. All of that happens on the computer that is actually built into the device. In this case, it's actually on the bottom side. We can't get a good look at it. But the photos here, you can see a lot more of them. The main chip here is the computer on this one. Same thing, I think, here and this chip here. Each of these devices will have a main brain that is the primary kind of computer, and that's the device that runs CircuitPython on all these different devices. That's the kind of stuff we're getting into. If you have any questions or anything like that, feel free to drop them in the chats. The two that I have open are the Discord and YouTube, which are both down on the screen below me. On Discord, we're in the Adafruit Discord, which you can join at ADAFRU.IT slash Discord. We are in the live broadcast chat right now, which is where folks tend to congregate when there is a live stream going on. How's it going, Axl Magnus? Let's see anything else here. CircuitPython, yeah, if you want to, CircuitPython, it's an open source project. Anybody's allowed to use it. You're allowed to put it on your own devices.  You don't need to pay for licensing or anything like that. You're just allowed to use it. It is developed or primarily funded by this company, Adafruit. This is their website, adafruit.com. They are a hardware and software company based out of New York. They're the ones who are paying the team who work on CircuitPython project. There's a core team who's paid full time to work on the project. There are other folks like me who are part-time and are paid to work on the project and the surrounding stuff. So thank you, of course, to Adafruit for doing that. Thank you to everybody who wants to purchase hardware from them in order to help support it, because obviously if you are buying hardware from them, that is helping keep the Adafruit factory running, keep money coming into them, which is allowing them to be able to pay the folks who are working on the software. So head there, buy yourself some toys. They make the microcontroller devices like the ones we discussed that run CircuitPython. They also make all sorts of stuff that you can plug into your microcontrollers. Like in the case today, what I have is this 14x4 segment device, which is a featherwing device, which was also designed and manufactured by Adafruit in this case, featherwing segment. So you can head there, get yourself all kinds of neat toys, including microcontrollers, as well as things that you can plug into your microcontrollers and do stuff with. In this case, we'll be playing with some of these things today, these 14x4 segments. Okay. How's it going, Mike Casey? No, excuse me, Mike C. I don't know where I got Casey from. Guess he got the K and Mike, but close that down. So today I'm going to be jumping into HTK 16. No, HT, I did it backwards, didn't I? But I put it, I probably put it backwards in the title even, didn't I? Did I do that? Or it's not in the title, I guess, technically. Ah, whatever. We'll go back and try to look at it later. I might have gotten it backwards. I like to call it HTK for some, HTK 16, I don't know. But it's actually HT16K 33, which is the driver. I have a pull request in there for some non-blocking text scrolling that I am getting back around to this week to look into the suggestions I've gotten, which are like, see if we can make it behave the same as the blocking version and then potentially try to refactor it to cut down the size of the library, like make one function rely on the other one so that we can get rid of some of the code in one of them, so that we don't have two copies of more or less the same logic. So that's what I'll get back to you. That's probably what we'll spend the majority of the time on. Before I do jump straight into that though, I wanted to actually play around with this for a minute, and I figured it would be perfect to do it since it kind of goes along with the same device, HT16K 33. This is a thing I saw go by the other day that got added to the community bundle. This is a library from Jose David has made this one, so a hug report to Jose. This is like a almost like an emulator that runs, that pretends to be this HT16K 33 driver. And so in my case, I'm using a 14 by four segment, but the same chip can actually drive an eight by eight matrix of LEDs like this, so this driver here that Jose has created is like, you know, kind of emulating a HT16K 33 on a screen, whereas obviously like the real one has physical lights, you know, physical LEDs inside of this thing. So this is like a virtual one, it's not necessarily, you know, using the same driver, but it is, you know, aiming to give you the same kind of visual output just fully virtual. So I thought this was really cool. I wanted to spend just a minute to try to load it up on a device and play around with it for a minute before I jump into the actual code for the hardware driver for that device. So we'll do that. I'm going to clone this. We can open it up. Oh no, did I just let it creative? I did. It's terrible. Okay, we're going to delete this. Really want a virtual environment for this. I just want to delete it. Delete it. I cannot let me delete it. It's terrible. Let's me no choice. Grab this, put it on a device display. There it is. It's in there. And I'll have to look in the examples. I'm not entirely sure how to like generate it. Let's initialize it or whatever. We go 14 by four first, since that's what I have the physical device of, server of a layer but can here. I think I turned out a reload off maybe. So I think we need to do this one here. Oh, and then it will need to have while true. Actually, yeah, that might be have that in there might be good to add that to the repo. Maybe we can PR that. Yeah, I should have probably while true here.  That's right. We'll just add that one in there. Save that should be able to do it this time I think. Yeah, nice. There we go. We have we technically have four digits. It looks like we might not have enough room or actually I guess maybe this is at I'm guessing this is x y maybe we can go let's go not so far down and then let's try we might need to go all zero actually I don't know if we have enough room to fit put this on here. Yeah, not quite actually we're a little bit shy on the room. It's all right 30 but then you could be able to change this with these numbers here would be able to change what it is. Is it a font or how does it font five is that the that for the segments? I think that's just like a picture oh that's in the docs yeah yeah yeah curious how it works let's take a quick peek in segments that just have shapes in here piping characters has bit mass for all of them numbers like shapes and thinking how digits go to points circle yep these are coming from vector IO nice and polygons for the segments so it's basically got one polygon for each segment and it basically makes this like pointed shape the line with the like comes to a point at the end just how seven segments are or 14 segments in this case neat okay so and then it's got I believe a very similar if not the same yeah API so it can also do stuff like marquee we could say instead of print maybe like time let it do that first and then whoops oh the sleep is before the show whoops oh and also marquee is blocking so we'll never actually show it straight that way get some scroll action going there nice cool uh let's do I want to do the RGB matrix real fat or not RGB but I want to do the matrix real fast and then we'll jump into the real hardware so I think was matrix yeah let's do this one matrix pick six but two were given looks like we need some extra arguments maybe these ones just have x y radius text by radius text that's pretty simple x y of the and there are no defaults so we only to pass them that's just x y coordinates and pixels radius is how big the LEDs to find if it will be used for text interesting I didn't know that the frame buffer interesting text so we'll do we'll do text false for now so we'll say say x um I'll just say maybe like I'll just do four y four radius we can go pretty small probably like two what if we do radius two or three let's try three text false it really is uncanny how much it does end up looking like the actual LEDs like I do have one of these eight by eights this is obviously the 14 by four not the not the eight by eight segments but does a really good job of pretending to be the the physical one six try to get it so it's like taking up most of the space we have on the screen there sure we feel a little bit like we don't feel equally it's like our x and y are not quite equal maybe y is not top left I didn't actually read all the docs no it should be top left yeah that's right we'll just move it up some enough dude zero or should we go negative even at all of it or do we have a little bit more down there that's definitely all of it now dude we could still come up just a tab to uh make it even but nice cool like I said uh hug reports to Jose this is in the community bundle now so if anybody wants to play with this it's not out on disc hub uh excuse me out on um github and you can also get it from like circa I believe if since it's in the community bundle um so yeah pretty cool and so what we are working on next is the actual hardware version specifically of the 14 by fours and what I am looking into most specifically is the non-blocking marquee which is what branch we're in we should probably try to update main though and merge before we really do much of anything else just because possibly there have been updates that it's weird and push those just so we're up up to date we're in line with main now or we're we're back to one or two commits however many ahead of main but we're not we're not behind by any so originally there was this function marquee um which is blocking when you call this function if if loop is true then this function will never return it will just essentially be a while true loop inside of here which you can see pretty clearly in the logic as well if loop is false then it will return but not until after it's done scrolling the whole text so if we were to scroll the text hello deep divers like we did earlier it will scroll the entire text hello deep divers and then it will return at the very end um which works fine if that's the only thing that you want to do but if you want to intermix that with other stuff like run an http server or have some neopixels connected and run led animations on the neopixels at the same time while you're running a marquee on the on the segments or whatever um then you can't really do this because of the way that this blocks means that no other code inside your code file like your code.py file no other code can really be executing once you have called marquee like this because you know it's either gonna stay inside here forever if that loop is true or if loop is false then it will eventually end but not until after it's scrolled the entire thing so that could be like several seconds or something which is far too slow if you're trying to do you know an animation or uh like run a server or something like that and so what I added was the non-blocking marquee here this one has basically the same arguments that have all the same meanings the the the arguments all do the same things the key difference with this one though is that it does return it returns instantly um you know pretty much no matter what and so what it will do is it will keep track of time on its own it will keep track of how like how long it needs to wait until it's supposed to you know do the next step of the marquee like scroll the letters over by one and then whenever the time comes to do that it will go ahead and carry it out um but then it will also just return right away again so the idea is you need to call non-blocking marquee inside your main loop um and each time you call it it will check and see if it needs to actually scroll or not if it does then it will go ahead and do it if it doesn't then it will just return instantaneously and what that means is you're now free to do other stuff inside your main loop because you can call non-blocking marquee you know once inside your main loop but then you can also call like you know ledanimation.animate and then you can also call you know myserver.pull or whatever like you can do all of these things all inside your main loop since none of them will be blocking at that point so you can kind of like it's it's not really the same as different threads uh because it is still serially done right one after the other uh but it it on the human time scale um you know in the in the terms that we think of in seconds and things like that it may as well be doing all three of those things at the same time because it's going through them so fast that we're able to essentially you know have each of the three do what we want with the time it's got so what we want to do though is uh test some more to make sure that non-blocking marquee and marquee behave the same that they make the text look the same as they're scrolling if there are differences most likely then those differences are going to be around the the period character which is a special character for this particular device because the period character makes it so that you can actually display eight total digits right ordinarily you've got your 14 by four that means you've got 14 segments inside of each one of these digits and you've got four digits so you know 14 by four and so ordinarily you could show four digits at a time right you can show four letters or four numbers or some combination of numbers and letters but because the period is actually on its own over here it's not part of the rest of the shape it can actually put the period on as well as show a letter or a number in that character which means that technically if you have all four periods on you actually can have a string with eight characters because it can be one letter or number then a period then another letter or number then a period another period another period so you can have eight digits total so if there is a difference most likely it's going to be around the handling of that we want to make them so that they behave the same and then if we can we want to make it so that um one or the other of these functions will kind of rely on the code in the other one that way we don't have to have essentially the same logic implemented twice because right now we kind of do inside of non-blocking marquee here it's essentially got all the logic that makes this work and then inside of marquee here it has well technically it calls scroll marquee here so it goes down inside of here but it's one layer deeper but it essentially has you know all the same logic that we have up here right these are in essence doing roughly the same thing if we could make one use the other one then we could get rid of some you know what is ultimately repeated code at this point it's not like character for character line for line the exact same it's just that it has the same functionality so um first thing we could do is let's just get it on our device it's been a little while since i ran this i don't even think i have ever done it on this device i finally have busted out a uh an s3 tft feather and put pins on it i've had one on my desk for a while but i did not have any pins on it so i was unable to use it with feather wings and things like that but i finally have soldered some pins on there so i can finally stop stealing the uh the s2 feather that i use for the time stamper during the weekly meetings when i run them we can copy that let's go to libs folder already exists yeah we'll overwrite it i guess because it looks like i did already have it i suppose but it's all right we'll overwrite it on there okay let's grab the uh non-blocking marquee okay yep i turned off auto reload we could maybe do we want to turn on a reload back on okay let's turn on a reload back on for now no itc address um well i think there's i think there's um jumpers on the bottom to change the address maybe mine has the non maybe i don't have the standard address i don't know i would have thought my sample code would be as whatever i had but yeah see these here are jumpers that are gonna let you set the address basically yeah yeah yeah here we go okay all so default is 0x70 but you can change it anywhere from 0x70 to 0x77 so 70 71 72 73 74 75 76 77 of eight total should be because we have three digits of binary basically uh let's look at mine actually no i guess this must be unfortunately we gotta take it off to get it visible ah yep there you go a zero okay so what does that mean a zero a zero sets the lowest bit so 71 we should have i gotta better put the camera back but i don't think i can do this without pulling it out of frame but we can get it lined up there we go and kind of see what i'm doing a little bit all right 71 we just go uh to here uh we should probably um kill the light from this so we have this neopixel is blinking back and forth between pink and green and then we have this text here is scrolling uh circuit python heart circuit python heart over and over and over and it with the standard marquee it would not be possible to have this neopixel blinking like this because marquee would be blocking we would not be able to set this back and forth but because we have non-blocking marquee we're able to have other stuff inside of our main loop here so we have some extra logic that changes the color of the neopixel here back and forth um and so for now i'm actually gonna get rid of the blinking of the neopixel we're gonna just scroll this and what we will do is actually let's scroll some different text with periods so let's say long text here circuit python and then i'll say like let's let's say uh let's say four digits with no okay four digits with no periods and then then four digits with periods then well yeah let's just start with that long text here circuit python eight eight eight five dot five dot five dot long text so if you notice when the periods come on it kind of gets like this stuttering type thing going on a little bit it feels like it stutters but the thing is that it's not technically stuttering really what it's doing is it's spending the exact same amount of time on every character and it's including the periods as a character so it's waiting while it's rendering the period but because the periods are special and they don't take up the segment place the uh the character place the characters that are visible stay where they're at during that frame when we render the period so it makes it so it kind of doesn't look like it's scrolling what i don't know for sure though is how does the original one look when you do that i do not know you just see if it's the same or not and then if it's not we'll try to match it um although i i did think about it a bit and i kind of think this is the best way so if this one is different it's worth considering whether we want to do it differently or not but for now we will try to match because the thing is you could get rid of that stuttering um by basically making it so that the periods don't take any time you could make them instantaneous but then you actually have you end up with the person who's reading it has less time to read potentially twice as many characters like they could have eight characters visible and they would actually have half the amount of time to read it as they would if we have it run this way so see what it does i don't think we is loop true by default i don't know it does skip them it does skip them so you you don't see the stutter you don't see the stutter but basically the consequences are actually that you need to be able to read this twice as fast which i guess like you know it's the periods anyway it's like it's not really eight characters it is it is eight characters but i don't know it doesn't exactly count okay so so we want to make it so that we have matching behavior so we want the we we want to basically not spend any time when the most recent character we rendered was a period whenever we render a period we want to just immediately render the next character instantaneously but not if it's but not if it is a period though right wouldn't this make it weird maybe shorten this a bit okay it keeps a steady rate does keep a steady rate go so much faster that first bit there that was interesting maybe that was the video stream maybe that wasn't the actual device i don't know i wasn't actually looking at it i was looking at the video so this should make it to where we can only see one character yeah by the time that we can see the next one the first one scrolls off the other edge whoops so it's actually closer to the current behavior but still not quite the exact same so how does marquis actually work so it says if it is a text a string rather so if that fill false i don't know what that does i assume that's going to empty everything out sort of fill the display fill the whole display with the given color i guess by doing false it's making the given color at zero zero and by color in this case what they actually mean is uh turn the light on or off which in our case we're going off because we're doing false if loop then we have while true inside here we just say self that scroll marquis scroll marquis says text string delay float scroll through the text string once using the delay so it says character is dot for character in text self that print which is adding a character to the right side i'm pretty sure print the value string or float decimal sure what that means both that print character add delay if the character is not a dot or more than two in a row if character is not dot or character is not dot or or is dot but this will be false the first time okay false the first time does sleep and it says if it was a dot then set this to true and then show which is like render basically it's like actually turn the lights on and off correctly how it's supposed to be okay so essentially what what it boils down to is if the current character is not a period then we have the delay or if the current character is a period and the previous character also was a period then we have the delay but if the current character is a period and the previous character was not then we do not let's look at the logic in here as well non-blocking this time if it is a string we set a variable with the current time if the text is the same non-blocking scroll text so this would be like this would be false if the user has changed the text since the last frame that we called non-blocking marquee like if they uh they i don't know how they would do that i guess maybe call set self that text or something right i guess they would just call this again with new text i'm not sure exactly how would that change i don't know let's keep going though if text equals non-blocking text so if it hasn't changed i'm sure we'll set this somewhere in here if length is greater than four if we delayed long enough and it's time to scroll so if the current time is greater than the last scroll time plus the delay the last scroll time equals now because we're about to scroll if there are characters left in the text so if the current index plus one is less than the total characters we have you know like if there is a character to our right if there's no character to our right then we don't need to scroll uh has gone super pencil from the youtube chat hope you're having a good day my friend uh non-block index plus equals one so increment that self dot push and so that will take basically take the character and like push it onto the right side of the display that's the way i think of it so like whatever character you give it uh it will render it in this far slot here and then it will push everything else to the left to make room for it so when we you know push a c it's going to draw a c here and then it's going to push everything else to the left to make room and then show so that it will actually render we have else here so this would be else if we are at the end of our string if the current index plus one is the last is is past the end of the string then we go into here we say if we want to loop then we will start back at the beginning if we don't want to loop then we will just do nothing essentially and it will not be looping anymore until the user changes something okay so that's all pretty straightforward we have the else here which is if the text is not the same different text so in this case we say non-blocking scroll text equals text so we update the non-blocking scroll text that way next time we know that it is the same if it comes in again update that we say the last scroll time is equal to now we save the time stamp we say if text if the length of it is less than or equal to four then we just print the full string but this logic is actually not quite right is it because because if the string was if it was if it was eight characters but with four periods like five dot five dot five dot five dot then this would be false but technically we should still we should still be doing this so we need more logic here to check like if the string uses periods how many length it can actually be and we say if it's longer than four though that's when we do this which is where we say non-blocking scroll index equals three we tell it we're going to start on index three which is the fourth index right because it's zero base zero one two three that's the fourth element and then we say that we're going to print the first four zero through three so the next time this will get plus one this will go up here it'll get plus one that's when we'll show index four which is the fifth character so if we could how do we do this self dot print character in text so that's going to be looping over the string one character at a time calling self dot print on that character what does self dot print actually do okay so we call print once and it puts it here how does print differ from push doesn't work probably we need show is print different than just push and show together if value is string then we call self dot text dot value underscore text if it is a int or a float then we call self dot underscore number value does well else unsupported type if auto right is true then call show do scroll the marquee and add a character at the end scroll the display and add a character at the end I don't really get how that's different than print it seems like they both do the same thing they both they both put one on the far right edge and push everything else to the left to make room I'm actually sure why they both exist just used somewhere else three usages one of them is mine though from blacking marquee text okay well so text so so print calls text and text calls push okay so ultimately print is actually getting into push hmm so if we can get it to where we're just using print and if we can have this same logic then it should work and then if we if we can get the logic of non-blocking text to behave the same as blocking then what we could do is inside the blocking one we could actually just have our loop and we could be calling the non-blocking one but it would be in a loop so that it wouldn't actually return we go back to being blocking for now I'm going to call this nb scroll marquee but it's tricky because it currently has delay in it we don't really want that I think trying to keep in mind the reuse so basically instead of sleeping here we're we're never going to be sleeping but instead what we would be doing is choosing to set the the last scroll time or not if we are going to sleep then we would set the last scroll time and if we don't want to sleep then we would actually just not set the last scroll time which means that it would stay even further back in the past further than delay which means the next time we come through here again it would still be in the past so I think what we do is now equals time dot monotonic and then if we want to sleep then what we do is set self dot non-blocking scroll time last scroll time equal to now if we don't want to sleep then we just don't update this it stays on what it was and it's never used and then this doesn't actually take delay so now in here instead of calling push oh but this is inside of a for loop though hold on that's not gonna work that's not gonna work we don't we can't have this whole loop in one function essentially we need it so that we call the function over and over and each time we call it it's one each time we call it it's possibly one iteration well this this one would always be one iteration but then inside of here we would be choosing whether or not to call it based on the current time oh there's a couple other comments over in the youtube chat let me let me catch up over here does print render immediately while push doesn't render until show that is true yeah if auto show is true then print will go immediately because it does have a check inside of it for that this is probably from a while back when I was talking about that sorry I didn't notice the chat until now scroll starts at the right print starts at the left and only scrolls when it runs out of room print seems to start at the right print does seem to start at the right not the left need a non-blocking for loop yeah maybe like a yield or something I don't know if I want to use a yield though I'm not that versed in them truthfully I don't know the right way I think what we want is basically to take this logic character is dot and then this thing here I think we want to take this and move it into here and then we would not really need this function and then we would be calling this then from inside of here at the very end I think we could change this up to be calling the non-blocking one to have a loop inside of here so we're going to try to take this logic characters dot so our character is this would be our character but that's going to get reset every time we have to have it on self otherwise its value will disappear in between calls to this function I want to call it actually previous prpreve at least because it's actually technically the last one right like it's we have only one variable and then we get the next one so this is really the previous one okay so what we will do is after we've done show we update this so we say preview after show we say previous character equals current character so now that is set for the next time around oh but uh we got to compare right right we don't want the actual character we want whether or not it's a dot it's a problem oh hold on text here we go text if that's a dot then set this to true I'll set it to false and then here we would say basically if this let's say character equals this character character is not dot or if previous character is dot oh we need to update the time yeah so here we don't want to update the time so soon we want to actually wait we want to actually wait for this this is when we update the time and then these we actually do here we always want to do these but we only want to update the time if we're going to pause basically so if we are going to pause then we update this time that means we'll wait another cycle of delay seconds until we make the next move if we don't want to pause then we don't update that which means immediately the next time you call this then it's going to go again in our case we're calling it really fast from main loop so that will be almost instantaneously that we go again and we update this and then and then instead of push I guess let's do print right we might as well do the same there I don't know does it make any difference in our case I'm not sure it's gonna matter the end of the day truthfully but we'll see okay so that was all only if there are characters left if we are at the end of the string then what do we want to do if loop is true then set index back to minus one which means it will plus one and go to zero next iteration uh because it increments before it actually oh shoot you know what we need to increment before we do this actually I'm glad I caught that we want to increment before we get this because that's how it's written is like this is going to negative one so that when it loops back around this puts it at zero okay so if we're at the end then if loop is true put that back to negative one we could go push a space I don't know we can print a space I suppose I don't know if it will matter we could get rid of show in fact we could actually we could just get rid of show on both of these uh delete I'm not sure what you mean delete I don't know what you mean delete these are ready use print and these are only if these are if it's different text so if it's different text then and we're always gonna start with the first four four we actually need to fix the logic so that it's more than four though how are we gonna do that all right let's worry about that afterwards this it's actually kind of complicated logic right because it's like it's four if there's no periods and then if there are periods it's like if there are periods every other character then it goes up to eight but if it's like two periods in a row then it's doesn't count up as much so that is tricky what how does marquis handle that so on marquis let's see it would be text you would go into here we call scroll marquis it would be looping for character and text which would only be let's say three characters and then it would just print the character so one thing is you would uh it's it would scroll a little bit unnecessarily text is only one two three you call marquis on one two three push the space across so another difference is marquis does not put a space in there for you whereas non-blocking marquis does actually put an extra space which i kind of prefer but i guess we could make it optional because it's hard to tell where it ends and then where it begins right this makes it a little bit easier to tell where it ends and begins okay so it actually starts with only one thing showing so it scrolls on even the beginning which that part's actually different non-blocking marquis it would put the entire thing and so maybe if we're not gonna if we're not gonna put the entire thing then maybe the logic is actually easier because we don't care if it's four versus eight versus dots every other we don't care about any of that if we're not gonna try to put the whole thing we always just go one digit at a time then it doesn't matter what digits it is because we already have logic handling it now specify how many spaces to put between maybe i don't know maybe i think space or no space is probably what i'm gonna aim for number of spaces is a little bit harder at one point in time i actually had in mind that i wanted to do something like what you say uh something like they're allowed to specify how many spaces but the way i was thinking about it was they're allowed to specify what string they want to be the separator so if they wanted to use a dash or star or whatever they could choose a different character or string in fact they could use multiple characters so like two spaces or three spaces or whatever um it got more complex than i wanted it to be though when i was trying to do that and so i ended up going back to making it simpler to just right now it's hard coded at just a space we might make it i think we'll make it so it's like either space or no space but i probably won't work on multiple spaces right now the the thing though is like i don't think inside of here is not the place for that because the other thing is like user code always gets final say how many spaces there are right like you you can put how many spaces you want inside this um in fact maybe that's an argument for not having the space at all because you could always put your own i still kind of like it if it would offer to put one for you just so you don't actually have to put that extra space in all of your strings but i think if you want multiples or a different character or something like that that's when it's like you know you could include that here whatever character you want you could just always put it into your string whether it's extra spaces or anything else similar character with kerning algorithm so if it is different text what do we want to do we don't want to just print zero to three like this if it's different text if it is different text we want to clear we want to clear the display which we saw before that was this we want to clear the display we we definitely want to change the text variable to be that we want to put the scroll time to now yeah i think we want to yeah i think we do want to put the scroll time to now uh and then we just want to print the first character i think that's all we want to do here we don't even need the sift statement at all we want to just print the first character oh we need to set the index too though how come nothing it well this is setting i see this is setting the index our we're going to be on um not going to be doing three anymore whoa whoa whoa whoa what is still eating my stuff geez okay uh we're not going to be on three anymore is it zero or one we want it to be on zero so next time through it's going to plus one get to one which means it's going to put the second character which is perfect because we're about to put the first character so we put that on zero we fill false to turn everything off we set the text so that we keep track of it for next time we get called we set the scroll time to now we print the first character and that's it print um text zero or obviously we could call this variable and we know it's zero because we just set it okay save this let's copy this all back over i'm just gonna delete and do it again okay so this is using blocking it's gonna let it run so we can see it so it starts on the left and then it goes over it does have no space let's do let's change that while we're here let's make it match at least currently with no space we'll add maybe an extra keyword argument or something for the yes space no space option oh this is the display one okay okay let's add one more variable called space between false by default we'll keep the default to be the same as blocking i'm with this oh good thing we didn't run it yet um we'll do here if space between do this and this one is on blocking i was gonna say we could we'll add it to here that way if you're using the blocking version you also get the option of space between it's actually gonna be easier though to wait until we make this one use the non-blocking one we ended up using this so i'll delete it once this one is calling the non-blocking one then it's super easy we can just add that argument here and then pass it through to the non-blocking one and it will get the correct behavior whereas if we want to do it right now we're gonna have to like add logic inside here which makes no sense because we're gonna not be using that in a minute so i may be wrong when you update the index wouldn't eu plus equals three and then your array indices would be uh index plus three uh i don't think so that would make it so we're not we're we're only scrolling one digit at a time we're not scrolling an entire screen of four digits uh if that makes any sense so uh if we maybe let's slow it down even further here let's say play let's put it on one second just so it's nice and slow so whenever one digit is displaying only it should be here and then after that it's here and here so like we only move by one digit we're not moving by like entire pages of four digits um if that makes sense like we're not showing an entire page of four and then changing to a new page of four what we're doing is showing one digit then showing the next one and scrolling then showing the next one and scrolling showing the next one and scrolling so on and so forth so we're always just moving by one rather than moving by three ever i don't know why this keeps resetting itself maybe that's why i turned out a reload off before i guess i don't we're not making any file writes in here at least not that i know if i guess maybe the ide is though okay yeah so it would be it would not be it would be tricky to add the space between there and it would end up being waste of time as long as we are actually going to make this reuse so i'm not gonna bother let's put this on one let's see if this behaves the same now uh oh i do wrong feels like we did not update the let's put this back to point two i don't i'm pretty sure my problem is not the speed though seems like it's just never going on well we have some kind of logic that's wrong inside of here we're doing i don't know if we need we might not need this anymore oh that's actually not only do we might not need this anymore that's actually what's killing us right now because we have only three digits so this is false therefore we're not doing it do we need to do anything separate i don't think so right we used to have logic that would place all of them on the screen but we don't want that anymore what we want to do is just scroll the however many digits we have because that's what the blocking one does i have it on really slow right now still it's on a one second delay we do now no longer have the space we're good there we could go so now we could go space between like this then we would get the space back hmm i think it's scrolled twice right yeah it's scrolled twice the space should be at the end why is it doing that are we off by one here should this not be plus one or should it be less than equals it can't be less than equals because if it was equal to the length then it will be too long and we have to have plus one why are we off by one if there are characters left in the text if index plus one is less than the length of the text so our text is three characters length of text is three current index would be zero one say two when the three is showing zero one two and at that point two plus one is three three is not less than three therefore we go to here loop is true roll index negative one if space between print space why does oh you know what it's uh with it's the time it's the time we didn't set the time we need this to be now we do this because what it's doing is actually it is putting the space in the right spot but then it's instantly scrolling again yeah because we didn't set the time here that that means the next time it gets called it will instantly scroll in in our case again it's getting called very very fast inside main loop so instantaneously it's called there we go this is what we want though that's looking good just meant to say comment slash delete the show function last time little typer thanks for the interesting stream yeah awesome i'm glad you found it interesting thanks for hanging out chatting along okay that's looking good looking good i like that um space between we don't have that choice up here but let's just make sure this looks the same no space between but that's fine pretty much like in the same okay let's go back to this one but let's do it just like this instead is b the same as eight capital b no much fancier much fancier but it is fancier just realized i was watching like 10 minutes behind oh my bad uh no worries not problem not a problem at all okay so this one's kind of the torture test one this one we'll see if it behaves the same i'm gonna take this back off for now nice it looks the same to me now yeah we don't have any kind of stuttering or anything going on they look the exact same now time i did actually happen to look down at the physical device that was totally just a hiccup in the video stream not the actual device the actual physical device has been scrolling at the same rate this whole time but the uh the video stream here kind of like slowed down and then caught back up really fast but that's not the actual device did not do that so in terms of reuse now we should be able to inside of marquee just call non-blocking marquee you know what we need though is we need to know when it's done because if loop is false then we need to somehow return at the end of this so we need to actually return from this whether or not we reach the end of the string and loop is false if if loop is false i mean if loop is true then we don't care we'll never return true in that case but if loop is false then eventually we want to return through or whatever to indicate that we made it to the end expected oh because we didn't actually put the return see the thing i mean it's it's optional or i mean i guess we could just always return false so we're we would return that here else if loop is not true and we made it to the end that is when we return but do we need to add more spaces is it supposed to scroll all the way off the left side return all the way off the left side i don't know let's comment this back out for now so let's go back to regular yeah i mean it has well if loop but we're saying if loop is not true yeah we don't care about loop what does this do does it scroll all the way off the left edge or does it does it stop when the three is here stops when the three is here okay it does not scroll off the left edge that's good that actually makes this much easier okay so yeah we just go here we return true uh everywhere else we return false if any every other place we return false any other possibility return false and then all this is is if it returns true that means that it made it to the end of the string and loop was false and so then in here we should be able to say so marquee if instance is string self dot fill false so we do that if loop we need if loop i don't know i don't think we need if loop i think what we do is this so i think what we do is uh just while true all true and we say if self dot non-blocking marquee and we pass through all the same stuff so we say text equals text we say delay equals delay we say loop equals loop pass through all the same stuff and then if that returns true that is when we return from the blocking function else if that does not return true then we just keep looping nice so far we got the same behavior nice oops accidentally saved it again so it's going to restart an extra time there now we're back to no longer returning because it's able to loop true if this was smaller it shouldn't matter nice okay i'm gonna go like this first i'm gonna put this back here do this we're just gonna compare one more time blocking and non-blocking so this one is blocking with just one two three this would be non-blocking with one two three and i'll go space between false that way it's the exact same so this should be the exact same perfect just obviously this is now passing pass a minute this must still let this get called actually i'm not sure about this yeah exact same as what we had with blocking let's go non-blocking with four characters four one two three four one two three four one two three four perfect okay you know i think i have two of these feather wings we could bust out another one i don't have another doubler ready to go though it would be nice to run it side by side one blocking and one not i guess that's why i had the pass here though is because of the uh it's empty it's invalid okay so that's one two three four blocking is the exact same and go there go back to this mega string one good and then we just want to make sure that non-blocking has the exact same here i think that's my camera feet again though right yeah it's the camera feet again one thing that we need to make sure is that it is actually returning when loop is false this one it just occurred to me we wouldn't actually know if it returned or not the way the code was before now we have a print so we'll see it okay yeah definitely does return perfect okay cool uh we did change this quite a bit so i'm going to grab this code and bring it back over to the repo and we'll go and do some cleanup here because i definitely left some come to that stuff and this could go away this i think is unused now no usages let's comment that out over here to make sure one's different it has a cycle i don't know what that's about i mean am i i'm in the display one i'm in the display one i changed anything in here that's interesting though the the display one that we looked at first i didn't realize that actually had non-blocking built-in already that's pretty cool this is where we want to be except i'm not i'm still not on the device let's get rid of all of this you no longer need show because print is on and print i mean print relies on auto show technically auto write how come it's called auto write but the function is called show i feel like those should match it either be auto show and show or it should be auto write and write this will make it not actually work that's actually the that would be the case with the currently released one truthfully i would say it probably just um probably just said it to true even if it's false this is the wrong copy of this many copies of too many things we actually ended up with space between here technically we could actually add it to here pretty much for free at this point because we could add this and just say pass it through i were doing everything else here this actually gives you new functionality that we didn't have well i mean it's back to what i said before honestly you could put the space in your string so it's not really new functionality like you always could achieve it you just would have to put the space in your string is all auto writes at the full so yeah i think i don't know that's maybe a separate initiative but it might be worth just setting that to true inside of both of these functions honestly like uh not really a good reason for you to be calling marquee if auto writes off because it won't be working so this is after a dot and before the eights just coming up right here there we had a dot before the eights this one it's much harder to tell honestly because the dot almost looks like a space anyway this one should be easier though because the four and the eight they would be right next to each other but now there'll be a space so yeah we had that space in between there was it then but if we do false we're back to no space so four and the eight will be next to each other hold up hold up we're inside marquee here this is gray which means it thinks it's not being used right uh yep yep yep yep yep yep yep yep yep that's not what we want turns out when you just hard code true then the value will be true there we go that's what we're looking for so now the four and the eight are next to each other no space between them right at the end here coming up right there and perfect grab this put it back in the repo cleaned up all right so non-blocking marquee's got all of this the only comments that remain are actually comments telling you about the code there are no random commented out chunks of code he says well he deletes this one real quick then i'm pretty sure so that yeah this is where we're back around full circle now i'm pretty sure we can just get rid of this we should have no usages now how's going did you have to make sure this still works it'd be basically the exact same now because we're not calling this anymore so we're on the blocking one still whoops we should be you know it'd be interesting is to spawn the virtual one and the real one the same display and since we have non-blocking now we would be able to do that be kind of a fun thing to do yeah we can definitely get rid of that delete this instead of copying it back what i'm gonna do is actually just head back over to the repo and delete it here watchdog again all right why is this mad expected two blank lines one found i don't know whatever just should i do that maybe i don't want to do that pre-commit free can it run a i guess okay like we had a pilot failure and use sleep yeah we don't use sleep anymore because now the blocking marquee is calling the non-blocking marquee so we don't have to call we don't have to call sleep anymore um you know i guess we could keep it and do it still i don't really see a need to though i think we just get rid of it is this like async io for segmented display not quite not uh not async io it's not gonna allow you to write your code using the async io syntax what it is though is gonna allow you to be scrolling the text here as well as doing other things on the device um so i can see how it sounds similar to async io but it's not it's not specifically the async io syntax but it is allowing you to kind of like juggle and do multiple things if that makes sense it's not using the actual like async await syntax somebody could add that i think now that there is a non-blocking scroll i think you could probably pretty easily add some awaitable functions and then you could use this with the actual async and await um yeah basically let's put the neo pixel back actually i'll show you the the main thing that this is good for is that we can have this so let's back on so right now i'm going to save this uh nothing is going to change we are just going to be scrolling this text here and nothing is going to change um and so this is illustrating how when we use the blocking marquee which is what this one is which is the one that currently exists today when we use the blocking marquee we cannot do anything else we cannot change the neo pixel which is what we're trying to do here it's currently just set to red because of something else set it to red and nothing else has changed it since then um but we have code here that's trying to change it it's trying to change it to green and then pink and then back to green and back to pink back and forth back and forth but it's not actually doing that because this code here is blocking it it's never actually making it down to here because we never return from this um you might think well okay well loop is true so maybe what if you just did loop false and maybe what if you put this down here like right maybe we could do it like this put the blocking one here we could say this you might think maybe this would work in this kind of a little bit this will scroll the text across and then after it's done it will change the led it'll like it changed but now we're kind of like stuck in here again now we're no longer scrolling this one i'm entirely sure why though i guess that's wait a minute why are we not scrolling that one something that's actually a bug i think i'm glad we did this because i'm pretty sure that's a bug if you finish if you have loop false you should uh it's not resetting the index i think right it's not resetting the index yeah when we return here we should actually be setting the index as well we should do this either way in fact maybe we just do this up here i guess right sorry short detour i'm gonna still tie it back together though here in a minute okay there we go so now the led changed once and then we scroll the entire screen uh string rather we scroll the entire thing then the led can change again then we scroll the entire string again then the led can change then we scroll the entire thing again then the led will change but what if what we really want is the led to blink back and forth while we are scrolling this so with the blocking marquee like this with the existing api because it's blocking we cannot achieve that we cannot be scrolling our text and blinking this back and forth at the same time but with the non-blocking marquee which is the new part that i have now added we can so we can have this blinking back and forth yellow and green and we can add this scrolling across at the same time uh and in fact we could have even more stuff going on if we wanted we could be running HTTP server we could be running led animations instead of just this basic blinking back and forth we could be doing fades we could be doing display IO stuff if we wanted we could be doing anything else we want because now this function returns pretty much instantaneously so we can put other stuff inside our main loop all right that was a very long-winded explanation but that's what this is giving you the ability to do is like scroll this text and have other stuff happening at the same time we did end up changing this again which means copy this again back to the old repo let me use marquee with seven this segment didn't even know it behaved like that and i still find whoever got that one yeah i essentially i found it when i was trying to make a web server that would let you set the text to scroll i found we couldn't do it because we couldn't have the web server running while this thing was scrolling that was my original motivation for adding the non-blocking that's pre-commit nope probably the same two things we had before right we're gonna have the exact same yeah unused sleep because we changed it in here but then i went back and copied back over it again so now we're passing it cut out the extra code i think see that in the change here got rid of our time sleep import of new variable nb previous charrs dot here we have non-blocking marquee got changed by black to be three lines instead of one we added the space between argument and doc string let's go ahead and type it we got rid of the logic for whether or not it's four characters or not because we had figured out that that's not actually important if we want to match the blocking behavior because it didn't have different behavior in that case rid of that and then change around inside of here how stuff works because we now have logic checking for the periods either like one period by itself versus two together this kind of moved down it shows it as being deleted and added but like really it just moved down a bit we have if space between we added that as an argument so we can check now we fixed this by updating the time no we fixed this by setting the index the time was always down here time we set because yeah we didn't want our space to immediately get pushed again we return true if we are at the end of the word ring whatever it is gonna be more than one word else set that back to zero this is else the text changed basically so if the text changed we want to go to zero we should test that though actually I didn't have not a test of that that's that we've always been scrolling the same text so let's say message one message two deep divers so then let's go scroll message one if now say start time maybe start time equals time dot monotonic and let's say if now plus 10 seconds 10.0 now plus that's right we don't want now that we want uh start time if start time plus 10 seconds is less than or equal to now let's just go less than actually if it's less than now then we do this and else we do message two so this will change so we can make sure that when we change between messages we start scrolling at the correct character because if there's a logic bug then we might start scrolling at like index one instead of also I am backwards on my logic so we have deep divers instead of hello but that's fine wait 10 seconds here it goes okay so then it changed to hello and I'm I'm pretty sure it did it correctly it's really fast though let's do this let's change these around let's slow this a bit as well just so it's like not quite as fast yeah so we started correct there got our full hello that's all looking good we wanted the d to show up here nice yeah that's perfect cool okay did I change anything I don't think I changed anything marquee got changed by black because I added an argument so it made it long enough that it wanted to split to multiple lines we added a doc string for the argument the new marquee now just calls non-blocking marquee inside of a loop and returns whenever it's time the old marquee actually had logic for the dots while it called actually scroll marquee which had the logic for the dots but in our case we got rid of that because now we can reuse non-blocking so that is looking good it is not still passing so I'm glad that I ran it again I was sure we got to not passing but that's all right so refactor the other marquee I wonder how many other marquee using libraries let's get improved to matrix panel I do not know about to me that one might be trickier apologize for SSD no clue would cause domino effect a lot of other libraries I don't think I don't think it did necessarily I mean either way I don't think you have anything to apologize for like just bringing something up is never gonna be a problem I don't think I mean like there's a couple other ones I think it's only a handful I don't know Dan was gonna look into it off the top of my head though I think it's like less than half a dozen I could be wrong maybe it's more I don't think it's that many though I thought it was the one library I think there's maybe like I don't know my my gut instinct is like maybe two or three maybe two or three there's more than one but it's not very many because basically the deal is it's like only the ones that are super old only the ones that existed before display oh and then like after display came into existence all the displays since then they've only gotten display oh I think for what's worth I think going back and adding frame buffer IO to the name of the frame buffer ones uh this is like definitely net positive change as well so like once we make that change I think it will be less confusing overall so I think it's a good thing like I said nothing to apologize for as far as I'm concerned okay we got that pushed uh I'll hang out for just a minute and make sure that this passes um actions it should because we ran it locally so hopefully it is I guess I didn't do the docks docks let's build so we should pass but we'll see um and then I'll head out after that so thanks for hanging out to everybody uh hope everyone has a good rest of your evening and all that kind of stuff if you are interested in this kind of content and you want some more of it you are in luck because I will be back at 10 a.m central time tomorrow morning um it is currently about 6 p.m central time and I'll be back at 10 a.m central time so 14 hours from now I'll be back again but I'll be over on my own channel on Twitch and YouTube I will be streaming some more work on circuit python stuff we made it pretty much to the end of this so I probably won't be working on this specifically but I will be getting into something and that something will definitely be related to circuit python somehow so if you're interested and want some more of this tomorrow morning 10 a.m that's the place to be uh you can join me back in the discord here I'll drop links when I'm about to get started otherwise you can follow me over on Twitch if you want notifications for that um we did pass so I will just leave a message here and then maybe re-request review I guess it's already there I don't know it's already there I don't know if it does anything I remove it and add it back does that like mostly what I'm interested in is bumping it down at the bottom here might not actually do anything though just because it's already requested maybe I don't know if you don't wait long enough there we go okay yeah now it says removed down there so we add it back nice yeah there it is gotta refresh that so it's on there cool looking forward to coffee in the morning 11 a.m eastern 10 a.m central time yep um so yeah thanks for hanging out everybody I had a let's see I had a marquee last time used on an old site nice I like that uh I like that submarine there that's pretty sweet pretty sweet I don't recognize what that's from it's like a cartoon or something but a game maybe except from uh so from the balloons game maybe there's some stuff that looks like that in the balloons game I know pretty cool looking though all right uh take it easy everyone have a good night I will see uh anybody who wants to follow along again tomorrow I'll see you in the morning otherwise uh I will bid you farewell for now and I'll see you next time uh you show up for a stream thanks for watching and I hope everyone has a good rest of your evening


There is a really fascinating movie to me, because on paper it sounds so lame. It's a two hour story about how Nike got successful in the basketball shoe line. Like, but it's even more minimal than that. It's about how Nike spent 48 hours trying to convince Michael Jordan to join their basketball shoe line. But it's even more minimal than that. It's about how one man's sonny and his small team convinced the boss to sign Michael Jordan to have a shoe line. Like, this is such a basic concept, but man, does it work well.