1 00:00:01,940 --> 00:00:06,580 Welcome to the CircuitPython Show. I'm your host, Paul Cutler. This episode I welcome 2 00:00:06,740 --> 00:00:11,340 John Romkey. John is a computer scientist, software architect, and long-time internet 3 00:00:11,380 --> 00:00:16,800 engineer who's been building and breaking networks since the early days of TCP/IP. John 4 00:00:16,860 --> 00:00:21,100 demonstrated one of the earliest Internet of Things devices, the Internet Toaster, controlled 5 00:00:21,220 --> 00:00:26,760 via SNMP in 1993 along with Simon Hackett. John currently works with microcontrollers, 6 00:00:26,840 --> 00:00:29,080 sensors, home automation, and full stack systems, 7 00:00:29,360 --> 00:00:32,040 with occasional detours into PCB design and development. 8 00:00:32,780 --> 00:00:34,840 John currently works with microcontrollers, sensors, 9 00:00:35,030 --> 00:00:37,260 home automation, and full stack systems, 10 00:00:37,500 --> 00:00:40,440 with occasional detours into PCB design and development. 11 00:00:41,090 --> 00:00:44,580 He enjoys programming in CircuitPython, Python, Ruby, C, 12 00:00:44,820 --> 00:00:47,360 and C++, and working with Docker 13 00:00:47,520 --> 00:00:49,620 and similar technologies for backend work. 14 00:00:50,900 --> 00:00:51,800 John, welcome to the show. 15 00:00:52,200 --> 00:00:53,780 - Hi, thank you very much. 16 00:00:54,000 --> 00:00:55,160 I'm very happy to be here. 17 00:00:55,240 --> 00:00:56,240 Thanks for inviting me. 18 00:00:56,980 --> 00:00:58,100 - How did you first get started 19 00:00:58,180 --> 00:00:59,380 with computers and electronics? 20 00:01:00,500 --> 00:01:04,000 - When I was a teenager, I got bitten by a radioactive chip. 21 00:01:05,599 --> 00:01:08,860 No, I was a really bored teenager in rural Maine 22 00:01:08,920 --> 00:01:12,000 in the late '70s, and the kind of thing 23 00:01:12,140 --> 00:01:13,980 that you would do at that point, 24 00:01:14,040 --> 00:01:17,440 some of us, the nerds, would hang out at Radio Shack. 25 00:01:17,680 --> 00:01:20,800 And Radio Shack in those days, when it existed, 26 00:01:21,320 --> 00:01:23,380 that was like the golden age of Radio Shack. 27 00:01:23,520 --> 00:01:26,220 And there was like, it was like electronics. 28 00:01:26,370 --> 00:01:30,120 It was almost like you walked into a 70s version 29 00:01:30,130 --> 00:01:32,420 of Adafruit in a store in a mall. 30 00:01:33,060 --> 00:01:36,080 I had a lot of exposure to electronics there 31 00:01:36,080 --> 00:01:40,720 and components and early personal computers. 32 00:01:41,500 --> 00:01:43,260 We were not a well-off family, 33 00:01:43,500 --> 00:01:47,200 but somehow my father managed to afford a TRS-80 for me. 34 00:01:47,920 --> 00:01:50,200 And that pretty much changed my life. 35 00:01:50,820 --> 00:01:54,900 And so between that and the access to electronics 36 00:01:55,240 --> 00:01:58,840 at Radio Shack, that kinda got me into that. 37 00:01:59,680 --> 00:02:01,760 At the time, we didn't have, 38 00:02:02,380 --> 00:02:04,660 if you wanted to program, write programs on a TRS-80, 39 00:02:04,760 --> 00:02:06,060 you wrote programs in Assembler, 40 00:02:07,560 --> 00:02:10,460 which was, or BASIC, I'm sorry, BASIC, 41 00:02:10,509 --> 00:02:12,640 which was not a lot better than Assembler, really. 42 00:02:13,320 --> 00:02:15,840 And it was very, very low resource machine. 43 00:02:16,220 --> 00:02:20,800 Like your baseline TRS-80 would have 4K 44 00:02:20,800 --> 00:02:27,760 memory. So, you know, going from there to like decades later and writing software for 45 00:02:27,960 --> 00:02:35,680 Arduinos and ESP 32s, it really takes me back there. Although we have such better tools 46 00:02:35,940 --> 00:02:41,000 for working in software these days, you know, and CircuitPython is a great example of that. 47 00:02:41,380 --> 00:02:50,780 CircuitPython, you couldn't even have imagined something like CircuitPython back then. But 48 00:02:50,780 --> 00:02:52,400 hung out at Radio Shack. 49 00:02:53,490 --> 00:02:55,080 - How did you discover CircuitPython? 50 00:02:56,160 --> 00:02:56,880 - I mean, through Adafruit. 51 00:02:59,520 --> 00:03:02,700 I got involved in doing work with ESP32s, 52 00:03:03,060 --> 00:03:05,160 or the ESP8266 at first, 53 00:03:05,560 --> 00:03:09,880 and looking for resources and looking for more hardware 54 00:03:10,000 --> 00:03:12,700 to work with, Adafruit was right there. 55 00:03:13,220 --> 00:03:15,740 And Adafruit does such an amazing job 56 00:03:15,780 --> 00:03:16,860 at fostering community, 57 00:03:17,280 --> 00:03:19,860 and also doing open-source hardware and software, 58 00:03:20,100 --> 00:03:21,880 which is very important to me. 59 00:03:22,680 --> 00:03:25,380 I was very drawn to Adafruit. 60 00:03:25,740 --> 00:03:28,420 Anyway, if you spend any time poking around Adafruit 61 00:03:28,640 --> 00:03:30,580 and looking at what Adafruit offers, 62 00:03:30,720 --> 00:03:33,800 Adafruit's put so much resources into CircuitPython. 63 00:03:34,540 --> 00:03:38,260 And I've done a lot of work writing C software. 64 00:03:38,580 --> 00:03:39,380 And I love C. 65 00:03:40,300 --> 00:03:43,240 C is better than programming in Assembler, 66 00:03:43,380 --> 00:03:45,960 but it's like right next to it, really. 67 00:03:46,600 --> 00:03:51,020 And it's so easy to shoot yourself in the foot in C. 68 00:03:51,640 --> 00:03:55,140 You just like misjudge the length of your array 69 00:03:55,140 --> 00:03:58,040 and suddenly you've written over your stack 70 00:03:58,220 --> 00:04:01,160 and what happens when you return, who knows? 71 00:04:02,520 --> 00:04:05,360 And your program just explodes in new and exciting ways, 72 00:04:05,460 --> 00:04:07,060 which are really difficult to debug 73 00:04:07,240 --> 00:04:09,800 'cause you're not on a full-fledged computer, 74 00:04:10,120 --> 00:04:11,940 you're on some tiny microcontroller. 75 00:04:12,540 --> 00:04:16,260 And CircuitPython just protects you from all of that. 76 00:04:16,380 --> 00:04:19,920 and lets you write code in a civilized way. 77 00:04:20,880 --> 00:04:22,420 For all the power that C gives you, 78 00:04:23,060 --> 00:04:25,100 when you start just manipulating strings, 79 00:04:25,320 --> 00:04:26,180 you're in a world of hurt, 80 00:04:26,720 --> 00:04:29,600 and especially on these kinds of microcontrollers. 81 00:04:30,120 --> 00:04:31,640 And if you're doing anything, 82 00:04:32,340 --> 00:04:34,140 like say you're doing a web server, 83 00:04:34,580 --> 00:04:37,680 which you can totally do in C, in Arduino, 84 00:04:38,480 --> 00:04:43,200 on an ESP32, or anyway, if you're doing that, 85 00:04:43,540 --> 00:04:45,020 you're doing a lot of string manipulation, 86 00:04:45,500 --> 00:04:50,180 And this is just not something that C is very inviting to 87 00:04:50,180 --> 00:04:51,320 or supportive of. 88 00:04:51,760 --> 00:04:53,100 C++, better. 89 00:04:53,660 --> 00:04:55,480 But CircuitPython's just got your back. 90 00:04:56,200 --> 00:04:59,220 CircuitPython just makes it really easy, 91 00:04:59,440 --> 00:05:01,920 especially since CircuitPython started supporting 92 00:05:01,920 --> 00:05:03,440 f-strings in Python, 93 00:05:03,750 --> 00:05:05,880 where you can just interpolate values in it. 94 00:05:06,300 --> 00:05:10,400 It's just, it's so much more relaxing to program 95 00:05:10,450 --> 00:05:12,580 in CircuitPython than it is in C. 96 00:05:13,340 --> 00:05:15,920 I know that some people get uptight 97 00:05:16,100 --> 00:05:17,740 about the overhead of CircuitPython. 98 00:05:18,140 --> 00:05:20,480 You know, CircuitPython has less memory available. 99 00:05:21,440 --> 00:05:23,100 CircuitPython is interpreted, 100 00:05:23,340 --> 00:05:27,000 it's much slower doing some operations than C is. 101 00:05:27,060 --> 00:05:29,100 It's actually shockingly fast for some things. 102 00:05:29,520 --> 00:05:31,500 But I think they lose track of the fact 103 00:05:31,620 --> 00:05:34,400 that your average program just doesn't need 104 00:05:34,680 --> 00:05:36,260 that level of performance. 105 00:05:36,840 --> 00:05:39,360 Yeah, if you're writing something on an ESP32, 106 00:05:39,620 --> 00:05:40,859 I keep coming back to that 107 00:05:40,860 --> 00:05:42,720 because that's the chip that I use the most. 108 00:05:43,460 --> 00:05:45,380 But if you're writing something on an ESP32 109 00:05:45,540 --> 00:05:47,380 that's very graphics intensive, 110 00:05:47,700 --> 00:05:49,760 like maybe you're writing some game or something 111 00:05:50,220 --> 00:05:53,460 that really pushes what you can do on an ESP32, 112 00:05:54,060 --> 00:05:56,600 then sure, you're probably not gonna write that 113 00:05:56,660 --> 00:05:57,380 in CircuitPython. 114 00:05:57,620 --> 00:06:01,280 But most people just write code that's like a simple loop 115 00:06:01,300 --> 00:06:03,020 and it's just reading some sensors 116 00:06:03,420 --> 00:06:07,100 or controlling some servos or something like that, 117 00:06:07,880 --> 00:06:09,540 or serving a webpage, 118 00:06:10,020 --> 00:06:12,320 and it's actually not even touching, 119 00:06:13,100 --> 00:06:16,320 getting close to the limits of the ESP32. 120 00:06:16,940 --> 00:06:19,000 And CircuitPython is great for that. 121 00:06:19,200 --> 00:06:21,600 There's plenty of capacity, plenty of resources. 122 00:06:22,300 --> 00:06:24,980 And anyway, it's a great tool for a lot of applications. 123 00:06:25,660 --> 00:06:27,860 - Speaking of tools, you've written a tool 124 00:06:27,860 --> 00:06:29,700 for CircuitPython called circremote. 125 00:06:30,380 --> 00:06:32,280 Tell me more about it and how it works. 126 00:06:33,180 --> 00:06:36,819 - circremote basically will send a chunk of code 127 00:06:36,820 --> 00:06:41,200 to CircuitPython, either over a serial port over USB, 128 00:06:41,900 --> 00:06:46,020 or if you have a device, which I believe only ESP32s 129 00:06:46,020 --> 00:06:49,600 do this currently, a device that supports the web workflow 130 00:06:50,120 --> 00:06:54,080 so that you could connect to it over Wi-Fi or Ethernet. 131 00:06:55,160 --> 00:06:56,720 If you have that kind of device, 132 00:06:57,560 --> 00:06:59,300 then it can do it over the network. 133 00:06:59,740 --> 00:07:01,300 So it doesn't have to be directly connected 134 00:07:01,320 --> 00:07:01,980 to your computer. 135 00:07:02,840 --> 00:07:05,819 So I do a lot of work with sensors 136 00:07:05,820 --> 00:07:09,960 and I've been building some of my own PCBs with sensors. 137 00:07:10,600 --> 00:07:11,380 Adafruits are fine, 138 00:07:11,460 --> 00:07:13,920 but sometimes I just want something a little different. 139 00:07:14,760 --> 00:07:16,240 Also, it's fun, honestly. 140 00:07:16,420 --> 00:07:18,740 It's just fun, and it's a nice stretch. 141 00:07:19,540 --> 00:07:23,300 There's a lot of stuff that I end up running frequently, 142 00:07:23,980 --> 00:07:25,720 like an IDC scanner, 143 00:07:26,520 --> 00:07:30,140 because most of the sensors that I connect are over IDC. 144 00:07:30,560 --> 00:07:33,500 I'm using STEM-QT for the hardware connection, 145 00:07:34,280 --> 00:07:35,160 which is awesome. 146 00:07:35,320 --> 00:07:38,580 It makes prototyping so quick and easy. 147 00:07:39,100 --> 00:07:43,060 But I am so tired of finding the IDC scanner code 148 00:07:43,060 --> 00:07:45,720 for CircuitPython and copying and pasting it in. 149 00:07:46,100 --> 00:07:48,420 And so I figured I'll write a utility 150 00:07:48,700 --> 00:07:51,060 that will just keep track of this for me 151 00:07:51,380 --> 00:07:54,120 and then send it to the device, 152 00:07:54,180 --> 00:07:57,320 whether it's over Wi-Fi or whether it's over USB. 153 00:07:58,040 --> 00:07:59,500 And once I started doing that, 154 00:08:00,160 --> 00:08:04,619 having drivers for the different kinds of chips that I use 155 00:08:04,620 --> 00:08:05,840 was the next step to do. 156 00:08:06,820 --> 00:08:09,440 And so I decided to, of course, 157 00:08:09,580 --> 00:08:10,960 make it way more complicated 158 00:08:11,080 --> 00:08:13,660 and add way more functionality to it, 159 00:08:13,940 --> 00:08:16,960 and just came up with this general concept of a command, 160 00:08:17,380 --> 00:08:18,960 which is the code that you send over 161 00:08:19,720 --> 00:08:22,560 and let it organize the commands and keep track of them, 162 00:08:23,220 --> 00:08:27,600 added the ability to have multiple paths 163 00:08:27,600 --> 00:08:28,740 to search for the commands. 164 00:08:28,920 --> 00:08:30,240 So it comes with, 165 00:08:30,860 --> 00:08:33,200 I think there's over a hundred things built in currently, 166 00:08:33,620 --> 00:08:36,099 And they're not all things for sensors. 167 00:08:37,080 --> 00:08:38,820 There are a lot of sensors it supports, 168 00:08:38,940 --> 00:08:42,479 like temperature sensors, light sensors, things like that. 169 00:08:42,820 --> 00:08:44,640 But also there are some utilities, 170 00:08:45,080 --> 00:08:47,800 like list the files that are on the flash drive. 171 00:08:48,600 --> 00:08:51,460 One of the utilities that I added enables web workflow. 172 00:08:51,770 --> 00:08:54,860 And so it takes the credentials for your Wi-Fi 173 00:08:55,080 --> 00:08:56,800 and the other information that you need 174 00:08:56,870 --> 00:08:57,940 to set up web workflow, 175 00:08:58,470 --> 00:09:03,000 and then just creates the settings.toml file on the device. 176 00:09:03,560 --> 00:09:04,780 Another one just resets it. 177 00:09:04,910 --> 00:09:07,560 You know, I got tired of typing import microcontroller, 178 00:09:07,820 --> 00:09:08,900 microcontroller reset. 179 00:09:09,590 --> 00:09:12,200 Another one puts it in UF2 bootloader mode. 180 00:09:12,900 --> 00:09:16,560 Another one can just display the contents of an arbitrary file on it. 181 00:09:16,810 --> 00:09:20,580 Oh, this is one, this is one that I really enjoyed and it's a little OCD. 182 00:09:21,520 --> 00:09:26,580 Like I use a Mac and I love, I love Apple mostly until they release major 183 00:09:26,860 --> 00:09:29,120 operating system updates and break everything. 184 00:09:29,800 --> 00:09:33,960 But one of the things they do when a Mac is writing to a flash drive 185 00:09:34,760 --> 00:09:39,400 with a DOS file system on it, like CircuitPython very reasonably uses, 186 00:09:39,600 --> 00:09:40,440 it's the right choice. 187 00:09:41,120 --> 00:09:45,320 One of the things they do is they just put all this trash on the drive, 188 00:09:45,420 --> 00:09:47,480 all these random little files, 189 00:09:47,780 --> 00:09:50,660 and these are keeping track of Mac-specific metadata 190 00:09:51,340 --> 00:09:55,120 or indexing for Spotlight, which is the Mac's search system. 191 00:09:55,550 --> 00:09:57,680 And it turns out Apple's not the only one. 192 00:09:57,680 --> 00:09:59,100 Windows does something similar. 193 00:09:59,810 --> 00:10:02,580 I use an editor that I would never recommend 194 00:10:02,680 --> 00:10:05,260 that anybody use called Emacs, which is ancient. 195 00:10:05,780 --> 00:10:07,060 I've used it for decades. 196 00:10:07,360 --> 00:10:10,060 It's basically built into my fingers at this point. 197 00:10:10,140 --> 00:10:12,840 And it's very hard for me to switch to a different editor. 198 00:10:13,540 --> 00:10:15,900 Emacs leaves trash all over the place. 199 00:10:15,980 --> 00:10:18,300 It leaves copies of files and checkpoints 200 00:10:18,400 --> 00:10:19,340 of files and things. 201 00:10:19,730 --> 00:10:23,340 And so this doesn't really take up all that much space 202 00:10:23,460 --> 00:10:25,120 because most of these files are tiny. 203 00:10:25,940 --> 00:10:28,740 But there's just all this crap on your drive, 204 00:10:28,800 --> 00:10:30,160 on your CircuitPython drive. 205 00:10:30,820 --> 00:10:33,820 There's a utility to remove the crap, it decraps it. 206 00:10:34,260 --> 00:10:36,460 I think it's actually called clean, not decrap, 207 00:10:37,000 --> 00:10:39,180 although that might've been a better choice for the name. 208 00:10:40,260 --> 00:10:43,020 So anyway, the point is there's a bunch of utilities there too 209 00:10:43,660 --> 00:10:47,360 and at this point I'm using it on an almost daily basis. 210 00:10:48,400 --> 00:10:49,980 There's stuff that I'm doing all the time. 211 00:10:50,540 --> 00:10:52,640 I've actually have, in my office, 212 00:10:53,140 --> 00:10:56,720 I have a LED matrix sign that I've built using 213 00:10:58,339 --> 00:11:00,340 Adafruit's matrix portal S3. 214 00:11:01,120 --> 00:11:04,240 That's another project that someday I'll try to get 215 00:11:04,360 --> 00:11:06,540 to a point where it's actually really releasable 216 00:11:07,060 --> 00:11:08,400 so that other people could use it. 217 00:11:08,920 --> 00:11:11,820 But one of the things with it is it's quite bright 218 00:11:12,200 --> 00:11:14,940 and at night I would like to turn it off 219 00:11:14,940 --> 00:11:17,680 and I haven't actually added an off function to it yet. 220 00:11:18,020 --> 00:11:21,660 So what I do right now is I have a thing that runs 221 00:11:21,660 --> 00:11:24,640 every night on my Mac, which just uses Cirq Remote 222 00:11:25,240 --> 00:11:27,920 in an automated way to poke the sign 223 00:11:28,120 --> 00:11:30,480 and just, I added a stop command. 224 00:11:30,740 --> 00:11:32,700 And all that does is it's just a loop 225 00:11:32,860 --> 00:11:35,100 that's like while true, pass. 226 00:11:36,200 --> 00:11:38,020 And then in the morning, I have another one 227 00:11:38,160 --> 00:11:39,600 that does a reset to it. 228 00:11:40,400 --> 00:11:42,880 And so the sign goes off at night 229 00:11:43,120 --> 00:11:45,440 and it comes back on in the morning and I'm happy 230 00:11:45,720 --> 00:11:48,400 and I didn't actually have to fix the code 231 00:11:48,440 --> 00:11:50,100 and the sign to do the right thing. 232 00:11:50,860 --> 00:11:53,440 So it's been really helpful to me 233 00:11:53,520 --> 00:11:55,120 and I hope it's something that may be helpful 234 00:11:55,200 --> 00:11:56,040 to other folks too. 235 00:11:56,420 --> 00:11:57,660 - You'll be happy to know that you're not 236 00:11:57,720 --> 00:11:58,680 the only Emacs user. 237 00:11:58,840 --> 00:12:00,840 todbot is a big Emacs user as well. 238 00:12:01,920 --> 00:12:05,940 - Yes, I'm not the final Emacs user in the world. 239 00:12:07,739 --> 00:12:10,440 Sometimes people ask me like, "What editor do you use? 240 00:12:10,440 --> 00:12:11,900 "I wanna use the editor you use." 241 00:12:11,900 --> 00:12:14,060 And I'm like, "No, no, you do not wanna use 242 00:12:14,120 --> 00:12:15,120 "the editor that I use. 243 00:12:15,120 --> 00:12:16,400 "You should use something modern. 244 00:12:16,880 --> 00:12:19,720 "You should probably use VS Code or something like that. 245 00:12:20,260 --> 00:12:21,600 Don't do that to yourself. 246 00:12:22,560 --> 00:12:24,520 Cirq Remote supports dozens of sensors. 247 00:12:24,560 --> 00:12:33,740 I plugged in a DPS 310 barometric and temperature sensor, ran Cirq Remote /dev/ttty/dps310 248 00:12:34,140 --> 00:12:35,620 and it installed the dependencies. 249 00:12:36,020 --> 00:12:42,220 And then I ran it again, and it spit out the temperature, pressure and altitude settings without me having to write any code. 250 00:12:42,900 --> 00:12:45,940 How are you able to support so many sensors in Cirq Remote? 251 00:12:46,920 --> 00:12:48,040 I cheated. 252 00:12:48,620 --> 00:12:51,700 So it's not really a cheat, but some people think it is. 253 00:12:52,130 --> 00:12:59,360 I actually had an AI write most of Cirq Remote and I have no illusions about this. 254 00:12:59,580 --> 00:13:02,640 I've been writing software since the late seventies. 255 00:13:03,560 --> 00:13:06,800 I've been pretty dubious about LLMs writing code. 256 00:13:07,580 --> 00:13:12,340 They've come a long way since just, you know, a year ago, even six months ago. 257 00:13:12,940 --> 00:13:22,020 I have to say that the rate of improvement and progress in LLMs is just stunning compared 258 00:13:22,020 --> 00:13:24,760 to other things that I've seen over the course of my life. 259 00:13:26,199 --> 00:13:29,360 So I could write most of Cirq Remote myself. 260 00:13:30,040 --> 00:13:33,820 I kind of didn't feel like it, and I was curious to do an experiment. 261 00:13:34,350 --> 00:13:38,280 The one part that I would have had some trouble with would have been the web workflow. 262 00:13:38,980 --> 00:13:45,560 to the device over serial over USB, not a big deal. The web workflow uses web sockets and I 263 00:13:46,200 --> 00:13:51,240 know how web sockets work and I've worked with them a bunch, but I've never programmed them in 264 00:13:51,500 --> 00:13:59,060 Python. And so just to be clear for folks, Cirq Remote itself is a CPython program. It's a Python 265 00:13:59,180 --> 00:14:06,819 program that runs on a Mac, on Linux, on Windows. Cirq Remote itself doesn't run on the device and 266 00:14:06,820 --> 00:14:13,340 isn't CircuitPython. What it does, though, is have a library of commands written in CircuitPython, 267 00:14:13,780 --> 00:14:18,940 which it then sends to the device. So we've kind of got these two dialects of Python going on there, 268 00:14:19,640 --> 00:14:28,140 but Cirq Remote doesn't execute the CircuitPython itself. So I decided, why not take a shot at this? 269 00:14:28,280 --> 00:14:34,819 Let's see what happens if I try to have an LLM write this for me. And at that time, I have a 270 00:14:34,820 --> 00:14:38,760 a good friend, Elena Hardy, who has been doing a lot of work 271 00:14:38,940 --> 00:14:39,700 using Cursor. 272 00:14:40,070 --> 00:14:45,000 And Cursor is a front end that works with VS Code. 273 00:14:45,620 --> 00:14:48,440 And it turns out there's a GC-EMACS compatibility 274 00:14:48,660 --> 00:14:49,540 mode for VS Code. 275 00:14:49,890 --> 00:14:51,620 And it actually is really good. 276 00:14:51,650 --> 00:14:53,960 And so that worked really nicely for me. 277 00:14:54,080 --> 00:14:55,360 Thank you, whoever wrote that. 278 00:14:55,560 --> 00:14:58,620 I am so grateful to you, or your AI, 279 00:14:58,840 --> 00:15:00,120 or whatever wrote that for you. 280 00:15:01,380 --> 00:15:08,320 And so Cursor can work with a variety of backend LLMs, and I've been having it use Claude. 281 00:15:08,740 --> 00:15:13,980 I think it was on Claude SONNET 4 when I did this. 282 00:15:15,220 --> 00:15:19,720 And you'll get different results depending on which LLM, which model, language model 283 00:15:19,820 --> 00:15:20,280 you're using. 284 00:15:20,660 --> 00:15:26,820 So I basically gave it a set of instructions, and I tried to be really clear, and I tried 285 00:15:26,740 --> 00:15:30,080 to not give it too much up front. 286 00:15:31,360 --> 00:15:33,840 And I don't think this counts as vibe coding. 287 00:15:33,960 --> 00:15:37,520 Cause I wasn't really just like throwing stuff at it and like, Hey, how about if 288 00:15:37,520 --> 00:15:39,140 we do this, how about if we do that? 289 00:15:39,200 --> 00:15:43,160 It was more like, I want this, I want this, I want this file location. 290 00:15:43,310 --> 00:15:44,880 I want it organized like this. 291 00:15:45,270 --> 00:15:49,680 It was a spec that I gave it and it worked. 292 00:15:50,560 --> 00:15:52,800 It was shockingly good. 293 00:15:53,780 --> 00:15:57,400 It wrote the code to send the code to it. 294 00:15:57,760 --> 00:16:00,060 One of the things that makes this work 295 00:16:00,340 --> 00:16:03,720 is CircuitPython supports this thing called raw REPL mode. 296 00:16:04,360 --> 00:16:06,340 And so this is something where it 297 00:16:06,540 --> 00:16:08,820 does no interpretation of what you're sending it 298 00:16:08,910 --> 00:16:09,760 as you send it. 299 00:16:10,200 --> 00:16:11,720 And then you send a terminator. 300 00:16:11,950 --> 00:16:14,980 And that's when it goes and it actually processes the code. 301 00:16:15,700 --> 00:16:19,720 And this makes it so much easier to automate sending code 302 00:16:19,820 --> 00:16:20,520 to it to execute. 303 00:16:20,940 --> 00:16:23,400 And Cirq Remote is not the only program that does this. 304 00:16:23,460 --> 00:16:26,300 There are other programs that use it this way as well. 305 00:16:26,340 --> 00:16:30,320 I think Fani does and probably Moo and a few other things. 306 00:16:31,540 --> 00:16:32,240 So that was great. 307 00:16:32,960 --> 00:16:36,460 So then I tossed in having it work with the web workflow 308 00:16:37,499 --> 00:16:40,360 and I had to intervene in a couple of places there. 309 00:16:40,400 --> 00:16:43,460 It didn't get the correct URL for the device. 310 00:16:43,460 --> 00:16:46,500 I had to look that up and I couldn't get it to work though. 311 00:16:46,800 --> 00:16:48,800 And it was having a bunch of issues with it 312 00:16:49,320 --> 00:16:50,180 and I got frustrated. 313 00:16:50,500 --> 00:16:54,420 And so I have done WebSocket programming in Ruby. 314 00:16:54,920 --> 00:16:57,660 And so I basically just went and said, 315 00:16:58,300 --> 00:17:00,400 okay, just rewrite it in Ruby for me. 316 00:17:00,540 --> 00:17:02,360 And it rewrote it in Ruby in one shot. 317 00:17:02,540 --> 00:17:03,680 It just, it did it. 318 00:17:04,780 --> 00:17:07,540 And the WebSocket code in Ruby worked. 319 00:17:08,160 --> 00:17:09,439 And so that was amazing. 320 00:17:09,600 --> 00:17:11,400 And so I lived with that for a few days. 321 00:17:11,760 --> 00:17:12,439 And then I thought, 322 00:17:12,819 --> 00:17:16,240 how much is the CircuitPython community gonna love me 323 00:17:16,300 --> 00:17:19,199 if I give them a utility that's written in Ruby? 324 00:17:20,060 --> 00:17:21,720 And I figured not at all. 325 00:17:22,480 --> 00:17:27,260 And so then I decided, let's just take another leap 326 00:17:27,600 --> 00:17:30,460 and have it translate this Ruby program 327 00:17:30,460 --> 00:17:32,420 that now works back to Python. 328 00:17:33,540 --> 00:17:34,980 And it did it in one shot 329 00:17:35,150 --> 00:17:37,520 and it worked the first time I tried it, 330 00:17:38,200 --> 00:17:39,960 which just blew me away. 331 00:17:40,180 --> 00:17:42,240 That was really, really wild. 332 00:17:43,360 --> 00:17:45,460 So that's been really positive. 333 00:17:46,520 --> 00:17:52,360 The negative to it has been that when things go wrong, 334 00:17:52,640 --> 00:17:54,240 they can go really wrong. 335 00:17:54,940 --> 00:17:57,140 And because I didn't write the code, 336 00:17:57,260 --> 00:18:00,720 I'm not familiar with it in the way that I would be. 337 00:18:01,380 --> 00:18:03,360 And it can be really tough to debug. 338 00:18:03,980 --> 00:18:07,040 And when the LLM, the LLM is more than happy 339 00:18:07,060 --> 00:18:09,660 to go deep, deep down a rabbit hole 340 00:18:09,780 --> 00:18:10,880 trying to debug something. 341 00:18:11,700 --> 00:18:15,779 But it's not very good at declaring defeat 342 00:18:15,780 --> 00:18:18,460 and realizing that you need to back up 343 00:18:18,520 --> 00:18:19,580 and take a new approach. 344 00:18:20,080 --> 00:18:21,100 I have to do that. 345 00:18:21,820 --> 00:18:24,780 And so one of the things I learned really quickly 346 00:18:25,460 --> 00:18:28,820 was not only did I have to recognize 347 00:18:28,920 --> 00:18:30,440 when we were totally going in the wrong direction, 348 00:18:30,760 --> 00:18:34,660 which is fine, but also it can be tough 349 00:18:34,760 --> 00:18:38,760 to unravel what it's done in going in that direction. 350 00:18:39,520 --> 00:18:43,280 So I just get, you know, like 99% of the rest of the world. 351 00:18:43,860 --> 00:18:46,220 And you definitely need to have really good 352 00:18:46,580 --> 00:18:47,900 hygiene with this. 353 00:18:48,380 --> 00:18:51,140 It's easier to just throw away the work 354 00:18:51,240 --> 00:18:55,380 that's been being done and go back to where you started 355 00:18:55,600 --> 00:18:57,180 when you started to debug this, 356 00:18:57,760 --> 00:19:00,900 than it is to get the LLM to reliably 357 00:19:01,460 --> 00:19:02,780 go back to a checkpoint. 358 00:19:02,960 --> 00:19:05,760 Now, it's quite possible that Cursor's pretty good at this 359 00:19:05,780 --> 00:19:07,960 and it's not something I know how to do in it. 360 00:19:08,380 --> 00:19:10,779 Cursor's got a ton of stuff that it does 361 00:19:10,780 --> 00:19:13,980 that I'm not an expert cursor user by any means. 362 00:19:14,600 --> 00:19:16,800 So there may be expert cursor users, 363 00:19:17,200 --> 00:19:19,560 like my friend Elena, who will listen to this 364 00:19:19,620 --> 00:19:20,740 and roll her eyes and be like, 365 00:19:20,760 --> 00:19:23,520 "I told you how to do this," and she probably did. 366 00:19:24,680 --> 00:19:26,580 That's some experience with that. 367 00:19:26,920 --> 00:19:29,000 So I also, you know, I wanted to support 368 00:19:29,340 --> 00:19:31,900 lots and lots of sensors and other devices, 369 00:19:32,580 --> 00:19:37,499 so I told Cursor to look at Adafruit's store 370 00:19:37,660 --> 00:19:42,060 and see what Adafruit sells and write commands for those. 371 00:19:42,960 --> 00:19:45,220 And that was partly really successful. 372 00:19:45,240 --> 00:19:48,320 It was great at scanning what Adafruit had available 373 00:19:48,660 --> 00:19:51,340 and it was great at organizing that. 374 00:19:52,060 --> 00:19:55,800 And the thing with Python versus CircuitPython 375 00:19:55,800 --> 00:19:58,700 is there's a lot of Python code on the internet 376 00:19:59,180 --> 00:20:01,260 and there's a lot less CircuitPython code. 377 00:20:01,740 --> 00:20:03,000 And they look really similar 378 00:20:03,220 --> 00:20:04,700 because they are really similar. 379 00:20:05,540 --> 00:20:09,880 And so the training, the base of code in CircuitPython 380 00:20:09,940 --> 00:20:14,120 for the language models to be trained on is much smaller. 381 00:20:14,860 --> 00:20:17,440 And so it doesn't do as good of a job 382 00:20:17,580 --> 00:20:19,680 with generating CircuitPython code. 383 00:20:19,780 --> 00:20:21,340 And sometimes it gets confused. 384 00:20:22,080 --> 00:20:25,980 And especially things for accessing the file system 385 00:20:26,020 --> 00:20:28,320 is different in CircuitPython versus Python, 386 00:20:28,640 --> 00:20:31,040 which is totally reasonable, not a complaint at all. 387 00:20:31,700 --> 00:20:34,219 It's actually just totally impressive 388 00:20:34,220 --> 00:20:35,800 everything that CircuitPython does. 389 00:20:36,740 --> 00:20:38,980 But so I found that the LLM would frequently 390 00:20:39,140 --> 00:20:40,360 get confused about that. 391 00:20:40,400 --> 00:20:43,620 And it would still hallucinate things that are not there. 392 00:20:44,519 --> 00:20:47,200 Mostly it did a really good job at figuring out 393 00:20:47,300 --> 00:20:51,160 the Adafruit libraries to use for the devices. 394 00:20:51,960 --> 00:20:53,460 Occasionally, I think once or twice, 395 00:20:53,460 --> 00:20:55,800 it hallucinated a library name that didn't exist. 396 00:20:56,640 --> 00:20:59,000 But mostly it did a good job with that. 397 00:20:59,420 --> 00:21:03,699 I had to manually intervene and fix things much more often 398 00:21:03,700 --> 00:21:07,400 with the CircuitPython code than with the Python code. 399 00:21:08,140 --> 00:21:12,700 I also, at one point, it had a sort of systematic error 400 00:21:12,860 --> 00:21:15,740 that it had done across most of the commands. 401 00:21:16,360 --> 00:21:20,160 And so I actually was able to tell it how to fix that 402 00:21:20,260 --> 00:21:22,240 and then have it apply that to all the commands, 403 00:21:22,570 --> 00:21:23,840 which was a huge time saver. 404 00:21:24,420 --> 00:21:26,640 I figured out the fix, it did the work. 405 00:21:26,820 --> 00:21:29,300 And that was pretty good, I liked that. 406 00:21:30,020 --> 00:21:30,200 Yeah. 407 00:21:30,780 --> 00:21:31,380 - That's pretty neat. 408 00:21:32,900 --> 00:21:34,260 - You do a lot of work with sensors, 409 00:21:34,760 --> 00:21:37,000 both for yourself and for your community. 410 00:21:37,080 --> 00:21:38,900 How are you using sensors in your community? 411 00:21:39,940 --> 00:21:44,640 - I am trying to do some projects to do sort of, 412 00:21:45,620 --> 00:21:47,640 I guess one word for it, one phrase for it 413 00:21:47,680 --> 00:21:52,060 is citizen science, so that people can have sensor networks, 414 00:21:53,180 --> 00:21:55,640 or communities can have sensor networks in them 415 00:21:56,200 --> 00:22:00,080 to track things like air quality, or noise pollution, 416 00:22:00,300 --> 00:22:02,660 or light pollution or things like that. 417 00:22:03,280 --> 00:22:07,240 Air quality is such a big, difficult question 418 00:22:07,680 --> 00:22:10,300 because we tend to focus on one or two things 419 00:22:10,300 --> 00:22:11,080 for air quality. 420 00:22:11,800 --> 00:22:13,340 We have the AQI calculation, 421 00:22:13,420 --> 00:22:15,060 which is really a synthetic number. 422 00:22:16,120 --> 00:22:20,160 And it tends to focus on particulate pollution, 423 00:22:20,480 --> 00:22:21,480 which is a big deal. 424 00:22:22,160 --> 00:22:25,240 But also there's a ton of other things, 425 00:22:25,400 --> 00:22:28,980 like respiratory irritants, gases like formaldehyde. 426 00:22:29,380 --> 00:22:31,120 I live in Portland, in North Portland, 427 00:22:31,420 --> 00:22:34,020 and there was an incident with a factory 428 00:22:34,900 --> 00:22:38,380 on the sort of not real residential part of North Portland, 429 00:22:38,960 --> 00:22:41,340 but which has been fined multiple times 430 00:22:41,340 --> 00:22:43,060 for releasing formaldehyde. 431 00:22:43,660 --> 00:22:47,320 And so I'd love for folks who are interested in doing this 432 00:22:47,320 --> 00:22:49,460 to be able to have cheap devices 433 00:22:50,220 --> 00:22:53,160 that they can put on a public sensor network 434 00:22:53,940 --> 00:22:56,100 that could monitor for stuff like this. 435 00:22:56,640 --> 00:22:58,860 And so that's kind of a passion of mine. 436 00:22:59,280 --> 00:23:02,420 I work with a local hacker space, PDX hacker space, 437 00:23:02,960 --> 00:23:04,940 and folks there help with this. 438 00:23:05,080 --> 00:23:07,560 And some of us are working on projects like that. 439 00:23:08,020 --> 00:23:10,500 Also like CO2 monitoring, CO2 monitoring. 440 00:23:11,020 --> 00:23:13,960 Like CO2 can build up in a closed environment, 441 00:23:14,200 --> 00:23:15,860 like an office space or home, 442 00:23:16,340 --> 00:23:19,060 but also it got used as a proxy for airflow 443 00:23:19,360 --> 00:23:20,140 during the pandemic. 444 00:23:20,800 --> 00:23:22,780 A lot of people were getting CO2 monitors 445 00:23:22,880 --> 00:23:25,640 with the idea that if CO2 levels went up, 446 00:23:25,740 --> 00:23:27,740 then the possibility of COVID, 447 00:23:28,340 --> 00:23:30,280 the virus in the air went up as well, 448 00:23:30,780 --> 00:23:33,380 because that's a sign that air exchange isn't happening. 449 00:23:34,160 --> 00:23:36,940 And so they were less concerned about the CO2 450 00:23:37,040 --> 00:23:39,300 than they were just about fresh air, which is fair. 451 00:23:40,160 --> 00:23:42,080 And so a bunch of folks at the hackerspace 452 00:23:42,180 --> 00:23:43,940 were very interested in that. 453 00:23:44,340 --> 00:23:48,120 One friend, Darcy Neal, is building personal CO2 monitors. 454 00:23:48,840 --> 00:23:52,240 And so we've collaborated on some hardware there. 455 00:23:53,140 --> 00:23:55,960 There's a commercial device called Purple Air, 456 00:23:56,280 --> 00:23:57,480 which does something similar. 457 00:23:57,720 --> 00:23:59,800 It's an air quality monitoring device, 458 00:24:00,180 --> 00:24:01,820 very focused on particulate matter, 459 00:24:02,420 --> 00:24:04,160 and they have air quality maps 460 00:24:04,280 --> 00:24:05,780 that they generate from their data. 461 00:24:06,220 --> 00:24:07,660 I'd like to generalize that. 462 00:24:08,220 --> 00:24:09,700 I'm fine with commercial products. 463 00:24:10,140 --> 00:24:12,860 You know, there's a lot to be said for just buying it, 464 00:24:12,880 --> 00:24:14,440 having it be supported, that's great. 465 00:24:15,000 --> 00:24:18,280 But I also like lower cost things available to hobbyists 466 00:24:18,820 --> 00:24:22,140 or DIY people, maker spaces, things like that. 467 00:24:22,660 --> 00:24:24,780 And so the hardware that I've been designing 468 00:24:24,880 --> 00:24:27,760 and the software that I've built is all open source. 469 00:24:28,570 --> 00:24:31,240 I got kind of waylaid by the tariff situation. 470 00:24:32,160 --> 00:24:35,760 There's a board that I was doing a lot of work on 471 00:24:35,920 --> 00:24:38,580 and got a final iteration of it in last spring 472 00:24:38,680 --> 00:24:39,680 before the tariffs hit, 473 00:24:40,280 --> 00:24:43,200 but they really jacked up the cost on doing everything. 474 00:24:43,780 --> 00:24:46,680 And I'm happy to, I'd love to build things in the US, 475 00:24:47,400 --> 00:24:50,060 but there's no options to do that. 476 00:24:50,260 --> 00:24:53,640 the businesses just simply don't exist at this time. 477 00:24:54,220 --> 00:24:59,080 There's a really great place in China called JLCPCB, 478 00:24:59,580 --> 00:25:00,780 and a lot of folks use them. 479 00:25:01,210 --> 00:25:03,980 And they have, it's just like it's so easy to work with them. 480 00:25:04,520 --> 00:25:06,720 You upload your designs through their web interface, 481 00:25:07,100 --> 00:25:09,720 you walk through it, and you get the order set right there. 482 00:25:09,780 --> 00:25:10,640 It takes minutes. 483 00:25:11,220 --> 00:25:14,600 And there's just nothing comparable to that in the US. 484 00:25:15,100 --> 00:25:16,920 And also what I found trying to price things, 485 00:25:17,040 --> 00:25:21,160 it's the factories in the US that do circuit board assembly, 486 00:25:22,260 --> 00:25:25,000 they wanna do hundreds of thousands of boards, 487 00:25:25,500 --> 00:25:27,540 which is fair, I don't begrudge them that, 488 00:25:27,540 --> 00:25:29,500 I don't blame them, I would much prefer to deal 489 00:25:29,580 --> 00:25:30,820 with large commercial orders 490 00:25:30,940 --> 00:25:33,420 than individual hobbyists as well. 491 00:25:34,260 --> 00:25:36,900 But it's just like, they don't wanna talk to you 492 00:25:37,240 --> 00:25:39,440 if you wanna do 10 boards, and that's fine, 493 00:25:39,540 --> 00:25:40,440 that's totally fair. 494 00:25:40,980 --> 00:25:45,240 So there's simply no alternative available at this time. 495 00:25:45,840 --> 00:25:48,160 And I know a lot of hobbyists and makers 496 00:25:48,660 --> 00:25:51,640 got really, had a really hard time with this. 497 00:25:52,300 --> 00:25:54,760 So I'm getting, you know, now that things have stabilized 498 00:25:55,040 --> 00:25:56,660 even though it costs a lot more, 499 00:25:56,760 --> 00:25:58,960 it's still orders of magnitude cheaper 500 00:25:59,000 --> 00:26:00,500 to do it through China. 501 00:26:01,140 --> 00:26:03,460 And so I'm trying to get back to that now 502 00:26:03,620 --> 00:26:06,520 and just, you know, hopefully don't get hit 503 00:26:06,600 --> 00:26:09,620 with a thousand dollar tariff or broker fee 504 00:26:09,720 --> 00:26:13,180 or something like that for $100 worth of PCBs, 505 00:26:13,300 --> 00:26:14,380 but we'll see how it goes. 506 00:26:15,260 --> 00:26:15,900 - That's pretty neat. 507 00:26:16,220 --> 00:26:17,980 Last question I ask each guest, 508 00:26:18,420 --> 00:26:20,460 you're going to start a new project or prototype, 509 00:26:20,900 --> 00:26:22,160 which board do you reach for? 510 00:26:23,280 --> 00:26:24,340 - That's a great question. 511 00:26:24,740 --> 00:26:27,940 And it would really depend a lot on the project. 512 00:26:28,640 --> 00:26:31,360 So like I have these LED matrix signs 513 00:26:31,700 --> 00:26:34,740 that are using Adafruit's matrix portal S3. 514 00:26:35,240 --> 00:26:36,980 And if I were doing an LED matrix, 515 00:26:37,100 --> 00:26:38,840 that is absolutely the board I would go for. 516 00:26:38,900 --> 00:26:42,240 That's just really well thought out, well designed, 517 00:26:42,680 --> 00:26:45,620 and actually impressively cheap for what it does board. 518 00:26:46,500 --> 00:26:50,120 If I were going for just a more general purpose, 519 00:26:50,800 --> 00:26:53,800 so almost everything I do is ESP32 based 520 00:26:54,020 --> 00:26:55,440 because I always want connectivity. 521 00:26:56,040 --> 00:26:59,100 But if I were going for just a more general purpose 522 00:26:59,640 --> 00:27:00,540 board with connectivity, 523 00:27:01,440 --> 00:27:02,680 Adafruit's feathers are great. 524 00:27:03,020 --> 00:27:05,680 The board that I'm designing, it's just called sensor, 525 00:27:06,500 --> 00:27:10,160 which is, you know, but it's got connectors on it 526 00:27:10,160 --> 00:27:14,500 to hook up some more specific things like a particle sensor, 527 00:27:14,720 --> 00:27:18,460 which needs a weird little ribbon cable connector. 528 00:27:19,000 --> 00:27:20,540 Adafruit sells a version of that, 529 00:27:21,380 --> 00:27:23,000 but I like having it directly on the board 530 00:27:23,200 --> 00:27:25,080 because almost all the instances of this 531 00:27:25,180 --> 00:27:27,820 that I'm going to put together are gonna need that. 532 00:27:28,460 --> 00:27:30,000 So, you know, it's not very satisfying, 533 00:27:30,100 --> 00:27:31,320 but I might go for my own board. 534 00:27:32,040 --> 00:27:34,520 But Adafruit in general, like the feather boards are great. 535 00:27:35,180 --> 00:27:36,580 For just general purpose boards, 536 00:27:37,000 --> 00:27:41,020 unexpected maker, makes some really, really nice hardware. 537 00:27:41,660 --> 00:27:44,040 A lot of emphasis on low power, 538 00:27:44,360 --> 00:27:45,840 low overhead in the power 539 00:27:45,890 --> 00:27:47,500 if you want to use a battery with it. 540 00:27:48,400 --> 00:27:50,300 So I often look at his boards too. 541 00:27:50,860 --> 00:27:52,840 So those are both really great choices, yeah. 542 00:27:53,180 --> 00:27:54,100 - Yeah, those are great choices. 543 00:27:54,920 --> 00:27:56,360 John, thanks so much for coming on the show. 544 00:27:56,880 --> 00:27:58,000 - Thanks very much for having me. 545 00:27:58,080 --> 00:27:58,860 This was a lot of fun. 546 00:28:00,680 --> 00:28:02,540 - Thank you for listening to the CircuitPython Show. 547 00:28:02,940 --> 00:28:04,120 For show notes and transcripts, 548 00:28:04,200 --> 00:28:06,900 visit www.circuitpythonshow.com. 549 00:28:07,440 --> 00:28:08,480 And if you're enjoying the show, 550 00:28:08,720 --> 00:28:10,120 do me a favor and share a review 551 00:28:10,220 --> 00:28:11,560 on your favorite podcast app. 552 00:28:11,760 --> 00:28:12,500 It really helps. 553 00:28:13,180 --> 00:28:14,780 Until next time, stay positive.