 Okay, Lady Ada beaming you in. So here's what we're doing, everybody. ChatGPT latest version for, we're using August 3rd version, we have a whatever pro account. Lady Ada is telling ChatGPT, hello, I'm Lady Ada, and we're going to write a library, or doing a library in the same style as, guess who, me. What we found is a lot, if not pretty much all of the microcontroller code out there that ChatGPT was trained on happens to be from Adafruit, one of the benefits of thousands of open source repositories. So, you know, there's a polarizing debate about should people even use these tools or is it going to take over the world, is it going to enslave humans, all this stuff. However, it seems like we're using it in an interesting way because it's using our own code. So Lady Ada is going to do a demonstration of using her own code, finding a PDF, doing all sorts of stuff to make an Arduino library. And for the folks that are super pros out there, and I know there's a lot, tell us how we can make this even better. We're using a plugin for a PDF, there's ways to go on the web. This is like my third day with this, you know, it's very new. And one of the things that we're trying to do is figure out when we do a, we do MIT license for everything, we're trying to figure out how do you, how do you credit? Hey, I co-piloted this with ChatGBT, but it was using my code on things, writing in my style. There's another feature of ChatGBT where it's a preference and you can say, hey, I'm Lady Ada, I'm the CEO of Adafruit. This is my directive. We're not going to do that, this video. Yeah. So without further ado, as they say, Lady Ada, why don't you write a library using a robot friend? Okay, so as an intro, you know, one of the things that I do a lot when we go to GitHub and show is we have a lot of repositories full of Arduino libraries, like we have 1.8k repositories. We have about like 500 or so Arduino libraries and circuit Python libraries as well that we've written for all sorts of chips. Every kind of sensor, accelerometer, OLED display, whatever, we write drivers to support them because that's like the tough part of getting something up and running. You just want to like wire up or plug in I squared C or SPI and like get the data out. You don't actually care about how the list 3DH does what it does. You just want to know what the X, Y, and Z acceleration is. And that's like what like me as the engineer at Adafruit like kind of does the most is craft these drivers and examples so that people can get started immediately and then I sell the hardware to help fund all of the development that we do. And so one of the things that I'm always on the lookout for is new fun chips. And for the last couple of years has been a bit of a chip shortage. So not a lot of new chips were coming out. A lot of my time was spent doing redesigns. I did like over 400 redesigns. But now I'm kind of getting back to like, oh, you know, like chips are available again, even ones that were released before 2021, you can now get them again. Like it used like for a year there, it was like you couldn't even get diodes, right? But now everything's available again. So let's make these breakouts and get these sensors back into the shop. And designing the hardware for a sensor is actually not that hard. I'll be honest, like for me, it's like, I don't want to make a humble brain. I'm not it's just usually like you just follow the data sheet and you connect up the power and you connect up the I squared C. And as long as you get the footprint right, and you add a couple capacitors and resistors here and there, almost every sensor I work with has the same kind of hookup. It almost always uses I squared C three volt power and maybe a level shifter. So there's a lot of like copying and pasting with the schematic and the board layout. That usually only takes me a few hours. But what does take a really long time is writing the Arduino driver. So Arduino drivers. So like, let's look at the VCNL 40 10. This is a driver that has Arduino and circuit Python support for it. And in the driver, you know, you have to set up all the registers and document them. And then there's always these enumerate like enumerations for all of the different settings you can set. And you want to have them pretty printed. I like to have the, you know, the enumeration be like visible so you can see like what it is that you're setting instead of just like to and like somehow you would know that that is the same as 7.8 measures per second. There's all these like sub register commands, you have to have the setters and the getters. And I have a certain style that I use, sorry, called bus IO. And this comes from circuit Python where we use a library that does the I squared scene SPI interfacing with registers, basically to avoid the error prone masking and bit setting that is historically used in, you know, like a lot of Linux kernel drivers, honestly is where I've seen it a lot where you actually read them the whole eight or 16 bit value and then you try to like bit mask off the bits and read and write them so that you only touch the bits that are relevant. Very error prone, very easy to like make mistakes and like, you know, you're trying to do hex in your head. So what I tend to use is this one, sorry, this is a not one that uses I squared C registers. This is a very old library. Let me find one that does I scored C register bits. Okay, so the INA, this is a good one. So what I tend to do is this is a different sensor that does current voltage sensing. So I'll have these getters and centers and what I do is I'll create a register. So let me see if there's, okay, for example, this, well, this bus voltage, I'll create the register and I give it the I squared C device. I tell it the register name, which is pound defined in the header. How wide the registry is this one is 16 bits, two bytes. Is it MSB first or LSB first? And then I can read from that register object and that will do the I squared C transactions. And then if I need to go into the bits, I can use one of those registers and reach in and say, I only want to touch the three bits starting with offset zero. So this is a three bit wide sub register address. And it will do all that masking for me. Is it faster than doing bitwise? No, it's much slower because I have all these levels of indirect computation. But it's a lot easier to read. And so far has been much, much more maintainable. And when we do make mistakes, it's easy to catch them, which is important for the chat GPT part coming up next, because chat GPT likes to hallucinate. And I don't know if it will hallucinate when I do this driver because I'm doing it live. But in past ones, it's made mistakes about bits and shifting. You have to watch what it's doing. But by using this style, this like Adafruit Lady in a bus IO style, I've been able to catch mistakes a lot faster. And then once I correct them, usually it doesn't make the mistake again. So obviously, you know, like I'm setting up like, how am I going to write this? I'm going to be using this existing style. And here's the good news. For the last like five, six years, I've written hundreds of libraries in this style. And so chat GPT four has been trained on it. And so I don't have to like teach you this new model. It's already learned from GitHub, and it can follow along to make a new library. So what I'm going to do is I'm going to make a new library for this chip, the VCNL 4020. I already made the breakout board for it. And I've been kind of like dragging my feet about making the driver. Because again, it's like it can take many, many hours. It's very tedious and not only is it tedious, but you have to be very careful. There's a lot of like, delicate, like don't met, you know, if you make one mistake early with a register, hex value, you don't catch it till later. And you're like so sad because you're like, I've been spending all this time figuring out why it's not working. You weren't even addressing the right register value. So one thing that Mr. Lady eight pointed out to me was that there was this plug in called AI PDF. And you can see it right here. It's in it's in like the shop. It's like a free plugin. I am using chat GPT four. I will say that I have used 3.5 and three, and it did not do nearly as good of a job with this kind of work. Could you get it working with 3.5? Probably. But for me, it's absolutely worth paying the 20 bucks. So you may not need to, but you know, here you go. So the first thing you're going to do is, you know, you find the chip you want. I get my chips from digikey, but of course anywhere else. And there's a data sheet. You click on the data sheets. And here's the neat thing. I'm going to have chat to be to reading the data sheet. And then I'm going to use it because I actually tried earlier to see like, oh, can chat GPT extract the data and make a table for me. And that didn't work out. But what did work out is having it reference the PDF while I'm asking it to write the driver. So we'll do this live, but we'll see how this goes. So I'm going to make a new chat and I'm just going to copy and paste the first prompt because I did, I didn't work on this last night, but I'm going to kind of like remake it. So the first thing you do is like, you know, one fun trick is you can tell it who you are, like who you want it to pretend to be. So I wanted to pretend to be me. And I'm going to make a Arduino library. I'm going to try to set with circuit Python too and see if that works. And then here's the PDF. And here's a typo. So I'm going to fix that. And another thing that I'll note is, you know, chat to before is a little bit slow. And one more thing is it is limited. There's only 15 messages per three hours. So, you know, bunch up your requests as much as possible. And, you know, I, when I first wrote a driver, I gave it all this positive reinforcement. I was like, good job making me this function. And that like wasted a message. You know, give a positive reinforcement and then immediately say, okay, here's the next thing I want you to do. Okay. So this uses the plugin to read in the PDF and it got all the text in. Okay. So, you know, it's kind of reading all this stuff. Okay, good. So now we are going to start writing the Arduino library in Adafruit style. Please make the header file skeleton to start. We are going to call it Adafruit VCNL 4020. So another thing is, is that you do need to like tell it what you want. And one technique that I've learned is that you, you do guide it like you pretend like it's an intern for like lack of a better phrase where you're kind of, you know, gradually telling it, you know, here's how I want you to write it and like what I want to call things in the function prototypes. So one thing that's interesting is that when I did this yesterday, oh, sorry, no, this, yeah, when I did this yesterday, it actually didn't have the register definitions because then I added them. So it's being a little bit smarter than usual. But one other thing to notice is that it kind of hallucinated some of these things. Like I haven't asked it to write these functions and also these functions are quite correct, but it's probably looking at other similar drivers that I've written. And this is a very common, you know, I often say like set proximity rate from like the VCNL 4010. So it's probably kind of grabbing that stuff. Still, this is a good place to start. Um, yes, actually, no, let's let me look at this library. So okay, so now we're going to ready to write some code finally. So the first thing I'm going to do is I'm going to write a very simple function. I haven't to have read this already. I want to actually do the product ID register because that's a kind of a really good one to start with. A lot of modern iSquared C sensors have a register you can read that will tell you that you're talking to the thing you think you're talking to. So I'm going to say, hey, I want you to make a getter for this register and I'm going to copy and paste it from the PDF so it knows what I'm referencing. Let's write the first function. I can't spell function. U and AT get pod ID. What's it called again? pod ID web. This will use Adafruit bus IO to create an iSquared C register to read register one part ID revision ID. And then actually, you know, it didn't make the full register definition. So I'm actually going to I'm going to put this in the put this in the parking lot. Let's start by having it make the register definitions. Now first, we need to make the register definitions. Starting with register. Starting with and ending at let's see, it's the last register. Sometimes they have a big table, not another big table. So I'll scroll down and the last register is called adjustment timing. Use pound defines to set the hex value and also put in doxigen comments. This is another thing that I like have learned as I do this is usually when I write code, I do I write all the code, I get it working and I add the doxigen later. But with chat, I just tell it, hey, do the doxigen comments as you go. So it goes through and one thing that I thought was actually kind of interesting and smart is it recognized that close this. This is register number 15, but the register address is 85 hex, which is like, you know, I could see how in a beginner would get that confused. You think, oh, it's address 15 because it's register 15. Okay, so good. It did all of these registers for me. Love it. So one thing I'll also mention as I do this is as it does little chunks for you, you'll want to copy and paste those into your like working VS code file because it can't output the whole file for you, it'll just output little chunks, but then you can just like, you stitch them together at the end. Okay, great. Now we will start writing the library. Then here's our command. So we're going to do the first function. And again, this function is very simple, because it's just going to read the eight bits and return it. And then in our setup, we're going to query it and just verify that it is the default value, which is I think hex 21. Yeah, so the value is, it's actually hard coded. It's read only. So I don't need a setter, I'll need to get her. And then my code later, I'll make it check that it's 21. Okay. So this is how it did it, but that's not the style I want. I want it in this style. Okay. Begin. Okay, so did the big begin function? Nope, I prefer that we define the bussio register within the function, not in setup. Nothing is as very wordy. It kind of likes to be like, hi, like I would like to tell you about my feelings. Okay, so here you go, much better. Okay, but we can simplify it just return the read directly. Let's see. And it's like, oh yeah, you're right. You just return the value directly. I mean, not that the code before was wrong, but it's like I like to make it nice and compact. And another thing I notice is you can leave off the, as that is the default value for the object prototype. You can simplify the code, you know, why go through and have it tweak the first function, the simple function, because it remembers this context. And then later, you'll, you'll see it leaves unnecessary stuff off. And it like does this compact style. Okay, so this is really good. So I'm not doing it right now, but normally I would copy and paste this again into my little C holder file, because I'm going to go through all the different registers. And it's not, it doesn't, it won't concatenate it for me. It only gives you one function at a time. Okay, so we've done that. So next step, we're actually going to skip the command register, because it's like really detailed, because I want to kind of get through this, you know, I don't want to do it all together, I want to do each kind. So I'm going to say next we're going to do this register. Next we will, and this is read write. So we're going to do setter and getter. We will write the setter and getter for proximity register two begin by making an enum table for the possible proximity weight values. They are three bit binary values. Okay, you know, every time I say this, I say it slightly differently. So I'm going to see like, if it can understand my instructions. So this is actually kind of where, this is kind of where I was like, Oh, this is really nice. So normally, I would have had to go through and like, had created this enumeration table. But it does it for me, I will say, check it, you know, make sure starts at 1.95. And then ends at 250. I say, okay, I want this to be a little bit different. Please rename the enums to be like prox rate 195 SPS or MPS. So if I want a different style, instead of having to go in and like hand edit it, it'll make those changes for me. And notice the very nice doxygen comments. I love it. Right. Okay. So you would put that type def enum. Oh, you know what? I want to change this. I want to call this. Please call it. I want it to be, I like to have unique enum names. So VCNL NL 40 20 prox call. I'll say the enum. I'll just change the type def for me. This would be like trivial for me to fix, but if you tell it to do it instead of editing it on your own, it will then reference the enum name properly when it creates the setters and getters. Okay. Cool. Now this is the way I like it. Let me see. It just finishes and it's like great. Now the proximity rate. So it's, it's updated the enum name. Yes. Now let's do it. Please write void set proximity. Let's see, prox rate. And then I like to, I like to give it the prototypes and get prox rate. And we'll see whether it can do it. So this is a challenge because this is a multi-bit entry within the register. It always gives me these, like the, it also gives you the function prototypes. Don't forget to save those also. Okay. So notice, well, technically this is correct. It's actually like not really correct. So I'm going to tell it, please check the datasheet so we can make the Adafruit bus IO register bits function to address only the proximity rate bits for the register documentation. All right. So this is the, we'll see if this can do it. So it's going to check the AI, these AI PDF. What I wanted to recognize is that the proximity rate is only the lowest three bits. While again, if you wrote these are not available, that probably nothing bad will happen because they happen to be the bottom three bits. I would like this to be correctly styled. So, okay, cool. It's like, hey, I noticed that it's bits zero through two. So I'm going to use register bits instead. Ooh, not quite. You, interesting, starting to make, starting to make different mistakes. Please make the bus IO register object first. Then you can use the register bits object to address specific bits inside. I'll have the correct function name. My favorite thing is it's like, certainly like, oh, yes, obviously that is the correct thing. It will always be very positive. Okay. This time it did do the right thing. So it created the register and it, again, it's like, you do have to do this once. But once you set the context, future registers, it like, oh yeah, that's right. I remember how you do this. You don't have to set that context. So it, let me see register bits. Let me make sure that it might not know the prototype for this. So I'm going to go to bus IO, and then I'm going to tell it. One thing I might do eventually is figure out how to tell it the register prototype. So this is the prototype for bus IO register. And this is the prototype for bus IO register. And this is the prototype for, let's see, register bits. Because it got, one interesting thing is it swapped here. It swapped bits and offset. It didn't know which one was which. The bits register, register bits object. Let me see if it's smart enough to realize that it got them swapped. I think in previous chats actually told it like what to do. Okay. So this time it did it right. It was like, oh, you told me the prototype. It's the number of bits and then the shift afterwards. Okay. So this is correct. And then this is correct as well. It did do the casting. Good. This one is correct. Okay. Good. So we did do that. Next up. Let's do, again, I don't want to like do a ton of different things. Let's do the read result register. Let's skip over to, this is a two byte register MSB. Please write ux16t get ALS void. Getter. This one's going to be interesting because it doesn't have bits that it has to look into, but it does have to recognize that the register is two bytes wide. It's not a single byte. So given that we earlier gave it the function prototypes, it should recognize that it has to do two MSB first. And let's check to do the high byte first. So that's the address going in. And note that it remembers that it made that table before. So it gives you like all the right register names. Nice. But you can just return the value directly. Next, I'll have to do the proximity result register. And then I think that's it. I mean, what do you think, Mr. LaVietta? Wrap it up. Yeah, wrap it up. This is a little bit like a cooking show. So do you want to like show the thing out of the oven? Well, I didn't finish that full driver, but I'll show the chats that I did before. Let me do one last thing. And then while you're wrapping up here, for the experts and all this, you know, experts, this has been around like for a month, for everyone who's really good at this, let us know what other things that make sense to do. But be a little specific, like if there's a plug in the tribe, right? If there is a demand for doing things a little bit different, we know about the preferences that you can put like, hi, I'm LaVietta from the start. So you have to introduce yourself. But, you know, a lot of this is new. And there's a lot of hype. But then there's a lot of practical things. We're probably using it in a very different way. I haven't seen anyone do anything like this. But if someone is, let us know as well. I also know there's developers that are just like, well, I'm using these tools, but I don't want to tell anybody. That's fine. We're going to always disclose when we use these. And I'll probably drop a note to OSI, I guess, or like, Ashwa, I don't know, and say, hey, like, what does it look like when we credit? To write oxygen header comments and give me the completed functions back. All right. So finally, let's say we did all this thing. And then I realized, oh, shoot, I forgot to do the oxygen comments. Because again, I always forget to do that till the end. But, you know, I have the CI that tells me I have to do the oxygen. So I'm like, not going to forget, forget. So, you know, I go through and I do it. It does that seem like, oh, you know, you're kind of telling it detail, detail, like, well, you know, is this really worth it? The thing is, is that I wrote a longer library before, and it does catch on, like you have to kind of tease it through the first one. And another thing is, is that I'm starting a new chat, I think that if I had like one long chat called like, I'm going to teach you how to do Arduino libraries, it would remember more of the context of like, it wouldn't be like, oh, I need the prototype for that function again, or like, how do I address the bits? And is it shifted first or with first? Once you teach it, it learns it. So, you know, I started with like a fresh chat, which I think does kind of give it a clean context. You might be better having like one long context where you kind of teach it step by step. So, the next thing is, you know, I'm like, okay, give me every function with the doxygen. So, one thing about, I'll say about the doxygen commenting is, it's always technically correct, but it's very like uncreative. And it doesn't like understand exactly what the data is like means and is good for. So, it's not smart in that way. It will, you know, one of the things that I do like is at least gives me like the, you know, at brief and it does the dots and it gives, you know, everything's nice and pretty and ready to go, very copality. And it does fill in some of the basics, but you will have to go through and make sure does the output give you like what you, is the output like technically correct? Because I have seen like you saw like bit swaps and like wrong addresses and I'll just go through, you know, quickly. I did this and many more functions and maybe, you know, I'll Mr. Lady, I like the output from this. You know, I started to get to more advanced things. So, like, okay, for this one, this was interesting. It got very confused about the bit width of a setter. And this was, I didn't use it enough. I was like, okay, I want you to take the input value LED MA and I want to divide it before you assign it. And it, you know, created the headers for me. And then it's like, it's a five, it's a seven bit LED current field. And I think it thought that because before you divide by 10, it probably would fit into seven bits. But I was like, no, it's check the bit width and it would do the AI field. And it was like, no, it's seven bits. It was like totally convinced. Eventually I just had to say, look, it's six bits wide. And it was like, oh, yeah, right. And then, you know, it fixed this bit width argument to the function. So, it will, it will, it will hallucinate. It will continuously tell you like this, this, this. It will not, it doesn't teach you everything about writing drivers, but like one of the things that I really liked about this, just like wrapping up is I'm writing drivers now, like very, very tired because I'm like taking care of a baby all day and like doing all the work I have to do. And then it's like, okay, now write a driver. And it's like, you know, midnight. And I'm really tired. And it's like, I don't have the energy to like relearn all that context. Like, where was I, what was I doing? With chat, I can use like my higher functions, but I'm not sitting there like copying and pasting and making like typos. It's easier for me to copy edit and make sure that the output is correct and for me to write it by hand where like, I'm hallucinating at like one in the morning. But so far, you know, I've written, you know, basically wrote this driver. And, you know, once, once it got the hang of it, again, once I told it, like, here's how you write a register, et cetera, and get her that actually just kind of like started popping them out pretty nicely, you know, ready to go with all the, you know, the doctors already already. And it would tell me it would tell me the bits, the documentation to remind me it's one bit of position three. And so if I made a mistake, I could easily look it up in the documentation. But you know, it's trained on like all of my libraries. And what's interesting is it's clearly like my style of code, like the way the register is set up and then the way I address the bits and read and write from them, it's like, it was, it's very nice to see like it's a little mini me. So you know, yeah, it was like it would start doing the enums for me. And it, you know, got my style that I like to type def. It's like, Oh, you like the underscore, you know, lowercase underscore and name. And then I can, you know, do some swaps. So this was a really interesting and like makes makes it much, much easier to do the very frustrating work of transcribing a data sheet into a driver. So this is my first experimentation. Again, like I only like signed up like three days ago. And I've been, you know, like my first experiment was just like, okay, I want to like turn a list into hold on. Oh my God, I can't scroll up to the very top. So I scroll. Oh, there's a school bar. Okay. You know, the first thing I was just doing is trying to do that TFT in it and then this conversion where I was like, okay, well, I'm just going to copy and paste from the data sheet. And this was using GPT 3.5. And it could do that. But then like realizing I could use the PDF was Mr. Lady 8 as really insight. Anyway, so that's me trying out chat GPT for writing Arduino C libraries using the data sheet, PDF data sheets, a reference. So far so good. Like, you know, I think this could be a really great tool for driver writers. You still need to think of a little bit. You'd have some human touch. But a lot of the heavy lifting is done for you, which is quite nice. Okay, if you stay with this long, please put things up in the comments be specific about ways we can make this better. If there's people out there doing stuff like this, let us know if there's plugins we should check out. We're also going to do an update. We'll post this code somewhere. Maybe I'll do a blog post. Yeah. And Lady 8, it cannot toss me the Python code. Sorry, the Arduino code. Yeah. And then we'll turn it by thumbs. Yeah, maybe next weekend. Yeah. Okay. Bye, everybody. Later.