 Alright hello everybody. Let's see looks like I got sound into OBS. Let me just shuffle the chats around here. Actually see all of these. Happy Friday indeed to Tammy and Liz. We made it out of beta. I call Thursday beta Friday because it's just like Friday except that it's followed by a weekend. Future is broken. I like it. Friday the 13th, yes. How's it going Paul SK? Welcome. Randall over in the YouTube and Biata. Nice yeah thank you for the heads up on the audio. Dishapu, how's it going today? Alright so let's do a quick introduction and then I'll dive in. So hello to everybody. See I switched the scene. Yeah we got the scene. Okay so let's put that back. Hello everybody. My name is Tim and I go by FOMIGuy on GitHub and Discord and this is the deep dive stream. Originally started by Scott the lead developer of the circuit python project but he was away for a little while on parental leave. He did I think return back to work this week. He's got a couple of months in and then he'll be gone again for a little while later further into the later part of summer I think it is sometime. So I've been filling in doing the deep dive streams and then I think you know eventually he may be taken back over but I don't know exactly when that will be. If it's going to be before he leaves again or maybe not until he gets back after the the second time. But I do think we'll maybe have some interesting stuff. We'll try to get together and do a joint one at some point. I think that's in the works so look forward to that coming up in the next couple of weeks I would guess. But backing up just a bit if you are brand new to all of this and you don't know really what we're talking about on this stream we are going to be working with circuit python related things specifically you know developing either like parts of circuit python itself or the libraries or examples and other projects that people can use. If you don't know what circuit python is you can head to this web page to learn more circuit python.org basically though this is a version of python that runs on these tiny computers called microcontrollers there's a bunch of them that you can see examples of here on the downloads page and we're writing python code that runs on these devices and allows them to interface with other hardware connected either via the iopins or some of them have hardware connected on board like the circuit playground express has a bunch of sensors and a speaker and a bunch of rgb neopixel leds on board so we're writing python code that can interact with all of those components that are connected to it. Specifically in this stream I'll be working with these ones these are a couple of different sizes of the Adafruit Pi Portal the nice thing about this microcontroller is that it has built-in wi-fi in this chip over here and it also as you can see on the front there has a nice big built-in display as well as a touch overlay so we'll be writing some code that will draw stuff onto the display and then we can interact with it through the touch screen there. Adafruit is the company that sponsors CircuitPython the development that's the company who's paying the core team that's working on CircuitPython paying some part-time members of the team such as myself to work on CircuitPython as well as do the stream so if you do want to support the CircuitPython project one of the ways you can do that is by purchasing hardware from Adafruit and this is their website Adafruit.com they sell all sorts of the microcontrollers they also sell all the sensors and other components you know LEDs speakers buzzers beepers buttons anything really that you could imagine that you're able to plug into a microcontroller they probably sell on Adafruit so head there again if you want to purchase hardware then that definitely is helping to support the project and all of us who do work on the project do appreciate it when you purchase hardware from Adafruit. If you want to get involved in the development CircuitPython is an open source project so you don't have to work for Adafruit to get involved you can actually if you just go to CircuitPython.org there's a contributing link here and on this page there is a list of open pull requests and open issues and these tend to be the the ways that we get folks started in development in CircuitPython. In particular on the open issues there is a good first issue filter right here which has all the issues that we've identified as being relatively easy or not requiring prior experience necessarily with CircuitPython. So head there again if you want to get involved in the development and the other thing I would say is if you do want to get involved in the development I would encourage you to head over to the Adafruit discord I think it's still linked down below right yeah linked down there at the bottom of the screen adafru.it all of the folks who do work on the project regularly do hang out in that discord and we have discussions and weekly meetings and all kinds of things related to the development so you can get involved by heading there and joining the discussion. So today what I'll be working on is kind of continuing on the the tab layout adventure that we've been on the last couple of deep dive episodes at least last week for sure we did the touch interaction this week I'm going to try to put that tab layout to the test and make some more kind of advanced examples that utilize it so the the first example or I'll say actually the first two examples because we had a touch one and a simple test one that didn't even use the touch those two are very basic they do kind of the most basic thing they throw a couple of labels into the layout and then they just sort of change between the pages and you know that's about it right they're not really reading data from a sensor or from any other type of component they're not live updating data on any of the pages they were just you know very very basic they were showing how to create the tab layout and show it on the display and then that was kind of it they don't really show you how you might use it in a you know an application that actually is fetching live data from something you know be at a sensor or be at the internet or be at whatever and actually updating the display with that information that you're fetching so that's what we're going to work on today starting out with I'll actually show one of the examples that a community member has made Paul over in the discord chat so hug reports again for Paul Paul created this example which we will look at first and then I'll kind of tweak and tinker to fit the hardware that I have here and then depending on how much time that is taken then we may also work on some other examples I have in mind for the for the tab layout ultimately the goal is kind of to try to recreate this interface which is in this pi portal user interface learn guide this one is relatively old I think this was created back around the same time that display is introduced so it does work but there's lots of stuff that has been made easier you know since the time that this was written so I'm trying to you know create kind of a modern version of this thing that shows like a relatively advanced interface like this multiple tabs different controls on each tab different live pieces of information coming from sensors and things on the different tabs so this is kind of our end goal and today will be kind of you know one of the other stepping stones on the on the pathway towards that end goal if you are interested in the tab layout or any of the other development that I've done that has made some of this stuff easier you can check out the the prior streams I've done a lot of work on both the deep dive streams which are Friday afternoons right now but also I stream on Saturday mornings on my own account on twitch and youtube and I do hang out on the same discord chat room when I do that so you can head there to interact when I am streaming on my own channel as well same way and you can see like all the development kind of that has gone into these different widgets and things to make this stuff easier so if you're interested in the history you can check that stuff out to start with what I'm going to do is I think pull up so well I mean first of all we can plug in a device and then I think I'll start with this example which Paul shared and we're going to be making a PR with this I think to get it included in the display layout library right now it's not it is pushed into github but it's not in that main ate a fruit repository yet so we have just a little bit of work I think that I want to try to do on the pilot side of things before we do make that PR but then once that's in we will make a PR in this example we'll get added kind of to the you know the official repository and folks will be able to find it there and in the documentation so I'll plug this in you know here's an example of the layout I think does this one have touch yeah this one does have touch and one thing that's weird about this one is I have this pink block on it I'll go and take that off basically last night I was doing some testing on this and I drew this block to try to get a measurement essentially I drew this block a certain number of pixels tall and I was comparing it to the tabs to try to verify what size the tabs actually were getting shown on the screen so that's what that's about but it is kind of just covering up that first tab there was kind of like just a quick and dirty way to to measure something I kind of do that a fair amount when I'm working on widgets if I want to measure you know how many pixels something is then I'll just draw a shape with a known amount of pixels and then put it next to it and then of course I could just look in and compare see Grover here not yet okay well I guess I shouldn't say not yet I don't know if see Grover will join us if see Grover does join us I have an idea that they may be interested in hopefully because the other thing I did last night was actually calibrate the touchscreen on my PyPortal titano and I used the script that see Grover created for that so first let's just get rid of the the pink box here we don't really need that anymore and this is actually let's see this is actually not Paul's example this is the touch example the base one that got put into their repository before so actually I will you can just leave that we don't even need to remove the pink box because what I'll do is I'll just copy this code over I already have another copy of this anyway and it's in the repo so I can just remove that paste this one in and now our pink box will be gone oh wow got the buzzers hopefully that wasn't too loud the phone just buzzed on the desk here um okay so so right now this one does have a pilot disable all and so that's what I'm going to try to do is actually undo this disable all and then go through and work through the remaining pilot complaints basically instead of doing that directly right on the device I think what I'll do actually is go ahead and open up the repo uh display IO layout which is well that's one of them but not really the one we want do I not have another one it must be in that list I just missed it somewhere okay hold on let's go open recent and just do one of these new window now we can go open actually in the right folder there it is display IO layout and it's tab layout example uh so I think we don't need the changes I have here let me double check what I have yeah yeah we definitely don't want that last night I along with doing some measurements I was chasing what I thought at the time was a bug but it turned out to just be calibration on the touchscreen needed to be done and as part of trying to fix what I thought was a bug I ended up changing the uh the tab layout because I thought it was going to need a change to work as intended but turned out actually not I don't think to need that I mean it may still need something but the uh the specific thing I had in mind was not not the case last night so let's go here I think let's have anything else to commit right okay so we should be able to change branches Adafruit main to start with and yeah I'll check out main let me check out main but then what we'll do is we'll actually make another new branch Adafruit main here we go and I'll pull I don't or fetch maybe is it gonna update for me here because it I think has been updated since I used the last maybe not though looks like we got the latest okay so I think to see all of our pilot errors what I'll do is make a new branch get check out dash B new branch name I'll say Paul advanced tab layout tab layout pilot I don't know I like using pretty specific names even though they're kind of wordy uh the branch we want to go from Adafruit main and then we can do no track this way our remote will not be set to Adafruit main when we go to push we'll be able to specify a different remote and a different branch speaking of remotes what do we actually have for remotes okay foamy guy and Adafruit that should be fine um and then actually I guess one thing is I do need to check is this the touch one or is this not the touch one because there actually are a couple of different ones of these right I think so well first of all we don't have it open yet so over here we do though this one is the touch one let me actually grab the the non-touch one because I think that was the one that is pushed into GitHub already this one is the one we want and one of the really cool things about this example is it has a bunch of um error handling and like reconnection logic for the sensors it's set up for two sensors or I say sensors more generically like just a component that's connected it's actually one RTC real-time clock module and then one um temperature sensor which is actually a more like a real sensor but it's it's cool in that it um it watches for those things to get connected and get disconnected and it handles it gracefully so you can actually just run the program and then connect them up afterwards or disconnect them and reconnect them and the program will notice that they got either plugged in or unplugged and then start grabbing data from them this is in hot plug sensor examples here and we will go back and play with the touch one as well a little while later I think but this one is specifically uh more like the simple test it uses the uh it doesn't use the touchscreen but instead uses the uh just cycling through the pages um using the function like test page layout next page right here time sensor it senses the flow of time that's true that's definitely true uh and I also don't know I do know my RTC is different than the one that's in use so I'll eventually hook up my own hardware to this stuff but we will have to change a little bit of it I have a different uh RTC I have a different temperature sensor so we'll have to tweak some things the good news is that most of the Adafruit drivers are actually pretty well built around the same APIs there's like a style guideline where the drivers are built using these same sort of styles uh you know each time a different type of driver is written for or not a different type of driver but a driver for a different device like all the temperature sensors have a very very similar API all of the RTCs probably have a very very similar API this way we can kind of like swap the initializer function and hopefully we won't have to change too much else uh of the code in order to um to actually have it start working with the new sensor uh so what I will do is I think uh we could just create the same folder in my local one here hotplug sensor examples I'll just make it like this samples hotplug sensor samples and then we'll do this file name I found file oh name of it yep yep I hope this does not have a space at the end of its name no okay doesn't that for a second the way I copied it from the uh web there might make it do that whoops it caps lock let's put that quartz crystal is how it does the sensing interesting yeah some kind of fancy crystal that pulsates when you give it electricity for some reason or pulsates probably not the right word but uh changes its electric conditions basically um so to start with let's we can take that off and then let's just run pre-commit and see where we're at oh we want to run it though run run a okay so we got a little bit of reformat from black and then we got these ones which are there's not too many so paul actually did a really good job knocking out this list there was a much longer list um and most of them are actually handled you can see we're at 9.84 so we're pretty darn close to the uh perfect 10 there what is this line too long that one's fairly easy we're not too i we're long by like a character probably uh but what we can do is just find a good place to break this to the next line function sets page 4 label 2 uh default text and makes empty label 2 so let's just say maybe makes empty and then put those on the next line save that and that should fix the uh line too long i think global ones we'll have to figure out here duplicate key in three dictionaries oh yep we have uh three yeah three and three one of these should be four i think small typo there probably okay what is this one global okay so it doesn't want us to use global um so let's take a look at how the code works a little bit i think the reason why it's trying to use global is because it's ultimately trying to put the sensor into this variable which belongs to kind of the outer scope like um this variable first gets created right here and we want to be able to update it inside the function like update it from inside the function in order for that to actually work we need to access the global variable a couple of these as well what are these ones are these labels or strings okay uh so one thing we could do is we could put this stuff on an object i think and then it wouldn't need to be global anymore another thing we could do is like refactor this function to return the things that it needs and then set them like outside of the function when you call it you get the return and then you set it into the variables that's another possible way to do it uh might you be uh might you use the tablet example to show off yeah yeah that's definitely the plan dfg over in the youtube chat um the the the longer term goal of creating the uh the new version of this one um when we first do it it will not be async i o but that is the ultimate plan is to actually make this project also utilize the newer async i o uh library and functionality from core circuit python so what we'll do is we'll beat it uh we'll build it synchronously first and then uh work on refactoring it and adapting it to actually use asynchronous code um ultimately so that will be that will be the goal i have i have no idea truthfully if it does work with async i o today there might be changes that need to be made in the tab layout um and we'll definitely cross that bridge when we get to it but that is the goal is to ultimately show this relatively complex interface um and show it using the uh the async i o apis um so i'm sure there are other ways probably to solve this as well and i'm thinking that i think i want to go with a basically like a context object where i'm pretty sure if these things are part of another object if they're an attribute on another object then i think we can set them from in here even though the thing is not global um which is a little weird but i think that it does work that way um i think what i'll do is try that first so basically everything that every one of these variables that has a global are basically four of them here five of them the sensor the boolean that represents whether it's currently connected or not and then the three strings here and then on the clock it's again a boolean that tells you whether it's connected or not the actual driver object itself and then else start that one i don't know is that maybe the time uh nope this one is a boolean if i'll start then set it to false or tc connected uh i'm not sure what that one represents all the way just yet get temp so in this one we can uh we could pass in the objects we need because this one i assume is not actually setting any of the variables probably this one would be accessing the temperature from the sensor uh formatting it into the string and then showing it onto the label so it has return value but that's a local variable that one's not global and okay it is setting a few of them here actually so it is setting the boolean it is setting the object these ones are all the label attributes handle date time this one's probably going to be similar um mostly this one's going to be getting the data from the uh from the rts well no i guess it's going to get passed in we're going to have the date passed in here it looks like similar thing here yeah so i will say one thing is i think are we down to just one kind uh it's a flag to indicate the boot time situation i got you okay i think well using global well okay a bunch of these are using global but no assignment which actually means believe this means that they don't need to be global so for instance um it's telling us on which ones it's telling us on all the labels it looks like in fact in in all of these cases they're all the labels uh i bet you then that we actually probably don't need global on any of these global's a weird thing like you it feels like you would need it to access the variable but you actually really only need it if you want to set a new thing back into that variable and even then i think you only need it if you want to set like the entire variable itself if you have just a single attribute like this one here page for label dot text equals a new thing we are putting a new thing into a variable but because that variable is actually an attribute on this object it doesn't require it to be global i'm pretty sure and we're going to try it here in a minute so we don't have to take my word for it that's my understanding as of right now though yeah um so i guess let's just start with those ones because those should actually be pretty easy and then realistically if we needed to we could pilot ignore the the remaining ones it would be best to get those solved as well um but if we are down to a single type then we might be able to get away with just disabling that one uh type of error i mean single type so let's start by trying this basically we just don't need because none of these get set again that's the attribute getting set yeah so i think we could go none of these ones and these ones oops too much on that there we go let me see that i think that gets rid of probably most of them except for like the first two maybe uh not quite not quite we got a couple more than two not by much though and it does get us down to only these ones which are just generally flagging on the fact that we have used the global statement which is not considered best practice necessarily according to pilot this is um and so i think in all the remaining cases though we are actually trying to set the variable like here we're setting it so that one either needs to be global or we will need to refactor it to uh to work differently um oh seconds yep this one's definitely setting it c seconds that one is as well refresh yep that one is being set also and this one yep also is getting set so all of those either have to be global or we have to refactor it uh that one is being set hold temp yep in set there this one only in the exception does it get set but it is still inside the function so it does fall into the same category and this one as well and this one too yep rtc probably in the exception or ah this one me oh nope does get set right there just it right at the beginning there uh and this one as well and that one tmp yep uh strings i think are right yeah they're all set to none here and string values here okay so that is all of the remaining ones are just those globals what i will do first is let's uh grab what we have so far put it back on the device and make sure that i haven't broken anything yet okay so far so good um we'll connect to repel also that's actually pretty good we could do that so we do get um no rtc found maybe we did break something because there were other there were other labels um let's say this let me try running the original one one more time actually not one more time i never did run it this time around uh i ran this one last night but not during the stream here see if i did break it maybe i'm wrong about those labels i was thinking we could get away with no globals on those ones but let's see no okay okay yeah looks looks the same so far so i think it's probably because we don't actually have the sensors connected then we're not seeing anything in the other labels especially because like in the else here it sets him to blank and here as well in the exception this one maybe it's like the old value so if it was blank before it will end up blank again still it looks like okay okay so let's uh let's try to connect some of our own devices so i don't have tmp 111 what i do have here though is a ht 20 actually i have a couple it's a tmp 111 that's a temperature sensor and i actually have these two here um a ht 20 and a si 70 21 those are both temperature sensors as well let me click to connect up one of those and we may end up having to switch to the pi portal standard instead the pi portal titano because i have not soldered the uh the little jumper thing on the back of the titano yet but and i think some stem of things don't like the default i don't know what it is i guess logic level voltage or something there's a little jumper on the back of the pi portals that use solder to change something between five volts and three volts and some stuff needs it to be one and some stuff needs it to be the other and it's uh i find it's more or i find more things that need it the opposite way from what it comes stock so i find i generally do end up having to solder that thing but we'll try it out here age t 20 um to start with let me actually grab well actually let's just connect our let's let's take the take a step back from the tab layout stuff and just get this connected and make sure everything is working fine with that so that we uh don't start questioning like whether or not we actually have that part set up correctly uh i'll go get hub oops oh that got us there anyway let's see we can replace our tc presence um yeah i was thinking that as well our tc present instead of the separate boolean it could also just be checking the the driver object if it's none or not because it all it looks like it always gets set to none um anytime it notices that it's not connected so therefore it could theoretically just check if that thing is none or not i think uh so that would get us away from one of those well a couple of them i guess actually two of them of those global variables they both serve the same purpose just one for the temperature sensor and one for the rtc uh so let's take a look here did we get some temperatures okay no module that makes sense we didn't install it you know what i kind of want to do one of these days it would it's not really a practical project but i think it would be fun is to set the storage to writeable for one thing because you'd have to do that but then make like a true hot plug i2c like program that it will constantly scan the bus and then when a new thing connects it will get its address and then it will have a map of all the addresses to all the drivers and then it will automatically download the driver for the device that got plugged in and then automatically connect it and start reading the data that's a lot of like dynamic stuff it would be kind of hard to make that um but i think that would be kind of a cool just like example of showing um um a circuit python program that actually kind of like is very dynamic it does stuff based on what's plugged in and it grabs the right driver for you because all the drivers are out on github um it could download it with a different requests or something like that i think all right so we are getting temperatures here we're good to go there and so our initialization is pretty similar what i'll do i think is copy this to ht20 simple test we'll go back to the one we started oops editing here it works in main if i replaced rtc present by if rtc is not none nice nice so i'll make that change as well basically this one is instead of using the present see so main is down here a bit instead of using the present these can be rtc if rtc is not none and the else is there uh as well and then this one would be if is this one temp or let's see this one is i tmp yeah that's is not none and then we're going to end up changing tmp as well but maybe what we do is go back here and then for my version what i'll do is uh refactor rename and then i'm going to rename this variable to temp sensor yeah temp sensor since ours is going to be a different one now um excuse me and then pycharm will rename that everywhere that it gets used and so then what we'll do is we'll take this out i'll leave this clock one for now but we'll end up switching that as well and then initialize it well we already have another name for it though oh right uh temp sensor equals and so we want to find the places where it's getting set to things other than none which here is one of them oops already have an equals and that one is none we got our one spot here inside connect temp sensor which makes perfect sense where that would be creating this um yeah and then i think we're probably always doing the ooh okay just like an extra second to save there uh temp sensor dot temperature which we should still have yep and yeah that's the only thing that's accessing something from temp sensor so just like i was talking about before because all the temperature sensor drivers use this temperature property to expose their data this means like we didn't really have to change very much the initializer uh the import that's pretty much it i chose to change the variable name but of course you could name your variables whatever you want so that would have worked even with the old name oops uh let's go here and see what we have oh nice there we go our temperature it was on page four uh we'll let it cycle back through there it is 23.05 i could possibly influence it it's a little uh it's a little warm in my house today 24 10 right there updated the data live so we got one and it looks like that's connecting what does it do does it change so let's unplug it here unplug and then let's see what it says this time back around i think does it change the uh okay just goes back to empty but then we could always just plug it right back in there and it may take it one extra cycle to catch up because i did it like right before it was about to turn i'm guessing see what we get here yep temperatures right back so look at that that's amazing uh that we can kind of just like put the circuit together as the program is running and the program like it never freaks out it has air handling in all the right spots um it has reconnection logic in all the right spots so we can just plug and unplug this thing and we continue to get live data when it's plugged in and the program doesn't crash or do anything bad when it's unplugged uh so again this is awesome thank you to paul who created this um this hot plug example based off the tab layout example um i think that this concept of of all this error checking and this live like reconnecting logic um i think lots of people will probably find this pretty pretty helpful in different projects so i'm pretty excited to get this example out there and shared and we do uh it seems that we didn't really break anything right with those labels that we removed so we can i think go back and well actually let's try to connect the uh let's try to connect the rtc now the rtc i have is different um and i'm not sure it's gonna work i don't know for sure that i've ever used it oh you know what uh i do not know which colors are which is blue sda or scl so mine is a ds 1307 this one i believe this is actually an older package ah it doesn't have any of the uh newer style yellow green uh yellow blue red black stemma cable looking um these are different guides all right this one actually goes through the breakout well we may we may just try it out or you know what we could do is look at a different thing maybe we let's look at um uh a lot from colorado i never remember the colors and guess yeah we might uh i might just guess i'm gonna let's try one other thing i'm going to search aht 20 this is the one we already have plugged in and this will probably have um fiatta yeah i have trouble remembering the colors as well so i will say yeah adafrit's pretty standard i think as far as the yellow and blue go because a lot of what i use these days are the stemma cables uh which is what i have here is one of the uh it's stemma on one end and then it's broken out on the other end i also have this one here which is like big stemma on one end and then small stemma on the other end i don't know if big stemma is the right term i'm probably butchering that i'm sure there's an actual specification for it um but even though i typically use those a lot i still don't quite i don't quite have it memorized but i do know that these pages some of these pages like this one here this will show us um i believe they do these the same color so scl it has as yellow here uh so i believe scl then is yellow in the stebas as well it's an older code but it checks out we're gonna go and one of the cool oops let me switch to the camera one of the cool things about the all these little stemma breakouts is these are uh chainable right this has one plug on one side another plug on the other side so we can now plug this one here and then wire up these things so i'll go ground and right there five volts is next to that i'm going to do five volts last yellow actually i don't know if we're gonna get five volts or three volts i guess we're gonna see yellow uh was scl we said right here it was a little tough to push in sda is right next to that so that's gonna be blue and then five volts is the last one which will be red offset that one by one row here to make it a little easier okay and uh doesn't look like there is any sort of uh power indicator led on this thing so we don't necessarily know if it woke up uh but what we'll do is start trying some code on it uh which actually i think this didn't say circuit python did it we need to it's maybe time to re-up this guide yeah because this one doesn't have circuit python but i do think there is circuit python github that d yet was it ds 1307 is that right 1307 yeah an example is here simple test nice and easy so actually let's go back to here uh i'll take my updated code here and put it in my edited file like this save that and then i'll put the rtc simple test here i like whenever i'm like connecting a new thing to a more complex program or complex circuit i always like to take the the simple test of each thing and like make sure that it actually is connected and is working how it's intended and then kind of like intermix it in with the larger more complex thing this way if there is a problem with my wiring or with the driver or with anything related to this sensor we'll know about it before we have a bunch of our code intermixed with that larger more complex program forced moon okay so let's see we'll probably get a failure for not having the driver makes sense we can install that no problem circuit to the rescue right there okay and there we go we got time uh it's not not the real time but it is time and the reason it's not the real time is just because it's actually to be honest with you it might be pretty darn close to the real time maybe this is like uh i'm gonna say european but really what i mean is just months before i mean days before months is that right no yes well is this what's actually printing yeah yeah day month year which feels backwards to me but this is how a lot of people write it is day first and then month and then year and so this is actually saying the 12th of may 2022 and then the time it has a 1635 which was yesterday uh 1635 is off by a bit i'm surprised it knows briefly though why does it know i mean did we just get lucky because my thought was it doesn't the rtc by itself keeps time but the rtc by itself doesn't know the time you have to set the time to it and then it can keep counting from there so from that point on it knows the time but before you set it it shouldn't know the time i thought so i'm actually fairly confused and kind of impressed that it's anywhere near as close as it is how's it going um let's see harry shuresh uh hopefully i didn't mess up your name too much if so i apologize i have no idea what you're doing but that's cool uh yeah if you would like a quick high level um intro i can there's one back at the beginning of the video if you want to catch it but also i can uh i'm happy to give you the sort of 50 000 foot view again real quick here if you want uh is set in line t so here well okay so what's false though oh i see if okay okay so that this is basically just like a boolean you can switch so yeah so it's not going to go here instead it's going to go here it's going to get t from the rtc format it uh sleep for a second i don't know maybe as part of the initializer in here does it uh first we can't look in that code um i mean we can but not in our editor right there it's uh npy files on the device but when you initialize this does it like uh not doesn't really do any like like ntp or anything like that maybe we just got lucky uh can you tell me how this works um well i can't tell you how this little thing knows the time that part i'm perplexed by but i can tell you like if you mean higher level uh like i was mentioning a minute ago just like generally what we're doing and how it works we are writing circuit python code uh so this is the circuit python project circuit python dot org you can head there to learn more basically how this works is these microcontrollers like this device right here is a circuit python device and when i plug it into my computer it shows up as a thumb drive this is how thumb drives show up when i plug them into my computer they come to this um you know uh file manager thing here and they would just show up as a new drive a new line here so there's a you know a thumb drive an external storage connected that's called circuit pi on that device there's a python code file called codepi that's the file that we are editing inside a pie charm right here and as soon as we edit that file and save it it will actually go ahead and run the latest version um so if i did something like print uh hello harry uh welcome welcome to deep dive and if i i'll open the terminal so we can actually see it when it prints leave that open and all i have to do is save the file i'm just going to press control s to save this file it's going to automatically notice that it changed and it's going to rerun and then right there is our new code uh hello harry and welcome to deep dive so this is how we are editing the code on the device it's nice and easy compared to lots of microcontrollers um like a pico if you mean raspberry pi pico uh it is similar to that the raspberry pi pico is one of the microcontrollers that circuit python supports uh in fact at this time it is the one with the most downloads recently of circuit python so there's definitely lots of raspberry pi pico's out there ours uh this one here is pi portal titano so it is a different device it's a samd 51 is the main uh microcontroller and then there's a esp 32 over here that it uh kind of talks back and forth over the uh spi bus um set up the factory but it hasn't had a battery in it until today that's the weird part is i've had this for probably at least a year and it i i just put a battery in it today so it shouldn't have been able to keep it i don't think but it also doesn't matter too much why it knows we can just say that's cool and be happy about it and uh and move on it is is very interesting to me that it managed to know yeah because i just put the battery in probably like an hour before i started streaming default but this one paul that's in your script is it i think though right this one is just the simple test for for this thing is that right or is that because this one this script here is yours line 23 yeah this one here maybe this did this get set i bet you yeah okay okay yeah yeah this probably got set into the device time because the the main chip also keeps track of time so when we ran this this ended up updating the time of our device so that it could actually know the real time that right let's see where it would have happened but i'm thinking that that must be what it what actually happened maybe even when you call what is this constructor up here maybe even when you call this is it set it into the system yeah i think you're probably right actually because that is the 12th and uh 1834 would have been that was pretty much the earliest one it had it's been running for about eight minutes now so we're up to excuse me 1842 but yeah this must be where it came from actually yeah so it is somehow when i ran yours it it saved it in there and so now this one has it so that does make sense so how are we so here we're accessing it with t equals rtc dot date time is that the same thing that happens in here well and also let's go ahead and take this out for now and swap it for this one once you ran it it sets the time yeah i think so i think so okay i get it now nice uh and you got this from adafruit i did yeah so the pi portal here this is an adafruit device this one actually happens to be also an adafruit device so is the one that's connected here uh the raspberry pi pico of course is not an adafruit device although they do resell them um so i think you can buy a pico on the website adafruit dot com generally but it's obviously was you know produced by the raspberry company or i don't know what their official designation is but so now we can find where the old one of these was set up and instead of this we can just swap in this one uh i'll undo the comment as well because the um i'm guessing probably the itc address is different i don't actually know we'd have to go look in the code for this one um but my guess is that it is different this does call rtc date time equals and then that date time equals something else so we set things into date time and then i think also later we will read stuff out of date time yep right uh nope nope nope that's setting into it this one here is reading out of it and putting into there uh and date time it looks like is the same api here so same thing i was talking about earlier where the different drivers use the same api therefore like it's very very easy for us to switch between them um because when i introduced the i start flag i got you to only set rtc once i just wanted to say this rtc discussion is really helpful for the project i'm working on great stuff that's awesome yeah thanks for uh thanks for watching along and thank you for mentioning that struts i appreciate uh appreciate that always always nice to like um you know hear folks that are interested in what we're working on what we're talking about all that sort of stuff so thank you not only for watching along but for mentioning that so we'll erase this for now let's go back to here put this one in code and i think it's probably just ready to run right i don't think i changed anything else that needs too much action so we got our bus numbers there creating tab now one thing is i don't know exactly which page the rtc does get shown on so we'll wait and watch this cycle through a couple of times we did get found and connected there so we should be good to go so page four has our temperature looks like page three is going to have our time yep right there date time and again it did end up resetting it back to that 1834 which was the time it started and you can have it fetch the time from the internet it's not doing that right now but it does this is one of the cool things about the pie pie portals is it does have that ESP 32 which is actually going to allow it to fetch stuff from the internet including like time from an NTP server and then it could set itself based off of that but it is continuing to tick that one was on 48 seconds i think let's let it cycle through again and make sure it's on something more than 48 34 47 34 56 maybe it was 38 the the previous time 34 56 so now we'll be on 35 something 3504 yeah definitely still counting so now our temperature and our time is live updating on the different pages as we cycle through them uh let's see here the need for setting external rtc was well yeah i was talking about yesterday the idea i came up with was initialize the external rtc from an external file gotcha number four excuse me in r3 uh you have network you can just hit your router and set the time oh okay it doesn't need to go to the internet necessarily it could ask the router for the time that's a good point yeah okay so we got this functional we have not broken it um by updating you know the two drivers or by removing those global variables that we did take out before so everything does still work um i assume it will still work with the original sensors as well of course i don't actually have them so i can't test it so maybe once we get done with this we'll send it back over to paul and he can check it on the uh the original hardware with the circuit that he built that has these devices um i will see what we can do to knock out the last of these so we're down to just only having the global statement is our only pilot failures right now and we have five of them because there's five of these functions well so rtc present actually we do know this one we figured out that we can do we can do um if rtc is not none i want to change this here yeah i think so so we did figure out this one but it well and this does let's see here so if it's not none it tries to set it but then if we got the exception it does end up setting it to none which we would ultimately need to set the rtc to none which we would actually need the global for there's the error and we could actually uh hot plug that rtc as well actually so if we go back to our terminal here the camera um i can unplug the uh unplug the rtc as well from this side and then it notices it right there probably disconnected so then it will just be blank on page three or the oops the default third third page is fun and we can just live plug it right back in as well there and then it will notice it i i think within the first or second cycle back through here let's put that back to uh actually maybe i didn't or does it only do maybe it only does hot plug on the uh temp sensor where did i jostle something loose here too maybe only does hot plug on the temp sensor let's take a look this is what part of the beauty is actually it should be pretty straightforward to find right so we do have a connect temp sensor we have a connect rtc word is this get called okay this is inside main right before loop number maybe rtc is not none i'm going to try that also the rtc okay maybe the way we change the boolean yeah i think maybe the way that we changed it to use uh like where we change this one to be is not none instead of the boolean changes the logic just a little bit because so if it's not none it goes to here but i'm thinking maybe that it is not none but it's also not the driver anymore or if it is the driver it can't access the data have it print this also i see change it up in here as well so we got our first one plug this right to at least here we go okay noticed it there and then i think the next time through will blank back out the three or go back to the default not quite actually it does keep this then will it show it here there it is yeah 34 47 34 55 yeah okay so we just yeah we did we needed to just change it here as well and then it's back to being hot plugable um in which case actually we can just take this one out all together and this one as well i think it will blank the labels we are connected now let me go back to this one or let me go back to this one as well okay i did make that change here that gets one of our globals taken care of before now so i think we can get by without this one anymore because instead we're going to do that tmp 117 is not none we'll still need to refector those ones or ignore i using a pilot ignore on a single thing like the global statements is the only thing we need to ignore that i think is a little bit more okay than the the wholesale disable for the whole file of every single check so even if we did do an ignore on the one global i think that that is probably okay there have been projects where i've done that as well rtc present okay so i think that we could still refactor this to not use globals at all i think what i want to do though for now is actually just pilot ignore the global statement check specifically and again doing that on one check i think is is better than the disable all and the reason why is because i don't actually know quote unquote the best way to refactor it what i want to do i think is put this back in whoops uh put this back in to make pilot happy for now and then what i'm gonna do is actually just start experimenting on kind of building a different one of these examples and in that one i'll play with a couple of different ideas for how to store data in such a way that different parts of the program can access it and then once i kind of get my head wrapped around which ones lead to good code and which ones don't then i'll maybe come back and i could suggest changes to make here um to update this one to work that way um i can never remember the uh the exact right syntax for this well i found a lot of disables colon pilot colon disable equals so it's statement statements oops statement but i haven't saved it yeah the class the class is one of the ways i was thinking of doing it either create a class that holds those values for you uh kind of like how it does in the async io guide speaking of async io from earlier this guide here it creates a or what it calls it um creates like a data this thing creates a class that holds a data value for you and then it's able to access the attributes of that class from multiple places without using the global keyword so that's one way to refactor it i think you could use a dictionary as well if you didn't want to have a class with like specific attributes um there's possibly other ways to do it as well that's kind of why i want to play with a couple of different ways to see which one i start see which one i start liking the best um and i'd rather not like i could give you my you know my first guess and it sounds like actually you maybe have done my first guess as well but i don't want to try to i don't want to send you down the road a road and then later on be like oh actually i i tried some more and i decided that this other way i think is better um put back here and we did get a clean pilot run this time around i think right yeah okay save that what i'll do is push this for now okay so here is the updated version of this with the changes i made if you have a chance paul try running this on your device with your sensors and everything just let me know if i broke anything it's possible maybe i didn't update some part of it that needed or i did update some part that didn't need it because this one is i was editing this in the repo rather than on the device so i have not actually run this one but if it if it doesn't run for you let me know and i can work through and fix anything if i did i did break it inside the class i use dictionary i have to search for the files um okay so that one's there so now i think i want to start another new tab layout example that will start looking more like this one so we're going to go portrait for one thing and we're going to have different stuff inside of these and we're also going to have some buttons inside some of them picture and picture so i don't remember what all the buttons do we could run this project okay and i i think you folks can't hear this so sorry you're watching me stare at the screen and listen to this person talk but running fallacy awesome so let's start with this let's make a portrait one let's make three tabs let's just start adding the stuff to kind of make it similar to this project i'll update that there we'll start fresh and we'll pull some stuff but not everything from we'll start kind of from this touch one we're not going to use shapes we will use label we will use touchscreen yeah we'll use all of this stuff copy the header as well we'll need tab layout we'll set the display the same way oh okay this twice we're going to go rotation 90 these will need to change some or actually i think it's these that need to change one of these has orientations yeah 90 okay calibration stays but the order of these pins changes make a main group i'll show it on display i'll make a font i will make a tab layout i'll make groups for each of the pages we're actually gonna only have three pages the rest of that can stay the same i'm ultimately i'm gonna make some new tab graphics as well we've been using this green and gray one that i had showing before here for a little while but one of the cool things about this tab layout widget is you can actually change the sprites very easily so you can have tabs that look like whatever you want um so i think i'll make some uh some other fancy tabs for this example once we so we get the functionality there um i'll make a little bit of content for each page let's start with just a label for each page and then we can always add more as we go i'll go without shapes for now we'll just add each label to its page add the pages to the tab layout should have enough room i think to use the full word here maybe we want to add that to our main group definitely we don't need to worry about this this was basically just showing that you can add new content to the pages after you've already created the the uh the tab layout and after you've already created the pages as well so this should give us the basic portrait tab layout with the touch functionality and indeed it does yeah i'll go this way um my style let's go and in fact we should yeah we can touch as well we got our three pages um they don't quite take up the full amount so you see there's little spaces in there the tab layout tries to use the available space as best as it can but there is there are limitations based on the size of your sprite um how big the tabs can actually be inflated is what it's called um and so the essentially what it boils down to is you have to inflate your tile grid which is what these ultimately are they're tile grids you have to inflate your tile grid to a size that is equally divisible by the tile size in your original sprite uh so my original sprites there's 60 by 48 i want to say yeah 60 pixels by 48 pixels that means that the tile size is one third of that so uh the tile size x is 20 pixels the tile size y is um was that 16 yeah 16 the 20 by 16 that's our tile size that means the total size that we want to inflate to has to be divisible by 20 in the x orientation and 16 in the y orientation and it turns out that the actual screen width which is now in portrait mode here so it's the small side of the screen does not divide evenly by that so that's why we ended up with the extra little spaces in there the good news is like we don't have to care about any of that math all of that stuff gets handled by the tab layout and the tile grid inflator um so that's one of the things that I think makes this a lot easier to code um and to update the code for because if we look in the code here you know it's doing all the same math it's just a lot of it in this example exists at the user code layer like um let's see here there's gonna be a lot of stuff that's like dividing the screen width basically yeah there's tabs height than width here and then whenever it goes and actually creates the tabs I miss it the tab button is called are they button one button two there's button view two ah okay tabs width that's probably a typo that's probably supposed to be tabs width I would think maybe not though I don't know these say tabs ah yeah here we go so this one is dividing the screen by three here um there's a couple other spots here as well where it's dividing the screen size out to figure out some different sizes for stuff one of the nice things about the tab layout widget here is it will equally divide your screen up based on the number of tabs you gave it so we just told it when we created it boom we want to have three tabs it takes care of all the rest of that stuff without us worrying about actually dividing out the screen size and all that stuff so um this is pretty nice uh so our basic structure is there that's all it requires so you know it's not nothing 90 code 90 lines of code a fair amount of white space sprinkled in but um you know not nothing but not quite as much and just easier you don't actually get a uh numbers in these things so I don't know how long that one is we could download it maybe and see of course we're not done yet either right there's still lots of functionality that exists inside this thing that we haven't created yet so um not really comparing right now anyway let's try to add the next couple of things so what all is on the first page here um full code let's close a couple of these this yeah we don't need that anymore so page one has text with the text box that says a size I think that's all what I'll do is uh play this and then I'll pause it next on this screen is wrapped so that all of it fits nicely into a box that is a certain amount of size and we have our two big buttons on the bottom and so the way this works is the tab layout actually is like the top you know two thirds or or three quarters or something I don't know the exact way it breaks down but it's this portion up here is the tab layout uh or or is what will be the tab layout when we recreate this using the tab layout of course this one was created long ago before tab layout existed so it's just using buttons and groups uh and things but our tab layout will be this part this portion up here I wish I could close this anybody know if you can close this there we go um that'll be our tab layout we'll have two buttons down here and I think I'll use sprite buttons uh which is also a newer thing that I created relatively recently I will get the background uh let's go here go and download this uh good night Nishipu uh remark on the script you updated asked me to run Cosmain and elsewhere all flags for RTC oh ah gotcha yeah yeah I may have forgotten a couple of them all the flags for RTC and temperature sensor were replaced by the if not none gotcha yeah I probably forgot a uh a spot or two or a couple of them there I think you see like how how it can get replaced though at this point right um let's grab our image just we'll grab all of these I suppose uh we don't need loading actually I'm not gonna do a loading I mean I guess we could add it eventually but I think this one is doing loading by having the pipe portal yeah I'm gonna also try to avoid using the pipe portal library as well uh I'm gonna try to do things you know quote unquote manually without the pipe portal library that way you could also adapt this program to other devices fairly uh more easily at least because it won't be trying to use the pipe portal library uh pipe portal library is great if you are using the pipe portal um but it's not necessary to do the stuff that this project does and if you want to run this on another kind of device then you might have to like replace those bits of the code so um we do actually already have all of those things so let's put our background in which is bg image I think the way I will do this is well actually the bg image is set for the pipe portal not the pipe portal titano maybe what we could do is just scoot it on the titano put it in a different spot we don't have any I mean we can scale it double but double is too big we could scale it up in GIMP but it will get a little bit fuzzy let's start by just drawing it and see how it looks so we basically want to add a bitmap to our background the easiest way is we can just use on disk bitmap um pull up the learn guide for that uh did I say good night to shippu I don't remember for sure good night thanks for hanging out um really not the one this is the one I wanted this time there's on disk bitmap this one and we should update these actually because these it still has the uh circuit python six and then the new circuit python seven way still has both of them we could actually get by with just the circuit python seven way at this point I think we're getting close to seven dot three oh beta or beta's already out we're getting close to seven three oh release I think so we can just put this on main group and I guess what we really would need is uh we want to put it at the beginning I'm going to call this bg tile grid and then this bg so here actually I think as well I think this will draw it behind the stuff oh oh I need uh images images just center the background yeah that'll I think that'll be what I start with so for the first one it's going to be in the top left doesn't look the best but it's not too bad but yeah I think we can just go x equals we're going to go play dot width over two minus bitmap that width over two same thing for y but this will be height and this will be height oh what is that white stuff it oh the text oh that is interesting did you see how it put those pixels from the label but like before it really rendered the rest of the label do you see that did I see that am I seeing things okay must also maybe have something to do with the fact that it was there before because when it restarts from repel it doesn't doesn't do that you know that actually maybe we should put this not centered y maybe we should put this still just at the top in the y since we are going to have our two buttons down here and our text is on top of Blinka there but I think it is in this one too yeah yeah totally is so I think that's okay we'll uh we'll make this a larger paragraph or it's I think it's a sentence or two and that one we'll make it be the same stuff um and then our buttons we have room for them down here does it actually say the text on this screen this is calling all of it fits nicely into a text box that is how do those get filled in it puts numbers in yeah so it's using pi portal for wrap nicely but we have access to that through display text now interesting I wonder why I wonder why it does this twice is this calls text box with this label with this I guess probably y value and the string with these placeholders and then right afterwards it calls it with all the same arguments but then this time it's going to fill these in I think I know so it it it doesn't know the size until after it does this once and so it's trying to print the size of the label but because it's wrapping it the size of the label doesn't get set until after it does its wrapping and so it's wrapping this one then it's looking up the size of the label in order to actually put it into the label I think what I'll do I'm pretty sure we have a wrap by pixels instead of wrap by characters which this one is wrapping at 30 characters I think I think we have a wrap by pixels so we could we could just put the pixels in before we call wrap I guess we won't know the height yeah we won't know the height what I'll start with is just put the width only and then if we want to we could come back and do the height later I think I'll just make a page one text okay well we'll put it on two lines then um so to start with it'll run all the way off probably yeah so what we'll do instead is get display text how does display text uh wrapping work okay it just has it has to it has wrap to wrap to pixels and then also wrap to um characters okay new line dot join and then we call wrap wrap is gonna return the a list with all of the lines in it let's do play with minus 20 because that'll give us 10 pixels of margin on the left and 10 pixels of margin on the right it should maybe a little bit more on the right because it won't wrap to the exact amount of pixels it depends what characters are there well it should just be terminal iofont yeah which it is next on the screen is 320 but it's 320 by 40 no no no 320 by 480 on a repo where it makes use of a class my vars nice cool yeah i'll check that out um afterwards what uh next width actual number of pixels on a line before wrapping but what do we actually get for the list also what is the uh label width does that come out to 294 so that sounds correct something is definitely odd though be do we have scale to scale to that's our problem yeah yeah yeah so we actually need to wrap to uh one half of the size that we are currently wrapping we're wrapping currently to 300 which is our display width 320 minus 20 to 300 uh but because we're doing scale two on the label that means that we actually need it to fit within 150 pixels because everything is multiplied by two everything is scaled up by two so we actually just need this over two and i'll do the same thing on this one in here and that should actually give us like either three or four lines and that should make our width less than 150 yeah 144 which means after we then scale it by two it does actually fit onto the display like so okay uh and then we can still fill in actually you know what we can do after we set it the first time we could just say page one label dot text equals page one label dot text dot format because we can still call format on it i think uh and it already still has the curly brackets so we can just go uh page one width page one height page one label not the page itself yeah there's our size now you know it does the scaling factors in so there's a case to be made like do we want to multiply these by two since we're actually scaling and therefore in in double the the amount right um probably doesn't matter too much one way or the other we can always just give it here this multiply by the scale gps datagram datagram i think is the word i was trying to think of earlier that's what the async uh learn guide i think calls it yeah yeah so this one it creates a class it keeps a list of strings and then you can update the strings you can read particular ones out of it and then you can clean which it looks like is setting it back to empty yeah something like this would work this would if we refactored it to use something like this then it would definitely get rid of the globals i'm pretty sure this one should work the same just the one difference is the scaling here so it tells us 288 and 178 is the size of the text box there um and then the background will stay there on every tab touches aren't quite uh maybe i wasn't pressing hard enough or just not in the right spot i don't know i wonder if our calibration does need to be modified actually also like such a weird angle i don't even know if i'm touching the right spot truthfully because it's like so i have it like leaning away from me so that the glare from the camera doesn't come back into the camera so i'm like it's kind of like angled down and away from me it's tough to see where i'm actually pressing let's make the buttons at the bottom for the uh neopixels yeah well one of them changes the color of the neopixel and one of them turns it on and off and this one is just using button which we could definitely use button i want to make it a little fancier i think though i'm gonna go with uh sprite button and one question will be is the size how big do we want to make it why is it so slow to change the page uh just because like internally it has to redraw the the bitmap that represents the screen it just depends on what how much stuff you have showing on the page and then like the display like that speed that you see there that's basically just the speed that the display updates and the larger your display the longer that takes to right so like if i switched over to the regular pi portal so the pi portal titano that will actually move quicker because it's fewer pixels um the other thing is like maybe there is yeah like this one didn't have to change as much so it kind of can go can go faster but then the one that does have the larger label does take it a little bit longer and i think that's just the that's like a limitation of circuit python honestly i don't think there's anything at the user code or the library level we could do to make that faster now internally inside display oh maybe there is some efficiency gains like i don't know if it's like i don't know maybe it's redrawing every pixel even the ones that haven't changed possibly there could be a a chance to um not do that as much only try to like try to only update the pixels that have changed maybe something like that could speed it up i think that's the reason though is i think that's just the that's the refresh rate that's as fast as the uh this particular microcontroller can send data to this particular screen and this particular screen can push it to the actual pixels um so one thing yeah sprite button we put labels on sprite button i think did we oh we could uh make this out of draft actually is the core one is in now and also the tau grid inflator is also in yeah an image load is where that ended up so i think our screen is 320 by 480 so if we wanted our buttons in this example they take up basically half of the screen so they would be 160 go farther than that let's try like that and then rounded make rounded buttons and i think let's go like a lightish gray for the outside then bring it in some and what do we want to do on the inside uh actually make it a little bit wider of a gradient there i like that that makes kind of the weird in between color kind of big actually i do actually like it better smaller yeah let's do it like that let's go deselect which is uh control alt a don't control shift deselect none shift control a select one thing is we actually got transparency on the outside which we don't really want we want the outside to be sharp that actually did change it to sharp okay uh let's go color map let's make sure pink is first wait and it is i think that's a big color map right there export this i already have i already have that fancy button one it is then maybe i should put 160 by 160 also in the name that an example i didn't add an example have an example though and i'll i'll load both of these i think i'm gonna uh for now just set them to the same one fancy oh no did i save it as a png we don't need png fancy button zero we'll set them both to the same for now eventually i'll come back and change change it so that it can be like uh oh this is uh this is not sprite button though yeah this one was just tile grids here we go yeah that's what we want go x0 we'll go y display height minus 160 i don't know why sometimes it wants to like import this longer chain width and height uh couldn't leave those off let's find out uh it does not use the uh this one just uses the paths maybe that's how we should do it though transparency index is gonna stay zero because that's where our pink is at um zero that does i well we don't need to use actually let's turn those off missing width so we do need width uh i guess we'll go 160 or is this in tiles i need to close that because that's actually tile grid button width no that looks like pixels i multiplied it by tiles i think it's pixels though that's not what we expected oh that's a different button yeah yeah we did fancy button one that's an even fancier button although it looked kind of messed up because it was supposed to be around how it must is it not i wouldn't know what's the size of the label i mean of the uh fit map 160 uh 160 doesn't divide by three that's actually our problem i think um hmm it's 59 let's say 76 yeah it should should it or yeah maybe let's do that so i believe this does want your sprite to be divisible by three because of the way the inflator works in this case we're not actually going to be inflating it to a larger size it's going to stay the real size that it is maybe we should make an exception in the uh sprite button that will make it allow that okay there we go so the the gradient looks a little weird especially through the camera at this angle i will say um it looks a little bit better to the naked eye but it is i mean you can still see the the diagonal defined in there pretty well but i will say the camera is honestly making it look a lot weirder a lot worse it's also kind of blinky in there with the refresh rate which doesn't i don't see that at all in person that's interesting let's do a scale up on the uh text i think we can just do label scale or something or oh we don't have label scale actually both that label i guess we could always just go self like button dot label dot scale let's call this the on off button oh right no we can't do that because label it uh it's like a string when you set it or i mean when you access it i think it doesn't um i think it converts when you set it to what this is wife's text to me here okay nice okay cool yeah i'll check out all the uh updated stuff out after the stream dropbox there i've set it back as well we can close this okay um i think this has like yeah label so label it returns the text actually have a way easily to scale it i mean you could give it a different font would work i guess this one not have a scale on it full font color yeah like we could uh you know use a bigger font that would just look bigger instead of scaling it that would work be nice if we could just scale the label too though i mean we can we we could probably do this even though it's not like not supposed to air quotes underscore does look a lot better though try four let's try four well it does it's getting off center four looks pretty good it's getting off center for ad folk like myself the long intro makes it almost impossible to get into the meat of the session the long intro do the video you mean patrick on uh on youtube there i do i mean i like to give the intro every time just because there can be new folks like who don't know at all what we are talking about i try to keep it brief because there are like i think the majority of people watching are um very likely like know what we're dealing with know what's going on probably have watched before but i do want to make sure like if we do have new folks which like people do reach out to me after after the different streams i've had folks reach out and be like you know this was the first time i watched anything like this so i do want to make sure that we at least give them a little bit of grounding in like what we're actually working on before we jump straight in i do sometimes do streams on other days of the week though where i will just like not do nearly as much of an intro or an explanation and just jump straight in and start working um so i would encourage you if that's the kind of thing you want like uh just more like get right to work and not do as much of the interactions and introduction you could um follow me on twitch or watch the live chat live chat channel on the discord and i'll post in there when i do streams sometimes as well so i can maybe find one of those other ones which is where the uh the format's a little bit different and it's not quite as uh interactive and i tend to just jump in much quicker i think it would be super nice if we could just go label scale like this we can't currently but i think it would be nice if we could um i'm probably gonna be heading out also before too much longer i'm not sure also what you mean for ad folk add folk i'm not sure what that means oh add probably not ad maybe i do know what that means just had to actually say it out so this is kind of off the off the beaten path a bit right because this doesn't actually exist and i'm just kind of adding it real fast like this but that will make it work might actually make it center correctly still too but maybe not i'm not sure about that last part no yeah it's not it is still messed up yeah this is why right here this is not accounting for the uh the scale hold on though because width and height here actually are the pixels okay this is some kind of logic that's uh if it's too wide it's trying to like remove characters until it fits actually no though would it be self width friend self width so does this value look like pixels or tiles pixels 160 okay so dims two actually this i think is what needs to be multiplied by level scale then i think this will put it centered check also i got another message from a wife okay so it is centered horizontally now which is nicer i do notice it's not actually centered vertically but that's just because uh y value here actually that should be half height maybe it is centered vertically it doesn't look like it to my eye also the diagonal diagonal might make it uh brick of the eye kind of make it a um which what do they call that um kind of blank optical illusion that's what i'm that's what i'm after i think it's not though honestly i think it's farther down i maybe the half height does not take into account the scale either that could be that could very well be i don't actually know for certain that's what that's what it feels like to me though and so right now we don't i guess we should default the text to off but also we don't have any touch logic on this either it has contains i recall correctly that has a contains we got our button presses there and so we could have it change to to show you that it's been pressed and then of course we would switch the label to on we'd have it turn on the light and then our other button over here will be for changing the color of it'll be the neopixel on the back um i think i'm gonna wrap it up for here though oh how's it going johnny uh thanks for joining us i i do think i'm gonna head out here pretty quick though um i will be back tomorrow morning so um saturday mornings at 10 am central time that's when i do my other weekly stream so um i mentioned at the beginning i'm taking over this one deep dive for scott for a while um but even prior to that i have been doing my saturday morning streams i don't have a good name for it really um maybe i'll just call it deep dive with tim on saturday or just call it deep dive also or something i don't know we'll maybe we'll think of a good name one of these days but saturday morning at 10 am central time that's that was my normal uh stream schedule before i started doing the deep dives and i am keeping up with that as well so i'll be back then tomorrow morning at 10 am and i'll probably be working more on this i don't know for certain i might uh i might get inspiration to work on something else in the meantime or early around in the morning so we'll see um but probably i think as of right now this i'll probably just pick up where we left off here so if you're interested in kind of watching the the progression of this project um you know creating the other button and then obviously creating the content for the other pages um then come hang out tomorrow i'll drop the links in that live broadcast chat room which is where the same chat we have showing on the screen right down below me there so um if you head to that room i'll you can always find the links when i do start streaming uh yeah thank you foamy guy dfg uh you're welcome for sure thanks for watching uh thank you to everybody else who's watching uh dexter paul definitely huge thanks to paul for the example that we were working on earlier uh johnny who else was around to shippu left a little while ago i think um also we see today i think we saw a couple other folks tammy strudz again thank you for your uh for watching and for your nice comment harry thanks for hanging out uh did we have l smart gambler thanks love the factory how's it going from colorado i don't remember i think i said hi but maybe not if so i apologize uh tammy and liz we're here at the beginning yeah i think that's who we got all the way there on discord biata dfg uh harry that's who we got patrick as well over on youtube so thank you to everybody who's watching again i'll be back tomorrow morning 10 am central um i don't know for sure about next week deep dive i still need to work with scott we might do a joint one or he might do one or something so uh possibly next week deep dive will involve scott but don't quote me right because i don't know for sure i still need to talk to him so maybe it's still me next week maybe it's a joint one um something you know there will be a deep dive one way or another uh but we just don't know exactly what it will be just yet so tune in next week for that and yeah i'll see you all next time tomorrow morning if you want to catch that stream