WEBVTT
NOTE
Transcription provided by Podhome.fm
Created: 7/6/2024
4:58:12 PM
Duration: 2909.599
Channels: 1
1
00:00:13.985 -->
00:00:25.440 Hello, and welcome to podcast dot in it, the podcast about Python and the people who make it great. When you're ready to launch your next app or want to try a project you hear about on the show, you'll need somewhere to deploy it. So check out our friends over at Linode.
2
00:00:25.875 -->
00:00:33.095With their managed Kubernetes platform, it's easy to get started with the next generation of deployment and scaling powered by the battle tested Linode platform,
3
00:00:33.560 -->
00:00:39.580including simple pricing, node balancers, 40 gigabit networking, and dedicated CPU and GPU instances.
4
00:00:40.495 -->
00:00:47.875And now you can launch a managed MySQL, Postgres, or Mongo database cluster in minutes to keep your critical data safe with automated backups and failover.
5
00:00:48.230 -->
00:00:49.370Go to python podcast.com/linode
6
00:00:50.790 -->
00:00:57.210today to get a $100 credit to try out their new database service, and don't forget to thank them for their continued support of this show.
7
00:00:57.715 -->
00:01:04.295The biggest challenge with modern data systems is understanding what data you have, where it is located, and who is using it.
8
00:01:04.595 -->
00:01:15.784Select STAR's Data Discovery Platform solves that out of the box with a fully automated catalog that includes lineage from where the data originated all the way to which dashboards rely on it and who is viewing them every day.
9
00:01:16.165 -->
00:01:23.784Just connect it to your DBT, Snowflake, Tableau, Looker, or whatever you're using and select star will set everything up in just a few hours.
10
00:01:24.280 -->
00:01:25.500Go to python podcast.com/selectstar
11
00:01:27.080 -->
00:01:31.820today to double the length of your free trial and get a swag package when you convert to a paid plan.
12
00:01:32.215 -->
00:01:45.130 Your host as usual is Tobias Macy, and today I'm interviewing Brian Pugh about Belay, a Python library that enables the rapid development of projects that interact with hardware via a MicroPython compatible board. So, Brian, can you start by introducing yourself?
13
00:01:45.509 -->
00:01:55.515 Hi. My name is Brian Pugh. I'm the lead deep learning scientist at a startup called Geomagical, where we develop the augmented photography application called Creative for IKEA.
14
00:01:55.840 -->
00:02:05.540So go check that out if you wanna see the handy work of our team. But, independently, I developed this library belay so that I could get my weekend projects done actually done in a weekend.
15
00:02:05.875 -->
00:02:08.135 And do you remember how you first got introduced to Python?
16
00:02:08.595 -->
00:02:15.254 Yeah. So, originally, I began my programming journey in c so that I could program PIC and ABR microcontrollers.
17
00:02:16.099 -->
00:02:22.680And then later on, I went to college for electrical engineering. And a lot of the classes, they all used MATLAB for assignments.
18
00:02:23.165 -->
00:02:26.225So that was my first time really using an interpreted language.
19
00:02:26.685 -->
00:02:38.740And then over internships and stuff like that, I began getting into deep learning where the de facto language is Python. It was similar enough to MATLAB that it was easy to transition over, and I haven't really looked back ever since.
20
00:02:39.275 -->
00:02:48.940 And so in terms of the BELAY project, you mentioned that it's something that you've built to help you actually get your weekend projects done in a weekend. I'm curious if you can just talk to
21
00:02:49.319 -->
00:02:57.465some of the details about what it is that you've built there and some of the story behind how you decided that this was somewhere that you wanted to invest in because it was an area
22
00:02:58.504 -->
00:03:03.644area that you were active enough that it was worth building a dedicated project? I guess just first in summary, Belay is a library that solves a problem. I want my computer to control some hardware.
23
00:03:07.690 -->
00:03:16.989 So with Belay, you can do something as simple as toggle an LED from your computer and just, like, make, like, 6 lines of code. And Belay achieves this by interacting with a MicroPython
24
00:03:17.595 -->
00:03:21.614compatible board via its REPL, its read, evaluate, print interface.
25
00:03:21.995 -->
00:03:32.860So it uses this to evaluate commands as well as to sync code between your computer and the device. So Belay really just blends the boundary between your computer application and the firmware running on device.
26
00:03:33.240 -->
00:03:35.900It should be noted that Belay doesn't run on MicroPython.
27
00:03:36.315 -->
00:03:43.615Belay is a library that runs on your host computer that is shuttling Python statements and expressions between your computer and microcontroller.
28
00:03:44.280 -->
00:03:50.940There's no explicit upload this firmware to your microcontroller step for the user to perform. It just works out of the box with MicroPython
29
00:03:51.319 -->
00:03:52.140or CircuitPython.
30
00:03:52.825 -->
00:03:55.004Source code is just transferred as needed.
31
00:03:55.305 -->
00:03:57.885So once you have this Belay library imported,
32
00:03:58.185 -->
00:04:02.650how it works is you decorate a Python function with the Belay task decorator,
33
00:04:03.190 -->
00:04:08.010and what this decorator will do is send the function's source code over to the microcontroller
34
00:04:08.390 -->
00:04:11.515project or a microcontroller board that's running MicroPython.
35
00:04:12.295 -->
00:04:20.280So this function is being sent over to the device, and the function on the host on your computer is actually replaced with a remote executor.
36
00:04:20.840 -->
00:04:29.980If you were to call that function on host as you would, like a normal function, it will actually send a command to execute it on device and return the results from the micropython interpreter.
37
00:04:30.585 -->
00:04:37.405So in some ways, it's sort of like Celery where functions are being executed on a remote machine. Just in our case, it's a microcontroller.
38
00:04:38.180 -->
00:04:45.320And so I created this library because the conventional approach of computer hardware interactions was super cumbersome and tedious.
39
00:04:45.835 -->
00:04:49.775Conventionally, if you want an application on your computer to interact with hardware,
40
00:04:50.075 -->
00:04:51.455there are 3 large efforts.
41
00:04:51.755 -->
00:04:56.030Number 1, you have to create the application itself. But I mean, like, you know, that should be the fun part.
42
00:04:56.410 -->
00:04:58.8302, you have to create the firmware for the microcontroller
43
00:04:59.210 -->
00:05:04.905that is interacting with the hardware. And typically that's done almost independently of your actual application.
44
00:05:05.285 -->
00:05:15.270So now your project actually kind of has 2 projects within it. And then finally, you need to develop a communication protocol to shuttle data between your firmware running on your microcontroller
45
00:05:15.810 -->
00:05:17.830and your application running on your computer.
46
00:05:18.205 -->
00:05:21.905So for simple projects, if you're just reading something like a potentiometer,
47
00:05:22.525 -->
00:05:33.910the communication protocol can be pretty simple. Your microcontroller can be reading those analog values in and can just be printing them out to the serial port, and then the computer can parse that byte stream without too much trouble.
48
00:05:34.405 -->
00:05:42.105However, if your project gets more complicated and you want more inputs or more outputs, the communication protocol also has to become more complex.
49
00:05:42.599 -->
00:05:49.660Firmware might have to listen for and parse commands, and your application might need to deserialize more complex responses from your firmware.
50
00:05:50.275 -->
00:05:52.134So command parsing, interpretation,
51
00:05:52.595 -->
00:06:12.845and result parsing, they're all pretty generic across many projects. So I figured, why not make a library for it? So with Belay, you don't have to independently develop that firmware and you don't even have to think about the communication protocol because that's all handled for you. I wanted to spend less time developing firmware and protocols and more time working on the actual fun stuff, the projects themselves.
52
00:06:13.145 -->
00:06:25.905 So Belay was born. In terms of the kind of scope of projects that Belay is intended to use be be used for, you mentioned that it's working from the host computer to relay those commands to the microcontroller.
53
00:06:26.605 -->
00:06:28.865And I know, too, that when you're writing things in MicroPython,
54
00:06:29.690 -->
00:06:41.525oftentimes, also, you want to just build an isolated project that's going to run on a continuous loop on that microcontroller board or, you know, triggered by some of the interrupts like the I squared c port or something.
55
00:06:41.905 -->
00:06:48.640So I'm curious if Belay is focused primarily on projects where that microcontroller is going to remain attached to the host
56
00:06:49.180 -->
00:06:55.920computer, or is it something too where you would also use it for developing some of those self contained projects on that hardware board?
57
00:06:56.345 -->
00:07:13.700 So, originally, I developed BELAY with the intention that the microcontroller is gonna be continuously attached to the computer. And it doesn't have to be like your main desktop or something. It could be a more simple single board computer like a Raspberry Pi. And it originally stemmed from 1 of my Raspberry Pi projects. I needed to read a potentiometer.
58
00:07:14.224 -->
00:07:17.604And the Raspberry Pi doesn't have a built in ADC converter.
59
00:07:17.985 -->
00:07:30.070And with the silicon shortage and everything, an ADC converter that's compatible with the Raspberry Pi costs, like, $15 or whatever. And I was like, no. I'd rather just buy a bunch of Pi Picos that are, you know, much more generically useful.
60
00:07:30.444 -->
00:07:35.585But then, of course, I then had to deal with this whole communication protocol, firmware development, and things like that.
61
00:07:36.285 -->
00:07:47.010And so, you know, that that led into developing this library because it was such a pain. But so, you know, for those projects, I intended the microcontroller to be constantly attached to the computer.
62
00:07:47.444 -->
00:07:56.585However, as I've been using Belay for other projects, I found that it's useful for generic development even if the end product is not going to be attached to a computer.
63
00:07:57.120 -->
00:08:00.580And that's because, you know, you have delay handling all these hardware interactions,
64
00:08:01.040 -->
00:08:20.430but hardware interactions are typically only, you know, part of the whole software you're developing. There's a lot of other logic going around too. So if you can move a lot of that development over to your computer instead of running it on micro Python, You can use a lot better debugging tools that normal Python gives you, like PDP or whatever IDE you're using.
65
00:08:20.810 -->
00:08:25.455So it can be used both for a full project and also just in the development of a project.
66
00:08:25.995 -->
00:08:31.695 As far as the, I guess, target audience for Belay, obviously, the primary audience is yourself.
67
00:08:32.070 -->
00:08:35.529And as you decided to release it as an open source project,
68
00:08:35.910 -->
00:08:42.795curious what were some of the, I guess, conceptual cleanup that you wanted to do to make it more broadly understandable
69
00:08:43.575 -->
00:08:49.675and sort of who you had in mind for who you thought might come along and pick up BELAY and start using it for their own projects?
70
00:08:50.160 -->
00:08:53.540 This is not my first project that has had to communicate with a microcontroller.
71
00:08:54.400 -->
00:09:36.635And whenever you're just working on a quick project, it's typically going to be hacky and dirty. And just whatever you can do to make it work, you make it work and then so you can move on. But I decided, I was like, you know, this is a reoccurring problem. I want to get it done right. I wanna get it done cleanly. I want it to be well documented. I wanted to solve it once so that I never have to worry about it again. That's whenever, you know, you start doing a little bit more software engineering rather than just hacking stuff together. So originally, I came up with an interface that I would like that I would like to develop with, and then I figured out how can I make this interface actually happen? And then, I flushed out the code to, you know, make it work that way. And then, you know, it's important that whenever you're designed that way, that it's also maintainable
72
00:09:37.095 -->
00:09:43.329so that if other people are coming to the project and let's say there's a feature that they want that is not currently implemented,
73
00:09:43.709 -->
00:09:47.970I don't want it to look too scary for them to try and come in and contribute a feature.
74
00:09:48.285 -->
00:09:53.985So I've been trying to keep it as simple as I can while still providing all the functionality we want.
75
00:09:54.445 -->
00:09:56.065 In terms of the typical,
76
00:09:56.890 -->
00:10:00.670I guess, workflow of building a project for a microcontroller
77
00:10:01.050 -->
00:10:10.135board, I'm wondering if you can talk to some of the common points of friction that you run into that slow you down and make your weekend projects span multiple weekends.
78
00:10:11.555 -->
00:10:22.520 Yeah. So embedded project development in general is, like, if you've never done it and then you move into it, it's really quite unpleasant compared to traditional software development that just runs on a normal computer.
79
00:10:22.865 -->
00:10:24.165There's a bunch of issues,
80
00:10:24.625 -->
00:10:29.445but I'd say some that I'd like to highlight that, you know, Blade does solve or at least, you know, is tangential.
81
00:10:30.040 -->
00:10:35.6601 of the first big problems is that you have to get your environment set up. Now if you're only using 1 microcontroller
82
00:10:36.040 -->
00:10:37.019from 1 manufacturer,
83
00:10:37.455 -->
00:10:45.155you know, this is a kind of a 1 and done, and it's not too big of an issue. But if you're, you know, switching around microcontrollers, switching around manufacturers, it becomes quite tedious
84
00:10:45.500 -->
00:10:47.680because for each manufacturer, for each microcontroller,
85
00:10:48.380 -->
00:10:57.195especially if you're programming in c, you'll have to download the microcontroller manufacturer's toolchain or IDE to, you know, compile and flash your code to your device.
86
00:10:57.655 -->
00:11:03.275And often these tools have a lot of unique quirks and features to those specific chips or manufacturers.
87
00:11:03.879 -->
00:11:15.825Typically, you know, several years, like decades of technical dead that, you know, they're like, this is just the way it is. So it takes a lot of time to become familiar with all those features and tools and the way it's done in that framework.
88
00:11:16.285 -->
00:11:30.710And so that slows down development a lot because, you know, even if you know c, you're in a whole other land now. So that's 1 issue with embedded development. Another 1, and this is probably the most critical 1, is the available debugging tools, especially for hobbyists.
89
00:11:31.235 -->
00:11:56.815So, you know, hobbyists typically have really inexpensive boards, and they don't wanna buy expensive tools. You know, I wanna buy that $5 clone, like, off Amazon or eBay or whatever. And if you don't have the proper hardware or software support, even simple things like breakpoints can be very difficult or impossible to set up, So inspecting program state can become quite hard, and this frequently reduces the programmer to doing things like just print debugging, which is never efficient.
90
00:11:57.340 -->
00:12:05.040And so if you think print debugging is not efficient, the biggest issue is the long iteration cycles. So this is the time between
91
00:12:11.685 -->
00:12:17.050and then the code being slowly transferred over to some serial port. And then the code being slowly transferred over some serial port.
92
00:12:17.430 -->
00:12:29.175During that time, you get bored or distracted. You're browsing Reddit or whatever. And then sometimes by the time your code is actually running, you forget the changes that you've already made. So now you don't even remember what you're trying to debug.
93
00:12:29.730 -->
00:12:47.860So for MicroPython development, if you're using an IDE like Phonny, this is less of an issue because whenever you save, it automatically syncs. So the delay is just a few seconds. If you try to develop MicroPython from the command line, it can quickly become tedious, though, because you have a single serial port communicating with your microcontroller.
94
00:12:48.400 -->
00:12:59.834And so you're using that serial port for both sending code over as well as the standard out, you know, that you're trying to get all your print debugging back from. So you had to be constantly switching back and forth, and, you know, that's just kind of annoying.
95
00:13:00.270 -->
00:13:06.450CircuitPython does alleviate some of these issues by allowing you to directly edit code on device. CircuitPython
96
00:13:06.830 -->
00:13:12.084mounts its file system as a USB drive to your computer so you can directly edit your Python scripts.
97
00:13:12.385 -->
00:13:23.030But the resulting project isn't exactly Git friendly since you're editing all these files on another system. And then if your file system gets corrupted, then you're kinda just screwed. So in my opinion, it's not an excellent,
98
00:13:23.635 -->
00:13:24.535experience either.
99
00:13:25.075 -->
00:13:29.255 So in terms of the pain points that you mentioned there, I'm curious
100
00:13:29.635 -->
00:13:39.480how many of them you actually aimed to resolve with Belay and some of the ways that you went about kind of building nicer interfaces or more convenient
101
00:13:39.955 -->
00:13:43.575iteration loops into your development workflow through this library?
102
00:13:44.195 -->
00:13:52.970 Right. So the primary goal was just to simplify the interactions between the computer and the micro controller. But, you know, while developing that, I inherently developed
103
00:13:53.430 -->
00:14:23.885what what I think is a better experience to develop with, and that's, you know, defining these short terse functions that are doing the actual hardware interactions. There's typically not too much to debug with that in micro Python because a lot of libraries, like, you know, from Adafruit or whatever, they do a lot of the heavy lifting for you. And so you only have to have, like, 3 lines of code. There's not much to debug. And then that moves the rest of the logic that, like, you know, is your custom? What do I do with these inputs? What do I do with these outputs? It moves it back onto your computer instead of on the MicroPython
104
00:14:24.190 -->
00:14:24.690interpreter.
105
00:14:24.990 -->
00:14:40.985So when it's on the computer, it's so much easier to debug because you can just set a breakpoint, and you can inspect the state. You can inspect the values. You have much better visualization tools. Like, if you wanted to plot a bunch of values, you have matplotlib available to you, that would certainly not be available on MicroPython.
106
00:14:41.699 -->
00:14:43.800 The other interesting element is
107
00:14:44.180 -->
00:14:55.785discussing kind of what are the pieces of developing for hardware that are just inherent to the problem space. You're never going to solve it, and you decided not to even bother trying to address them in belay
108
00:14:56.089 -->
00:15:04.245and maybe some of the ways that you modified your own kind of development workflow or the way that you structure your, maybe, function definitions
109
00:15:04.625 -->
00:15:08.245or sort of code workflow to be able to make it more
110
00:15:08.705 -->
00:15:11.445accommodating to the hardware constraints themselves?
111
00:15:12.250 -->
00:15:20.430 Right. So, you know, whenever you're developing in Belay, you naturally try and make your tasks, your functions that interact with the hardware as short as possible.
112
00:15:20.935 -->
00:15:26.075And, you know, so not everyone does this, but it's actually gonna end up enforcing good practice
113
00:15:26.455 -->
00:15:29.800because it abstracts away the hardware interactions So
114
00:15:32.837 -->
00:15:33.337even
115
00:15:36.615 -->
00:15:43.675So even though Belay is sort of like, if you don't use it in your final product, it encourages better code structure
116
00:15:44.320 -->
00:15:46.580just just for the maintainability of your project.
117
00:15:47.280 -->
00:15:49.220 So in terms of the actual implementation
118
00:15:49.600 -->
00:16:00.885of the Belay library, I'm wondering if you can talk to some of the, maybe, built in Python capabilities that you leaned on, some of the ways that you had to design around, some of the specifics of MicroPython
119
00:16:01.265 -->
00:16:05.820and the constraints of the hardware that you're dealing with and maybe some of MicroPython's
120
00:16:06.760 -->
00:16:10.380lack of inclusion of different standard library of modules?
121
00:16:11.075 -->
00:16:16.855 On the computer side, Belay is built on top of an interface called PyBoard from the MicroPython repository.
122
00:16:17.394 -->
00:16:21.570I believe it was primarily developed by Damien George and Paul Sokolowski.
123
00:16:22.269 -->
00:16:29.345And what this utility is, it's basically an adapter that makes it much easier for a Python program to interact with the micro Python REPL.
124
00:16:29.725 -->
00:16:37.860Because if you ever use the micro Python REPL or any Python REPL in general, there's, like, a lot of characters on the screen. Like, you know, you might have the 3, you know, less
125
00:16:38.240 -->
00:16:46.395or, yeah, greater than symbols at the beginning of the prompt to tell you to type in. And then, also, there might be elements that you don't even think of. Like, whenever you're typing
126
00:16:46.775 -->
00:16:50.075characters into a REPL, it's echoing the characters back.
127
00:16:50.450 -->
00:17:14.510So what this package does is it sort of just abstracts all that away. It takes care of all the things. It knows how to send commands over. It knows how to get the byte stream back to you. So this was all based off of the work that they already did. And with that, you might think that the problem is already solved, and in many ways, it is, but Highborne adapter did make developing Belay significantly easier because it handled all of the low level communication logic.
128
00:17:14.945 -->
00:17:25.380What BELAY brings to the table is it adds a ton of syntactic sugar to it, abstraction, and a few features that make the common use case or what I believe is the common use case to be much simpler.
129
00:17:26.080 -->
00:17:58.170So if you were just to use this PyBoard module, this PyBoard, you know, script, whatever you wanna call it, there are several extra steps that you need to perform to get the similar functionality as Belay. So you can just think of this as you can send a string command over, and you get a byte stream back. So if you we want to send source code over of some function that you want to run on device, you have to first, you know, package it up into a string, send it over. If you want to improve the efficiency of the transfer, you should probably minify that Python code before you're sending it over. That's like doing things like removing unnecessary
130
00:17:58.470 -->
00:18:00.570white space, comments, docstrings,
131
00:18:01.190 -->
00:18:02.010stuff like that.
132
00:18:02.630 -->
00:18:11.920And then to actually invoke the function on device, now that all that source code is on device, you would need to parse together a Python expression calling that function with the arguments you want.
133
00:18:12.800 -->
00:18:22.625So that can be a bit tedious, a bit error prone. Belay also handles that. We can get into that in a little bit. So you have this command that will execute the function on device, but now you wanna get the results back.
134
00:18:23.005 -->
00:18:32.360So before you actually send it over that source code, you have to modify it a little bit because returning the value from the function isn't quite doing what we want. We actually want
135
00:18:32.740 -->
00:18:54.590to serialize that result and send it over standard out so that our computer gets the result. So So you have to do a bit of serialization and printing the standard out. And then finally, your computer has to parse that serialized byte stream back into an appropriate Python data type, whether it be like a list, a 2 pull, an integer, whatever it might be, exactly what the developer would expect and hope to get back, you know, the useful representation. So these are the challenges that
136
00:18:58.617 -->
00:18:59.117So
137
00:19:02.690 -->
00:19:11.750So we do this with 1 or 2 methods. We have a classical sync method that will sync, you know, full files over to the micro Python file system,
138
00:19:12.095 -->
00:19:24.690And it does a few smart things, like it'll check hashes of local files on the MicroPython system to make sure that if a file has changed, we can sync it over. If it hasn't changed, we don't need to waste the bandwidth sending over the same files.
139
00:19:25.150 -->
00:19:30.865But then the more useful 1 is decorating functions in your Python script with this task decorator.
140
00:19:31.404 -->
00:19:42.409So in order to get the source code of the function we're decorating, we use the built in Python module inspect, which does a bunch of cool things, but it essentially allows us to get the source code of the function we're decorating.
141
00:19:42.950 -->
00:19:48.570We had to come up with our own minification script. This uses another Python built in called tokenize,
142
00:19:49.005 -->
00:19:50.305which is a Python
143
00:19:50.925 -->
00:19:52.705well, it's a Python source code tokenizer.
144
00:19:53.085 -->
00:19:56.945It basically breaks up, you know, this giant Python source code string into
145
00:19:57.280 -->
00:20:00.500what each individual element means so we can sort of determine
146
00:20:00.800 -->
00:20:15.000what parts are valuable, what parts are not. So we can strip out docstrings and comments. We can reduce the indentation level. Like, if you had 4 spaces for 1 indentation level, you can reduce that to 1. So typically, you can make your source code, like, 3 times times smaller just with naive minification.
147
00:20:15.700 -->
00:20:32.960So now you have that minified codes. You know, Belay sends it over. We record what that function name is. We know what the function name is on device so that whenever we're parsing our string command together, we have it. And then we actually do something that I feel like is relatively clever. We have to figure out how to serialize and deserialize
148
00:20:33.340 -->
00:20:34.400these Python objects.
149
00:20:34.940 -->
00:20:40.695And for all Python built ins, if you use the built in repr command for representation,
150
00:20:41.475 -->
00:20:50.590this returns a string for, you know, an object. And if it's a Python built in, the return string contains exactly the information to recreate that object.
151
00:20:51.050 -->
00:21:04.450So if you do repr of an integer, it'll return 5. And then in order to turn that string back into a Python object, you can use the built in literal eval from the AST library, the abstract syntax tree library,
152
00:21:04.910 -->
00:21:06.770and that will perform a safe
153
00:21:07.070 -->
00:21:07.570deserialization
154
00:21:08.430 -->
00:21:15.325of that string. So you have an object. You can feed it to repr to produce a string, feed that string into ast. Literaleval,
155
00:21:15.784 -->
00:21:28.259and that will produce the exact same object back. So we use that for serializing the parameters that we're sending to the micro Python device, and we're using it to deserialize and serialize the results being sent back.
156
00:21:28.625 -->
00:21:33.445And so in doing it that way, we're able to represent all the built in Python objects.
157
00:21:33.825 -->
00:21:37.445I didn't know about this. Originally, I was using JSON serialization
158
00:21:37.799 -->
00:21:38.380and deserialization
159
00:21:39.240 -->
00:21:41.340because it seems like a pretty obvious solution.
160
00:21:41.799 -->
00:21:49.985But the limitations of that, which I didn't like, was you couldn't represent Python sets because that's not valid JSON, and also you couldn't represent
161
00:21:50.765 -->
00:21:53.585binary data because JSON doesn't support bytes.
162
00:21:53.890 -->
00:22:07.275Soon after, I was like, oh, wait a minute. We can just use representation literal eval. So moved over to that and it became a lot cleaner and stuff like that. It is also good because not all libraries are available across all micro Python and circuit Python implementations.
163
00:22:07.895 -->
00:22:13.570Like, for example, in that file syncing I was mentioning earlier, originally, we were hashing files using sha256
164
00:22:14.190 -->
00:22:16.050just because it was built into micropython,
165
00:22:16.510 -->
00:22:23.005and it was easy, good enough. You're gonna get a unique fingerprint of a file. However, whenever I started making Belay CircuitPython
166
00:22:23.465 -->
00:22:23.965compatible,
167
00:22:24.345 -->
00:22:32.210it turns out CircuitPython doesn't have that, you know, cryptography library, that hashing library built in. So I had to figure out a new hashing function.
168
00:22:32.590 -->
00:22:36.690So after a bit of Googling, I discovered this well, I mean, I discovered it on Google,
169
00:22:37.265 -->
00:22:54.059this, cool hashing function. I think it's called f n v 1 b or 1 a, something like that. It's an incredibly terse hashing function. It's like 3 lines of Python. So then I was able to bundle that in with Belay for file hashing instead of having to rely on circuit Python or MicroPython
170
00:22:54.360 -->
00:22:58.295specific features. That was another, like, cool little, internal implementation
171
00:22:58.595 -->
00:23:11.460detail. But yeah. So between all of this, you know, it it's a lot of syntactical sugar where taking the source code, remitifying it, sending it over. We're automatically parsing the commands for you. We're automatically serializing and deserializing
172
00:23:11.840 -->
00:23:15.765the parameters and results, and we're sending that back to you so it's all done seamlessly.
173
00:23:16.305 -->
00:23:22.245So I guess at at a medium level, that's how Belay works. There are finer details here and there, but that's the general concept.
174
00:23:22.940 -->
00:23:24.320 As far as the,
175
00:23:25.020 -->
00:23:26.000I guess, workflow
176
00:23:26.300 -->
00:23:34.145of using Belay, you mentioned that it's largely, you know, add a decorator to a Python function. It will handle sending that back and forth
177
00:23:34.685 -->
00:23:35.745to the micropython
178
00:23:36.045 -->
00:23:40.830board. I'm curious what you are using as sort of the kind of triggering to
179
00:23:41.610 -->
00:24:10.425as somebody's going through the development process, is it just, you know, I just need to run Python my file name, Or do you set up some sort of file watches with Belay where you can say, every time I save the file, just resync the state so that I don't have to, you know, do this manually. I can stay more in the flow of just writing something and then see what happens and just kind of managing that back and forth workflow of writing on your laptop or writing on your host computer and then being able to interact with that microcontroller.
180
00:24:11.420 -->
00:24:39.975 Right. So that automatic detection and stuff is what you're describing is available in circuit Python. Whenever you edit a file on circuit Python and you save it, it'll automatically reload the Python interpreter and re execute your file. But late doesn't have anything magic running in the background that's watching files or anything like that. It's just a conventional Python script. So if you have your main Python function, just run Python main dot py. It'll execute it. The 2 main features of getting code onto the board, you know, the sync call as well as these decorators.
181
00:24:40.434 -->
00:24:55.090You know, the you can put the sync call at the top of your script to make sure that if you have any changes in the Python libraries that you wanna send over to your device, that those are automatically sent over. And then all of the task decorator functions, those are sent over every single time
182
00:24:55.395 -->
00:25:08.500because those are only stored in the interpreter state. It's not like they get synced to the file system or anything like that. So workflow is basically a standard Python project. You're editing your script, you get to run it, and then that's all it is.
183
00:25:09.040 -->
00:25:18.355 Another interesting challenge whenever you're dealing with kind of resetting the state of the code on a device is having to reconstruct the prior
184
00:25:18.975 -->
00:25:24.100operational state. So for instance, if you're trying to debug something and resolve an error
185
00:25:24.560 -->
00:25:37.424and maybe you had to, you know, interact with a few toggles or, you know, it's dealing with some sensor inputs where it's only gonna trigger when it hits a particular temperature threshold or, you know, luminescence value if you're dealing with a light sensor.
186
00:25:37.750 -->
00:25:40.490I'm wondering if you have any kind
187
00:25:40.950 -->
00:26:09.765 of practices or ways that you've approached that challenge of being able to kind of regenerate the state of the program at the time through the error so that you can, you know, make a change and then quickly get back to that point? So if we, like, make the assumption that the issue lies in your own code and not in some third party's code, yeah. So, Belay allows that to happen quite easily. So, you know, if you have an uncaught exception, if you run postmortem debugging on your code and only hardware interactions are in the delayed tasks,
188
00:26:10.145 -->
00:26:11.430then the whole
189
00:26:11.750 -->
00:26:22.615weird state that your hardware stuff generated, that should still be in your Python interpreter state on your computer. And so you can, of course, save that state to, like, a pickle file or whatever for future debugging
190
00:26:22.995 -->
00:26:46.529so that whenever you're trying to debug what the actual issue is, you don't need to do all your hardware interactions again. You already have the important state in your interpreter and save to a file, so you can reproduce it over and over again. Without that, you would just look and be like, ah, well, something weird happened, and I have no idea if we can ever reproduce that again. By, you know, abstracting once again the hardware from the actual logic, it makes it much, much easier.
191
00:26:46.830 -->
00:26:55.615 Yeah. It's definitely very useful, and the point of being able to kind of pickle the operational state and use that as a test case for debugging
192
00:26:56.235 -->
00:27:02.575is interesting. And I'm wondering from that what you have kind of started as your own practice of managing,
193
00:27:02.955 -->
00:27:04.929kind of building up a test suite if
194
00:27:05.230 -->
00:27:09.490you're iterating on a particular hardware device and, you know, doing a long running project
195
00:27:09.870 -->
00:27:18.325and then building up a library of some of those saved error states and then building up a set of unit tests around that given project so that you can, you know, make changes
196
00:27:18.945 -->
00:27:27.090and understand, like, am I introducing a regression that's bringing me back to this problem or some of those kind of testing and debugging over a longer period of time?
197
00:27:27.470 -->
00:27:31.169 Unit testing is a good point. Unit testing on embedded
198
00:27:31.615 -->
00:27:48.049projects is always a bit difficult. You know, it's quite easy to add in unit test to the business logic, if you will, once it's isolated from your hardware because that just runs anywhere. It's not actually specific to the hardware it's running on. And this is actually a big struggle with Belay because
199
00:27:48.635 -->
00:28:05.680the entire library is centered around interacting with hardware, interacting with hardware so that you don't have to worry about it. And so writing unit tests for Belay is very hard. For some of the stuff, it's quite easy, like minification and stuff that doesn't interact with the serial port with the boards and all that, but
200
00:28:06.025 -->
00:28:16.910actual unit testing of the functions is difficult. You can't really just have a GitHub action that, you know, is like, oh, yeah. Just make sure you have a PyPico attached and run these commands, and it'll be fine.
201
00:28:17.210 -->
00:28:24.075So, actually, if anyone knows how to set up better CI for hardware projects, I'm I'm all ears. I would love to hear about that.
202
00:28:24.635 -->
00:28:34.640And then, you know, pickling your current state so that triggers a bug is always great because you don't necessarily wanna use that exact pickle file in a unit test because that's kind of opaque.
203
00:28:35.020 -->
00:28:49.025However, you can typically find out what was the exact edge case that caused this to trigger. And so then you can create that simplified unit test that triggers that exact use case, not only just to prove that you've solved it, but then also you don't make the same mistake in the future.
204
00:28:49.565 -->
00:29:01.665 In terms of some of the weekend projects that you're using Belay for, I'm wondering if you can share some of the types of projects and some of the ways that Belay has helped you with some of that development cycle and how it maybe
205
00:29:02.045 -->
00:29:09.025changes the way that you think about the design of your programs because of the fact that you do have these faster and more seamless iteration cycles.
206
00:29:09.530 -->
00:29:19.515 Whenever I have an idea for a project, I'm much more likely to actually do the project now. Previously, I would be like, I really don't wanna deal with the serial port. I really don't wanna deal with
207
00:29:19.975 -->
00:29:30.360all this new line parsing and, like, what happens if it disconnects and all these other edge cases. So now that I have this library that abstracts all that way, I'm much more likely to actually do projects.
208
00:29:30.820 -->
00:29:43.755Belay is quite young. It's only about a month and a half old since I made it public. So I've only used it really for 2 projects so far. 1 is a personal project I haven't released yet, but it was simply just used to read a potentiometer
209
00:29:44.055 -->
00:29:47.090from a pipe echo. That made it a lot simpler because,
210
00:29:47.550 -->
00:29:48.050tangent,
211
00:29:48.510 -->
00:29:51.570whenever you're uploading projects with Belay, you feel a lot
212
00:29:52.110 -->
00:29:57.904more confident because no matter what, the firmware the quote unquote firmware, the code that's running on the device
213
00:29:58.205 -->
00:30:17.015will always be up to date with the code that's running on your host. So previously, you'd be like, oh, I need to reflash the firmware that's running on the microcontroller and make sure that it's up to date because otherwise, I made these backwards incompatible changes in my core application. You really don't have to worry about any of that since the code is automatically updated every single time you run the program.
214
00:30:17.395 -->
00:30:27.570So you're much more likely to make changes, and then you don't have to be as mindful to make them backwards compatible because you know the code running on the microcontroller is always up to date.
215
00:30:27.915 -->
00:30:29.855So 1 of them was just, you know, radio potentiometer.
216
00:30:30.235 -->
00:30:45.265That's actually for a little project where I have this old school radio that I have a bunch of media player instances running all at the same time, and I have a tuning knob that changes the volume to all these different, quote, unquote, radio stations. So I have, like, a potentiometer
217
00:30:45.645 -->
00:30:47.105hooked up to that running delay
218
00:30:47.485 -->
00:30:51.265to send the analog values over to a Raspberry Pi that's playing a bunch of audio.
219
00:30:51.630 -->
00:30:56.130Another project that I released, maybe I think it was, like, 2 weeks ago, is a magnetometer
220
00:30:56.669 -->
00:30:57.330or Gaussmeter
221
00:30:57.870 -->
00:31:03.295command line project. So this is also on my GitHub. But, basically, it's a PIP installable package
222
00:31:03.755 -->
00:31:06.255that has all the firmware bundled in with Belay,
223
00:31:06.610 -->
00:31:09.430and it can hook up to a bunch of I2C
224
00:31:09.809 -->
00:31:10.309magnetometer
225
00:31:10.610 -->
00:31:14.630chips. A lot of them are available, like, on Adafruit. I used their drivers,
226
00:31:14.985 -->
00:31:27.620And it just takes all of the magnetic field values, prints them to the command line, and also plots a nice graph in them and stuff like that. And that's because in an upcoming project, I'm using a bunch of magnets for stuff because, you know, magnets are always cool.
227
00:31:28.000 -->
00:31:31.045And I needed to get some readings to make sure that my
228
00:31:37.285 -->
00:31:39.385gaussmeter is typically, like, 1 to $500,
229
00:31:40.299 -->
00:31:44.320while an I2C chip that does basically the same thing as, like, $10.
230
00:31:44.620 -->
00:31:58.145So I was like, hey. This is a great chance to use my library and then also get a really cheap tool. Yeah. And so it's very cool because with most microcontroller projects, typically in the setup phase, you're like, alright. Download this firmware. Download this toolchain.
231
00:31:58.450 -->
00:32:05.909Compile it, flash it, make sure it's all up to date. There's a lot of steps. But with this, so long as your board is just running circuit Python,
232
00:32:06.255 -->
00:32:16.399you just run the command and the firmware's automatically uploaded and everything's already figured out. So you could have some whole other project running on your device, and then you just run my magnetometer
233
00:32:16.779 -->
00:32:17.279project.
234
00:32:17.580 -->
00:32:26.185And now different code is automatically running on it. So you don't even have to think about the hardware at all. It's all bundled together, and so I think that's a pretty cool use case of delay.
235
00:32:26.565 -->
00:32:32.150 And to that point of you don't have to care about what program was running on it before, that also brings up the
236
00:32:32.630 -->
00:32:33.770interesting point of
237
00:32:34.150 -->
00:32:55.470if you have multiple potential use cases for the same hardware device where maybe it has maybe it's something like 1 of the Adafruit circuit playgrounds or something where it has multiple different sensors and interfaces on it. And so depending on, you know, what you're doing is part of your general activity, you wanna run different programs on it. In the case
238
00:32:56.169 -->
00:33:12.750of the standard of way of having to load the projects in, maybe it's cumbersome, and you say, I don't really wanna deal with that. But if you have something like belay where you just say, I just trigger this, and then it's doing the thing that I want it to do, that makes it a little easier to kind of make those boards multipurpose or just kind of, like, repurpose them from previous
239
00:33:13.210 -->
00:33:33.180projects that you're working on. Wondering how maybe some of the ways that you've incorporated that into your kind of project flow, or maybe in the morning, you want to, you know, use it to measure the temperature of your coffee and make sure it's the right temperature. And then in the evening, you wanna use it to, I don't know, figure out what is the temperature outside to see if you need to throw out a sweatshirt before you go walk the dog or something.
240
00:33:33.605 -->
00:34:08.090 Definitely. I mean so, like, previous to using belay, I would, like, have, like, sticky notes or, like, some masking tape on each microcontroller for, like, what project is it for so that I don't mess up firmware or I don't, like, you know, erase something that, like, was sort of tedious to set up. But now on my desk, I just have a bunch of pipe echo boards just sitting around. It doesn't matter which 1 is which. I just pick up 1 and then run over to my other project, and it allows me to use it for those super ephemeral cases like, oh, I need a magnetometer. Well, I just picked up 1 from my desk, and now I'm just gonna go use it for that project. It lowers the barrier to entry so that you're much more comfortable
241
00:34:08.525 -->
00:34:10.305doing these things, where previously,
242
00:34:10.845 -->
00:34:21.510it just always seemed like a lot of work. And whenever it's a lot of work and it's meant for fun, then you just sort of don't feel like doing it anymore. So I think I've been able to do a lot more creative projects since then.
243
00:34:21.810 -->
00:34:23.110 In your conversations
244
00:34:23.490 -->
00:34:25.590with, you know, friends, colleagues,
245
00:34:26.015 -->
00:34:27.715people who have come across the project.
246
00:34:28.175 -->
00:34:28.835I'm wondering
247
00:34:29.135 -->
00:34:45.185what their sense has been as far as is it largely people who are already engaged with hardware development, and they say, oh, this made my life easier? Or are you also talking to people who are saying, oh, well, hardware development seems interesting, but maybe I'll actually give it a try because this part is simpler?
248
00:34:45.725 -->
00:34:46.945 So, invariably,
249
00:34:47.245 -->
00:34:55.150a lot of my friends don't do a lot of hardware development, but I have posted to some of my friends for helping teach their kids programming because
250
00:34:55.610 -->
00:35:05.025the conventional setup is still a bit cumbersome. This makes it a little bit easier. And then I think whenever you're teaching programming to children, if you can well, I mean, you know, children and adults,
251
00:35:05.485 -->
00:35:14.839like, if you can make it more interactive, see physical actions happening based off of, you know, the ideas and the actions that you typed, I think that makes it a lot more enticing because
252
00:35:15.140 -->
00:35:21.355writing something on a computer and making something on a computer happen, it's kinda cool, but like, you know, it doesn't really spark the creativity,
253
00:35:21.815 -->
00:35:31.470but, you know, typing something on a computer and now a motor's turning, or now like, yo, a speaker's going off, that's a lot more exciting. So I think you can get, you know, people more engaged in programming.
254
00:35:32.009 -->
00:35:45.105 Recognizing that it's still a fairly young project, I'm wondering what are some of the most interesting or innovative or unexpected either ways that you've seen Belay itself used or projects that you've seen people use Belay to help kind of catalyze.
255
00:35:45.800 -->
00:35:52.460 Right. So, yeah, Belay is young, so I haven't really seen too many projects explicitly use it. I did see 1 user on GitHub
256
00:35:52.924 -->
00:35:53.904use it for developing
257
00:35:54.285 -->
00:36:00.840I'm assuming this is for school or something, developing a Sumo Bot. So I was, like, checking out their code a little bit, and they were primarily
258
00:36:01.220 -->
00:36:06.200using it with a few different lidar sensors to make sure that the lidar sensors are producing
259
00:36:06.580 -->
00:36:13.525exactly what they want so that their sumo bot would go in the correct direction and stuff. Because, you know, whenever you're programming for a microcontroller,
260
00:36:13.905 -->
00:36:39.130you might just be sort of blindly making changes and then hoping it works out, but this expedites the process a lot more because they're able to get this stream of data easily from a lidar device without having to write a bunch of code that they would just throw away, you know, and plot it out on a computer and be like, yeah. My sensor is working. My code is working. So now I can, like, you know, figure out the logic of what do I wanna do whenever my LiDAR sensor is giving me these values.
261
00:36:39.545 -->
00:36:56.460I thought that was a pretty cool use case of it. Definitely on the end of delay is not gonna be in the final product, but it's being used as a helpful way of getting your project started. Oh, and actually, I was going through their read me a little bit as well. Another nice thing about Belay is that the setup environment is so simple
262
00:36:56.855 -->
00:37:18.875that you feel much more free about making changes. You can come back to a project a month later and not have to worry about, I don't remember how to set up the tool chains. I don't remember how to set up all the environment variables. I don't remember how to set up all of these parameters. Well, it's all already taken care of, so you're more likely to interact with it and also collaborate with other people working on the same project. And so I thought I I really liked that.
263
00:37:19.415 -->
00:37:23.194 To the point of kind of managing the specifics of a given board,
264
00:37:23.540 -->
00:37:27.240I know that some of that is handled by the kind of micropython
265
00:37:27.540 -->
00:37:36.555aspect of it, but I'm wondering what are some of the elements that you've incorporated into Belay to be able to maybe auto detect, oh, this is a PyPico. Oh, this is an AdafruitGamma.
266
00:37:37.335 -->
00:37:44.130You know, this is the baud rate. These are these are the serial parameters that I need. Just, like, curious how much of that you've incorporated into Belay as well.
267
00:37:44.590 -->
00:37:55.055 Right. So I think there's a fine balance between exposing everything to the user because, you know, people can get overwhelmed with choices. Like, why are you giving me a choice if there's only 1 good value for it?
268
00:37:55.355 -->
00:38:00.599So with that, I don't wanna, for example, change a baud rate. There's a default baud rate in MicroPython and CircuitPython.
269
00:38:01.220 -->
00:38:16.335You can, of course, change it, but most people might are gonna be drag and dropping their firmware onto their PyPico or whatever. And so there's gonna be 1 set baud rate. They could, of course, compile their own version, but then, like, you know, that's all of a sudden becoming more work, and I think that's more of the minority.
270
00:38:16.809 -->
00:38:24.5101 feature I did implement for, you know, these specific device identification stuff is detecting whether or not it's running MicroPython or CircuitPython,
271
00:38:24.970 -->
00:38:26.029which is typically
272
00:38:26.525 -->
00:38:39.020the biggest driver of what your upstream code on your computer will be running. In my Magneto project, I'm like, hey, all these libraries, they only work on circuit Python. I'm not about to rewrite them to be, you know, more generic to micropython.
273
00:38:39.640 -->
00:38:47.345So I will detect if you're running circuit Python, it'll run. If you're not running CircuitPython, I'm gonna raise an exception and be like, hey. You need to run CircuitPython.
274
00:38:47.724 -->
00:38:49.585You're currently running my MicroPython.
275
00:38:50.280 -->
00:38:51.260As for specific
276
00:38:51.640 -->
00:38:52.619device identification,
277
00:38:53.000 -->
00:38:57.820it gets a little bit hard. I wanted to do a bit of automatic device identification,
278
00:38:58.315 -->
00:39:02.015but it seems like a lot of the identifiers aren't very well defined.
279
00:39:02.475 -->
00:39:04.255So for example, a Pypico
280
00:39:04.715 -->
00:39:06.255identifier running MicroPython
281
00:39:06.715 -->
00:39:16.940is different than a pico running circuit Python. 1 might return, like, raspberry pi pico blah blah blah. The other 1 might just return rp 2040 for the microcontroller
282
00:39:17.320 -->
00:39:21.005it's running. So I didn't quite feel like building up a whole
283
00:39:21.464 -->
00:39:32.599dictionary of what mappings, all these different identifiers map to different boards, But maybe that might be something we do in the future if people actually need it. As far as device agnostic stuff, MicroPython,
284
00:39:33.140 -->
00:39:37.535you know, everything is nothing is device agnostic. You have to be like gpi05,
285
00:39:37.995 -->
00:39:38.495gpi06,
286
00:39:38.875 -->
00:39:39.375whatever,
287
00:39:39.675 -->
00:39:40.895but circuit Python
288
00:39:41.515 -->
00:39:41.950attempts
289
00:39:42.349 -->
00:39:52.115to abstract as much device specific stuff away as possible. So that's 1 thing I really do like that CircuitPython did. I like MicroPython and CircuitPython for different reasons, but CircuitPython
290
00:39:52.415 -->
00:39:53.795attempted to make everything
291
00:39:54.175 -->
00:40:01.609board agnostic, all the interfaces, so that you're not gonna have a bunch of if statements scattered throughout your code if you wanna support a bunch of different devices.
292
00:40:02.230 -->
00:40:13.075 As far as managing whether it's running MicroPython or CircuitPython, is that something where it's largely going to be kind of hard flashed into the board, or is that something else that Belay could potentially
293
00:40:13.694 -->
00:40:44.200handle where you say, you know, this time I wanna run MicroPython, I'm going to automatically download and flash the MicroPython core before I load my program onto it, or, you know, this 1 should be circuit Python, handle that flash, or is that something that's sort of out of the bounds or something that Belay should be concerned with? Well, so that was the original reason why I wanted to actually identify the boards because sometimes I'm running micro Python on some boards, CircuitPython on others, and I'm like, it's kind of annoying to have to I'm getting so spoiled here. It's kind of annoying to have to then reflash the different versions of MicroPython to CircuitPython.
294
00:40:44.805 -->
00:40:59.420 The issue is is that, like, then we started getting into having detect, you know, these fake USB drives they're mounting to your system, and then we had to be also figuring out what's the correct URL to pull these firmwares from. And it started getting very
295
00:40:59.720 -->
00:41:28.829device specific and stuff that might be very fragile and might have to change a lot. Like, you know, what if the URL changes or what if it mounts to a slightly different name? And then, like, you know, I don't wanna accidentally mess with someone's file system in a bad way. So I figured it was a lot of work that would end up being very fragile. While it would certainly be useful, I'm quite okay with, you know, dragging and dropping my firmware for now. But if anyone else feels strongly about that, maybe they can open up a GitHub issue on the Belay project.
296
00:41:29.769 -->
00:41:30.269 Absolutely.
297
00:41:30.970 -->
00:41:40.035In your experience of building and using Belay for your own work and your own hardware projects, what are some of the most interesting or unexpected or challenging lessons that you learned in the process?
298
00:41:40.575 -->
00:41:42.515 Whenever using Belay, I guess,
299
00:41:42.974 -->
00:41:45.810I didn't realize how flaky the USB connections
300
00:41:46.349 -->
00:41:50.530are. So especially whenever you're connecting to a bunch of other electronics.
301
00:41:51.069 -->
00:41:59.875Like, on my radio project, my pipe echo, I don't know, like, for some reason disconnects every, like, 10 hours or so just randomly. For my magnetometer
302
00:42:00.255 -->
00:42:06.790project, I would notice that in my setup over there with a bunch of, like, magnets and stuff going around, maybe it's generating interference,
303
00:42:07.250 -->
00:42:14.025but it would crash, like, every few minutes. And so that plus, you know, what someone else wanted on GitHub, they opened an issue, was
304
00:42:14.325 -->
00:42:18.744can I recover from a crash? Because whenever you disconnect or the Pi Pico
305
00:42:19.110 -->
00:42:38.850or whatever board you have temporarily loses power, it loses that whole interpreter's and so the way that we ended up solving that was to record all commands that you send send over so that whenever the pipe echo or whatever board comes back online, we can replay those commands to try and recreate that internal state.
306
00:42:39.230 -->
00:42:55.080So it's not always gonna perfectly recreate the internal state, but for most projects where you're just doing simple IO, you're turning on motors, you're turning on LEDs, you're reading in buttons, there's not a strong internal state. So you just need to get the driver code back over on the board and then automatically reconnect.
307
00:42:55.620 -->
00:43:21.095So that saved a lot of headache in some of my projects because typically I'd have probably like an extra 150 lines of code to try and handle a flaky serial connection that's now been moved over into this library. I can delete that. That's typically how a lot of my libraries develop. I have a project I'm working on. I ended up developing a lot of code that's starting to get kind of complicated, kind of hard to test, move it over into a library where it's in a much better
308
00:43:21.474 -->
00:43:33.730architectural state so I can test it and be confident in it, and then delete a whole bunch of code from my other projects so that it's more about, you know, the exact task I'm trying to accomplish rather than all of these auxiliary tasks that also need to be solved.
309
00:43:34.109 -->
00:43:44.555 For people who are interested in kind of embarking on their own hardware projects, what are the cases where Belay is the wrong choice or it's not going to solve the problems that they're running into?
310
00:43:44.930 -->
00:43:46.950 Belay is the right choice for rapid prototyping
311
00:43:47.250 -->
00:43:47.910and for
312
00:43:49.010 -->
00:43:50.150nonperformance heavy projects.
313
00:43:50.450 -->
00:44:00.914Belay is the wrong choice if you need to squeeze out every last bit of your resources, whether that be your serial connection or the processing power on your microcontroller or memory usage,
314
00:44:01.390 -->
00:44:03.650because it inherently runs on MicroPython,
315
00:44:04.190 -->
00:44:04.930and MicroPython
316
00:44:05.230 -->
00:44:06.049is inherently
317
00:44:06.430 -->
00:44:21.349gonna be interpreted much slower than, you know, the native running code that's been programmed in c or maybe even Rust that's on the device. Like, it's gonna be 1 to 2 orders of magnitude slower. But for a lot of projects, you don't really care your 1 to 2 orders of magnitude
318
00:44:21.650 -->
00:44:25.270slower. I mean, you know, the I think it goes running at, like, 133
319
00:44:26.290 -->
00:44:33.545megahertz, something like that. Don't know. It's over a 100 megahertz. While a lot of people's projects would work perfectly fine on, like, an 8 megahertz
320
00:44:33.925 -->
00:44:35.625ancient AVR microcontroller
321
00:44:36.005 -->
00:44:37.549from, like, 20 years
322
00:44:37.849 -->
00:44:41.789ago. So for many things, I would trade off a lot of hard software development
323
00:44:42.170 -->
00:44:46.109for easy, maintainable software development with still acceptable performance.
324
00:44:46.445 -->
00:45:05.495But, like, if you're trying to quickly interact with stuff actually, you know, even quickly interacting with stuff, if you're using the PIO on the Raspberry Pi Pico, you might still be in good shape. But, you know, if you're trying to squeeze out all that CPU power, if you are pushing your serial connection to the limit, like, if you need to transfer a bunch of binary data in between your computer and your microcontroller,
325
00:45:06.195 -->
00:45:23.245Belay is probably not gonna cut it simply due to the naive serialization we're doing with that repr literal eval, you know, combo, it's probably going to be 3 times less efficient for sending binary data than you could if you had a custom bespoke protocol that you made for your specific project.
326
00:45:23.625 -->
00:45:34.090So for those people, I would say, I believe not for you. It might be good for prototyping your initial idea, but then if you start getting bottlenecked, you'll probably have to move into your own custom, more complicated solutions.
327
00:45:34.710 -->
00:45:36.330 As you continue to
328
00:45:36.645 -->
00:45:41.545use Belay and tinker with some of these projects, what are some of the things you have planned for the near to medium term?
329
00:45:42.005 -->
00:45:50.349 Near to medium term, I always wanted to build, like, a robot arm and stuff. And, like, you know, with those things, a lot of the processing is gonna be done on the computer.
330
00:45:50.650 -->
00:45:52.430But I never wanted to do
331
00:45:52.875 -->
00:45:57.455all of the protocol and firmware development. I always felt like that would just be, like, kinda difficult.
332
00:45:57.835 -->
00:46:02.540But I always wanna build a robot arm. I've got my 3 d printer. It's all about just, like, you know,
333
00:46:03.080 -->
00:46:11.555building up the courage to actually start that, and then also, you know, have it sit on your desk for, like, several months. So that might be 1 thing I have in in the near future.
334
00:46:11.935 -->
00:46:16.915 Are there any other aspects of the work that you're doing on Belay or your overall experiences
335
00:46:17.410 -->
00:46:18.390or suggestions
336
00:46:18.690 -->
00:46:19.190for
337
00:46:20.050 -->
00:46:25.575building hardware projects or prototyping hardware projects that we didn't discuss yet that you'd like to cover before we close out the show?
338
00:46:25.895 -->
00:46:36.680 No. But, you know, if you like the library belay, just please also check out some of my other projects on GitHub. Some of them are hardware projects like this. Some of them are generic Python libraries for
339
00:46:36.980 -->
00:47:03.925 other tasks. Some of it's deep learning. There's a there's a little bit of everything on my GitHub repo. So, you know, check it out if you like stuff like this. Alright. Well, for anybody who wants to get in touch with you and follow along with the work that you're doing, I'll have you add your preferred contact information to the show notes. And with that, I'll move us into the picks. This week, I'm going to choose the Gunnar brand computer glasses. I had been using some of the kind of cheaper ones for a while, just some of the blue light blocking glasses since I spend all day on the computer.
340
00:47:04.225 -->
00:47:35.160Recently decided to kind of level up into a nicer pair because my last couple of pairs broke. So the Gunnar ones have been great, comfortable, so definitely recommend those for somebody who spends a lot of time on front of screens. So with that, I'll pass it to you, Brian. Do you have any picks this week? No. That's it. That's it for me. Thank you so much for having me on the show. Alright. Well, thank you again for taking the time today to join me and for the work that you're doing on the Belay project. Definitely very interesting library. Great to see people investing in kind of reducing some of the points of friction involved in hardware projects because
341
00:47:35.460 -->
00:47:45.185definitely seeing a lot of kind of renewed interest in building for more constrained devices. So appreciate the time and energy you've put into that, and I hope you enjoy the rest of your day. Alright. Thank you.
342
00:47:47.450 -->
00:48:00.565 Thank you for listening. Don't forget to check out our other shows, the Data Engineering Podcast, which covers the latest on modern data management, and the Machine Learning Podcast, which helps you go from idea to production with machine learning. Visit the site at pythonpodcast.com
343
00:48:01.585 -->
00:48:03.200to subscribe to the show, sign up
344
00:48:03.839 -->
00:48:09.380for the mailing list, and read the show notes. And if you learned something or tried out a project from the show, then tell us about it. Email hostspythonpodcast.com
345
00:48:10.800 -->
00:48:11.619with your story.
346
00:48:12.045 -->
00:48:16.944And to help other people find the show, please leave a review on Apple Podcasts and tell your friends and coworkers.