On the latest Desk of Ladyada, we shared our experiments with Claude Code, a new large language model (LLM) tool, to streamline hardware development – WAIT WHAT? That’s right! Streamline hardware development!
We are using it to automate parts of the coding and debugging process for an Arduino-compatible Metro Mini board with an OPT4048 color sensor. Using Claude Code’s shell access, we can compile, upload, and test code in a semi-automated workflow, allowing the LLM to suggest fixes for errors along the way.
The process involves using Windows Subsystem for Linux (WSL) to bridge hardware interaction gaps, as Claude Code doesn’t run natively on Windows yet. While the AI isn’t perfect for high-level driver development, it’s proving VERY useful for tedious debugging and super-fast iterative improvements, bringing hardware automation closer to …reality – video.
Transcript (human edited from a transcription by Trint):
[00:00:00] Alright, Ladyada, what is this?
[00:00:03] So this is a really interesting project I’m doing right now. This is a Metro Mini, so it’s Arduino compatible. This is a little sensor, and I purposefully am picking a sensor that’s not particularly complicated. This is the OPT4048, and this is a tri-stimulus color sensor. It’s basically a light color sensor. And what I’m doing is I’m experimenting with this new LLM technology that just came out called Claude Code.
[00:00:28] Claude Code is like, I’ve used Claude a bunch of times. It’s an LLM where you have a window and you type back and forth, you use the API, you use like a whatever, some GUI. And sometimes you can use stuff like cursor where it’s embedded in your editor. But I’ve never really liked the embedded editor part of cursor. I really liked to kind of work with my files.
[00:00:48] And also… Something that’s very interesting about Claude Code is it gives you shell access to the LLM, which I think if I told myself to years ago about this, they’d be like, this is incredibly stupid. Why would you give this crazy AI access to your shell? But you know what? We’re living in amazing times. So the fact that I can tell Claude now how to run shell commands means I can have it automatically compile code for. Arduino compatibles with the Arduino CLI, and then upload the code, and then check the output and fix the code. So I have a full debugging cycle where I’m there, I’m driving the car, but I have this co-pilot that’s telling me where to go. So we do it together.
[00:01:34] I’ll show you how it works through the command line tool. It’s like a weird cross between IRC and a BBS or whatever, and also using CMake. Or whatever. Um, but just to show you, so this hardware is connected to my computer. Like I said, Arduino compatible, and it’s got this little sensor connected over I2C.
[00:01:53] So now let’s go to the computer. Um, so like I said, if you want to use Claude Code, I think it’s out of preview mode so you can install it. I’m running windows. I’ll say just like, I’ll have some hints up later, but basically if you’re running Windows 10, you need to be running Windows 11 to do hardware interaction because you’ll get through like the call installation, then you’ll realize you have no way to access the USB device. And you have to access the USB device using USB IPD, which is the WSL, that’s Windows Subsystem Linux, way of getting hardware that would normally be here. It’s not appearing here because I’ve bound it into WSL. Now you’re probably like, why am I using WSL? ‘Cause cloud code doesn’t run on Windows native yet. So there’s a lot of these like weird ass workarounds I’m doing just because it doesn’t run on Windows natively yet. Why? I don’t know. I’m sure they’re working on it. I’m sure Claude and people who tend to Claude or like going back and forth. But it does work under WSL. I’m using Debian in this case. Um, there’s tutorials on how to do USB IPD, but basically, um, you know, you have these, you know, devices. And in this case, I’ve attached. the Scilabs chip, which is a USB serial chip, COM port into Debian.
[00:03:14] And so in my Debian desktop here, I’ve got, let’s make this nice and big. It shows up here. And then I’ve got a ttyusb0, right? I’ve got access to the serial device through WSL, not through Windows proper. Okay, then you’ll have to install like Arduino CLI and you’ll have to install some other tools, whatever, and like, you know, I’m not going to go through all that. So the way I’ve kind of come up with this, like workflow and I’m using this, I’m just using notion, which is like a way of like having text with an easy way to copy and paste it in. I’m trying to come up with like prompts that can kind of recycle and reuse. And one thing that’s like, you know, as I’m doing this is frustrating is of course, like LLMs have this like randomness in it. running the same prompt over and over doesn’t always get you the same output, but you can kind of sort of tweak the prompt until it gets really close.
[00:04:18] So one of the things I’m doing is I’ll show on my main screen. You know, there’s the data sheet. Right. But the data sheet is massive. And also it’s like weirdly formatted and only work with text. So we have to tell it to do. and I do this in the initial prompt is I kind of give it some ideas of like how to style, etc., and then convert the PDF into a text file.
[00:04:48] So here I’ve created, another thing I’ve done where I’ve separated the Arduino, like I’ve created a separate folder for like my Arduino work. So it doesn’t touch like my main library folder. And in this folder I created a new library, OPT4048. And I have the PDF file. The PDF file is the datasheet.
[00:05:08] So now you launch Claude after you’ve done the NPM install and it’s like, hi, I’m here, I’m ready. And like I said, you know, one thing I did, oh, by the way, you need an API key for this and it’s not super cheap. So just be where you’re, you’re going to be burning API queries, but I ran this over and over again until I sort of, I feel like “Thank you very much. Thank you very much. very close.” Um, so I’m kind of running this live. Hopefully it’ll work. Um, if it doesn’t, I’ll try to fix it.
[00:05:34] So I paste in, you know, my prompts. And like I said, I, you know, a lot of the prompt is just telling it like, please don’t write all of the code at once, but it kind of does anyways, ’cause it’s Claude. For everything you want to do, reading files, writing to files, diffs, et cetera. It’ll tell you like, for example, it wants to run this bash command. And I can tell it you could want it this time. You could always run PDF to text. I’ll just, for now, I’ll just say yes. And you can see it’s kind of got this like nice curses, you know, colorful boxes. I kind of feel like I’m like back in like the nineties. Okay, so now it’s converted it, it reads the text. And what’s interesting is I think that this is how like ChatGPT was reading PDFs. ‘Cause I was like, I’d upload a PDF and I was like, how are you reading, like how are you parsing it? And I think it was just using PDF to text. So if not, I don’t know, I’ll find other tools. I don’t know if converting it to Markdown would be any better.
[00:06:32] Okay, so what’s nice is that it gives you a diff and like my text is really big. Again, I think once they get this going, it’ll be more integrated with an IDE. So what’s nice is that it tells me like, okay, it has the Doxygen formats I’ve asked it for. I tell it to use busio. I tell it, okay, please just make that register map like all of the registers in the data sheet and give me a little information. And you start with just the instantiator and the begin. And then it says, do you want to make these edits? What’s nice is that it doesn’t make changes, even though it has the right access to files in the directory, it doesn’t automatically do it unless I tell it.
[00:07:12] I was talking to someone who does a lot of like work with machine learning and I was explaining how I use LLMs and she was like, yeah, because you do Open Source, you get to treat it differently because you’re using all the history of my stuff.
[00:07:25] Okay. Now it’s going to write the CPP file. Ditto. It kind of copies my standard boilerplates, you know, license text, the header, it does the I2C device delete, create, you know, you can pass in the Wire, you can pass in a separate I2C address. In this case, what’s interesting is I actually told it not to do this yet, but it did it. And I don’t know if it’s because I’ve run this prompt so many times that it’s like been added to some history somewhere, but anyways, it creates the CPP file. So this is actually where I would normal, like I’ve done this with Claude and I’ve gotten to here and then I would actually just copy it. Like literally I’ll just copy and paste all this text and say, make the header, make the test. Here’s the, I know that’s the test example. It creates the object. It starts serial. I tell it I always want this baud rate and then halt if you can’t find it and then do nothing else.
[00:08:18] Where it gets interesting is I created those files and I saved them to the filesystem. Great. In this case, I already did this, but I’m gonna copy. Like I said, it kind of skipped ahead. I told it like, don’t write the test function, but it will write the test function. Anyways, now what’s cool is I’ve edited the prompts to now ask it “Can you check if you’ve already done this?” Because one thing I’ve noticed with Claude Code is it doesn’t save your context at all. There’s no way to, like, you can compact it and you can tell it to write to like a Markdown file. But basically every time you connect, like as usual with an LLM, it’s like a totally fresh connection.
[00:09:00] Next up, that’s where it gets interesting. We can actually tell it, okay, let’s compile the code with Arduino CLI. I installed Arduino CLI and I tell it “if you’re having issues, use the verbose mode”, but let’s just try getting it compiling the sketch. I tried to make this generic so that I can reuse this prompt for other chips without having to tweak and edit the prompt. Hopefully this is going to work. Okay, cool. It was able to compile it. You can see, it does give you the output and I think I told it lto use verbose mode. Let’s seeif it used verbose mode at all. I didn’t ask it to. Why is it taking so long? I think the first time it compiles, it takes a while. You get a little bit nervous when you’re just sitting here for like 30 seconds. What are you doing? It’s just good.
[00:10:02] Actioning.
[00:10:03] I think I’m going to just tell it to stop. Okay, it compiled. Now let’s try uploading. I don’t know, it kind of went. Okay, so now I’m telling it to, like I said, every time you run it, it’s like, it’s not determinant. It’s indeterminate.
[00:10:21] Okay, so it found the USB port because I tell it to run boardless so it finds the port. And then that’s how it knows what my USB port is called. And then the first thing I do is actually I don’t upload the test sketch it wrote. I actually tell it to upload the I2C example from Adafruit Testbed. And the reason I do that, you can see this, this was just blinking, is I want it to verify the hardware connection and also just to verify like it can actually do the upload.
[00:10:48] Second, I want it to get the serial output, right? Because I want to see like, did this work? So I use grab Serial, you can use STTY, you can use like whatever, but the trick is, you know, it’s not. You need to tell it to like do a timeout or like don’t, it doesn’t know how to quit things, I don’t think. I think it only runs in non -interactive mode. So just make sure any bash commands you want it to run are non -interactive.
[00:11:10] So in this case, you know, it tells you the output and I say, you know, look for the I2C address 0x44, which it finds. And it’s like, great. Now I can continue with uploading the sketch. It uploads the sketch. And then now I’m going to tell it to check the output. And then this is gonna be interesting because sometimes I run it, oh yeah, it works. Sometimes it gets the bytes, the chip ID backwards and it does eventually, I didn’t record it, but it got the byte order backwards. It thought it was like 0x2108 when it did the comparison. But then by reading the output and I told it like, we’ll try to fix it based on what you see the I2C traffic is. It was able to say like, oh, I see what happened. I have to swap the bytes.
[00:11:58] That’s how far I’ve gotten so far. But I think this is like the hardest part for me, getting the context started, because now I can just say like, okay, let’s just go and do all the registers. And then for each register, like what I do is I have on my side monitor here, the data sheet, because I don’t trust the LLMs, like they do make mistakes, especially as the context gets started long and they start to like get confused.
[00:12:28] So what I do after, once I get like, okay, it’s started, I say okay, let’s go through the register map and find where the register map is because it’s like how to use it. I say like, okay, add setters and getters for the register map, the components and the LSB. You probably could do an okay job, but I found that so far, because drivers are complicated. It works best if I tell it to go forward five steps and then let’s test that and then go forward with the five steps. The next thing I would do is have like the operating mode. Add getters for all of these counters and stuff. And then eventually, I’ll tell it, okay, now convert this data into like the lux or XYZ data and do the test.
[00:13:19] I’m kind of interested, you know, it’s like I said, I’ve used Claude Code and Sonnet for hardware work before, but it’s always been me just like doing this copy paste back and forth, you know, a little delicately, trying to make sure that as the context gets long, it can start rewriting the right things, trying to make sure that I’m getting everything in the right spot. What’s neat, also, is there’s a couple other extra things built in, which I haven’t used yet, but I’m interested in. One is you can compact the conversation, and then another thing you can also do cost, you can say, you know, how much.
[00:13:58] How much does it cost?
[00:13:58] 60 cents.
[00:14:00] This is not bad, it’s like an arcade, it’s like a token.
[00:14:05] Two Pac-Man runs.
[00:14:06] Inflation, man.
[00:14:07] There’s another thing I’ll say. I can’t quite figure out how to get there, but there was a way, you can go up to look at previous commands, but there was a way to get to like the conversation and fork it off. I don’t remember how I got there. I have to like some like special command, but anyways, cool stuff. I think this is the first time that we’ve gotten automated hardware.
[00:14:31] Let’s take this one offline.
[00:14:33] Yeah, it’s like, let’s do hardware development fully. You know, like having that hardware workflow where it like does the coding and tests. And even like, I’ll tell you, I wouldn’t, again, I wouldn’t use it for like the high level thinking of how a driver should run, but like stuff like, oh, there was a compile error or like, I forgot a typedef.
[00:14:54] You know, if I didn’t copy and paste something right, it’ll fix little bugs like, oh, I thought there was an underscore and there wasn’t. It will see the compiler error and then it’ll just fix it. So I think for library developments can be kind of neat. Hardware development, people always ask me “How come you can’t do continuous integration with hardware?” And I’m like, how would you have automated upload and then look at the output and know what it meant. But I think we’re getting close to it now. Anyways, check this out. Thanks for watching!
[00:15:20] Well, you know, I’m sure these techniques and more are in Apple and, you know, yeah.
[00:15:27] They’ve got something. Yeah, no, they have something, but it’s like, it doesn’t make sense for them.
[00:15:29] It doesn’t make sense for laymen to do it. We’ll never know. It’s a secret sauce with so many things. This is cool. This is like we’re making advanced manufacturing. We’ll never know. It’s a secret sauce with so many things. in a unique way.
[00:15:39] Yeah. So I’m going to continue. I’m gonna continue.
[00:15:40] For 60 cents.
[00:15:42] I mean, it’s a bar, I will say, you know, you’re paying per token, so it’s not going to be as cheap as the flat $20 fee, but like, if I can, you know, getting it to this point and then again, continuing on with the driver, I’m going to try it out.
[00:15:54] I haven’t actually gone, like I just got this working to this state where it’s like, okay, I can consistently get it to upload code and check the output. And the next step is to do this, but like, I feel like I’m getting closer to having a semi-automated way of doing driver development, which is like very tedious. And this will also be very interesting for CircuitPython and Python hardware development, because again, like Claude is really good at Python.
[00:16:21] They all are. So that’s the neat thing. It’s like almost a native language.
[00:16:25] Anyways, so that’s uh more later More later.