 All right, I forgot to auto start on YouTube, but I think we should be live now or about live now So I'll say what I said before I forgot to turn on YouTube Check the description for time codes if you want to skip around usually Usually I'll take a couple minutes to get going here and then Yeah, just we won't get started immediately and the stream tends to be long so check the time codes But Vin is in the picture and she doesn't necessarily like Me talking so she's like wondering what I'm doing. I May have to let her out. We'll see Not every day Vin's in the on the stream with us We'll see how long she lasts So let me say some hello's I even check my time my List and I forgot to do that. Yeah, we'll take a look. We'll take some time to hear to say hello's and Get things going Hello Thomas hello mark. Hello Jed top-notch cat footage. That's what we strive for here at Adafruit top-notch engineering cat footage Hello, Beata double the cats You can see she's deciding whether she's gonna stay or not She wanted to be on my lap and I ignored her so she went to go sleep with her brother instead Hello, Ham's labs Hello, Tammy. Hello, foamy guy. Hello, Annick data. Hello, Keith Hello, DCD. Hello Patrick. Hello to Shippu. Should I just do two hours of cats? Hello, Adeeb Hello X micron hello two two three one puppy. Hello Andrew R from Cornwall Hey, Paul Thanks everybody for joining It's these two cats woke us up last night fighting You wouldn't know they would fight But they do as well They sleep together and they fight as well Yeah, so I'm a little tired, but that's gonna be my MO this year. I think because if you don't know we're expecting a human being in this family that will keep us up at all times of night, so These cats are in for something. We're all in for something Abadus say that right Abadus maybe all right Yes, please two cars two hours of cats equals a happy forever Well, we'll see how long we have two cats. She's keeps looking at me All right, let's do housekeeping. Let's get the show on the road. I'm yeah, like I said, I'm a little tired I've been trying to get myself into Focus mode so we might actually dive into some code here today, which I'm looking forward to Um, all right, maybe we'll switch off cats here Even though it's it's up in the corner still do the cats know any Python. I Don't think so They're good at finding treats. I'll tell you that much okay, so Hello everyone, my name is Scott and I work for Adafruit on circuit Python Adafruit is an open-source hardware and software company based out in New York City But I work remotely for them here in Seattle from my house and Circuit Python is a version of Python, which is a really easy programming language to get in to get into and learn But we designed it for microcontrollers, which are little inexpensive computers like this one So underneath this metal cover, there's a small computer chip that can do Wi-Fi and be Lee and run circuit Python And it does USB as well So if you want to support me and Adafruit who pays me, please go to Adafruit.com purchase some hardware there and Yeah, thank you so much in advance for doing that and I should also We have both cats here so you can see there's Vin and Spook Vin is the one on top And she's got like a smaller patch of brown than than her brother who has like brown onto his ears There are siblings And they have a love-hate relationship Yeah, so that's me and the cats and Adafruit If you want to chat with me and a bunch of others We do have an Adafruit Discord server, which everyone is welcome to join by going to the URL adafru.it Discord and that will pop you in and that chat lasts all week long all weekend long So that's a great resource for folks to get help with circuit Python and other Adafruit hardware stuff So I highly recommend folks join there This is a deep dive. It happens every week for at least the next Few more weeks. I'm not exactly sure so I'm not exactly sure what I'm going to stop streaming Fomi guys already said that he'd like to take the slot over so Expect to see some streams in this time-spot slot even when I've finished doing them Um They're normally Fridays at 2 p.m. Pacific Which is now ish And they typically go for two hours or more so we'll I'm kind of tired so we'll see She she got mad She is currently Showing her frustration out on the digi-key box that I have on the floor here. She really likes the cardboard Paper packaging that they have um Yeah, so obviously this is a casual stream We've got two hours to hang out and and work on some stuff. You have questions about circuit Python or electronics I'll do my best to answer them But there's also a lot of knowledgeable folks that typically are in the chat So if you have questions feel free to Feel free to ask those in the in the chats I'm following primarily the YouTube and the discord chats But I do have like LinkedIn and Twitch via the restream as well Last up all notes are available on github. There's a github.com slash Adafruit slash deep-dive dash notes And that is where we kind of collect all of the notes that David usually David creates For the streams super helpful. So thank you to David and then ask Patrick W Does a good job curating everything there? So if you check out that repo you can actually Search it to find a topic and then actually click a link to jump right into the timecode of The relevant video about that topic. So it's a great resource and thank you again to Patrick and David for putting that together Let's say a few more hellos and then I think I might have to kick this cat out because she's Threatening this digi-key box Hello unexpected maker Thank you for posting the link at ask Patrick W Sounds like Ham's lab starts a new job. So congratulations Congratulations on the new gig hello pup-dev 2 2 which I think is 2 2 3 1 puppy on YouTube. So yeah Patrick says I fixed issues with the get-of-actions to make that work as a hobby ah Mark says early question Did you ever cover how the compiler works in circuit python on one of these deep-dives? I don't Think so I I saw your question about the linker Is that what you're thinking? Let me I'm gonna take my mic off here and just let Vin out and then we'll get back to it That Abby's asking unexpected maker when Unexpected makers s3 boards will be will be available. Maybe I should stand I Adjusted my desk a little bit. Oh, that puts me a little higher I like it a little bit higher when I'm standing Do it for a little while Abadus is getting some feather RP 2040s, which is awesome What do the cats think of that paper wrapper that comes in the digi-key boxes? Vin really likes to tear it up and and Shred it even more Hello, King or North and hello Bruce s on YouTube And I expect to makers is later today I released them to patrons yesterday and giving them some time to purchase first. That's a great perk That's a great idea. I expect to maker Giving your patrons an early access to buy new hardware. It's a good idea Gary T says cool. Sheriff. Thank you. It's a weird. I don't know if you can see the like the seat is weird, too I'm like I Like it and I don't like it. It's not meant to be super comfortable It's meant to be something that you want to like not sit on for hours It's something that you're supposed to like want to sit on in a bunch different ways. So I Think it it does fit that bill Mark says did you see that Zephyr now has support for the RP 2040? I did not I'm not surprised Mark says looking from both points of view linker was for the actual linking of the circuit by then core and just General knowledge and compiler for more how the internal Python compiler works To save maybe some time going through the 3,000 lines of compiler.c code. I don't I Don't necessarily recommend you worry about how compiler.c works. Honestly Unless you're adding a Python feature that's like syntax related you you could just ignore it That's my suggestion. I think one One thing I've seen a lot of new software engineers get really hung up on is actually Feeling like they need to understand everything before they can get started and that's just in large code bases That's just not not tractable. You'll never be able to to do everything there It's At least I could do for them put out the dramas and me getting to this point Hemslife says I'm curious about your shirt. It looks cool, but I can't figure out what it is. Well, let me step back I'll show you my shirt. This is a local band Smokey brights is a local Seattle band here. So it's a it's a foot with a rose underneath it And then I'm actually and I'm actually know what this is It's a band a band a local bands t-shirt. They actually played it our wedding reception, which was really fun I'm sure Adafruit would be happy to stock the S3 boards It's just the supply chain is so limited right now. I totally get it And oh, I should point out talking about the compiler stuff for mark Bruce S linked to a page in MicroPython where they Where they talk about the compiler itself. So yeah, I mean generally we rely on on MicroPython to do a lot of that those changes On David posted a link to smoke it writes Yeah, there I'm fans. I'm huge fans of theirs. I followed them for years. So one thing that my partner and I are trying to do is trying to figure out how to Support local and one way to support local bands is to buy their merch So she's gotten me a lot of different local Local t-shirts from like local music venues and local bands Thomas says regarding 5881. Thank you for an example of how to use device info service for connections can now start coding for connecting Only to the currently desired central connections In the future would be desirable But enhancing the ability to find out more about the central's behind the connections of the future would be desirable No need for now to go into more details of this right now. Yeah, I was I Was starting to dig more into the beley stuff just for this nimble thing And it's actually not super clear to me how to get the MAC address of the connection on the underlying stuff There's there's some complexity around that because in order to be Private the the numbers the the identification numbers get broadcast and be a we actually rotate If you have it set up to do that, which you should That's one way so that it makes it harder to like Follow a device if the device is changing its identifier from time to time And then the there will be cryptography that that other devices can use to determine who's actually talking so it's not I've been keeping an eye out when I've been digging in the stuff to see if we can figure out what the Identifier of the connection you're connected to is but I haven't still been across it yet I Was think that deep diving with Scott is the perfect Monday activity make us all happy My Mondays are usually pretty busy. I like ordering from did you key to I tend to buy a lot of stuff That's not super urgent from to key if I need it urgently actually get it from a different because they'll pay for the shipping S3 boards ordered Nice, yeah, I'm very interested in the S3. We'll see I've made some progress I've just been chatting. I did have some idea what I wanted to talk about today So first I just want to do a quick talk about sacrifice in 2022 And We've talked about this the last few weeks and I shut it down at the end of January and and did a final post. Hey, Michael But I actually got another one today and since the stream last week, I also got notes from Katniss, right? I thought it would be Human Friday I Thought it would just be cool to just I think I Think it's worth just touching on these Things here, so let's go Nice People are purchasing from unexpected maker. That's awesome way to support the maker community So here's the desktop Pierces has got not entirely surprised the nr 52 chips and soft device have default Mac address But can be changed really easily I think we're talking more about the Mac address of what you're connected to and not your own Mac address You could spam the channel with S3 board stuff. That's fine. We're talking about a series today. It's related Okay, so I just wanted to briefly cover I think it's only These last two that we haven't covered yet Do we do go little dog async support Fido USB stuff The BPA 3 should be pretty easy. I think it's just a setting But I don't really know home kid. I think is complicated and Redis I'm not so sure Let's see that was posted Friday of last week, so maybe we didn't talk about it It's all good I'm fine with it. I got this one today from Axel is talking about having memory allocation issues And it turned out that it's actually on the M4 boards on the pipe portal and RGB matrix So they're taking like two rather large projects and trying to mash them together That is running at a RAM and and doing some having some crash problems, which is Like it's really tough It's really tough when Or was it Using the ladder it crashes after a few days like any crash that takes a few days to happen is just so hard to debug, right? Like Crashes that are so intermittent and Unclear kind of what led up to the crash is just like really You can take you can spend a ton of time trying to fix those Because it's so so difficult Badabby asks does Adafruit have any plans to support a 5 gigahertz wide 5 chip? I Don't know I don't I don't do as much on the hardware development side I think it's just a matter of like I don't know of any chips that support 5 gigahertz. Do you I? Just I just don't actually know what's out there for those. I know that Espressif did announce at one point the ESP 32 c6 which is a Wi-Fi 6 capable It's not available yet But it's Wi-Fi 6 capable, but I don't know if that's It's still only 2.4 2.4 gigahertz not 5 gigahertz, so I don't know of any plans We're focused pretty much on this on the s3 right now It's kind of at least what I'm working on so The last one the last thing I wanted to highlight for the circuit by the 22 22 is Katniss post so if folks aren't aware of Katniss so Katniss is is working works for Adafruit has worked for Adafruit for five years or four or five years like pretty came into the project pretty early and Has this really strong really good at writing very beginner-friendly tutorials and documentation and is really good at Keep it getting people unblocked and leveling people up so Katniss done an amazing job building the circuit by the community which is important to highlight and It's it's important to talk like so much of these deep dives are about the technical side, but the there's no way that Circuit Python will be what it is without community, right? Like this deep dive is part of the community But There's yeah, there's just so much other stuff to do in an open-source project to make it successful so Katniss a key part of that and I wanted to highlight that When we summoned Katniss So yeah, if you don't know who Katniss Katniss awesome And so I wanted to take the time she got me her circuit by them 2022 at the start of this week And so I just wanted to highlight it even though It's not Yeah It's a lot it's it's a lot of awesome community work, so let's just go over this. Maybe I'll drop the link So Katniss just posted to the it every blog itself We're confusing Katniss Okay, so oh Yeah, and the other thing I should say is if you've ever seen the code plus community equals circuit Python moniker That was directly Katniss idea So Katniss the the source of all of that so that's that's great and Katniss done a lot of revisions with our moderators on our code of conduct and And then I think they were just saying that they joined a photography discord that like uses our code of conduct for discord as Well, so it's like it's it's very cool to start to see like The catney in particular has put a lot of work into the code of conduct and to see other people adopt it is is awesome, so Okay, so let's go over here so successes We should keep the community in mind and everything we do and I think generally we do she says that we do a pretty good job I Can say that this has been a success Includes awareness when designing and updating API's so for example one thing one change that Caddy's made to the core is Catney went through and made sure that the When you print out a pin in circuit Python if there's multiple names for the pin The first one is the one that get ends up getting printed So catney went in and made sure that like all of that ordering was correct So that the one that got printed it was the thing that you see on the on the board itself, so Lots of details like that make up the the experience that we've got going here um The documentation and support needs have regularly been discussed in applicable pull requests and we have had consistent follow through Yeah Probably has the most circuit pythony post of circuit by 222 Yeah, and I think it's important to Also remember that like the beauty of having a community is that people compliment each other so like Catney's a great compliment to the what I do and what I don't do So I think that's that's a large part of it that is important to realize it's important to realize that That a community can run a project and You know in the same way that when we do our meetings on Mondays and we do hug reports like None no single person of us needs to know everything that is worth thanking people for in hug reports, but collectively we can shine the light on other people on the the stuff that other folks are doing so Um, there's a there's a huge strength in having a strong community So, okay, so room for improvement In the last couple years one thing she pointed out last year and and still wants us to continue is um Like we do this annual planning um, hi aza Um, we do this annual planning with circuit 521 22 Um, but catney thinks that it's something that we should kind of be more open to and we should we should be more explicit about throughout the year Um, so I did say that in my wrap up post. I'll like it's never too late to let us know what you're interested in Um, but I think maybe we should be more explicit. Maybe with major releases or releases um Compliments and compliments Um So, yeah, that's uh, that's a good point And I think we we continue need to make to do that is like Talk about how we're always open to hear what people want to do That doesn't mean we prioritize what people want to do But I think it's really helpful and I have talked about this with circuit 522 Said it's really helpful to just say hey, I'm interested in this thing and then We have spaces where people can collaborate to make those things a reality right and one thing that I've always tried to do myself is that like Always I always prioritize unblocking people above any of the technical work that I'm doing right like I do emails And I do reviews every day and if folks have questions on discord, I'll get those to those every day every work day um So it's really important to me that like people don't get hung up and that like as people Come along and want to do stuff they can do that so um I think we should be more I agree with catney that we should be more inviting to like facilitate People saying what they'd like to see in circuit python and finding the spaces and the people to work with on those things um, okay, so let's see this second paragraph is Talking about keeping up with issues and pull requests and this goes very much into what I was just saying I'm like it's no fun as a new contributor to like create something and then let it languish and and not actually see it Be contributed to the greater good right like the the the main project so um That's that's kind of what's been still a bit of a struggle throughout last year, but um, it's been getting better Uh JP Tantanao says I was reminded recently about the proverb it takes a village and circuit python is no different 100% But it is really like a shift like it's it's sometimes really tricky to to recognize that um It's worth the time right like It can be really hard to to believe that it's worth spending An hour and a half on emails every day and forum posts and things Okay, so let's see looking to head to 2022 It is incredibly important to build up those around you That's been great. Katni's been mentoring folks We as admins and moderators strive to keep the community space Community space safe and welcoming however the matter the fact of the matter is that the community does most of the work for us Yeah, that's been awesome. It's been great to be able to Uh rely on other folks and and and the team that we have for moderation When we first started the discord, it was really me like trying to read everything But we quickly got kind of people people going Oh nice. Ham's lab says I started an EFF group here in Buffalo and used that code of conduct Hello, Johnny. Okay, let's keep going three helper roles for the aid of fruit discord as a way for folks to level up and The meeting is public. We have hug reports so this is This section here is a is pointing out that hug reports is actually still um limited to the people that are able to make the Monday meetings and um Katni's saying here that we should make more of an effort to put hug reports in the hug reports discord channel Because that's because it's kind of an asynchronous way of doing it. We can just kind of like Do it all through the week and include people that can't make make it to the voice meeting I think that's a good point um Yeah, good first issues Good first issues and then also highlighting the new folks that we get contributing every week It's been pretty awesome Like we keep track of like how many people are involved in filing issues and how many authors we have and The number is going up, which is good Show and tell is a great way to see what folks are doing The community bundle is really taken off. Um, it languished for a little while, but it's it's definitely taken off Ha ha um And then for 22 FOMI guy is gonna be able to spend more hours working on Adafruit stuff because we're paying FOMI guy part time Which is super exciting and and tim who's FOMI guy Uh has already like really made a dent in the backlog of library pr. So that's been really awesome I mean like I said, the plan is for tim to take this time slot when I'm out on paternity leave um Then catney says thanks to ann and tim and bruce For the graphics and thank you to the moderators adafruit the more npt And then says we say code plus community equals circuit python the more both circuit python and the community grow and evolve the more true the aphorism aphorism becomes I want us to continue to remember that circuit python requires this community more importantly. I hope we can properly Express to the community what their importance to us and circuit python. Thank you to everyone for being a part of it I'm excited to see what happens next so thank you to catney for Reminding us all of the different components that go into building the community that we have And thank you to catney for her hard work and also all of you as being a part of that um Okay, let's let me get caught up on the chat here So asa says anyone successful using platform i o vs code win-tell to build an upload Arduino or idf to the adafruit cutie pie esp 32 s2 That I don't know Do not know platform i o md robert says how does the circuit python 2022 resolve? Are you going to publish a manifest or something? So I I think I did try to do that in previous years but I It's tricky And this is the one that we try to try to walk a lot right like There's a difference between circuit python prioritization as the larger project Which is made up of a lot of volunteers and then there's also the prioritization of The folks that adafruit pays to work on circuit python and I am one of those people so I did kind of want to I think in the past Not last year, but maybe the year before before that even like I did try to kind of summarize everything But that's really hard and I think instead This is always planning and doing is saying like okay Here's all of them And the way that I see it is it's really just a like hey check them all out And I covered them as well right so Like It's more about let's let's all talk about it and find the people that we relate to and collaborate And so I don't plan on doing kind of one Summarization all of that Part of it's just I'm not the spectacular writer And I also don't want to like I don't feel Like I can impose on other people what they should be working on either right like I consider myself to be kind of the leader of circuit python core but um It's kind of really just like I want us to all like the same way that we have hub reports It's important for us to build And communicate about shared values But I don't necessarily think that that needs to Be in like one formal document Um Rather it's like a bunch of people contributing their perspectives on it um But maybe that's also just my cut out. I don't know. Um I think I think the other piece of this annual planning that we do the circuit python 22 is uh It really does highlight and this has kind of been my theme is I've gone through it this month is like It really does highlight the principles of what is important to those of us that have been involved for a number of years And like the things that we hold Core to like the way that we make decisions doesn't necessarily change from year to year and it's just cool to see how those principles and philosophies have just um Informed what we've done and and how successful those things that we choose to do are I think Generally, we make pretty good decisions in terms of what we're going to focus on And how we balance straight off. So I think it's We're going the right direction. I think it's just a matter of like Uh Yeah, it's It can get hard to go in the same direction for a lot of years if you think you're done, but I think it's important to remember that things are really quite hard still Um, so I think I think there's more room than we think there is Which is different from the like idea that that you can get bored of doing things But yeah Thomas has a question Uh I asked them this story, but nobody seems to know the answer Does anyone know about a driver for windows to make a bluetooth? Comport to the Adafruit BLE services Nordic UART service accessible by standard windows operating calls The Bluetooth 2x 3x SPP serial port profile is supported out of a box in windows, but Nordic's UART seems not to be Yeah, that I don't I don't know. I don't use windows regularly. So that's part of it But if any of any windows folks out there know how to do do UART over BLE Reach out to uh, Thomas And Paul points out that catney will be the first guest on Paul's new circuit python show podcast Tammy says the principles and values of the community and of Adafruit's culture are I think the secret sauce of the community piece of circuit python and then Pira asks when is the first circuit python show podcast scheduled to be out and Paul says march 1st And thank you to Paul for doing that. I should say that Paul and I Recorded our episode already And it will hopefully be good Should be good, but I think Paul is thinking I'm going to be the sixth episode. So it'll be a little while I might be on paternity leave when that comes up, but I'm sure it'll be good Okay, any other questions or should we dive in this in bluetooth? I'll show you where I'm at I'll take a cat break here Do I need like cat break music? Spook all on his own I see no questions And no objections to doing some bluetooth stuff I know there's a bit of a lag Sorry if I made you young so what I've been working on and honestly struggling a little bit with is I think I'm trying to remember where it was last week so we have There's these like two roles pre-connection for for bluetooth Can you hear my fan spinning up? I don't know why it is So there's the central role and the peripheral role then there's also the Broadcaster and observer roles as well Yeah, this is what he does all day. He just sleeps So I was initially really confused with all the different terminology From we have palms in Seattle. We do I was not pleased about it But yeah, you're right. This is a They have like hearty palms they can handle like some cold temperatures And They put them Oh unexpected makers got to go get a flux pen You've got an hour and 20 minutes or so I think we'll get I need to get some really work done. So we'll do that After this cat break so Let's see Let's switch back to the desktop Yeah, so or maybe I should do So there's kind of the process of bluetooth is You have two devices one of them One of them that's off-screen one of them is like broadcasting out. Hey, I'm this here's some information about me And it's like not encrypted. Everybody can see what that information is although it could the data itself could be encrypted And then you have another device that can be listening for that Um, and that process is kind of like the thing broadcasting is the Broadcaster and then there's the the observer Um, are you linking linking to me to from the note stock from last week? Where I was last week. All right, let's see Hello 9 58, let's see. What did we talk about? Good morning threading mqtt Adding the bealee Wait, no, this isn't last week. We're missing one We're missing the 28th There's been a bug You might be able to get the transcripts from the youtube api um Anyway, so I did I think I did scanning and advertising And then so that's the the broadcasting and the listening and then the next step after that is initiating a connection Um, and so what I did manage to do is I I got it so that it could advertise and then connect and then disconnect and uh but that was only Me connecting to it instead of it connecting or My phone connecting to my test device Um Rather than the reverse so there's like The person that broadcasts and the person that scans and then the person that scans is typically the person that initiates the connection And that's that's known as the central and then the person that they're connecting to is known as the peripheral role um And then once you've established that connection, there's a process to discover The services that each side presents. So for example Like my an iphone will present you with the device info service the current time service That allows the other device regardless of whether it's central or peripheral to request information from from the other device um Which I guess is Kind of hard to understand So let me just get into the The actual stuff so, uh If you look in the eta fruit circuit by von billy repo. There's an examples folder And there's um these two The things that I was trying to do while I added a couple new ones Um for thomas I added this device info service So this allows you to just do this generic advertisement and then print out what when you are once you're connected to something printing out the manufacturer And the model of the thing that connected to you um So that's the it's the It's the peripheral role because it's advertising And then it's the client of the device info service on the other device Which is the server So there's a lot of different terminology It does make sense, but it took me a long time to kind of get over that hurdle um So I added that one and then I added just like this other simple advertising tests Um, that doesn't require any of the services stuff to work Um, and so the next thing I was looking at getting working on the s3 Is this um Is there a battery service available to Um, we can see so in here we have a different ble and then we have services And standard device info hid But I don't Think oh, yeah, here's battery service So if it's in this dunder and knit that means it's kind of like you import the name of the folder and then you'll get it automatically Um And one thing that I did that's kind of weird, but I'm still pretty happy with it is I I used a very declarative form of python so There's this object battery service and you say like oh, there's a u and a characteristic on it That has the max value 100 you can read it and you can notify so Maybe we should Maybe this is what we should talk about today because I don't think I've done a good job explaining it and somebody was telling me I should write a guide for it and I'm not a huge guide writer Uh, but maybe you covering this is a good plan And it matches with how I titled it so so there's two main terms or or things that Or specifications that they'll talk about for beli blue to low energy gap And gap is the thing that manages advertising stuff And connecting and then there is higher level stuff That is uh gat, which is the attribute stuff and we did talk about this last week because I remember Asking what they what they stood for Um, so this this library is really building on top of gat So gat is is the process of providing Services to the other device that you're connected to or other devices you're connected to and then um The reverse is being a client of the services or servers that the other devices provide Um and one thing that I try to do that's kind of weird, but um I think I didn't manage to do is uh Make it so that you can have one object be kind of both So what does that mean? So um, if you are The let's just use the examples because the So if we look in the examples, you'll see that there's two ur things So ur is typically It's a very basic serial link to and from Or like Bidirectional serial links who just say write this and then the other side can read that data And so we've got two things here. We've got a client So this is the I'm not running the service on myself, but I'm talking to it remotely And so the way that that works is you say oh if I'm connected to something and What you can do with this library is you can say if the service is in the connection Um And then this is this is python fanciness. So so this is known as a comprehension So I think it's better to read it kind of like this. So for every connection in our connections Do this thing which is check for a ur at service in the connection. Hello mate 507 um And then then it runs in any call. So if any of those are true, then it will be true as well Um, and then if that's true, we're connected to something that provides the service Now we try to find the connection that actually provides us the service And then this is how we get an instance of a ur at service class That represents the service on the other device so we say Within the connection give us the ur at service And then what we can do is now treat it like a ur so we can write to it the words or the characters echo and then we read Each of the bytes back and print them out and then we loop around to do this same thing So we while we sleep and then we we do an echo again So what you should be doing is you should get used to say echo and then from the other device get echo back um If you're not connected to something now you've got to start scanning to find a device that That says that it provides the ur service So that's what this is doing Umut says hey there. Can you point me to a circuit python joystick hit example that uses analog inputs for the pi pico? um I don't know if we have one the place I would start is the usb hid Custom this guide customizing usb devices in circuit python There's an hid one it talks about consumer control Custom hid devices And joysticks are game pads. I think so the game pad is the one that you want Um, the other thing to look at is like click into the library and just like we're browsing the examples there For the hid one you could do Uh This like game pad example There's a move joysticks So what you'll do is you you would do like an analog read and then say move joysticks between those numbers I don't I don't know of a guide that specifically does what you're asking Um, but that's where I would start And then the other place to start is if you don't know how to read If you don't know how to read analog stuff, you can start with the Getting started with raspberry pi pico guide Which has some examples And maybe the potentiometer will tell you how to read Because the joystick is basically a potentiometer So you kind of need to mix those two things And if you have trouble the discord's the place to go. So the the chat above me is the discord server um, you can go to that by going To itifrew.it size discord And there's lots of helpful people that can get you unstuck if need be Okay, so going back to bluetooth um So this is the The client side of interacting with the service and then on the Server side, this is what it looks like. So You just create the object um, and it's the same object that we that that does both things but it The way that you create it or get it dictates whether it's like a local or remote um But it's like the same definition of the characteristics which Has some trickiness underneath the hood But I think it's actually quite cool once you learn how to do it Is that you just declare the characteristics in your service and then you've got both your client code and your host code um So here's what it looks like on the On the local server side Um, so you're serving the uart service Lots of terms um, so you create a A provide services advertisement. This Um is a way to say hey, I provide this service To everybody that's around you. You don't care who connects to you um and then There's so you start advertising that and then you just wait for somebody to connect to you And then once somebody's connected or while somebody's connected you you read a bite If there is a bite there Then you print it and then you write it back to them. So it's it's echoing it um So pretty simple. I think this is the simpler of the two things um But that's kind of like both perspectives of um of Using kind of services over BLE Turns out that this part is Making this side work is actually Going to be kind of hard Unfortunately, and it's hanging me up on this this work that i'm doing um and the reason that it's hard is because a lot of Bluetooth stacks including nimble are really designed so that um It's just designed around the idea that you know all of the services that you're going to do up front before you start up everything Um, but that isn't the case because that isn't the case for circuit python Um because you could actually have bluetooth running when you actually get to this point already um particularly with the BLE workflow where Um circuit python has its own BLE services that it makes available so that you can see The serial output and also so that you can edit the files So there is going to be Those two services already plus there's two other standard services that are basically required um, so you're actually going to when this code starts you're going to have four services probably running already And the thing that uh, some stacks don't do and and what nimble doesn't allow for is that um This here this uART service instantiation is adding a service that we want to provide and The Nordic soft device that we use on nrf 52 is okay with us adding services as long as when we add them we add them kind of all in order And we should talk about what makes up a service. I don't know if we we probably talked about this before when I did BLE workflow But I don't remember We can recap it Thanks pier. I have a good one Have a good weekend Yeah, so what makes up a service? Let's talk a little bit about that um A service is kind of like A collection so the primary thing that you're reading and writing or what what are known as characteristics um, and I think of characteristics as kind of like fields Where they're just like some particular state so at the simplest level pier was talking about like the battery service um Or the device info service is really straightforward, right? Like the the two fields that you're talking about are manufacturer and model number And those are just characteristics. Those are characteristics of this service and the They're characteristics of the device and and within the category of kind of like the service So that is pretty straightforward um, that mental model of just like there's a value there You might be able to read it. You might be able to write it um That's pretty straightforward um, where it gets trickier and trickier is that um Things like the yurt example where it's not really that you have Like values that you have state for but rather like a stream like a continuous stream of values Um, and that's where the model that they went with with all this gat stuff kind of It gets weird So what happens is that The there's some complexity around characteristics where not only can you read and write them but um You can also like Decide to listen to when the values change so you can say like hey Hey server, I'm a client of yours and I would like you to notify me Whenever it changes versus me having to ask you constantly whether it changed um And where is serial number it is documented so, uh, yeah, that's getting into a little trickiness um So there are optional characteristics on these services and so, uh, if you look at the implementation and the thing that would cause it to be documented If we go into services standard device info We'll see that there's actually There's there's more fields than just the two that i'm printing off um But the reason the example only has those two is because that's what iphone provides So because these are optional characteristics um The Version of the device info service just on the iphone doesn't have it So if we actually look at, um Bluetooth org We might be able to find the specification here For device info service Dice device information service. So let's click that Let's take a look at it It's pretty good There's a pretty good amount of stuff that is is documented You can see the people that like came up with this It's interesting. There's nobody from apple there um Nothing like reading specs Yeah, so the service is a primary service and then there's these uu id's which are What are they universally unique universally unique identifiers? Maybe that's what it means Basically, they're big long numbers that are meant to be unique to identify a service And then there's also uu id's for characteristics and uh descriptors as well. So descriptors are like state on characteristics, which is Uh Probably the the clearest example or the simplest example is you can have a descriptor for a characteristic That is the like a user friendly description of what it is Like there's a user description characteristic that you can add to all of There's a user description descriptor that can go on a characteristic so that you can discover it dynamically um, and that's really the thing about uh where it is so um So the device information service may expose one or more of the characteristics shown It's possible that none of the characteristics below are included Um, and you can't have multiple copies of them. So Just because it's documented doesn't mean that the the server that you're connecting to actually presents it And what you'll find is that if you add serial number to that example, it says that the Uh, it's unable to find it or something. Um, so Because the server stuff is really hard what I've been working on is the client stuff So the client stuff is the you are client Example is what I've been working on And I made some pretty good progress So, uh Let's show it off So what pieces are actually happening here? so first What really happens is we don't have a connection. So this actually this bit happens second. Let me make it bigger In case folks are actually watching I know people are listening, but I don't know if you're looking so, um The thing that they're The thing that happens first is really this part of scanning So what you do is you initiate a scan and say hey, I'm looking for anything that's scanning that they provides any services and then When we get when we see an advertisement that includes that let's Skip any of them that don't have the uART service And then if we do find an advertisement that's Some other device saying hey, hey, I've got this uART service available. If anybody wants it Um, if we find that then we tell the bealy radio to connect To the device that matches that advertisement So there's some I did some identifier in the advertisement that can tell you like What other devices is saying that? So the first thing that that happens Um in this example is initiating a connection. So I've added that Previously I allowed things to connect. I think I think in what's checked in you're able to have something else connect to you But you're not able to initiate the connection. So in the code that I did this week You can now initiate the connection, which means that you're the central That's the the the bealy term is that you're the central device When you do that connection So after you connect we've hit disconnected We'll stop the scan because we found the thing that we want to connect to And then we'll do this connected check. So this is just making sure that we haven't disconnected for any reason Networking is fun because things can just disappear at any moment And then this process is actually one of the trickier things. So we list the connections. That's pretty simple But actually determining whether a service is available in a connection Or over a connection is kind of a better term for it Means that we have to do this process called service discovery so Bealy has this process to say Okay, given this connection I want to figure out do they have this service or get me all the services that they make available And so because we're doing this you art service in connection We know the unique idea of that service So when we say hey, I want to know if this other device that I'm talking to or this other device I'm connected to I want to know if they have your service They should because they advertise that they do but There's no there's no reason you can't fake it out like that if you wanted to like those are More distinct processes than a lot of people think I think or at least as when I first came into bealy My understanding was so it's really important to think that advertising even though there's like these IDs that are shared Like they're really separate processes the the gap side Which is advertising and connecting and then once you're connected doing this sort of like discovery and interacting with servers or services Like that service is The definition of the thing and then when you're hosting it you're the server And if you're interacting with it you're in the client role And you'll see that in libraries. It's pretty common to have like A gat s versus gat c so to say like this is a server thing that you're doing or a client thing that you're doing Um So there's this discovery process that you can do so you've connected and now you want to say do you have a uART service? Um, so there's a discovery process Which I've implemented And kind of and let me just show you that code This is a deep dive after all Shouldn't be scared to go deep Okay, so, uh, I'm pretty happy with how object oriented Even though c is not Doesn't want to make it easy. I think our code's pretty pretty well object oriented. So, um, We're in the connection object. So we're in ports expressive beliaio or common howl beliaio connection So this is on a per thing that we're connected to basis And then there's this These are callbacks There's this uh So functions that start with common howl are things that are kind of mirrored um That that are exposed in python land. So there's an a python equivalent to this um and This is where the beliaio library plays some tricks to to convert that Hey, is this is this uart service class in this object? It's going to behind the scenes call discover remote services And it can take a service whitelist, which is a like, oh, I just care about these uuid's essentially um So what we do is we say, okay, like we're going to run this discover remote services process and we're going to pass in the whitelist That's what's above that And so we say Oh, like if the whitelist is none that means we just want to discover everything. So this call here is the um nimble call to get all services And you can see here that it's got this gatsy portion to it Which means that it's it's kind of like part of the gap client api So discovering what the other device provides over gap So one of the things i've been having to learn a lot about is Oh, what's really common In the nimble api is that you give it a callback. So you give it so this here is actually a function pointer and then the next parameter is the object that gets passed back to you when that callback's called So what we have to do because we kind of expect discover remote services to be blocking meaning it does the whole process and then returns What we have to do is we have to use the free our toss primitive to say like, okay I'm just going to wait until this thing's done So that's what this take is So take is saying like, okay, I'm going to wait until I get notified That it's my turn to there That I get notified it's done So discover all services we'll call this discovered service callback And then there's a different version of this which is if you give it a white list of uuids It does this gatsy discover services by uuid And it's in a loop But it uses the same callback as the first one And it also has its own take So if we scroll up We've got Discovered services callback it gets a connection handle the error the service information and the argument that we asked it to give it back to us We check the error status if it's Any error status besides success then we give back so it will potentially call this callback multiple times And the last time it calls us it will say it's done. So there's an error step There's a success error status and there's a done status, which is a little weird But we're basically we're trying to wait Until it's done. So if it's If the error status is not success Which includes done Then and it's the first time then we kind of finish So we we store it in a variable we can read later and then we also start back that other task Um If we just got an item we do some allocations So we allocate an underlying service object and that's That's the service object that like billy the billy library wraps in the uART service thing um Yeah, so the service room connection creates a service object That is remote and then The the GAT stuff is like there's a big long list of all of the services Characteristics and descriptors that are made up that that are available And they have these unique numbers for each of them Which are called handles. So so the handles tell you like what item what What index in that table the thing is So when you learn about a service you'll you'll figure out what handles Handle range encompasses the service And we have the uuid of it So we'll make an object of that as well and then we add it to our remote service list Going back down to discover remote services So we've done it either one of two ways we either discover them all or we're discovering them by uuid It does take time So uh discovering by uuid will be faster Because instead of discovering that whole table you're going to discover just the section that you care about um And there's I think there's like a lot of back and forth and stuff. So If you're if the connection process or getting that the first time is slowed and you might want to try to do just the services you care about So once you know the services and the ranges the next step is to discover all of the characteristics So that's what this call is doing is discover all characteristics again It's gat client and now you're doing it You're saying I want all the characteristic info for this section of the table That is all of the things for the given stream So that's where you're using the services start handle and handle and handle to like narrow down what part of the table You care about there's another call back to To get that information and then lastly you you do that again So for every characteristic now you get all the descriptor stuff and that's what this is doing um And there's appropriate callbacks here um For each of those things But they're not that different. There's some like data Data differences between the the things like here's properties about whether you can write or read or notify or things on different characteristics um But kind of fundamentally what services characteristics and descriptors are doing is they're creating the objects for you to use later um Even though the objects have like slightly different data in them So once you've done that now we're back up the common howl we create a new tuple and we put it back Patrick says missing show notes are live in the repo and maybe I fixed the bug with adding the thumbnails that was breaking the action nice Thank you for doing that All right. Well, that's the weeds Um, but this is something that I got working And so once you're able to discover the service and creating all those objects now you can use them Um, and so I've been working you can see here. I've been working in characteristic a bit um I think I'd actually written some of this code before but I hadn't tested it So now I was able to write stuff. So let me We got 45 minutes Let me actually run the the example code So I've got two things here on my desk that you you won't be able to see but I'll tell you what they are so first I have Well that camera is closer than it used to be this is an nrf 52 8 40 board our feather And uh on the side you can see here that's kind of got this similar like module on this So this is our the first chip that we supported with beli um, and so what I have here is some code running the The uart test so the server side of the uart stuff So I'm going to plug that in on my desk here and I basically just leave that running As something that I can connect to from the esp And it actually pops up and I'm gonna Just mount it and then eject it Because I don't actually care about it And then I've got this Make sure I'm making sure it's the right one. So I've got this esp as three board and um, it's got the client uart code on it Um, so that it can connect to the nrf and try to do the echo test Which dan pointed out to me when I was talking to him He's like a lot of our examples do GAT client stuff So like if you ever seen like a bluetooth thermometer that you're connecting to like that's all GAT client It's not glad get GAT server Unfortunately, the beli workflow stuff is all GAT server stuff. So once I finish this stuff up then I will be moving on Next week into the server world Okay, so Let me pull up this I've got this lovely set of four Four things here and I'm trying to remember how I had them set up So this one I think I had set up as dev Serial By id usb a to root So this will be the top rate will be the serial output From my the nrf board and you can see here it is getting echoes and then I wanted to do over here the serial the usb serial connection to the s3 board So if we connected that we can see that we are printing out Welcome back unexpected maker. I got deeper into GAT service discovery stuff And now I'm showing you where I'm at on this demo Lots of weeds in beli land. Yeah Okay, so this is what's happening is that I We've discovered the services and characteristics We are writing Let's go back to our example here So when we're talking about here, we've Discovered the service. So this is true We've found it true again here Or yeah, and then we've been able to get it out And when we call write We can see that the word echo is getting to the nrf and then What this is actually telling us is that it's getting back to us on the esp side But we're not doing the right thing with it. So that's what this unhandled connection event is Is that there is a there's an event That's coming back into a callback in in from nimble that we're not handling So if we go back to our example code We've done this successfully, but this read is not working That read is not reading the data And the reason that is Let's stay in these beli weeds because they're Not super clear So how does the read work? How does he how does ur at service actually work? So let's take a look at that And I'm going to open it a separate window or a separate tab So in a different beli we have services And let's look it's under nordic. So nordic are the folks that had to kind of design Defined this kind of standard ur at service You'll also see it abbreviated as n us for nordic ur at service So it provides your like functionality via the nordic new ur at service And our goal is that this api looks like bus i o ur right? So there's two fundamental things that so here's If it's not a standard beli uu id they tend to be really long. So this is the standard unique id for the service itself That's what the uu id member is and then we have two internal characteristics that we're talking about one that does Transmission and one that does receive And you can see that they have different uu id's as well and we are defining buffer sizes So then we have to do some a little fancy stuff here Some tricks under the hood. So if you initialize ur at service If you pass in a service object like a lower level service object, we'll pass that up And then what we actually do is we we flip Which one we're talking about depending on whether we're The service itself or not. So that's what this is doing here um And we call ourselves connectable to which I don't know why that's there. That seems weird. That's an advertising thing um So how read does read just reads from the rx read into reads from rx And read line Rx in waiting reset buffer and then write writes tx so uh We have stream in and stream out and they actually get um These are related the tx and rx are names for the server side So like if you're not the server Or hey, you swap them at some point like it's you are you don't I'm always confused about how you swap them When in doubt swap them So let's take a look at stream in and stream out um And they're characteristics. So we're going to look in characteristics and their stream so This is where I play some tricks some python tricks. So so these are both complex characteristics So what complex characteristics are? Are they're kind of like I think of them kind of as placeholders. So At some point you'll when you define the service you'll say server tx equals this stream out But what happens is that when when it actually starts getting connected it gets replaced So that object actually doesn't stay there. Instead it gets replaced by um when it gets bound to so um This initialization of stream out happens Before the service object is actually created because it's a data descriptor Which means it's kind of like outside of function This is deep python stuff. Um, but it's all in service of being very declarative at the outer level um So holding onto some settings and then complex characteristics to have this bind thing so you can say hey I have this service object bind to it and then It can do that at the top level and then we have some specific stuff that we do Um, if the service is remote meaning that we're the client then we use Characteristic buffer to write so This is stream out of the server. So if we are remote There's stuff coming from the server to us and we have to buffer it Um, otherwise we have bound write stream, which goes the other direction And then stream in is going to be very similar. It's just going to do the reverse It does bound write stream if we're remote and if we're not then we have to buffer incoming stuff um So they both rely on this characteristic buffer, which is actually a primitive A native primitive for beliaio Um, and then bound write stream is like this object that gets replaced and it just has this right call And it just writes to the characteristic there One thing that write could do to make you art faster is actually It could If you wrote multiple times small things it could like actually piece those together to to put those together into packets, but It doesn't So I think I've covered all of the pythony stuff and there's definitely tricks here Um into how this works where it like gets replaced and things But it seems to work pretty well And it does make it very declarative, which is cool um I guess I didn't talk about the super classes, but I don't I don't want to get into those weeds right now because we have 35 minutes to fix this demo so we have characteristic buffer and What does it have so we we can construct it we can either construct it Like dynamically where we're allocating memory or we have a version that takes the memory in in case we want to In it initialize it without Uh without dynamic memory, which is very useful for um the circuit python Uh beli workflow stuff, so we can statically allocate a characteristic buffer for the ur Uh service that we provide as part of like core beli workflow Um And then we provide read And how many characters and things are in our buffer And whatever connected so it's it's like not too complicated Um, although this is not the full implementation So this is the expressive version and you can see Kind of that there's a lot of this ring buff stuff So ring buffer is a a memory Area that you're like writing values in and when you get to the end of it you'll start putting them at the start So you're kind of like keeping a sequence of values together, but that sequence can wrap around Hence the term kind of ring So we kind of have a standard ring buffer implementation for that Um, and that's what buffer size is all about too So this is the thing that doesn't work Um, it's not actually putting the bytes that we're receiving So the the way that the bytes come out of a Nordic UART service is that they it happens through notify So This is the hey, hey, I'm a client. You're a server I'm not going to keep asking you whether this value changed. Just tell me when it changed And that's what the there's two mechanics to do that. There's Um Notify which is like hey, let me know that this happened and there's also indicate and Indicate is like hey, not only should you tell me that this happened, but I have to you should require me to tell you I I heard that Keep these ee says not too complicated. This is a deep dive true deep dive. Yeah, we're getting We're getting pretty deep, but Uh That's what it's all about, right? If you have questions, please ask them um, if I'm if I'm Skipping over important bits, uh, please ask I'm happy to take a step back and try to explain what I'm doing so I do think this is an interesting design choice from the bealy side of Having these two terms for notify and indicate in one direction when there's also kind of like the corresponding Uh, sort of commands going the other direction So there's two ways to write to a characteristic. So I'm a client and I want the server to have this, uh I want to have this value and there's two ways to do that. I can do right and I can do right without response so, um Bruce s is Was up too early and hasn't had a nap yet So right right is just like indicate it says I'm going to write you this value and you have to let me know You got it back Whereas white right without response Can say hey, I'm going to write this value and you have to tell me or you don't have to tell me that you got it um And the other piece is that um There could be a long time between like when you write like milliseconds between when you write when you hear back And so it's much quicker to do the right without response Uh stuff both white right without response and notify can be a lot quicker than the ones where you're required to wait But yeah, it's It's understandably tricky It took me a long time like the only reason I have this Good of an understanding is because I've done it before Which is also why it's kind of hard for me to want to work on it again. It's like I've been there Not learning a lot Bluetooth is tedious. Yeah We haven't even talked about any of the security stuff yet And the state that you're supposed to store with that we'll get there maybe Or I'll hand it off to Dan Hopefully I can at least do the server stuff Who implements the security stuff we did well that was one of the things I was doing with the bealy workflow is getting the security stuff Kind of on by default Bealy has a lot of moving parts Yep, I agree with you A lot of what I've been thinking about is also trying to kind of figure out what our long-term bealy plan is Because we have the Nordic soft device But the soft device in Nordic is actually closed source. Like you can't look at it. It's just a binary blob And So I think I what I'd really like to see is like Version of like a a bluetooth stack that is very similar to tiny usb where it's just like we have one bluetooth stack And we use it for everything um We use it for everything that has bealy in the same way that we use tiny usb for all of our usb stuff So that like my long-term goal is like I'd love to see us just use this one bealy stack for everything um, and that could be really cool too for the Nordic chips is because we Talked about the nrf 5340, which is the later the newer nrf chips And that's not supported by a soft device. It's supported by zephyr But there's also It's also supported I think it's supported by nimble as well So nimble could be the way that that we go just like this is the stack we're always going to use How do we go about building circuit python? You have two files for boards that aren't in the download list um If they aren't in the download list that probably means that they Uh, don't have a board definition, which is pretty easy to do um There's two tutorials that will get you started and as always the Discord's a great place to get help, but um, if we're if we don't support the board you'll need to add a board definition um, so here's the tutorial on how to build circuit python And then there's also a tutorial to How to add a new board It's faster for me to search my browser history than to find it on learn um So between those two things that should be able like you should be able to add it and then, um Please Submit it and we'll get it on the downloads list. That would be awesome So i'm not familiar with tiny sb. Is the b only workflow moving to be? Tiny usb, but over bluetooth not usb. No tiny usb is more Tiny usb is not not workflow specific Uh, in the same way that bluetooth has This beley stuff that we're talking about has layers like usb has layers as well So like Usb has this lower level link layer, which is what they call it The beley also has a link layer and then kind of on top of that link layer. There's this standard Um, it's almost like services like we're just talking about right like But what's the term? Um, like usb hid usb midi usb mass storage Are all different um classes and descriptors and stuff. So it's it's very much like what Is built almost on top of gat In beley land is also what you need for Free usb. So they're not I they're similar in the way that there's like protocol code That you need that sits atop kind of a standard hardware api Where is like the the amount that you need to change chip to chip is actually not that much Um in beley land In beley land In in usb land that's usually just like there's a few different types of packet types on the wire And then it's all a matter of like putting those together and there's like a pretty small api That you have to implement like on a per hardware implementation basis but then there's also the uh Like but then there's a whole bunch of stuff that's standard that's built on top of that and that's what tiny usb does And then in beley land There is this pretty strong api that the bluetooth spec lays out called hci So there's there's two core components to beley, which is the host and then there's the controller And the controller is the thing that's like pretty timing sensitive Uh, and then there's a there's an api between the controller timing sensitive stuff Out into host land and that's the hci interface um, and so the host side of that can really be um There's a standard api and that could be shared and that's kind of where what what we're all talking about right now um, the lower level link stuff is what the controller handles and that is usually like Something that the vendor provides Uh, which means it's pretty easy to to fit A standard host stack on top of the hci api Ideally Hams lab says i'm gonna set up building circuit by the really soon I let a friend borrow my linux system while i fix theirs and for some reason Things weren't good. So I just reinstalled linux. It's this deep dive started Goodness, that's a lot. Thank you for the explanation Yeah I'd much rather have one stack than a lot of stacks to maintain though. I'll tell you that much And so we were what one thing that we've been doing is like we're The micro python folks have like Two or three beli stacks that they maintain Uh, maintain not the whole stack but maintain working in micro python um And our philosophy has always been to like really pick one And one of them that they use is nimble, which is what we're using here So we're trying to like collaborate with them on on maintaining nimble And changing it in ways that benefit both of our projects because you know Circuit python and micro python have common problems of being more dynamic than usually these stacks expect us to be um Which is the services thing is an example of But yeah, lots of lots of details Okay, so there's how to add the board stuff and discord's a great way Great resource for that There's no software engineering problem. They can't be solved with another layer of abstraction Yeah, Tammy. I've heard that too I think that The main thing is getting the the abstraction in the right places But there's some pretty neat things like the micro python folks have been using nimble for a while And they've actually gotten bluetooth from micro python on linux working Because on linux you can talk hci to like a usb dongle So you can have a usb dongle device that's running a controller and then over usb You can speak hci into your host host nimble stack in micro python um It's very like it's pretty standard. The problem is that not everybody gets it exactly, right? As is the case in most specs It's pretty standardized Okay So what are we thinking? Let's take a look at the Let's take a look at the implementation for The nrf version and see how it works in nrf Which i've already done, but we'll do again And I think we're running out of time because my voice is tired So we'll go another 20 minutes and then call it Okay, so we're in characteristic buffer, but this time in nrf So nrf has this right to ring buff And then it has this characteristic buffer on billy event So this is similar to the callbacks that we were looking at earlier And we can see that there is event IDs. We can see gats so this is server Event right or gatsy If we're a client then we got hvx, which I don't know what hvx stands for But it's basically we received the notification So in one case we write to the ring buffer because somebody directly wrote to us, but And the other case We're a client and they they since we wrote back to us Using that So you can see that this like this use really fuzzes the idea that you have this like One single value that you actually care about In this case, you actually care much more about just the the data that you're sending back and forth Um, but that's the key piece that we're missing here. You can see that We're adding We might want to leave this open So we're so in the constructor for characteristic buffer. What we're doing is we're adding an event handler So we're saying like hey like whoever manages this event handler, which is kind of a global Like hey call this function and give our object back to us if Whenever an event happens and then there's actually like A lot of events that flow through here that we just don't care about they just fall into this default case um And then further down it's all this standard ring buff stuff. So it's really just a like All right in the nordic stuff We have this event handler that gets called and then snags the data out and writes it to the ring buffer And then we read it from the ring buffer as we need it So that's what we need to do on The expressive version as well but this The nordic stuff has kind of like one One event handler to rule them all Whereas a lot of the nimble stuff is like if you're doing an advertisement Like you provide a callback and when the advertising finishes for some reason that callback gets called. There's kind of not Not necessarily one kind of event handler to rule them all But there is one that gets this information about when notifications happen Uh, remember, we're only focusing really right now on the gat client case Because the gat server stuff is hard for other reasons Um, yeah the gat server stuff is hard Um, so what we need to do and I think the way that I decided to do it is um I just need to essentially have this event handler system to delegate, uh, handling of some events down to individual Individual characteristic buffers or we also have another way to buffer, which is packet buffer Uh, unexpected maker says just for clarification. This is all bealy workflow stuff You're working on right now not just standard bealy support for the s3 I missed you starting work on this today. So this is More the ladder it's more just standard bealy support than it is workflow specific um, the workflow stuff Is built on top of our standard bealy apis. So there's a lot of sharing Um, the one trickiness that the bealy workflow stuff adds on top of this is the fact that it It needs to be able to work without doing dynamic memory allocation Um, so you'll see in in these apis that we've got here. We've have these like underscore versions of things Um, and those are the versions that don't allocate memory. They take the memory in Um, and then we have this wrapper version that gets called from python that does do the memory allocation So a lot of it's shared There's not a whole lot of difference But the thing that is different is the fact that we we do have to think about memory allocation um This is not actually working on the bealy workflow side though Because what the bealy workflow stuff needs is to be a GAT server not a GAT client unfortunately and there is difficulty and and and harder things to do and that In that space. So I want to get the GAT client stuff working first, which is GAT client is all about Talking to another device to get information from it um, so after this gets in you should be able to say like Oh, I found this thermometer and I want to read values off this off of this thermometer And then we have scanning working in main now. So it's good to know this is continued support Yeah, so this main currently has scanning and advertising And you can connect to the device, but you can't initiate a connection from the device this code has initiating that connection and um Discovering the services that that device has and then talking to it Handle value notification or indication Right. So handle is like the numbering in the attribute table values the thing it's pointing to And like I said notification indication is like hearing back hearing back from a device to know that something changed I think it should be a little bit more symmetric, but they do like having separate terms or separate things which Is generally a good policy It's just you have to be able to describe them well and Not all the resources I've seen describe them well All right, let's see how far we can get because I did start this so I've added Let's go back to expressive Actually, I'm gonna I think I want to steal this Let's see if we have this in here already We don't I deleted it which is good so, um You can see that we have the same static handler entry here And I changed the name of that I need to figure that out. I should probably move this event stuff Some of the event stuff out. So it's shared So like the names are are different. I'm gonna have a problem with that um But we can do this characteristic buffer on view the event thing So we need those what I was renaming this is I don't like abbreviations So I I renamed this to beauty event handler And the cool thing so the way that the handler works is We're not going to finish this today, but Well, I might finish it after the stream, but Don't go for the stream is ending So the way that the event handler happens is that you can add a handler remove a handler Which are just functions you can add an entry and what this allows you to do is Add something to the list without causing an allocation. Which is great if you're Doing things statically like you do in the bealy workflow and then the way that the You store all of those things is what's called the links list which for any of you who are A classically trained software engineers will have done lots of linked lists stuff um But the basics of linked lists is that uh, you have A struct object and it points to the next thing Um, so it's got a pointer to another entry So that's what this next is and a linked list is defined by Uh, a bunch of pointers between entries and the last entry doesn't point to anything it points to null So next will be null on the last entry of that list um, the advantage of doing this is that, uh There's a couple things one is uh How do I say it? What's nice here is you can mix statically allocated stuff and not statically allocated stuff And we also know that the statically allocated stuff will come at the end Um, it's also nice in that if you need to add more things you don't need If you have an array where you're like everything's right next to each other If you need to make it bigger you have potentially have to move it and copy it and that gets really tough But um, the nice thing with linked lists is that like the things that you add to it can kind of bring the memory with them um Which is really convenient Because so in the case of like the characteristic buffer um In the buffer object itself we can store its entry For for that. So if we look i'm sure it's in there So it makes memory allocation and ownership easier to manage Oh, it's not in there I expected it to be That's interesting Maybe it should be Um This add handler will allocate a separate one Okay, so we need that and then we need The callback Let's just call it the same thing Let's copy these two things This is what i've been doing a lot of so I take the nrf version And I decide how I want to change it one thing here is the right to ring buff I don't actually think I need this so these critical region things are um Making sure that Uh, something doesn't interrupt what we're doing Which then leads to memory issues But I don't think we need that here. I don't think we can be preempted or interrupted By something so I think what we can do here is we can just write Uh, it directly will be fine We don't have a bunch of code that we need to copy in places. It's just one call And then the bule event that we're dealing with is different It's no longer a Nordic thing gap event function So I actually have a second Sublime text open So you can see this is actually the function type for this And it gets the this type of event That's what this is here And the param is the same thing we're going to want to cast it and then we can treat it as self And then event here is It has a type and then what I've also been doing is in default. I've been saying Um If circuit pi verbose bule Let's just print f that we got Uh Handled gap event Which might be redundant. We might get a lot of those prints But it could be kind of handy and that's actually what we're seeing right now as well Handled gap event and then the ones that we want to support So we're gonna actually need two callbacks because in in the Nordic case we get We get events for both writes and notifications But I think the callbacks that get the writes are different than the callbacks that get the notifications So we're just going to do one side of this thing right now And the way that we're going to figure out that is I think in this giant header file So this is the struct that they give you so there's usually like a substruct that matches the type So like periodic transfer scan request received It doesn't make sense a lot of it sense to me that this is in the gap one. It's really not a gap event it really should be gap level but It's complicated as we've all As we've all seen so this one's interesting. So this says uh, something subscribed to you So if you're the server, this tells you that somebody's listening and you need to notify um, so that's interesting and that's actually how It gets really complicated if you think that You know, you are is like you are talking to one other person but you can actually have multiple connections And both of those things can listen to notifications of a value So you have to play some tricks about like well, if you only really want to send it to one place You've got to kind of have a way to figure out who you send it to Um, notify tx. This is saying like something finished Uh that you hint that you did on the server And then notify rx is is if you're a client and you heard back So this is the one we care about and this is actually the The The type that matches up to it So what it gives us is it gives us a buffer of the raw data A boolean essentially to tell us if it's a notification or not um The connection handle and the attribute handle So what we're going to want to do here is it's the equivalent of this And Let's delete that because we're not going to use that here So let's do the equivalent of here This is an anonymous struct. So I don't actually think I want to do this I think what I want to do instead is it must be a notification and event handle much Must match the handle for my characteristics. So we're going to say event And we want to know if it's a notification. So we're actually going to do notify. Oh, you can't see this other part. That's okay Notify rx dot indication And we're going to we want that to be equal to zero If it's one, it's an indication of it's zero. It's not So that's the equivalent test here and then to get the handle we say event notify rx Dot adder handle So that's the attribute handle there and then the data is In this o and buff. This is what I'm looking at So I'm looking at here. This is where the data or data is And this could be more complicated Because it could be non consecutive buffers Which is kind of annoying Um And I don't know it very well So so osm buffs are basically linked lists of buffers, which is convenient if you Don't want to have to do an allocation just to merge stuff together um And that's fine. That's ring buff is copying the data. So we can we could do it piecemeal We just have to get figure out how to get all the pieces out of the m buff Which I don't know how to do Make fetch sub modules is taking a long time Shouldn't be that long It's a lot better than sub module in it, which will pull down a giant github repository For raspberry pi You could do it selectively Patrick says has there been any discussion of doing bealy mesh support? I'm not sure why I'd want that, but I'm curious if Much discussion has gone on about it um I haven't seen any discussion really nimble does support it so That would be a good foundation to build an api But right now I'm focused on getting the existing bealy api that we have going um I figure we would want to do it at some point, but I also like broadcast net But that's my bias I don't know. I'm not sure I've seen a lot of people doing bealy mesh If you want to add it that'd be great Yeah, exactly good community project I mean, that's the advantage of doing something like nimble right is like We could add a bealy mess We could add bealy io and bealy mesh apis that were just standard I don't I think it makes a lot of sense to have a common common stack Hand's lab says it's doing a boat boat ton of clones. That's what fetch sub modules does We have a lot of sub modules And did we merge in this st1? I think I did so yeah, there's even more We have a lot more st Ones now All right, so the next thing that I'm gonna have to do is I'm gonna have to figure out how to split apart this om buff stuff um And then once I can do that I can I'll just add each individual buffer to the ring buffer because I there's no reason I need one giant buffer to copy it over I almost need like a I'm sure there's an example in here somewhere Like here you can copy data Out of the om buffer So I should just I could look at the implementation of that And see how they loop through it. Just do that copy into Concatenate Extend a lot. I don't know what that means Rearrange the chain so that length bytes are contiguous I mean, I don't need to do that. All I all I need to do is go over through through each one So yeah, I think I want to just look at the implementation of Where was it? Copy data if I just steal This I don't see a way how to just say like for every mbuff do this It is really nice that it's open source Copy data Patchy my new offers the world's first fully open source bilistag To play it with bluetooth 5 Yeah I wish it was What people were still working on but I think zephyr has got a lot of folks working on it All right, it's 401. My voice is tired. I'm gonna try to actually get this going today And I've gotten an hour before I'm playing some video games. So I'm gonna wrap it up Thank you all for joining me. Sorry if it costs you to yawn It's been a pleasure hanging out with you Follow along I do push all my changes. So I'm in this ESP bili gat client and it's still running hasn't crashed That's good um So check out my repo. You'll see this ESP bili gat client. I use it as my backup So if you ever want to see what I've been doing check that out um Let me just pull up my Notes to make sure I don't forget anything um As always I'm sponsored by aterfruit to work on circuit python And do all this bili stuff and do these streams. So please support them. They support me You can support them by going to aterfruit.com doing some stuff there Uh, if you want to hang out with me and everybody that you've met today Through the chat, please join the discord adafru.it slash discord That's where we hang out all the time. There is a There is a circuit python dev channel that if you're trying to build stuff, that's a great resource Um, if you're trying to do internal stuff core stuff, that's a great place to start um deep dives happen every week, uh probably for the next Month Um, probably not much more than that at least from me Uh, normally fridays at 2 p.m. Pacific should be true next week as well That it'll be friday 2 Uh, I typically go for two hours or so I haven't done them more in a while. I think I've got to talk less if I'm going to make it past two hours Uh, and then thank you to patrick and david for david for taking the notes and patrick for organizing them on github at github.com slash aterfruit slash deep dive notes Um, thank you to them for doing that. Uh You'll tip yeah, check that out if you want to go back and take a look at stuff. Um Yeah, yeah next week's on friday Hopefully I'll get a pr out or at least makes some progress on this cat client stuff today and I'll pet the cat and we'll get out of here. Uh, we'll see you on the discords and streaming next week All right. Have a great weekend everyone