 Welcome to the show, it's me, John Park, and here we are. It's time for John Park's workshop, and this is it. This is my workshop. We're in here and we're ready to go. I am enjoying a delicious beverage. I hope you are too. This is kind of a weird one. This is some cold brew coffee, oat milk, ice, and some Trader Joe's chai iced tea mixed in there because why not? We've got people over in our chats, if you're wondering who I'm talking to, it's not just me talking to me, although that's certainly a component of it. We've got our chat over here on Discord. If you head to adafruit.it, sorry, adafru.it slash discord, that'll get you right into our Discord server instant invite type of situation. Once you're there, look for this live broadcast chat channel, you can see it here on the left. That's where this chat is going on. And we've got Andy Calloway and Dexter, Mike P. Jim Hendrickson, C. Grover, Paul Cutler, all hanging out here. And then also we've got our YouTube chat with Dave Odessa and Johnny Bergdahl and Anthony Bacara hanging out over there. So come one, come all, join in. If you're wondering where the chat is, if you're over on Twitch or somewhere else, Facebook, I'm just not watching all of those chats. It's just too much. So I recommend heading over to our Discord. It's a lovely place if you can. Well, let's see what else is going on. We have a job board over at jobs.adafruit.com. And if you head there, you'll see job openings and people posting their resumes, their info. Whoops, that's the wrong page. There it is. This is the jobs board. If you go to jobsadafruit.com, here's one of the positions that's been posted recently. This is someone looking for a contract job, building some matrix portal projects. They say they intend to use a company website to display messages on several matrix displays in several different developments. Purchased the 8.16 with a matrix portal M4 to play with. I wanna implement my process design. So if that looks interesting to you, that could be a fun project. Could be an interesting one. And you can of course negotiate pay with people if you're looking to do work on any of these types of gigs that you find. We just wanna connect you. So go check out jobs.adafruit.com. There's more there too, if you take a look here. A bunch of jobs, full-time, part-time, remote, contract, in-person, out-of-person, extraterrestrial, it's all there. That's jobsadafruit.com. What else is happening? I have a show on Tuesdays, which is, hey Franklin, Franklin says sup and has a cool little sticker there. I haven't really looked at the stickers here in Discord, but they're cool looking. If you are interested in Adafruit products, you might wanna stop by on Tuesdays for my product pick of the week show. I bring on a new product or a product from our back catalog of cool stuff. And I do about a 15, 20-minute show where I talk about the product, show it off, do a demo, go into some of the code, if it's a code-based thing. And then I do a little one-minute recap. This is it. This is the recap for this week's product pick, which was this cool little Pi TFT. And I'll show you that recap right now. It is the Mini Pi TFT. It is a SPI, SPI, bus-based display. It has a couple of buttons for GPIO and it's got that little STEMA QT connector on the bottom so you can plug in something like this GPS. Let's see, you wanna add GPS to a Pi project. It's just as simple as plugging into there and then using Blinka, the circuit Python for single board computers with it. You'll see this has header pins to plug into the first 12 pins. I have a little bit of code running on here and what it'll do is display some important information the time, your SSID, your IP address of the device itself, the host name and even my ping I've got here. It's an IPS display so you get real great readability from angles. Mini Raspberry Pi TFT. And as I mentioned on the show, we had a lot of those in stock. I haven't checked stock but hopefully we've cleared up some of those issues we had with low stock. It's not possible in all cases as you can imagine. There's a lot of repercussions going on with the global parts shortages and supply chain. Hello, Andreas from Sweden who stopped by over in the YouTube chat. Thanks for stopping by. Let's see, what else is happening? This is probably a good time to do a circuit Python parsec. Let's just jump right into it. All right, let me open up the right code. That's not it. Hang on. Oh, that's weird. Hold on, let me close this, try reopening it. I think it had cached some code. There we go, that looks a lot more like reality. All right, what I wanted to talk about on the circuit Python parsec today is display rotation. So I've been doing this little series on display IO things. And often you'll display either text or shapes or bitmaps images onto one of the displays on a circuit Python based board. And that can be built in board like here. I've got the PyGamer edge badge edition. Could be a separate display that you've plugged in. And it works pretty consistently across all the displays. When you display an image, you have a choice of your orientation. Is it essentially a sort of horizontal display, either in that orientation or that orientation? Or is it a vertical display, either that way or that way? And depending on how you have a thing mounted or how you're using it, you may want to pick different orientations. Sorry, words are difficult. So what I have here is an example of some cool pixel art. This is of a little Casio keyboard. And then when I press A, I can switch to a different image. But you can see this image has a vertical orientation. So it makes more sense to turn the screen this way. And when I do that, I'm going to want to switch the display rotation. So this changes everything to do with your display, all of the values of where zero zero is, for example, X and Y. All of those things get updated as you change this rotation setting. So if I go back to this horizontal image, I can switch that rotation there. And you'll see the way this works inside of circuit Python. It's really straightforward. When you've set up your display, you can see this value, display.rotation is set to zero. And that's the sort of default. But we can put it zero, 90, 180 or 270 to get those four different orientations. We can't do partial angles, just these four orientations. The way I'm doing that in code here is that when I press one of these D-pad buttons, I'm simply updating that display rotation equals zero, 90, 180 or 270. Then I'm also using the A and B buttons to just do a sort of mini slideshow between images. And so that will then be used to update as I load different images and palettes in. And they are going to use whatever that current display rotation is based on pressing these buttons. And so that's how you can adjust display rotation inside of circuit Python using display rotation. And that is your circuit Python Parsec. Yes, circuit Python. There I am. Hey, over in the chat, I'm glad to see that at least one person is excited about this. Dexter says, this changes everything. Hopefully you're referring to this display rotation. It's really convenient because you can imagine all of our positioning of things when you're placing text, for example, with the example I did last week, is based on an assumption of an origin point. And we use the upper left corner. But that can change. So if you go to this vertical orientation, you can now consider this to be 0, 0 rather than having to start expressing y and x and x and y and doing a bunch of crazy stuff like that. So oh, good. Yeah, Paul Cutler says that they just used that yesterday. Excellent. I can bring up our Discord there. You can see the conversation. And the other thing I wanted to do is give credit to the artist there, by the way. You saw that cool little bit of pixel art that I had on display. And you probably saw me show this earlier. This is something I don't remember where I ran across this. But this is an artist in Ankara, Turkey named Meral Ezgi. And they have a beautiful collection of mostly vintage electronics that they have created using some voxel-based art programs. So voxels, if you're not familiar, they're 3D pixels, essentially, volume pixels. And so these have actually been modeled like with Legos. Like if all Lego bricks were just sort of a cube with no studs and holes in them, but just stacking blocks, like building with blocks, and they can be textured with different colors or set to different material colors. So I love this collection of gorgeous, look at this Game Boy here. And if you click on one, I think there's usually a series of different images for them, at least for some of them. Let's see, there's, oops, let me go back. I know there is on this 808 drum machine. Yeah, there's a nice little series. So you can see all the ports back there, some nice close-ups, so gorgeous stuff. And I needed a source of something here. These are not open source or anything like that. So don't go giving them away, but I just wanted to display them and show them off on the parsec there. All right, let's see. What else have we got going on here? Oh, that's interesting. Calvin says this sort of art seems very popular in Turkey, very interesting. How about that? Yeah, I've checked out, there's a particular piece of software a lot of people like to use for building pixel art. And there may be info about that in, I'm just checking here, no. I'm not sure what people are using to do that, but I used to build pixel art landscapes for a video game, the whole Novelogic series like Delta Force and Apache and Armored Fist, all those pre-graphic card games when you couldn't really push polygons around very fast, had these big, big terrain engine that Novelogic had built using voxels. So there you go. Let's see, next up, I wanted to have a look at a sort of revision on a project. And I showed a little bit of this on show and tell yesterday, but I've made some changes and some additions. If you recall, where did I put it? I don't think I have the old one anymore. If you recall, no, it's gone, it must be dead to me. I had taken a Trellis M4 and used some code that Todd Bott had posted about using Audio Mixer in order to essentially mute or unmute audio loops that are all in sync with each other and are all playing. This is a really cool feature in Circuit Python. And I've got a little addition today that I think will make it even clearer what's going on. I was gonna build this as a learn guide and Lamors said, why don't you do it instead of on the Trellis M4? Why don't you do that on a breadboard? So I have here this sort of breadboarded, I'm using a PERMA Proto, just so things will stay together a little better as I'm working on it. But you could build this right on a breadboard. It is simply a KB2040 and a series of buttons. I've got eight buttons on here. I have a little noise canceling audio circuit, a little RC filter circuit. And then you can see the addition that I didn't show yesterday as I now also have a fader on there. I'm using the Neo Slider, which is a Stemma QT fader, so that there's one audio track that I can just fade in and out in sort of a gradual fashion, whereas the rest of them are sort of muting in an unmuting of tracks. But the neat thing is when the software starts, all nine of these wave files are playing and since they're all designed to be synced with each other, they're all in sync always and we're just listening in on them. So let me do a little demo over there and then we'll take a look at how this works. So let me jump over there. I'm gonna actually risk turning off my AC for a moment because the fan blows this camera mount a little bit, which can be distracting. It's also a bit loud. And for safety's sake, I'm gonna pop open my Discord so that I can see if anyone has questions or notices audio disasters happening. So let's hop over there. All right. So I can zoom this a good bit. So you can see there I've got my KB2040 keyboard. I have that plugged into this Promo Proto board by using some headers, so that I can remove this if I need to. And I've soldered these buttons straight down to the board, run them all to ground and then run them all to individual GPIO pins. The output from the D10 pin is a PWM audio and that's going into this little resistor and capacitor circuit and then out through this headphone output. So we should hear the different sort of subsections of the amen break that I've been playing when I'm doing these. And then the new addition is, and I can play those while I do this, but just so you can hear it, there's a sort of loop of a record scratch going on. And so it's just always playing, but I can fade it in and out. And that's the audio mixer voice level. I'll show you in code how that works, but now you can see we can have one audio track going and then start fading in this other one. And by the way, that audio of the scratching is definitely not in the same tempo as the rest of it. So apologies for that, but I think it just gets the point across. Okay, so let's have a look a little bit more at the hardware and then we'll take a look at software on this. So I'm gonna go ahead and unplug power from that. I just have a USB-C power running to this and then I have my amplifier running over a 3.5 millimeter. Happens to be a stereo out. I'm actually only connected at the moment to one side of this. I still need to bridge. I'm only using a mono output, but I can bridge that to both left and right, which just helps with some amplifiers that you're sending that to. And then conveniently this being a little STEMA QT, I can add that. I would need to update code to run it without because it's gonna, the code will look for I squared C device and get angry if it doesn't find it. But if I go in and edit code, I can tell it that I'm not using that or use something entirely else. We could use an accelerometer. We could add a little display to this. We could use a rotary encoder. Nice thing is that it's up to you and you can string together over I squared C a bunch of different items as long as you have different I squared C addresses for those. And then taking a little closer look at this, you can see these are these little 12 millimeter momentary buttons that we have in the Adafruit store. I can show you a link to those. And one issue is that I couldn't find, I have some of the square caps, which I think will fit with this spacing. This is basically the, excuse me, this is the closest spacing you can do on a breadboard or on this Permaproto, which is essentially two spaces between each of the buttons. And that is too close for these round caps. So I actually ground off the sides of them just so I could fit it. I'm gonna double check though. I think for the guide, I'll recommend the square caps, which I believe are meant to fit. The tops of these are fine, but there's a little rounded skirt here at the bottom that is just a little too wide for these to set next to each other that close. And I couldn't get an even spacing on this board if I had increased that, it would have been much too wide if you compound that by eight buttons. And then this is kind of a nice way to have the best of both worlds, which is maybe you don't want to dedicate this particular KB2040 to this project all the time, but you don't want to use a breadboard. Most of this is Permaproto right on there, very permanently soldered on there, with the exception of the microcontroller and I've used some of our lower feather headers. Actually, these are regular sized ones so that stands proud of it just a little bit. So you could get a little lower, you can see there's a little bit of a gap there with I like the short feather headers, those are great for doing this kind of thing. Could do this straight to the board, you could probably even use the cast-related pads and no pins if you wanted to, but since we're plugging things into it and out of it, it's nice to have it on mechanically fastened on header pins. And then this, maybe I can bring up the fritzing over here on the computer. This is a fairly typical high-pass filter circuit for audio to just cut out some of the high-end noise and also prevent some of the big pops that you'll get when you're plugging things in and that's a audio to a 1K resistor and then that 1K resistor goes both to this capacitor which goes to ground, filters out some of the noise and to a 220 ohm resistor, which then goes over to the headphone out and then I would bridge those since I'm using this actually as a mono. So that's a pretty nice little compact thing. You could expand on this. You could do pretty easily 16. I think we definitely have 16 GPIO available on this particular board. So if you doubled up on Permaprotos or just built your own circuit board for it, you could get a lot of buttons on here. Beyond about, I think, 18, 19 buttons, something like that, you'll then want to use something like a diode matrix and then you can get tons and tons by using rows and columns. But these also come in a bunch of colors so you can do these fun little color ways, sort of an 808-ish color scheme I've got going there. I decided to be fancy and kind of keep my colors matching the caps there which of course makes life a lot harder when you're trying to actually determine which wire is going where I should have just used alternating colors with as many colors as I had but I felt like getting fancy, so there you have that. All right, so let's take a look. Let me head back over here. We'll take a look at the code, run it into this and I'm also gonna turn that AC back on cause it's a little hot here today. By the way, if you didn't notice, I had switched. I've been still tinkering around my TV set but for the moment I have switched that little dolly vapor wave clock to one of our little LCDs and a lot of the LCD panels that you can get displays on Adafruit have a composite in so they don't just have VGA and HDMI, you can also put in a composite in. So Lars is hanging out with a clock over there. All right, so let's switch on over to Adam. Yeah, we'll look at the, one second here, we'll look at the code for this and then we'll take a look at the circuit diagram. So I'm gonna plug this in over USB-C. Whoops, a C clamp just fell noisily and let's open up, let me close the existing one so it doesn't get confused about that cache like it did. Okay, so, hey, that did it again. That's funny, how is it getting confused about, oh, do I still have that plugged in? I do, I have two circuit Python drives plugged in so I just picked the wrong one. There we go, okay, so you can see here this is similar to the Trellis M4 version that I did, bringing in the keypad to do the button presses, using audio core and audio mixer to do the wave playback and then the levels and I'm using audio PWM IO since we don't have an analog DAC on the RP2040 chip and then I'm bringing in simple math map range and that's what allows me to map the values zero to 1023 that come off of this slide potentiometer to 0.1 to 1.1 which is the range that we can use to adjust the volume of one of the mixer channels or voices and then I'm using seesaw to be able to do both the reading of the analog pot on here as well as writing to the neopixels that are under there and I'm using rainbow IO color wheel to deal with the give myself an easy way to light up the neopixels and some nice colors. Then I have a stack of wave file names here so those are all the different pieces of that amen break and then also the scratch.wave and that's a wave from freesounds.org. Then we set up the pins that we're using for the buttons and those are I'm using the RX D234567 and eight so there's some my RX is the same as D1 basically. Actually I don't even know it might work as you might be able to call that D1 there I'm not sure. And then setting up keypad to use those setting up the Neo slider over I squared C. By the way this is a nice change that started in I think it was 7.2 of circuit Python. I can now choose board.I squared C and that will pick the right I squared C depending on the board because this is running on a RP2040. It's actually SCL1 and SDA1. Normally those would just you'd have to sort of know that and type the right one. Now in this version of circuit Python you can just say board.I squared C and it knows which chip it's encountering and uses the right one. Setting up the fader as an analog input setting up the Neopixels. There's four of them and they're on pin 14 of the little seesaw chip on here. Here is a little fader to color wheel function that's just used to run through some of the color wheel setting up D10 as my audio out and then setting up the mixer object to have however many many voices in this case it's nine however many voices the length of this wave files list is and this is a nice way to do this so you're not being explicit with the values in case you change the number of voices that are in there for some reason you don't have to update that. Set the sample rate, the channel count, bits per sample and the sample is signed. Set up audio play on the mixer and then we have this handle samples and that'll start or stop samples if we're running them that way and then we also have the handle mixer so with this function or this loop right here we start playing all of them they all start at the same time and then this handle mixer function what this does is allows us to just toggle the voice level of each mixer channel essentially from zero to one. The main loop here checks for key presses and then either toggles those voice channels using that audio mixer or if you take a look at this late breaking addition here we're changing the pixel color based on faders and there's this remap here I'm remapping the value of the analog input that's zero to 1023 to 0.0 to 1.0 and then this mixer voice eight which is that ninth one this is zero indexed which was that scratch that value is just being continuously updated as I move the fader. Now I just put this in the last second I'm gonna update this so that we as I've done with some of the other fader code we don't constantly rewrite that but wait for changes so we can tell if that slider has changed and only then will we send them and that works pretty well as well. So give me one second to handle something. Hello MetaX from Istanbul Turkey nice to see you thanks for coming by. All right Dexter says they've built one but based on streetchicken.wave that's fun. All right so let me know if you have any questions in the chat about this but I think this will be a nice way to sort of illustrate how you can use mixer here's this is a couple of variations on it you can just pop the values up and down using the buttons or you can slide and fade them continuously you could also do things like cross fading if you wanted you could have one slider adjusting two values which would be pretty cool and let's see I think that'll do it so I will be working on a guide for this I just by the way just finished up a guide for the little let me find it here little excuse me web server let me go to my oh this window got big hold on it's a little better if we go to new guides you all actually this just came out I haven't had a chance to blog about it yet so I just wanted to point it out this is the personal and portable ESP32 S2 web server so the feather ESP32 S2 did I bring that inside I don't have it right here that can act as a web server it's also got a little display built onto it guide shows you how to set that up right now I'm just showing the Arduino version we have both a easy drag and drop UF2 file as well as the Arduino code if you want to adjust it and then flash it using Arduino IDE I should be adding a version for Circuit Python working with Dan Halbert who's been writing a similar web server inside of Circuit Python and then I also go into a in this case sort of the example project I've shown is scraping one of the open source wordle alternates or clones and having this run off of the device so in this page called create the web server I've got Reactl which is a really nice clone that we found Reactl you can just download this the files that you need and put them on the drive or got a little bit here on using Wget which is a command line tool for cloning that web page and supporting files so that you can kind of suck down any web page that'll fit and will work on your own so it doesn't have to be the one that we've put up there and then it talks about setting up your secrets JSON with your SSID and password as well as the access point name and password if it doesn't get on a network it'll serve up its own and then also made a nice little case for it so you can 3D print that let's say build the server case so you can 3D print this little case if you want to or come up with your own method and I've also added a little switch there so that we can power it on and off using the enable pin to ground and a lipo battery which you can charge over that USB-C port so just wanted to let you know that is out since we covered it on this show if you're interested in checking it out please do alright anything else I think that's gonna do it okay thank you everyone for stopping by and by the way there's gonna be an Ask an Engineer this evening I believe at 8pm but don't quote me on that what I'll do is show you one way we can find out let's go to live broadcast announce let's see if it's announced here yeah 8pm so this this is another channel on our Discord live broadcast announce we can put little notices up here this one says Thursday 8pm Eastern Time tune in for your usual Ask an Engineer things the week got busy and so it got bumped a day alright thanks everyone for stopping by I will hopefully see you there in the chats for Ask an Engineer a little later today and don't forget that there's gonna be a foamy guy deep dive tomorrow and then we'll start our usual sluice shows over again next week so that's gonna do it for me I'm John Park for 8th Fruit Industries this has been John Park's Workshop bye bye