 Hello everyone! Happy Friday and good day to all who are watching. Let us get a few of our windows straightened out here. Let's make sure that I turned on the YouTube. Yes, looks like we got the YouTube on. All right. Good day! Happy Friday! How's it going? To Beata Graph over in the YouTube. Nice to see you, my friend. I should have put the keys away earlier, but I did not, so let me just put those there. Let's do the introduction for anybody that might be new. This is a weekly deep dive live stream program, which is on some weeks. Let's see. What are we trying to pull up here? We want circuitpython.org. You know what I should pull up is the YouTube playlist page. Let's do that real quick. I don't normally pull that up, but you can see I'm in my own little feed there. Let's get what I want, really, is the playlist. So deep dives. That's going to talk, though, actually. I don't want that. So deep dive playlist is where you can view all the deep dives for anybody that didn't know. If you want to go back through the history, you can see that. So this is a weekly live stream program. Some weeks it is with Scott Shawcroft, the lead developer of circuitpython. When Scott's not available, then I am here instead, as long as I'm available. Which is the case this week. Scott's not available this week, so I'm doing the stream this week. This is the last deep dive of the year, I do believe. So I won't be here next week or the week after. I don't believe Scott's going to be either. So I think this is the last one for the year. So thank you, everybody, for watching all the deep dives that you have this year. And I know, certainly, I look forward to coming back around next year to the extent that I am needed. And I imagine Scott would say the same as well. Ortega Computee Shikhan. Computee Shikhan? I probably got the name wrong there. Apologies for that. Hi there. Nice to catch a live one. Thanks. Yeah, for sure. Thanks for tuning in. How's it going to DJ Devin as well? We've got a hug reporter upcoming for DJ Devin, but let's get through the intro. So you can see the whole history of the deep dives here if you want to. We are typically working on Circuit Python stuff. So Scott's the lead developer and the name Deep Dive is because he is typically working deep inside the internals of Circuit Python. I typically work a little bit higher level either on stuff that is not quite as adventurous when we do venture inside the core. But oftentimes we also spend time more at the library level and the project level, which is more where we're at today is kind of in library land working with some Python code. Ultimately trying to make an enhancement for one of the libraries to make a new feature. If you are brand new to this though or you're catching the video in the future and you don't know what I'm talking about, Circuit Python is the main project which is worked on in this live stream program no matter who is doing it that particular week. You can learn more about Circuit Python at circuitpython.org right here. It is basically a version of Python that runs on tiny computers called microcontrollers. In fact I have one here which is kind of almost like a little tablet this one is. But these microcontrollers come in all different shapes and sizes and there are 468 of them currently that support Circuit Python. This allows them to connect to a computer most typically via USB although there is Bluetooth and web as well. So they'll connect to the computer. There will be a code.py file on the drive that shows up especially on the ones that do connect via USB. They'll show up as like a thumb drive basically. On that thumb drive there's a code.py file. You edit that file put Python code inside of it and then the microcontroller whenever that file is saved or whenever the microcontroller boots up it will automatically execute the Python code that is inside of that file for you. It can interact with all sorts of other hardware peripherals. In today's case I have a PyPortal Titano which is also listed on this page over here. PyPortal Titano this one has a display as you can see and a touch overlay a resistive touch overlay on top of that display which allows it to get XY coordinates when we touch it either with our finger or stylus or whatever. So all different shapes and sizes though that's just the one that I am working with right now. You can see all these over at circuitpython.org slash downloads for the whole list of them. Always need to say thank you to Adafruit. Adafruit is the company that is financially backing the circuit Python project. So Scott who does this live stream as well as a couple other folks are paid by Adafruit to work on the project full time. Some folks like me are paid by Adafruit to work on the project part time and all of us do very much appreciate it and if you want to help support the project and Adafruit you can do that by just going over to their website adafruit.com and purchase hardware from them. They design and manufacture the microcontroller devices themselves like the PyPortal Titano that I have right here is an Adafruit device. It is in stock if you wanted to get one. So they make this and all sorts of other microcontroller devices. They also have loads of things that you can connect to your microcontroller to do stuff with be it a camera kit or displays or breakouts for sensors or all kinds of little electronic doodads pretty much anything that you could imagine you can find over there. So get yourself some new toys and help support circuit Python while you do it and thank you if you choose to do so. Let's see how sorry for that. Yeah, no worries. Not at all. Not at all. No worries for the name. More like a Latino American oriented name. The translation would be something again to Ortego computation. I see. Nice. Okay, so we are working with the PyPortal Titano and specifically the hug report for DJ Devin. I should have pulled this page up in this browser, but unfortunately I didn't. So let's ourselves back there by randomly tracing these breadcrumbs. Today's hug report is for DJ Devin who has created this whole project feather weather project. Let me drop the link goes further up. I was in the first one, right? The link. Yeah. Oh, there it is. I think I saw it. Yeah. This is the link to the full project. Oops. This is a link to the full project. I'll put it in the Discord. Folks can grab it and put it in the YouTube or Twitch or whatever as needed. I cannot see the Twitch chat, by the way. I can see the Discord and the YouTube. If anybody out there is watching on Twitch, I know we are live on Twitch as well. If you happen to be watching on Twitch and want to ask a question or make a comment or something that you want me to see. Unfortunately, Twitch is not the place for it. Either Discord or YouTube are the places to go for that. This, though, feather weather project, thank you to DJ Devin who's made this. This is looking super cool. As part of this project, DJ Devin wanted to correct me if I'm wrong here. This is my understanding of it. So if I am correct in some part of that, feel free to drop in the chat the true story. But my understanding is this device, it can connect to the Wi-Fi network, obviously, and you want a way to be able to enter the Wi-Fi network name and or password on the device itself. Typically, that would be a thing that you would put in like settings.toml, for instance, or the old way would be secrets.py. DJ Devin wants a way on this project to be able to put that in on the device just like you would on your phone, right? With your phone, you don't connect it to the computer and then from the computer tell the phone which Wi-Fi network to use. No, you go to the Wi-Fi settings and you find the network you want and you type in the password on a little soft touchscreen keyboard. And so DJ Devin has put this together with grid layout and it looks super cool with all these different labels inside of it. And the part that we need to do, the part that I intend to work on today is once we have this super cool looking grid layout with this whole QWERTY keyboard on it, how can we figure out which key was pressed, basically? We're going to end up with XY coordinates that come from our touch driver. We want to take those XY coordinates and figure out, you know, for XY, whatever, is that the U key, for instance? If the XY coordinates were right where my mouse is at here, then we're going to say like, we want to be able to know which key got touched. That way, ultimately, you can type that character into the input and then, you know, eventually save it in order to save the password in there. But before we can start worrying about typing it up here, before we can worry about saving it or doing anything else, the core problem is take those XY coordinates, which are going to be coming from the touch driver, figure out which key in the keyboard actually got pressed. Mostly for family members that are used to the device having everything self-contained. Nice. Yes. Okay, so I have a portion of this code here that is rendering the grid layout with all of these nice letters and characters and digits inside of it. What I don't have yet is any touch screen code. There was touch screen code. Whoops, this is the advent. Let's go over to the device workspace here. There was some touch screen code. I think I left it, but I commented out because I'm not sure it's TMP spy. I'm not sure if this is the same touch driver or not. One thing this project was made for when DJ Devon made it. It runs on a 3.5-inch TFT feather wing with an ESP32S3. In my case, I have the PyPortal TITANO, which is the same size display. But there are a lot of other differences about it. It's not the same main chip. It's not the same... I don't think it's the exact same touch driver, although we're going to find out right here. So let's pull up a TITANO page. Sorry, I'm late. No worries. How's it going, Jeff? Never need to apologize for being late. Come and go as you need. Not a problem at all. The video, the vod's always there if you want to catch it after the fact. Even if not, that's cool too. You got other stuff going on? No worries at all. Let's get to the guide. There should be something about the touch in here. Let's see if we can find a basic touch. Not that I actually have this one. So there is PyPortal hardware FAQ, maybe this. Let's go back to here. Let's search on touch screen. Make touch on touch screen. Let's see anything about the chip or anything. Touch screen. Resistive touch screen. Let's not see anything about the chip. So we could figure it out from maybe looking into the PyPortal library. We could do an STPM, STMPE 610. Is the feather wing one there? All right. Let's go different route here. PyPortal, circuit, Python GitHub. I'm going to go to PyPortal library. And inside of there, it should be initializing the touch. Check. So yes, here we go. Perfect. It is slightly different. It's not the STMP one. It's this Adafruit touch screen driver. So we're going to gank this up that in our code. And I cut out a lot of stuff. So I have a lot of imports that aren't used. So we might as well just do it in the same place, right? We can move that import though. We don't need that. Just be randomly here. Then go what? Debug we don't have. We can just print. That's fine for now. Self. We don't have self. We're just going to say touch screen equals Adafruit touch screen. We should have all those on board. The next problem that we'll worry about is our calibration. But let's go one problem at a time. And so let's just do this. And then let's get... Let's go to Adafruit touch screen now, actually. Adafruit touch screen. Good hub. Circuit Python? Should I have done Circuit Python? Yep. Circuit Python. Four wire resistive touch screen. So this one doesn't use spy. It's just a four wire, I guess. I think it's like four analogs or whatever. They have zero to 1024 or maybe 65,000, whatever. Actually no. Here we go. So we can say now in our loop, if it is got a touch point, equals touch screen. Touch point, if p, print p. Let's do that. I do have to, but I do not have auto reload. So we need to auto reload it or manual reload it, I should say. And it touch screen. Okay, we have that. Should I go the other way around? So right now we're not worried about which key, but we're just like, do I get points? Yes. And then do the points roughly correlate with low numbers, top left, big numbers, bottom right. And yeah, they do roughly correlate with that. One thing we could do to make it even better than roughly correlate is let's get a copy of this real quick. Next, our report for the night goes to see Grover, I think is who made, I'm about to use here in just a second. But is it in a different library? I've done this before, right? Is it in the different library? No, it's in this one. We want to use this to get some calibration values. So when we initialize the touch screen, all the way back up here, we had these random, they're not random, but we had these numbers right here that are just kind of here as hard coded numbers. This calibrator is going to help us find numbers that are like dialed in for our specific touch screen and our specific circumstances and just general vibe and life in the universe. So that it can give us the best possible X, Y coordinates, which is going to be good because we are aiming for pretty tiny little rectangles. So we want pretty precise touch points if we can. First thing what we want though is a copy of this. Let's just call this QWERTY test. Now in CodePy, I'm going to grab Calibrator, save that, reload. Touch screen might work for the feather wing. I chose to use the base library based on the abstract. Hope our library is nice. Yeah, the feather wing library is nice. This calibrator to make, yeah. Yeah, it's amazing the difference that it can make what we have here incompatible. Probably we have, what, something that's being display text, would it be? Touch screen. I mean, we just used touch screen, right? Simple IO. It's probably simple IO. So our problem here, it says it on the screen there. It's kind of small, sorry. I guess maybe it would have said it over here. Wait, where's our TO? Why are we in this one? Okay, let's close these. It does say here as well. Incompatible MPY file. What that means is there's an MPY file that was made probably for CircuitPython 8.0 something, but what we have is CircuitPython 9.0 something and they're not compatible. In fact, one thing we should just do while we're here is update the PY portal because right now we're on Alpha 2 and I think there's Alpha a lot more than two at this point. At least. Let's do that. Bootloader. And substituted those values. Nice. Yep, yep. Calibrator. We'll spit out some values for us once we run it and follow the instructions on it and then we can copy paste those into the code pie. I broke that reading and bearing up the chat there across a little bit of dating action. There we go. Okay, we do still have incompatible MPY file but now, but I mean we didn't change the MPY file so we expect that but now we should be on a newer boot out. It was on here still though, which I really hate when it does this to me. I start the question if anything we're looking at is real and it's stuff and prefer to just know that everything we're looking at is real. Then stuff like this happens where it's like is that really what's in this file? I kind of don't think that's really what's in this file. Yeah, see? I'm pretty sure that's what's in this file so I'm pretty sure my charm is lying to me right now. Probably should have closed TO. Good thing it doesn't just keep going back there, huh? And we believe what our editor says. Still no. That is mighty unfortunate. Am I looking at the wrong file? What's wrong? With boot out it doesn't matter, right? The contents of this file don't really matter but the contents of the code file matter kind of a lot and if I can't really trust the editor to be showing me the files that are actually currently on the device it's kind of like sketchy to just go on with trying to write the file. Gosh, that is whatever I guess. Let's try one more thing, unplug that close, let all this stuff close. Yeah, like I said, I mean I know this doesn't matter, right? The contents of boot out does not matter at all, right? It doesn't matter if it's a little bit out of date or if it's even the wrong number, it still wouldn't matter but I really want to be able to trust the text that is in the primary editor that I'm using to edit the code. Like trust that it is actually the code that is on the device right now currently. Okay, we are here now, so let's get back to our guess of I believe it is probably simple I.O. so we want to go I'm going to just do uninstall simple I.O. And then install simple I.O. and that should give us the latest one. And importantly it will give us the one that is compatible with 9.0 or 9.x Very good. Now we have Calibrator. Use the stylus to swipe slightly beyond the four edges of the visible display area. The stylus little red box is going to follow us. We basically want to go to all of the edges and once we have gone kind of round and touched each edge what you'll notice is now the box is way better at tracking where the stylus is. Give it once more on each edge for good look. And then we will grab these which are now the calibration values. Put them back into our original code pie which was now code QWERTY. Save that. And then what I want to do is actually I bet you this is actually on here wasn't it? Touch calibrate is actually already on my device. I did not necessarily need to grab it from the example. QWERTY test and we're now going to put that back into code pie. Overwrite our calibration relaunch Alpha 6 still running 827 on the feather weather because I need it to maintain stable. Yeah, I try to just always get the newest stuff. That way I can be potentially finding and reporting bugs. But I was behind by a few on this. I don't use this device as much. Yeah, that's true display. It has had a ton of changes with nine breaking stuff as well. Especially if you are using an external display like you would be for your feather wing, that's a good very good point. So I have modified the code to just be doing board. Not display which is built in. But yeah, if you have an external display like four wire and all kinds of things bus display I think and some other stuff like all kinds of things related to the display are now in different different modules. So you need to change your imports if you want your code to work on the new versions. Okay, so we should be getting our touch points now and our touch points should be like pretty darn good at this point. So like our screen is 480 by 320 like in the far corner down here you know we're pretty close to 480 by 320. We're not like exact but that's fine. We should be good enough at this point I think. So what we're going to be doing now is taking those two numbers those XY numbers and we need to solve which cell within the grid at that location and in my mind approach for this I think that I am interested in to try first is in the grid layout. Grid layout is what's positioning all these things in this nice square thing. So we already have git cell tuple. We already have git cell tuple which takes the cell coordinates which would be like 0, 0 would be this cell either 1, 0 or 0, 1 I don't actually know. Probably 1, 0 but again I don't actually know. One of those two would be this one 2, 0, 3, 0 so on you know 0, 1 or perhaps 1, 0 the opposite of whatever this was would be here and they would count up. We can easily take cell coordinates and get back an object. Let's make sure that that works for the multi-spanned cells. So like enter spans multiple columns so to slash but it's only 2 enter does 3. Space does even a lot more let's actually do space so space would be 0, 1, 2, 3, 4, 5 let's call it 6 as long as we're somewhere in the middle that's all I really want to test for is like does this find space even though we're going to ask it about a single grid and space is multiple so let's say 6 and then 0, 1, 2, 3, 4 so we want either 4, 6 or 6, 4 let's just do some test action on that let's say print layout.get cell let's just say 6 I think it's going to be x and then y so let's go 6, 4 I could be wrong it's 50, 50 and then that's going to give us the cell which is going to be like what that's going to be like a thing oh hey we have this could be helpful this could be helpful maybe well that's going to be the display IO content so in our case that is a label because all these things right here they have created a label and then added it to the grid add a given x, y coordinate location and add a given cell size 0, 0 is first row the second row and so on sounds like math yes definitely we're going to have some math coming up I've reached the portion of the program that is math you could have 6 keys for space giving them yeah I think we won't need to but I'm not sure that's what we need to figure out is if it's going to just handle it for us which is going to be awesome if it does or if we need to actually worry about the fact that some of our things span I think it's just going to handle it for us though so we'll see so get the cell at 6, 4 that's going to give us a label so we could just say that text and that should give us the text from our label to print out and so that will be space if it's the space bar or it will not print anything at all if okay here we go so it says it does not contain those coordinates I think maybe I should have been cell coordinates no it's wanting a two-pole did I get them backwards I must have got them backwards down first maybe down first it doesn't contain 4.6 either really let me see here I need to get this let's go into monsku um could do 6 okay yeah yeah why do we need a 4.6 I think that's not true is it right we should index that does not contain cell at coordinates okay so maybe the truth is it does not actually handle this so let's look at the let's look at the actual logic here so we're passing in those coordinates we're saying for index and cell in enumerate the cell content list if the grid position is equal to the cell coordinates then it returns that so yeah it is actually it is not actually gonna work if we wanted it to work we would need like right now without changing anything else if we wanted to work we would need to pass um the left edge of space I think let's validate that which I need to actually see the things spawn again before I know what it will be great on topic for my own work today nice working on some uh some kind of touch screen situation as well okay so let's see we okay so that would be actually unfortunately I'm still no closer to knowing if it's 6 4 or 4 6 let's go with my original one 6 4 and then what we would say though is instead of 6 actually be 4 so 4 4 which means it doesn't matter which means we get to put off knowing which of our 50 50 is actually right until we choose a different thing to test with it's kind of a little bit amusing in a way um so I pressed save but now my editor is a little bit ghosty on the mouse it's not ideal hello and it is not the day for pie charm I guess false file contents now we're just locked up I usually don't I mean like honestly I don't usually have issues occasionally I will do something that drives me a little baddie but is actually pretty bad like even this instance over here is locked up I assume it's like trying to write and like spazzing out and failing um if we just give it the ol reset I think that will probably pie charm back cannot save unable to write data let's make sure that it's not full or something like maybe it was full I don't know got wrecked by that recently honestly I should be checking if it's full way earlier okay we have plenty of space 2.4 megs I mean microcontroller getting some of the new products ready for the big are pie mostly kernel and device tree stuff nice deep in the deep in the raspberry pie inner workings only we could have quality based virtual keyboard on those touch screens those long touch screen on the long display the keyboard will actually compute a USB HD key code that could be directly used for emulation that's for print hello okay so they are row first okay so it was yeah so 64 would have been right if it worked 64 would have been right if it worked and then 4.4 I think can work but we are in safe mode which I guess is probably why the right failed earlier I don't know lemon guess things are probably related what I don't know is are we did this get saved or not so we are unfortunately a little bit back to a scenario okay yeah yeah did back to a scenario where I'm not positive if what's in code pies like the current state of the drive since it kind of passed out when I tried to save it but we made it it is it does do space and so that that handles our question of does it just handle that for us which is to say no it does not so really what we would need to do is we either will need to you will need to do what we will need to account for those different sized cells let me just print cell and see what kind of data we have here hopefully we have like size and stuff okay so our objects have these things we have it's a dictionary we have content which is our label we have cell size we have cell anchor point and we have grid position so what we need to do is check not only if now we are just doing the most basic check of did they pass the coordinates that are the coordinates for this cell a 10, 3 so maybe no columns are first my 6, 4 was wrong and my 6, 4 should be wrong I think because columns are first if 10, 3 can exist but maybe this is backwards from the other thing I don't know we need to check not only the cell coordinates though but also the size so we want to say not only if it is equal to that but also we could either just have a big or but this is going to be kind of gnarly I think I'm going to write them as two different if statements so this would be exact location and then this is going to be multi spanning cell and in the case of the multi spanning cell what we want to know is I'm going to think about X first but obviously we need to solve for Y too but I'm a one thing at a time kind of a problem solver although I am also a little bit ADD so it doesn't always work out but we'll see how it goes so we want to know if the number that was passed not only is equal but it could be equal to anything between this and its X plus its width so if cell grid position zero that's its X if that is less than the coordinates that we asked for cell coordinates X and oops we want zero and if that is less than so less than or equal less than or equal less than or equal yeah because four we should trigger on four as well we definitely want equal if the current thing we're looking at is if its X is less than or equal to the X that we asked about and then if the X that we asked about is now less than that things X plus that things width that things X is this and that things width is cell size zero now probably I'm off by one here and I could like reason through all the math and figure it out but also I'm kind of a guess and checker so what we're going to do is set this up and then just test the cell that's at the far right edge of the space and that we're going to tell us whether or not this part is right or not except for right now this part is definitely not right because we need a colon let me catch up on the chat as well you mean to build a touch USB touch keyboard for plugging into a computer yeah keyboard that you plug into your computer but it's a screen soft hard keyboard that's kind of cool idea actually I do kind of like that soft keyboard that is a physical USB keyboard it might be padding to take into account not sure if the cell yeah well worry about the padding I don't think the padding is gonna matter for us ultimately but we'll see wow no shape rectangle to do contains yeah so we don't have we don't have just an easy thing to do a contains on like that but I mean that's what we're trying to make ultimately you know effectively so one thing you could do though like on that you know in that vein you could so right now we have a label inside all of these one things we could do though is we could change all of these to be a button or a sprite button either one there's two kinds of buttons these could be a button and they could still have their little letter on them but then they would have a contains and then you could loop over all of them and you could say contains the XY coordinates that would work I believe fine it's just like the looping is not necessarily as ideal and then the other thing about it is like you need to have a button for each one of them and that button occupies more memory than a label because it is a label plus some other stuff so doing it the way that we're headed for here with our code means we'll be able to do it without the button which means we can keep just the label we don't need any extra objects but we will effectively land on the same solution as being able to say like each individual cell if it contains the touch points we'll just get there without actually having to in our user code loop over all of them in this library code in this function it is effectively just looping over all of them still but okay uh yeah let's test space let's hit it with the manual reset and I didn't actually catch all the way up on the chat as well did I maybe I did if somebody switches a lot between German and US ANSI that would be that would indeed be useful as a dev keyboard also does mouse if it also does mouse that would be interesting too if I could do mouse too how's it going Paul okay good evening to you more good day have I seen the icon animated example I have yeah I came much made icon animated for a project that I was working on at the time so you have seen that one just played with it recently had a quick check and it uses contains which is to find an icon widget which calculates the widgets x y yes so contains on icon widget is basically coming from widget the superclass widget and then control it might be I think it might be control actually not widget control but in our case so like you know we could make a label that extends control and then our label would gain the contains function because that's basically what control gives it the control I think it has interface Python doesn't really have interfaces but you know class parent class basically so we could extend control with like a special label or even with label itself and then you could do it again like you could then loop over your labels and and all the sudden labels become buttons effectively they get the contains function that's possible that would work but yeah I'm gonna try to take this approach of instead of so so like all of those approaches boiled down to it's the user codes job to loop all of these keys and then test each one to see if it contains whereas with the solution that I'm going for here it will be the grids layouts job the the helper class grid layout you'll be able to give that grid layout your coordinates and then it will figure out the rest for you so that your user code does not have to worry about looping all these different things in here wonder if I try to contains if it would work uh it won't I don't think I mean it's possible that I'm wrong but I'm like 99% sure it won't because group is not what has contains it is uh it is control I'm almost positive maybe does group have a contains maybe group am I missing now so maybe group did I add a contain does group have a contains either way though I don't think each cell doesn't have a group it has a label and we can't be guaranteed that it will be a group label I think does extend group but it might be um but we can't guarantee we're gonna have a group so we might have a tile grid although you could make the case the tile grid should have contains to either way though I want to do it with the grid layout here because I really want the user code to not have to loop these so honestly even if those things exist they're not how I want to do it group I don't think can have contains though because it doesn't know it doesn't it doesn't have like a width and a height group like by default it doesn't keep a width and a height so if group has contains it would also have to loop over its children but it's possible it got added at some point or if it's on tile grid then it could be used here but again it's back to the looping in the user code versus the library code problem is often ugly code gets left behind yeah I'm a thousand percent guilty of that I have all sorts of guilty code in all kinds of places because I definitely am like I get it to work and then it works and I move on to something else to a fault sometimes for sure has gone Keith to E been a while since I've been able to catch this one hope everyone's having doing great yep nice to see Keith I hope you're doing great as well so yes yes yes yes so we um a lot of stuff now where did our space go why did we not print space anymore are you for real I don't know something seems wrong with the saving maybe but I mean we were on were we on the old one when that happened the first time or is it after I already updated because after I already updated there might be a storage issue on uh be a storage issue on when we updated to not positive like I can't say for sure I charm is trying to do way too much stuff general but that's actually the second time and then did we yeah we are also in safe mode again so got the same symptoms at least which is I went to save and it just froze and then we reset once and we came back to safe mode and then I reset again and now I'm back to normal mode did I change that to four zero or we messed it up because it's not checking the why also so we are right right right right we false positive on the four because we didn't didn't bother to check the why whoops I guess both dimensions are pretty important fortunately this means I get to go through here and find this again so multi spanning so we only we're still we're only true here also if I'm gonna say for right now and and the cell cell grid position one now I'm gonna worry about just the case of equals right we just disconnected again I was going K match Friday which is with him great day for deep diving yeah for sure nice to see my friend um boy I think we might be having a problem here I think I'm inclined to maybe take a one back and see if we are still getting the same problem or not the pirate style as well stuck in safe mode but I'm accidentally triggering safe mode we're not trying to and trigger boot loader but I'm going too slow which gives you X Y and pressure yeah we're not doing anything with pressure right now yeah now I don't think this would be probably not an issue with 8 to anything I could probably go to 8 to 9 I guess it would be more stable but I do not know it could not it could be a problem with my device as well or it could be a problem with pie charm there's a bunch of places where the problem could lie right now but by dropping back one what we'll do is start to try to narrow it down so if we don't have that anymore happen that we know like it's related to something in alpha 6 we do keep getting it then it's like either not related to alpha 6 specifically or it's like you know pie charm is at fault or my device maybe I need a format or something who knows alright so we want to check if the cell that we're checking is has a Y value for now I'm just going to say equal to the cell that was asked about and that should allow us to work on the space bar example nice wait we didn't actually well yeah I mean we got better at least we're no longer false flagging on the 4 so that's good false positive return I mean so we could yeah let's no 6 it's got to be the we know where those came from come on space nice we still got space okay so let's try so now the far edge that's what we really want to test here so now we're in the middle we know now the middle works 6 7 8 9 is the far edge of space so 9 should still be space but the next one after that should be something else let's do both 9 and 10 and we should get space and then left arrow although I don't think left arrow probably will print correctly in here but it might I don't actually know time to switch to new maybe but probably not but maybe I used new for a little while mostly it'll be time to like update PyCharm and try to fix it because it didn't use that some point I will want to try to get back to PyCharm because it's just my environment of choice one thing I forgot is we're printing a bunch of stuff so unfortunately our space is like way up here in this giant land of dictionaries but we did get our next thing which is probably that somehow we'd have to like Unicode something so we could figure out what it is but it's probably that perfect so 9 10 didn't that means that our right edge is correct that means that I guessed properly on my thing here technically we don't have to so for this keyboard right here technically we don't have any grids grid cells that are spanned vertically so the code we have now actually will work for every key but if we wanted this to actually support the grid layout and all the possible variations of cells we would need to change this part here to basically be kind of like the first part it needs to say cell position 1 less than or equal to cell coordinates 1 which is then going to be less than cell grid position 1 plus cell size so that should make it work for cells that actually span 2 rows more than 1 row doesn't really matter how many as opposed to spanning columns which is what we have now let's turn off the print also where's that print nice okay we're good let's do one thing not one thing we got a bunch of things left to do but the next thing I want to do is let's do one up let's do the slash let's just like extra super duper make sure that our x-coordinate is exactly what we think so 10-3 right here that should be the slash so we should get space and then slash the problem is if my logic inside here is wrong then the whole list of everything I want to build on top of it is going to be wrong so I want to make extra certain that it's doing exactly what I think it's doing and it is okay so now we have it to where we can give it an x-y coordinate and then it will give us back the cell that is at that coordinate the next thing we need to do is just convert our touch point our pixel y location into grid coordinate system some cap touch displays in the 4-7 inch range would be nice yeah for all all possible displays make all the displays make all of them touch on one of my projects I use coordinates as calculations based on the generics 4-3 height reference I'm not familiar with that generic is a generics 4-3 height reference I don't know what that is okay now our grid has a width and a height yes the next part should be pretty easy right we just need to know like our cell size and then we just need to do some like division with our cell size and our width here we have height and width in pixels typodemon sorry generic oh no worries hypodemon no worries generic 4-3 height width height difference does not actually have this is it I think in my misremembering it's not is it not width and height but it's like there's one that gives you all 4 right it's like size maybe grid layout extends group I mean there's underscore width and underscore height so I guess we can use those let's run it like this I mean it should crash if the the IDE is to be believed that those don't exist all that's going we can figure out where our width and height go once they get set like what is this used for okay this will be helpful this gives us the size pixels of a single cell we still need the width though right now and the width is only available on underscore width which is kind of lame truthfully let's make it width that's going to be an int and that is going to be the width in pixels of the grid layout how about this I think it's just mad because there's no code inside of it it's definitely wrong for something else I think I guess this is wrong right yeah there we go we want height also how about these these are I feel like these are new we want to be one I guess we won't hope if the font doesn't display no I think it was saying move because PyCharm seemed to be locking up my device something's locking up my device or it did twice spell height wrong yeah I did for example tft.drawCircle my width times 8 over 16 my height times 14 over 24 my width times 4 over 16 times 1 so the 16 by 24 well that's a 2 by 3 8 to 20 sorry yeah I'm still not sure how the 4 by 3 factors in that's oh that makes sense actually because we have one less for I will say I'm a very like visual person though honestly like just looking at a formula there are very very very very few formulas I can just look at and know what's going on with it I really need to like run it and see what it does on a screen and then like play with some of the variables and once I've done that and been able to like watch what happens when I change inputs and outputs and stuff then I can start to understand what the font like what the math is doing what the equation is doing that's for 320 by 240 I got rotated as well okay so we 478 is that right what are we making here let's double check so where does the layout so there's this this this okay so our width is the width of the entire display which is 480 minus 2 so we end up on 478 which is perfect and our height is 320 minus 100 which leaves us at 220 which means that our cell size print cell size that is now layout that gets cell size what is that thing called cell size pixels and not the best name necessarily is that a property or a function is a property okay so print that as well that should give us the number of pixels inside each cell which should basically get us almost all the way to where we need to be in order to translate our touch point in pixels into our coordinate our cell coordinate system because now what we're gonna do is we have the height and width of each cell so on our touch point we're gonna go you are gonna go what we are gonna go well we want a function first of all property this is not a property this is a function def I'm gonna just go with this name for it now which cell contains so that is gonna take a pixel coordinates location pixel location and that is gonna return either a tuple or none so optional so first thing we can do is throw out any pixel locations that are outside the entire grid if it's not in the grid then it's definitely not in any of the grid cells so we don't care about it for this purpose should work out on smaller disgraces so it is dependent on the display yes it should adapt itself adapt itself down so we want to check if it's in the bounds of our entire layout so if self dot x is less than we're equal to pixel location 0 and if that is now less than self dot x plus self dot width this will tell us if the x coordinate is inside of the grid layout so we can say and and we can basically have the same stuff for y because if it's outside the whole grid layout then none of the cells are the cell that it intersects with we get past that then we know that our touch point is inside of our grid layout so now the next thing is we figure out which cell it is by dividing we figure out which cell it is by dividing the location x somehow we're going to need to factor in the x and the y I don't know exactly how somehow that's going to have to go in column equals row width divided by cell width row equals grid height cell height from memory that gives you a xy grid which you can look into an array and yeah that's stubbornly harder than it looks like the slash slash floor division will be use 7 and over yeah yeah we can do slash slash at the end so we take the location x we divide that by the I'm going to keep the cell I'm going to keep the cell size as a thing here let's go cell size layout dot the name of it again already all size pixels I was on the right self though that's why that's how we're going to get let's keep that so that we can refer back to it so now we divide our x by our cell size x but we have the x problem x chord chord equals pixel location 1 cell size that should be 1 and that should be 0 let's just do that for now that's going to be all wrong so it's going to be all wrong we need to offset by the xy but where does the offset go this is where like being visual kills me because like once if I could just see it on the screen I'll know exactly where it goes but all right I guess let's just try running it and see what it does we're not calling our function so it's not going to do anything let's go down here and let's say if we have a touch point then pass it into our new function which is called layout dot which cell contains pixel location p print so I think we're going to have problems I don't think it's going to register correctly we might change our y coordinate while we test this is actually getting a guess which I'm kind of surprised at so it thinks we're touching 0 to but the problem is if I touch up here it thinks we're touching 0 1 also implies that our also implies that our logic for the bounds of the layout is wrong right when in doubt print it out that's how it goes f string let's go I always like to just put my whole condition in a big string like this that way I can right away just see what is wrong I'll just jump in what is he working on I am first of all welcome thanks for tuning in I'm working on logic that is taking the touch coordinates of where we touch on the screen and trying to figure out which key in the soft keyboard was pressed the advantage of integers are we on 0 to 0 our top left is messed up for sure but I don't know exactly how we need to subtract somehow we need to do that subtract or add something one of the two we need to subtract or add the x and the y from something hopefully these printouts are going to help us find out what it's not going to get us all the way there though this should help us at least troubleshoot the the first condition here oh ok I know what the problem here is actually it's that this shouldn't be and right so let's just quick sanity check here is 2 less than 144 yeah this is a less than equals technically but it's counting is 2 less than 144 yeah sure is then is 144 less than 2 plus 478 yeah that's 180 so 144 is definitely less than that so our x-coordinate was within the grid layout but our y-coordinate was not our y-coordinate actually says is 100 less than 59 no so we actually want or because what we want is if we're outside the x or we're outside the y then that should be returning none if you still have the default sprite buttons in the menu now I don't have any no buttons anymore only the grid layout and all of its contents ok there we go we're actually getting none now for the stuff out here which is good ok so let's try that right there so it got 0 2 0 3 on q 0 4 on a so we're kind of like off by why we need to then subtract it from no add it subtract it we need to take the number that came in and subtract why and we need to do that before the division which means we need parentheses and I'm just going to guess this is probably the exact same logic although it's going to be way harder for us to tell with our width only being too less than the display but because it's not at the top of the screen yes exactly right yep pick up some old t-counter code column equals x over width plus margin row equals y over height plus margin and then those are over with integer division so those are going to toss out decimals aha there we go ok so 0 0 1 0 2 0 3 0 heck yeah we are good 0 1 I came down to q so w would be 1 1 ctrl that's 1 4 alt that's 2 4 space that's ok so where I touched it was 5 4 but 4 4 is the first one actually 1 4 and 2 4 are both ctrl actually well no 0 4 0 4 and 1 4 are both ctrl alt would actually be 2 4 and 3 4 ok let's get rid of some of the spam we are printing more than we need probably just nuke these actually all together I'm just referencing Google once I got some proper search terms it's definitely relate to that where you're like looking around for something and you just don't know the right words to you like you know Google has this knowledge if you just knew the right way to ask for it because I was just I just had one of those actually yesterday or the day before I think what it was but um ok let's see we should be able to just let's stop printing this we stopped printing those so we were now only gonna be printing which cell contains so we're only printing one thing per iteration cool one thing you'll notice is I am getting a little bit of slip like sometimes what I touch it's getting the next one over I think debouncing is gonna help with that and you know what we don't have on here is a backspace or a delete you might need to well I got maybe that's part of your menu I suppose there is this I guess which is like reset it looks like I suppose that's kind of like a delete all type thing it might be nice to lose it might be nice to lose control and alt and gain delete and backspace unfortunately I the bottom left corner is not the most intuitive spot for delete or backspace but like ironically for me it is kind of because I use my left thumb down there but I don't know how the ordering could work maybe reset could move everything else is kind of spoken for though because it's like part of QWERTY so maybe the way my keyboard is these these two arrows are on the other you know effectively they're on the other side of what would be the space so I have like up down or over here and then right left or over here I would free up a slot over here which could become either delete or backspace and then the other slot there could be the other anyway reset would do it as well I assume the idea would be when you click this one it will kind of empty back out your text and replace them with special characters caps oh yeah yeah yeah like a like a caps like a shift lock basically some things will do like if you hold on shift turn on the lock something would have to have the logic for how long you've held though okay let's uh let's try to so let's get a little bit of debouncing which I'm not gonna actually do literal real do bouncing what I'm gonna do is just time dot sleep it but what I'm also gonna do is try to make an indicator of what button got pressed so we are getting our which cell contains so let's say touched cell is equal to that we don't really need to print it because we're gonna be able to see it visually after this if it works do I have two commas uh yeah it looks like there are two commas actually I had not noticed that before but yeah it looks like there are two good eye uh Gordy G I don't know if they're different somehow but it does look like there's two but shift where control is yeah bottom left that could be I guess happy holidays yeah happy holidays to you as well Jeff gotta run but it's been uh interesting watching circuit python dude work yeah take it easy Jeff hope you have a nice uh day and weekend and all that happy holidays to you if you're celebrating uh as well move shift to the left to give oh yeah that was back up there okay honestly don't uh didn't know what to put there so just added errors I got you yeah it's kind of one of the tricky problems with mobile keyboards too is like when you have a soft keyboard it means you can change the keys out and so it's this dance of like which keys are most relevant to the user right now it's kind of like always changing depending on what the context is um eventually it might be cool I don't know if you've thought about this at all DJ Devin but uh one of the things I thought of it might be kind of cool to encapsulate this keyboard as a library so that folks could be able to just kind of like create a soft keyboard object and add that to their group and then like everything else has kind of been encapsulated in a class um I think that'd be super neat to have it just built up and ready for you to treat it like a soft keyboard and not worry about all the details of rendering it yourself and bring about which thing got touched you could be able to just ask it like hey you know which thing got touched you know you won't have to tell it to render you could also build in a couple variations of like you know include number row or don't include number row you know include control and alt or don't include you could have a couple of different um you could even do key layouts and stuff like that if you wanted to take it super far oddball idea could the could be memory intensive have a color bitmap yeah what I'm going to try to do is that basically so it is a little bit memory intensive but the thing is we actually are cheating a little bit because our labels are already there and our labels are already consuming memory I think we will not need to consume any more because we can just make use of the label that we have already which effectively is going to be backed by a bitmap which is taking up memory so we'll say the touched cell was that and remember that's going to be the tuple so next up we want to from our tuple get our cell object what I call like a view typically is how I think of it but it's not it doesn't have an official name I don't think we're going to say layout that gets cell we're not going to pass nine four instead that's going to be the touched cell and then we are going to say we need to say um cut uh we need to say if touched cell so if because that's going to be none if they didn't touch a cell so if that's not none then we say layout that gets cell that's going to be our label so from there I'm pretty sure we got like a background color action maybe background color color timed out sleep of you know I don't know let's give it a little bit and then set it back back gorned back gorned so thing isn't it back deformed okay yeah that's also wrong I think that will work I'm not sure we'll find out yeah I have a class for one of the attributes display group and then coordinates key to bat mail you it's a bit sad that it's an ortho keyboard that is not a bit sad ortho keyboards are the best thank you but the internet is full of hardware ortho keyboards I could see a c64 virtual keyboard or zx spectrum virtual keyboard but we need to make more flexible and key position one thing I will say grid layout which is what's being used to render this going to be very hard to use grid layout for a non-ortho keyboard it could be done but you would need to cheat basically you would need to like cheat yourselves to all be two by one instead of one by one and then that way you could offset by half which is actually one cell instead of a fraction of a cell because it doesn't work with fractions so it would not it would not easily support the non-ortho case but also ortho keyboards are better my opinion now that I have seen the light I honestly don't know what's best it was just the thing we need to make yeah well and that's the thing like once we get this into a library there's a million different ways it can be extended or added upon or all that kind of stuff like you have laid the groundwork which I think is awesome by the way yeah let's try it out did I run it I'm gonna run it just in case I don't want to like anti-climactic touch it and then I didn't even run it you have to make all yep yep yep yep like if you wanted one that was non-ortho my recommendation would be to either not use grid layout or to modify grid layout to support it better to make offsets that are arbitrary by pixels you could do the you could cheat it by making each one and then like they'll technically be bigger or smaller or whatever but heck yeah look at that so one thing is it is uh I was expecting it to do the padding which it didn't but that's fine it's like we're able to tell what we touched it would be nice probably to change the color of the label to because right now what's happening I don't know how well is it coming through that comes through pretty well so right now the one thing is that the white of the foreground text and the green I chose a bright green which like gets washed out in the camera here but it's not there's not enough contrast you can't really see the letter when the green is showing so what would be nice is if we show the green and then at the same time ooh let's I guess save that touched cell I'm just going to call it view because again that's like the what I think of these objects as even though there's not a word called that in circuit python I mean technically it's a label in this case but like from the grid layouts perspective it could be any thing that's allowed to be put inside of a group which is any pile grid or group label extends one of those too so it counts as well I think we have color is it color or label color especially for the pinkies hexagonal keywords are not better but are cooler I probably agree with that hexagonal keywords probably would I'd say look cooler than ortho I mean honestly a regular non-ortho probably looks cooler than an ortho it's just that once you use an ortho the C key the C key is the biggest stickler for me once I started using an ortho then every non-ortho the C key just feels like way in the wrong spot and it makes it so that you kind of like for me at least it made it so I was using the wrong finger to type C like C I guess is technically a middle finger supposed to be a middle finger type but on non-orthos for me at least it's more natural to go ring finger but then my ring finger is doing double duty on X and C which is weird thank you to coming to my Ted talk about the C key and why I think ortho keyboards have better placement of the letter C oh my okay yeah we do not need caps lock I'm assuming white was what these were set to if we could go back and check in a minute it's like off white we'll change it to that we want to match what it was before hopefully yep exactly right yeah whenever you do change to a light background then you can do a dark foreground so that you retain some contrast oh yeah that's better okay so there the padding looks weird you know like on P you can't really see the left edge very well there's a couple like you could tweak the padding and come up with some ways to make it look prettier but this is good enough for sure and the accuracy is actually pretty good I was a little worried if the accuracy was going to work out but the accuracy honestly looks really good like we're hitting those perfectly on the key that I would expect for every single one of these okay let us hit us 530 my time let us make one more input and make it seem like we're typing stuff into it because it's because its resistance is designed to be used with the stylus or a finger but I've noticed the finger can actually work well I think I missed something here catch up iteration after the initial logs to be proof of concepts is always easier we go with the opposite the background yep iteration okay there we go yeah iteration okay what else do we want so let's make a label up top let's do it before the grid layout I will call this input label trying to think if there's if I change this padding we could make it to where our box is going to be bigger but it's still not really going to do what I want ultimately so I don't think I'm going to mess with it alright we'll make a label that's going to be what we need the font so let's say terminal IO font for now let's go default font I will go scale to so that it can be as as big as the keyboard letters I will say text equals empty to start with color equals white which I think might be the default but I'm not sure background color alright so when you press a key there's a bunch of different ways that you could do this here's what I'm going to do alpha numeric below my left middle finger is j do you use non-quarty or do you have your left hand like in what I would call a weird spot it's not really weird it's wherever you put your hand is fine honestly but like you keep your hand not on the homerow it must be non-quarty right alpha numeric so I'm just going to make a big list of all the possible alpha numerics and let's say we're actually going to call these ascii charrs charrs but I always say charrs in my head which is the Java teacher I had misproved basically I want a very easy way to say is the key that they pressed one of the keys that can be represented in our input because like enter is not a thing that shows up in the input other than like it could be a new line I guess but we're not doing new lines right now you know shift is not a thing that shows up in the input although it could modify what you put in there so I want to be able to answer that question of is the thing that got pressed a showable ascii character or not is it one of the like special use or whatever instead so the way I'm going to do that is make a big tuple that contains all these showable ascii characters then we're going to be able to say if a thing is in that or not we do whatever I do not think I'm going to make it to the end of this live stream without needing to start dancing though so I think in just a moment here I'm going to go and run to the restroom and then come back H-I-J-K-L-M and oh perhaps not the most efficient way to have done this but the vorac nice that is much better so we made it to Z we need what we need some things like comma dot slashes quotes literal slashes not break everything because it's escape character I'm going to do single quote here so I can start on the new line and put these two next to each other because it feels like they're friends right we wouldn't want to separate them I don't know that feels cruel and unusual okay we got everything right we got our tick mark we got our minus we got our equals we got our square brackets we got both slashes we got our single quote semicolon would not be able to write JavaScript code be a shame now we got everything I think oh space but space we're going to do space in this one we'll handle space separately for now to where that leads us so now when the user presses a key we want to get the key key label key text is equal to this dot text if key text is in ASCII chars then we say input label dot text plus equals key text did I set an xy on that input label I don't think I did do it something like that well bottom row can be handled differently yeah yeah we'll need separate logic for the non printable the non ASCII characters including the space bar even though a space is ASCII but we have the whole word so we'll need that for the arrows for the control to shift everything we'll need that kind of stuff what in the space just be space or empty string it could be a string with a space a literal space bar inside of it but we don't need it because we what we're going to test for is the word space we could put it in there and we could eventually maybe still use it from there but we're going to have to test for it separately anyway so I'm just going to do that I think alright so let's say be crash nice okay touched cell view is not defined yeah because that's because I did that obviously before we did this so you just cannot do that and then also of course that means this needs to be down here okay let's try that space bar is really just multiple occurrences I don't know if there's a space there no is that an empty string no it has a space wow guess discord spaces are really thin yeah the label yep exactly right the value that's showing in the keyboard that's our key and then in the case of the ASCII ones that's our literal what we're going to type for right now we'll worry about uppercase lowercase like shift I understand is here which would be uppercase lowercase this version is not going to handle that just yet but it should at least let us type okay I did not add it to the group let's add input label to main group I didn't do that main group gotta append input label hit it again let me see let's go B L I N K or A doesn't work I did not put A what's wrong with our A I didn't put A that's right there uh oh well a few things a few things here input label is teal instead of white which is that's because we only got five F's why does our A not work do all the rest of the letters work the equal sign doesn't work there's going to be no wrapping as well so we're just going to run right off the edge here okay almost everything works like A does not work and equal sign does not work which is but like it's turning colors is there a space maybe it's A space which is A by itself that's interesting okay so pros up again that's not the version of circuit python or if it is it goes back to at least the crier version as well means we should be in safe mode yes refresh again to get back to regular then here I guess we I really want the changes I don't know how to like wish this would get out of my way and let me get my code no terminal IO has to have the characters because they're visible in the grid right if it didn't have the character it wouldn't show here and I mean is that a different font I mean a thousand percent if terminal IO font was missing A somebody would have noticed it so I am confident that it does have A equal sign I'm less so but A I'm very confident and equal sign I would say I'm pretty sure but it's not as confident and it is definitely terminal IO font here there's A if it didn't have that in terminal IO font then it couldn't show it here either that's still teal that's because we didn't save last time gosh I should start copying my code to the pie before I save that way if it fails on me then I I bet you I'm missing a comma yep okay that's exactly why the equal sign and the A are broken no comma in between here and in Python one of the few things about it that does drive me a little crazy is when you have two strings with no comma or other operator in between them they just get ANDed together silently the rest of your program just runs and you're like what? forgot to copy haven't done space yet I think I accidentally touched with my finger up here in the corner and that caused a 7 so we're just gonna go with blink of 7 equals oh wow discord is gone I just fall off the internet I'm pretty sure discord just died yeah alright well we were here then it's just uh that's discord right now seemingly for everybody alright well that's alright youtube's okay so far yeah the stream is still here that's super weird discord is like uh wrecked I bet if you hit up twitter right now or uh search through uh the last time I searched twitter I used a thing called knitter so that you could search with that signing in I don't know if there's other ones but I bet if you uh hit up twitter right now you'll be finding people blowing it up talking about discord being wrecked okay okay let's do our space real quick and then I'll probably wrap it up here pretty fast so elif key text equals space then we want to add a space a literal space so we just go plus equals there I can't recall ever seeing discord do that before honestly to just go blink out of existence for everybody at once like that I don't recall I mean like I here and there I'll have problems with it like the client will be wonky for a little bit on a certain day or whatever but to have it just suddenly blink gone for everybody is pretty nuts hopefully they didn't uh delete anything too important not to touch the screen here we should have a space equals space fun sweet improved mobile experience has arrived this week we'll begin rolling out to all users new mobile updates including midnight theme super charge research and so much more out of discord release notes sounds like the way they write their release notes the I don't know what those are called but these little sparkly things I feel like I see in their release notes a lot alright so we've got the basics some things that are not working yet is like the arrow keys don't do anything the shift doesn't do anything the control and alt I think the control and alt are not going to do anything for this one because this one's all about typing in and control and alt don't modify what you type shift it would be nice to have right now we are in shouty mode only so everything we type is uppercase if we wanted shift to work what we would need to do is send our characters to lowercase by default but then actually you know what we don't have multi touch we don't have multi touch therefore shift needs to be I would almost argue shift should just be like caps lock because you can't like hold shift and then press a letter I guess the way that works on the mobile phone though is like you tap shift and then you tap a letter and then the first letter you tap after shift gets shifted and then shift turns off and if you have caps lock on which is usually done by long pressing shift then you keep pressing letters and they keep being uppercase ok anyway though the point was the shift doesn't do anything yet the control and alt don't do anything the reset doesn't do anything the arrows don't do anything so everything else works but those things don't it is able to be used as a basic input like this which is super cool there is definitely still work to do to encapsulate this into like a keyboard class that could then go in its own library be just a ready made component oh I think we are back shockingly OBS actually managed to come back and pick up the pick up the the chat on us too as well which is pretty crazy if nothing else one thing I will say to them to discord is like props that their thing came back without being refreshed right like I didn't touch it and it managed to come back and start working enough for OBS to pick it up even alright I think I'm going to call it for now I am definitely ready to get up and stretch out and move around and do some other stuff for a while I will wait for the sirens to pass because I don't know how much of that's getting picked up by the microphone I will be back tomorrow morning for folks that are interested in more circuit python action I will be around tomorrow morning at 10am central time over on my own channel so here we are on the Adafruit channel be over on foamy guy if you are interested you can just hit up the discord assuming it's working in the live broadcast chat I always post links in there when I am getting started I will be back for that tomorrow I don't know about next week I am not ready to say for sure on next week or not but yeah definitely tomorrow I will be around for that so come on by if you are around in the morning and want to watch some more circuit python action otherwise I will say have a good night have a good weekend thanks for hanging out and I will see you next time although do remember again this is the last deep dive for the year so January January whatever the first Friday is January 5th would be the first opportunity I am not saying for 100% sure that there is going to be a deep dive that day but that's the first one where there is even a chance for it so until then potentially or perhaps the week after so long thanks for hanging out for all of the deep dives that you have watched this year and I will