1 00:00:05,160 --> 00:00:08,400 Welcome to the CircuitPython Show. I'm your host, Paul Cutler. 2 00:00:08,940 --> 00:00:11,080 This episode, I welcome John Fletcher to the show. 3 00:00:11,680 --> 00:00:14,860 John is a self-taught programmer who holds a Master's in English Literature 4 00:00:15,060 --> 00:00:18,400 and a Master of Fine Arts in Writing from the University of Alaska, Fairbanks. 5 00:00:19,239 --> 00:00:20,340 John, welcome to the show. 6 00:00:21,040 --> 00:00:22,640 Hi, Paul. Thanks so much for having me. 7 00:00:23,020 --> 00:00:25,460 How did you first get started with computers and electronics? 8 00:00:26,000 --> 00:00:30,760 Well, I share a lot of commonalities with other folks that you've had on the show before. 9 00:00:31,500 --> 00:00:37,540 My father, he worked in the insurance industry, and his office at home had a Commodore 64 10 00:00:38,280 --> 00:00:40,220 that my brother and I were allowed to use. 11 00:00:41,040 --> 00:00:45,000 So on that machine, I really learned to be frustrated with the command plane. 12 00:00:45,760 --> 00:00:51,800 Otherwise, the influence came from kind of stereotypical dad stuff, guy stuff from the 13 00:00:51,980 --> 00:00:52,360 80s. 14 00:00:53,400 --> 00:00:56,980 My father had home stereo, home theater type equipment. 15 00:00:57,110 --> 00:00:58,760 He had dual VCRs. 16 00:00:59,210 --> 00:01:03,960 He was big into re-recording and editing home videos, 17 00:01:04,220 --> 00:01:07,480 especially things for my brother and I to watch. 18 00:01:08,040 --> 00:01:10,040 And he was the one that got the Nintendo 19 00:01:10,330 --> 00:01:11,380 and brought it into the house. 20 00:01:11,930 --> 00:01:13,060 I grew up a gadget guy, 21 00:01:13,720 --> 00:01:16,880 firmly in the generation of thought that opening scene 22 00:01:16,940 --> 00:01:19,800 and back to the future, fiddling with the amplifier, 23 00:01:20,740 --> 00:01:22,020 one of the coolest things ever, 24 00:01:22,720 --> 00:01:27,240 as well the interior of the Batcave from Tim Burton's '89 Batman 25 00:01:27,460 --> 00:01:29,380 with all of the monitors set up. 26 00:01:30,340 --> 00:01:32,100 That's a drool-worthy setup. 27 00:01:32,780 --> 00:01:34,160 I think John Park is doing his best 28 00:01:34,280 --> 00:01:37,280 to sort of recreate it in his workshop. 29 00:01:38,400 --> 00:01:40,580 But the rest of it, you can blame Pokemon for. 30 00:01:40,920 --> 00:01:45,160 And I love the fact that we sort of have this shared lineage 31 00:01:45,760 --> 00:01:49,020 where it was video games that got us into programming. 32 00:01:49,480 --> 00:01:56,500 with you was EverQuest, with me it was Pokémon. But the first generations of Pokémon required a 33 00:01:56,620 --> 00:02:02,860 connection, connection cables and things for doing the trading. But they also had hacking. 34 00:02:03,930 --> 00:02:08,679 And so trying to catch them all really was what provided my first exposure to 35 00:02:09,479 --> 00:02:14,740 trying to understand and work with any sort of a code base. 36 00:02:14,740 --> 00:02:17,180 How did you discover CircuitPython? 37 00:02:19,080 --> 00:02:22,680 I discovered Adafruit before I discovered CircuitPython. 38 00:02:23,200 --> 00:02:26,460 What I mean by this is I'm an avid DIYer. 39 00:02:27,360 --> 00:02:31,780 I've got fundamental skills for pretty much all areas of home improvement. 40 00:02:32,440 --> 00:02:35,260 I'm a pretty skilled amateur woodworker as well. 41 00:02:35,840 --> 00:02:38,960 So I found Adafruit a little more than five years ago 42 00:02:39,280 --> 00:02:43,740 while I was looking for some simple, practical electronics and things 43 00:02:43,740 --> 00:02:47,260 that I could integrate into some of my home projects. 44 00:02:48,050 --> 00:02:50,400 So we're not even talking at the microcontroller level here. 45 00:02:50,480 --> 00:02:54,060 We're talking about motors, actuators, et cetera, 46 00:02:54,160 --> 00:02:55,860 for really basic mechanisms. 47 00:02:56,720 --> 00:02:58,320 But again, it was Pokemon that brought me back 48 00:02:58,320 --> 00:02:59,100 and back to stay. 49 00:03:01,190 --> 00:03:03,620 So kind of a long story short, and if you know, you know, 50 00:03:04,420 --> 00:03:09,160 I was looking for a way to recombine power and data 51 00:03:10,120 --> 00:03:13,040 from power over ethernet splitter 52 00:03:13,040 --> 00:03:15,260 And because I remembered Adafruit, 53 00:03:15,260 --> 00:03:17,760 I went back to the website, ordered a couple of things 54 00:03:18,310 --> 00:03:19,140 to try to do that. 55 00:03:19,420 --> 00:03:22,520 But I also added a couple of extras into my cart 56 00:03:23,739 --> 00:03:26,020 because such is the nature of Adafruit, 57 00:03:26,220 --> 00:03:29,000 things are priced so reasonably that it's, well, 58 00:03:29,200 --> 00:03:30,940 while I'm making the order, I might as well. 59 00:03:31,860 --> 00:03:36,380 So I picked up a QTPY, a SamD21, a time of flight sensor 60 00:03:36,380 --> 00:03:37,180 to play around with. 61 00:03:38,700 --> 00:03:40,900 Long story short, I never got the power and the data 62 00:03:41,040 --> 00:03:42,020 to recombine. 63 00:03:42,500 --> 00:03:45,580 But the time of flight sensor, I integrated 64 00:03:45,920 --> 00:03:49,540 into a nighttime stairway illumination project 65 00:03:50,080 --> 00:03:53,580 that's now in its maybe second kind of version. 66 00:03:54,580 --> 00:03:56,300 And yeah, really writing the code 67 00:03:56,400 --> 00:03:58,760 for that time of flight sensor was definitely 68 00:03:58,900 --> 00:04:00,500 an aha moment for me. 69 00:04:01,320 --> 00:04:03,940 So I knew that working with CircuitPython 70 00:04:04,020 --> 00:04:05,040 was something that I wanted to do. 71 00:04:05,680 --> 00:04:06,140 - Very cool. 72 00:04:07,100 --> 00:04:09,000 One of the fun questions I sometimes like to ask 73 00:04:09,100 --> 00:04:10,460 is about your Discord nickname. 74 00:04:10,860 --> 00:04:15,600 It's spelled J-O-H-N-N-H-O-J, John and then John backwards. 75 00:04:16,620 --> 00:04:18,900 Set the record straight, what is the correct pronunciation? 76 00:04:19,560 --> 00:04:27,700 BF: Yeah, to me, there's no end of comedy for me with this. 77 00:04:28,860 --> 00:04:33,180 When I wrote the name, I didn't have any pronunciation in mind. 78 00:04:33,700 --> 00:04:40,280 I mentioned to Tim Foamyguy on one of his live streams that it should perhaps be pronounced 79 00:04:41,420 --> 00:04:43,200 like "you know". 80 00:04:43,320 --> 00:04:48,460 And so as a result of that, he's got this kind of Northern European Scandi-influenced 81 00:04:49,300 --> 00:04:50,320 take on it that I like. 82 00:04:51,420 --> 00:04:57,680 John Park always goes much more British sounding with "John Nodge", which I think is maybe 83 00:04:57,840 --> 00:05:01,400 more appropriate for considering my own name's heritage. 84 00:05:02,540 --> 00:05:03,820 I tend to think of it as John O. 85 00:05:04,500 --> 00:05:04,580 Yeah. 86 00:05:05,500 --> 00:05:07,260 - CircuitPython has the online code editor 87 00:05:07,460 --> 00:05:09,200 at code.circuitpython.org. 88 00:05:09,540 --> 00:05:10,860 You forked that repository 89 00:05:11,040 --> 00:05:12,600 and created a port of CircuitPython 90 00:05:12,680 --> 00:05:14,560 that runs in the browser using WebAssembly. 91 00:05:15,360 --> 00:05:17,800 First, what is WebAssembly or Wasm 92 00:05:18,060 --> 00:05:19,980 and what led you to create a WebAssembly port 93 00:05:20,000 --> 00:05:20,620 of CircuitPython? 94 00:05:22,240 --> 00:05:24,500 - Yeah, so I won't claim to be completely familiar 95 00:05:24,860 --> 00:05:26,760 with WebAssembly myself. 96 00:05:27,340 --> 00:05:29,640 So anybody who is expert in this 97 00:05:29,640 --> 00:05:31,219 will probably find this a little painful 98 00:05:31,220 --> 00:05:36,100 please reach out and correct me if I'm wrong. But in essence, the same way that CircuitPython 99 00:05:36,380 --> 00:05:42,560 is compiled in order to run on microcontrollers, the C code can be compiled to run wherever 100 00:05:42,820 --> 00:05:48,400 JavaScript runs. So that compilation process sort of breaks down the higher order C language 101 00:05:49,160 --> 00:05:53,980 into something friendlier for machines, much less friendly for people. For CircuitPython, 102 00:05:53,980 --> 00:06:01,420 the target is the assembly language or the instruction set for a given chip, your RP2040s, 103 00:06:01,500 --> 00:06:08,540 your CMT21s, and so forth, so that your code can work in tandem with the hardware. And as its name 104 00:06:08,720 --> 00:06:16,060 suggests, WebAssembly or WASM, however you want to pronounce it, runs on virtual machines in the 105 00:06:16,480 --> 00:06:22,460 JavaScript runtime environment. And since CircuitPython is C code, by using a different compiler, 106 00:06:23,020 --> 00:06:28,400 we can break down the CircuitPython code to work in those JavaScript virtual machines, 107 00:06:28,940 --> 00:06:33,880 and instead of the physical hardware. CircuitPython is normally compiled using CMake, 108 00:06:34,600 --> 00:06:42,640 but for WebAssembly we use Emscripten or EMSDK, which I think uses LLVM or Clang under the hood. 109 00:06:43,500 --> 00:06:46,320 So what led you to create a WebAssembly port of CircuitPython? 110 00:06:46,780 --> 00:06:53,220 Yeah, so creating the WebAssembly port really grew out of a larger, long-term project, 111 00:06:53,900 --> 00:07:00,520 working on an extension for VS Code, and really thought that it would be beneficial to use 112 00:07:01,400 --> 00:07:08,180 WebAssembly within that extension. One of the, not necessarily issues, but potential sticking 113 00:07:08,220 --> 00:07:17,640 points of working with CircuitPython and Python in general is the need to create virtual environments. 114 00:07:18,460 --> 00:07:25,560 And I thought having something more portable, since VS Code is a web browser basis based on 115 00:07:25,940 --> 00:07:32,480 a Chromium browser, why not be able to have a portable Python interpreter that wouldn't need 116 00:07:33,180 --> 00:07:39,100 the creation of virtual environment because it's already pre-compiled. It's more or less a closed 117 00:07:39,400 --> 00:07:47,380 system. And then you can sidestep some of the issues inherent there. So the biggest advantage 118 00:07:48,190 --> 00:07:54,040 to the WebAssembly port, it gives folks access to CircuitPython interpreter in the browser 119 00:07:55,180 --> 00:08:03,160 without needing a physical board. In that case, the browser in some sense is the board. And 120 00:08:03,160 --> 00:08:06,780 to create a port of CircuitPython specifically, 121 00:08:07,900 --> 00:08:11,100 MicroPython, for example, has its own WebAssembly port. 122 00:08:11,680 --> 00:08:17,440 PyScript is a well-known variant of the MicroPython WebAssembly 123 00:08:17,560 --> 00:08:17,760 port. 124 00:08:18,360 --> 00:08:22,040 The issue with that is, even though it's 125 00:08:22,060 --> 00:08:24,020 based on MicroPython, there are certain things 126 00:08:24,080 --> 00:08:27,800 in CircuitPython that we'd like to have specifically. 127 00:08:28,560 --> 00:08:35,020 And for the PyScript, PyScript has a very specific goal in mind, 128 00:08:35,300 --> 00:08:42,000 which is to provide a Python interpreter in the browser and very little more. 129 00:08:43,060 --> 00:08:50,800 And that causes a problem for anyone who is interested in integrating more of the hardware awareness. 130 00:08:51,440 --> 00:09:01,440 And so the CircuitPython port was able to add back in some sense of board, pin, these sorts of protocols. 131 00:09:02,540 --> 00:09:06,060 So how does CircuitPython work in the browser? Does it drop you right into a REPL? 132 00:09:07,300 --> 00:09:15,280 Yes, it should. After you spool it up, very, very quickly, it should drop you right into a REPL. 133 00:09:15,440 --> 00:09:22,100 Of course, in the webpage that needs the intermediary program of having a pseudo terminal to work 134 00:09:22,400 --> 00:09:23,480 just as a UI. 135 00:09:25,820 --> 00:09:31,300 So when you ported it over, you used the Windows subsystem for Linux, WSL, and branched off 136 00:09:31,340 --> 00:09:32,540 of CircuitPython from there. 137 00:09:33,580 --> 00:09:36,200 Any challenges working with the Windows subsystem for Linux? 138 00:09:36,220 --> 00:09:41,140 I know folks have sometimes run into problems compiling CircuitPython itself in WSL, but 139 00:09:41,140 --> 00:09:42,620 how was your experience in using it? 140 00:09:43,440 --> 00:09:52,140 I didn't really run into any issues in using the subsystem for Linux. I had used it before. 141 00:09:53,160 --> 00:10:00,320 I tried building the Unix port of CircuitPython, and of course I used the subsystem for Linux in 142 00:10:00,420 --> 00:10:06,420 that regard as well. And so it was, I found it to be very straightforward to use. 143 00:10:08,140 --> 00:10:13,420 The biggest problem I found was interoperating between the Windows subsystem for Linux and 144 00:10:13,420 --> 00:10:18,560 Windows itself in order to keep my files straight. 145 00:10:19,920 --> 00:10:24,380 And I suppose that's more of a workflow issue on my part than anything else. 146 00:10:25,930 --> 00:10:29,360 How did using Claude Code help in porting this over to WebAssembly? 147 00:10:30,780 --> 00:10:35,880 At base, the WebAssembly port would not exist without Claude Code. I simply don't have the 148 00:10:36,000 --> 00:10:43,400 skills. It certainly wouldn't have happened within the month or so that it took. Maybe 149 00:10:43,400 --> 00:10:48,380 but it really was essential to getting this off the ground. 150 00:10:49,340 --> 00:10:50,900 - Any challenges with the prompts? 151 00:10:51,040 --> 00:10:52,860 I know there's not a lot of CircuitPython code 152 00:10:52,960 --> 00:10:56,120 out in the world for the LLMs to learn from. 153 00:10:56,640 --> 00:10:58,600 How did you work with the prompts 154 00:10:58,680 --> 00:11:00,380 to get it to do what you wanted it to do? 155 00:11:01,560 --> 00:11:03,260 - That was a large learning curve, 156 00:11:03,400 --> 00:11:07,500 and I think that's true for anyone who first comes 157 00:11:07,660 --> 00:11:09,940 to using anything like Claude Code. 158 00:11:11,160 --> 00:11:13,700 And as to figuring out some of the quirks, 159 00:11:14,480 --> 00:11:18,500 I tend to think that Claude works very well 160 00:11:19,260 --> 00:11:21,320 to work on a code base 161 00:11:21,760 --> 00:11:23,800 as opposed to working with a code base. 162 00:11:24,600 --> 00:11:27,580 In this case, because it was C code and not CircuitPython, 163 00:11:28,700 --> 00:11:30,320 it was a little bit more, I guess, 164 00:11:30,420 --> 00:11:32,320 straightforward on Claude's behalf. 165 00:11:34,300 --> 00:11:37,439 But nevertheless, it still wanted to default 166 00:11:37,440 --> 00:11:43,340 to always be adding something to the code base 167 00:11:44,360 --> 00:11:48,080 rather than working within the confines 168 00:11:48,120 --> 00:11:49,200 of what was already there. 169 00:11:49,940 --> 00:11:52,560 That quickly became a source of annoyance. 170 00:11:53,720 --> 00:11:56,220 There are workarounds you can leverage agents 171 00:11:57,120 --> 00:11:58,920 and things to kind of keep the Claude on track 172 00:11:59,860 --> 00:12:01,580 and give it a little bit more of a direction. 173 00:12:02,720 --> 00:12:06,660 The other issue was the context window management. 174 00:12:08,340 --> 00:12:09,680 While I was working on it, 175 00:12:10,779 --> 00:12:15,120 Anthropic kind of kept bumping up the context window, 176 00:12:16,620 --> 00:12:21,120 but certainly there were sessions in working with Claude 177 00:12:21,360 --> 00:12:23,900 where we'd come to the end of the context window, 178 00:12:24,300 --> 00:12:26,560 we'd need to compact the conversation, 179 00:12:27,200 --> 00:12:30,799 and I should have just called it a day at that point 180 00:12:30,800 --> 00:12:36,940 because it really was sort of like working in Groundhog Day, 181 00:12:37,420 --> 00:12:39,920 where we're starting all over again. 182 00:12:40,260 --> 00:12:42,600 Nobody has any knowledge of what came before. 183 00:12:43,980 --> 00:12:46,380 So also a source of frustration. 184 00:12:47,780 --> 00:12:49,140 - How can folks test out 185 00:12:49,300 --> 00:12:50,480 running CircuitPython in the browser? 186 00:12:51,960 --> 00:12:55,700 - So if they are able to navigate to the repository, 187 00:12:56,080 --> 00:12:58,619 the repository has instructions 188 00:12:58,620 --> 00:13:02,700 for being able to spin up a local server. 189 00:13:03,340 --> 00:13:05,880 They can self-host the webpage. 190 00:13:06,380 --> 00:13:10,640 They can get in, select the virtual workflow, 191 00:13:11,460 --> 00:13:15,640 and that will drop them right into a CircuitPython REPL. 192 00:13:16,160 --> 00:13:17,980 Not an emulation of it, 193 00:13:18,420 --> 00:13:21,420 or sort of under the hood, 194 00:13:22,220 --> 00:13:26,380 kind of clever text-based thing, 195 00:13:26,800 --> 00:13:28,440 but the REPL itself. 196 00:13:29,720 --> 00:13:31,000 - I'll make sure I link to your repository 197 00:13:31,100 --> 00:13:32,240 on GitHub in the show notes. 198 00:13:34,080 --> 00:13:35,780 John, if anyone wants to learn more about you 199 00:13:35,780 --> 00:13:37,080 and your work, where should they go? 200 00:13:38,320 --> 00:13:39,920 - Yeah, I've got a couple of other 201 00:13:40,120 --> 00:13:43,740 CircuitPython related repositories through my GitHub, 202 00:13:44,580 --> 00:13:48,000 so people can feel free to poke around there as well. 203 00:13:49,200 --> 00:13:52,140 If folks really wanna learn more about my work, 204 00:13:52,520 --> 00:13:53,780 I'm looking to make a career change. 205 00:13:53,820 --> 00:13:56,039 So if you or anyone you know and love 206 00:13:56,040 --> 00:13:59,040 looking for someone, I'd love to do that. 207 00:13:59,770 --> 00:14:02,800 Good to know. Last question I ask each guest. 208 00:14:03,380 --> 00:14:05,960 You're going to start a new CircuitPython or microcontroller project. 209 00:14:06,510 --> 00:14:08,920 Which board do you reach for to prototype or build with? 210 00:14:10,420 --> 00:14:12,760 Probably a QTPY or Trinkey 211 00:14:13,220 --> 00:14:16,220 with an RP2040. I mostly work 212 00:14:16,420 --> 00:14:19,280 on a Surface tablet convertible, 213 00:14:19,630 --> 00:14:21,700 so something small and light that I can plug in 214 00:14:22,680 --> 00:14:25,060 that doesn't weigh down the side. I do wish the 215 00:14:25,040 --> 00:14:32,400 the Trinkey had some exposed ports or pins, so kind of in a pinch I've resorted to using 216 00:14:32,580 --> 00:14:38,360 WaveShare's variant. Sorry, Adafruit. I do hope that we can see some of the RP2350 217 00:14:38,920 --> 00:14:44,680 versions in those form factors soon, once the new stepping becomes available. But of course, 218 00:14:44,680 --> 00:14:49,040 if I'm just looking to play around with the CircuitPython interpreter itself, 219 00:14:49,780 --> 00:14:52,000 there's a handy WASM port that I can use. 220 00:14:52,000 --> 00:14:53,660 There absolutely is. 221 00:14:54,260 --> 00:14:55,760 John, thanks so much for coming on the show. 222 00:14:56,240 --> 00:14:57,120 Thank you so much, Paul. 223 00:14:57,220 --> 00:15:00,380 I hope I can do something else cool soon and come back. 224 00:15:00,980 --> 00:15:01,800 I look forward to it. 225 00:15:03,200 --> 00:15:05,040 Thank you for listening to the CircuitPython Show. 226 00:15:05,360 --> 00:15:09,460 For show notes and transcripts, visit www.circuitpythonshow.com. 227 00:15:10,180 --> 00:15:13,580 To follow the show on Mastodon or BlueSky, check out the links in the show notes. 228 00:15:13,900 --> 00:15:16,720 And if you're enjoying the show, I'd be grateful if you could leave a review. 229 00:15:17,400 --> 00:15:19,120 Until next time, stay positive.