Guest Tutorial #11: Hardware + JavaScript with noopkat

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
- Hello, and welcome to another guest tutorial on, (train whistling) The Coding Train. Yes, this is The Coding Train. What you are about to watch is an edited version of a live stream from a couple weeks ago about hardware, (imitates ghost) and JavaScript. (imitates ghost) And I was near the hardware and it didn't light on fire which is kind of blowing my mind right now. Now, this video will not feature me. It features a wonderful guest that came here to do a live stream in the studio. Her name is Suz Hinton aka Noopkat, and yes it is pronounced no op kat, even thought for the last many years I've just been saying noop kat. Noopkat. She does a live stream every Sunday on her own Twitch channel. Check this video's description for a link to that Twitch channel, highly encourage that you go over there and subscribe. And, what you're gonna see actually is a version of my, well of the, a 10 Print coding challenge, but on a hardware little ELT screen OLED screen thing with JavaScript controlling it and Arduino. It's crazy. It's amazing. You got to watch this video (laughs). Okay, so I'll, thanks for tuning in. I gotta stop talking because you're here to see Noopkat. Goodbye. - Thank you Dan for having me. I'm so excited. I'm such a fan girl of The Coding Train so I'm like really excited to be here, and also, so I do a lot of hardware stuff so I wanted to sort of briefly intro myself on that. I work on a lot of open sourced JavaScript hardware, which I know for some of you you might not typically associate JavaScript with hardware, but I promise that it's actually super fun to get started with it and it's really really quick to prototype with JavaScript hardware. So that's kind of its main attraction, but you can also just create your own kind of fully implemented like real contraptions and still run JavaScript to control it. So, I'm gonna show you one way of controlling hardware with JavaScript today. We are gonna be work with an Arduino and it's an Arduino Uno which is kind of the most common one that a lot of people get started with. And we're gonna be driving this thing called OLED Screen and I'm gonna explain all this just to make sure that Dan's not super scared. (laughs) 'Cause Dan told me he's really afraid of hardware. And I'm really afraid of generative art because I feel like I'm not good at it, so I'm trying to combine the two together because Dan's really good at generative art, so somewhere in the middle we're gonna find like a nice happy place where we're both learning something. So, hopefully that's gonna go well. So, yeah. Thanks so much for joining us. I'm so excited. I'm normally streaming on a Sunday, and yeah I'm streaming on a Friday which is blowing my mind so yeah. So, I am going to just take you through a couple of the tools that we're gonna be using today. Just forgive me, this is not my computer so we had some sort of last minute shenanigans but I think it's gonna be okay. So I'm gonna be using Johnny-Five which is kind of the beloved hardware, JavaScript framework. It has been designed to be like the jQuery of hardware. So if you've ever used jQuery before then you know that it's a really nice API. It's super accessible to get started with it so Johnny-Five was designed by one of the contributors to jQuery, Rick Waldron and he's done a fantastic job. And there's been a lot of contributors ever since. So I think there's at least 70 something contributors now, and that was when I checked a couple years ago so it's probably even bigger now. So we're gonna be using this with our Arduino. So if you wanted to follow along with some of the beginning code examples that we'll be using today, you can jo to Johnny-five.io. It's kind of like the Short Circuit robot character si I really like that it's named after that. And we're also going to be making use of a module that I wrote a little while ago about three or four years ago, and it's called OLED JS and, OLED is the type of screen that this is. It's an OLED screen just meaning that the little pixels that are showing up on the screen are actually driven by OLED's which is like a type of LED. And so I wrote the module to be compatible with Johnny-Five so that you can start really easily drawing to the screen without having to know a lot of the stuff that's going on underneath. So, I'll cover a little bit more on that when we actually get started but we're also gonna be using that as well. So I wanted to give a shout out to my friend Tim Holman because he's actually the one that finally got me playing with generative art super recently. We hung out at JSConf AU in Australia and he gave this awesome talk about generative art and how you just need a simple things in a tool kit to get started with and it's the first time I've felt like not afraid to do it (laughs). So I just wanted to, so you should check out Tim Holman's website. It's tholman.com, and yeah. He does really really really hilariously funny stuff on the internet so you should absolutely check him out. So I wanted to thank him for finally getting me started with it. So the generative art that we're gonna create today is, well at least on this website it's called a Pseudo-maze. Is that what it's actually called Dan? - [Dan] I dunno. Maybe it looks like the 10 Print design. - Is that what it's called the-- - [Dan] Is it 'cause you just pick randomly like a left or right line? - Yeah yeah yeah. - [Dan] So it's not actually a maze 'cause it would just, - Yes. - [Dan] No that's exactly, I have a coding challenge that's exactly that pattern. - Yes. - [Dan] And it's from the old Commodore 64. - Oh. - [Dan] There's a one line code 10 Print, go to 10 where you could randomly pick a forwarder. - That makes sense. So that's-- - [Dan] That's perfect. This is good synergy. (Dan laughs) - So I noticed also that you did like a coding challenge on Floyd-Steinberg? - [Dan] Yes. - Yeah, so displaying like photos or just like high resolution images on these screens, it's very affective to use the Floyd-Steinberg algorithm too. So, this is me trying to get you less afraid of hardware because you're still using the exact same stuff on this. So if we have time, I don't think we will but if we have time, I can also show like displaying pictures on this thing but for today we're actually just gonna work with lines which is super simple to do. And just to kind of like explore the concepts of generative art. So if you've already seen Dan's coding challenge, this is gonna be pretty similar, but it's gonna allow to see how you then apply it to something like hardware I guess. So I think it will still be super interesting. So, thanks for tuning in. Okay, so that's sort of the super quick crash course to stuff. I do actually have a folder right now that I've created. I did pre-install some stuff ahead of time, just so that we don't have to sort of like sit around waiting for an MPM to install, but I will be doing this with Node.js today which is a way of running JavaScript outside of the browser which is really cool. So if you go to nodejs.org, (typing) just like that you should be able to read up about it but it's really really cool. So that's kind of what Johnny-Five runs on top of. But recently I did get it working in the browser but that's for another episode probably (laughs). Cool, so I have this folder here. I've installed Johnny-Five. I've installed OLED JS, just those two packages that I showed you before and that's it. And then we have our code editor here. I didn't quite get Bim set up. I was on a mission to get Bim going (laughs), because if you've seen my stream before you all know that I use Bim but, so we're using Visual Studio Code instead and then I'm gonna just keep crossing back and forth between Iterm and Visual Studio Code. So let me know if you can't read anything and Dan will yet at me and then we'll figure it out (laughs). Cool. So, I do actually have the Arduino plugged in right now as you should be able to see. So we're not actually gonna plug anything into it yet. We just want to kind of establish a connection to it first just to make sure that we can do our little hello world, and then we'll start plugging in the screen. So I sort of wanted to do a lot of this stuff from scratch just so you can kind of see it from the beginning. So I've created a black file called artjs because that's what we're creating today. And I'm going to start just by requiring the dependencies that I actually need. So, in Node.js with JavaScript instead of maybe doing Import which you could do, I'm just gonna be using require which basically says, hey I've been sold these libraries and I actually want to start using them, so I can then assign them to variables. So I think the first thing I want is Johnny-Five. So I'm just gonna call that five for short just because it's quicker to type. And then I'm just going to require that and it should be smart enough to figure that out because Visual Studio Code is kind of amazing. So that's me actually requiring Johnny-Five and saying that that library from now on when I want to access it, it's called five. The next thing I want is the actual OLED library, and because that's a class I'm gonna capitalize it and let's see if it's smart enough to figure this one out. It didn't. Oh there we go. So, now that we have them, we can actually start working with them. So, before we do anything with this OLED screen, we want to just test that Johnny-Five is working and is able to talk to the device right? So, we can do like a hello world with it, but I kind of wanted to first describe on the whiteboard kind of how Johnny-Five actually talks to the Arduino before we actually start on that. So let's go do that. Okay. So, we've got our computer right here and this is kind of the confusing thing for some people to understand exactly how Johnny-Five works. So I'm gonna draw a really bad keyboard here (laughs). But you get the idea. And then this computer is like okay well I want to talk to this Arduino right? So, we can have back and forward communication with it. So let's just say that this is the Arduino. Everything has a smiley face too so (laughs). So this is the Arduino. So what's actually happening when we run Johnny-Five is that every time we start that Node.js process, it actually uses this really cool library called Serial Pod to establish like a two way connection between the Arduino and the device, the laptop itself. And what it actually speaks is called the Firmata Protocol, which I don't know if you've head of before Dan? - [Dan] I have. - Yeah. - [Dan] Yes. - So have you used this before? (Dan laughs) - [Dan] I think I went to a workshop once where somebody was teaching with Firmata. I know that students sometimes here use it but mostly the students at ITP use like the Arduino, sort of directly. - Okay that makes sense. Yeah, and so if you wanted to use the Arduino directly, this particular Arduino we're using today only sort of understands C ++. So that's why we wanted to start with something a bit higher level and it's a little bit easier to sort of stay on your machine. - [Dan] So if you're using Firmata you can write the Arduino code basically with JavaScript? - Yeah so you can - Wow. - write sort of like you can basically become the remote control for the Arduino through the Firmata protocol. - [Dan] Got it. - So we have like our JavaScript, which understands the Firmata protocol, and then we have a C ++ script running on this board here which understands the Firmata protocol too. - [Dan] And that's like an out of the box thing you download and run on the internet? - Exactly. - Wow. - So I'm gonna actually run that, well I'm gonna run like a very quick script to install that on my Arduino's, and I'm gonna show you how to do that so you don't even have to download the Arduino ID or anything. So, we can do that. And the way that these talk to each other is because the know the same language which is Firmata, they just kind of send op codes between each other. So, that's not even a zero. So, maybe zero FF or just, that's like a byte that has value like 255. Maybe that means something very, like substantial in the Firmata protocol. Maybe it means hey, start sending power to this pin so that you can turn an LED on or something like that. I don't actually have the Firmata protocol memorized but I do know that it is based on the Midi protocol. So it uses like, - Ah. - like I guess the notes and everything, which is I think a really really cool part of like Firmata's history that it uses Midi to do it. So that's like a super high level view of how it actually does it, just because the stuff that we're working with today is so heavily abstracted. So we want to just make sure that you still understand that this is walkie talkie thing happening, and that the JavaScript never actually goes and lives on this device, it's really just a remote control. So, and we're gonna have a whole different protocol talking to the actual screen which I'll draw here later on as well. Cool? Alright. - Yeah. - Let's do it. Okay so now that we've got our dependencies we actually want to make sure that it's talking to the device. Now we mentioned before that the Arduino needs to actually know what the Firmata protocol is right? So we actually have like a pre-made sketch that Arduino itself publishes with the ID and it's called Standard Firmata. And so we want to use that. But, having to open the Arduino ID and then flash a script to the Arduino and then close it again is sort of just annoying because that's the only thing you use it for. So I ended up making a package and it's called Firmata Party. And I think I installed this on Dan's machine. I did (laughs). So what Firmata Party does is it allows you to have a party with Firmata by just being able to transfer the Firmata script onto the Arduino device that you actually have. So that's literally all it does, but it does actually get you started and up and running really quickly. So it's just a command line up that I wrote in Node.js so we can run Firmata Party. And then we're gonna write the name of the Arduino board that it's actually supposed to be flashing so that it knows what to look for that's plugged in. So we're gonna run Firmata Party Uno. Literally all that does is it takes the Firmata Part C ++ script that the Arduino needs to run and it just uploads it and then we don't actually upload any scripts to the Arduino after this. We're just running JavaScript on the laptop as we said to just kind of send stuff to that Firmata script that's running. And it's really just sending commands it's not actually sending any code or anything like that. So hopefully that actually works. It seemed to have worked. I think that, I think that I need to do -v just to see if it did. Oh wait no. Maybe it's debug. Anyway, I can see that it's actually working. (laughs) So maybe it is --debug let's see. Oh there we go. Just so you can actually see what it's doing. So it says found Uno on port, blah, it connected. The reset was complete. It's flashing the code and then we have a nice green status saying that it's successfully completed. So now that we have Firmata running on the device it's actually ready to start listening for any commands that come in via that USB connection. So, now that we have a five instance, we want to create a board right? So, we want to create this board instance so then we can start kind of sending stuff to the board and receiving stuff from the board. (typing) So I think we just need to do a new, whoops. Five.board I think. Wow this auto complete is blowing my mind. (Dan laughs) I don't use Visual Studio Code very often but it is like super nice. Okay so we have a new board. What that actually does is it just goes and like looks at all the serial ports or the USB I guess ports on your computer and it goes are you an Arduino? Are you an Arduino? Are you an Arduino? So it's actually really awesome because it takes a lot of that stuff out of your responsibility to do. So then the board comes back as an object that you can listen to events on. Again this is very similar to jQuery, so normally where you would have like document.('ready'), or document.on('ready'), you can actually do board.on('ready') which is actually pretty chill. So I feel like Dan you could totally do this. (typing) (laughing) - [Dan] I'm following everything so far. - Okay cool. So now that we have an, we've sort of attached a listener to the ready event which basically says that, we've been able to guarantee that there's a good connection happening with the Arduino, we just want to console.log out that it's actually ready. So we can just write, yay!! I guess. And then, let's try and run this just before we sort of get ahead of ourselves and start writing extra stuff. (typing) So, whoop. So I'm gonna do node I think art.js and let's see what happens. Alright. Seems to have found it. And then we got yay!! So that's pretty cool. What Johnny-Five does too is it actually gives you a REPL which is a read, evaluate, print, loop, which is really cool because you can actually start looking at anything that you create globally to be accessible in the REPL. So we're not really gonna use that today but I just wanted to say that it's a really nice feature. So, by me writing this, that's actually the instance of the board. So you can see a whole bunch of stuff comes out if you wanted to inspect that further. So to exit I'm just gonna do, I'm just gonna send like the control C. Just the C again twice and then, or the interrupt, I forget which one it is but yeah. So we're gonna do that. So, we wanted to actually start using the screen now, because that's really the only thing that we're gonna do with like using Johnny-Five is to be able to use it to speak with the screen directly. So we kinda have to go over a little bit of theory of what we're doing today. But we also want to plugin this screen as well. So I think we're actually gonna start with the theory first. Alright so we have this here but is sort of wanted to just start like a new section over here just for now. So we wanted to create this generative tile effect, so we want to sort of explain that first. So, let's imagine that our screen is here, our little tiny OLED screen, and the maze before looked really complicated if you're sort of not able to break it up with your eyes but what it really is is it's just a grid. So this is what we're gonna be programming today and this is not actually to scale of what the screen actually is but it's just giving you an example of like a really small cut away of the screen that we're going to be doing. So in order to create this generative art pattern, we actually are just gonna draw one of two things. So we're gonna generate a random number and then depending on whether the number is more than .5 or not, we're gonna draw a line that's facing like either, it's either pointing one way or it's pointing the other. So we have like one of two lines. So it's going to be either this line, or it's gonna be this line. That's it. So it's either gonna be leaning forward or it's gonna be leaning back. So for example if I was to use my own brain to do this which is actually harder than it looks (laughs), we can just start sort of generating these lines, but if we let the computer do it instead it's gonna be a lot quicker (laughs). And we might actually get some really nice effects out of it. So that's sort of how that algorithm actually works. We just split the screen up into tiles, and then we just figure out how to actually draw those lines by cutting out the screen into pieces. So hopefully that made sense. Cool. So the actual screen itself that we're using is, the dimensions are 128 by 64. So I want you to remember those dimensions 'cause they're like super super important, and I was gonna explain how the screen actually works but I might just leave that till the end if anyone's got questions about it. But because I did write the actual screen library I can actually explain to you how it actually is able to take pixel data and stuff like that but for today, maybe we'll just keep going with that. Cool. So the screen actually speaks a protocol called I2C, or it's actually I think technically I squared C but I always call it I2C because that's just like how I read it. But it stands for I think Inter Integrated, Communication? I think Scam Line's gonna know the answer to this (laughs). So it's a way of communicating and it's actually a really really cool protocol because it's very efficient. It doesn't take a lot of wires, and you get a lot of control over things like the clock speed and things like that. So I'll try not to get too deep in the weeds, but it's really cool to kinda know how these devices actually work. (sniffs) So generally you have, two different devices right? So I'm just trying to make sure that you can actually all see this. I'm not going off the edge of the screen. But, we have our Arduino here. Now our Arduino is know as the master. And then we have our screen. - [Dan] Sorry. Inter Integrated Circuit Bus. - Thank you. I always think it's connection instead of circuit bus but yeah. So okay, so Inter Integrated Circuit Bus, which is really cool. So, we have our Arduino and we have our screens. So the Arduino is known in this I2C or I squared C relationship as the master, and then the screen is known in this relationship as the slave. Now I don't really like the whole master slave kind of, like metaphor. So I like to call this Arduino the captain. (writing) And the screen is the sailor. (laughs) So we're gonna go with them today 'cause I think it's a really cute metaphor. So the captain is responsible for like, sending out commands to the, like the crew on the ship right? And the sailor always takes that direction. So generally the captain is controlling the whole scenario and the sailor is just kind of like carrying out those commands. So that's like the best way to think of it. And so in I squared C we have our regular power and ground, but we also have like two other connections. So this is gettin' a little bit small but one is the clock and the other one is just like the data line. So we have only one line that we need to use in order to send the beeps and boops back. And by the beeps and boops I guess I mean the zeros and the ones. And then the clock is an external, is an external kind of wire as well because then we can actually without getting too much into like how this stuff works, we can use the clock externally and to actually specify the speed at which we want everything to run. So I squared C is actually a really cool protocol. If you want to read more about it you can definitely look on sites like Spock Fun and other sites because it's super super cool. So that's what we're gonna be using today, in order for our Arduino to actually like talk to that screen. So you don't see a lot of that when I'm actually coding, because I've heavily abstracted that but that's the gist of what's goin' on today. So I guess that's what we're gonna do. So let's get going. - [Dan] I think there was a question that I noted at one point which was, - Okay. - [Dan] I don't, this might've been from a little while ago so apologies if this messes up the momentum but, so how much space, well actually I think I might know the answer to this question now I'm actually realizing, but how much space does Firmata and all the js libraries take up on the Arduino? Is that a concern to keep in mind? - Yeah that's a really good question. So I know that the standard Firmata C ++ sript for the Arduino is a pretty big one. Whenever knew features want to be added to Firmata, sometimes you have to take other features away. So that's why we have standard Firmata and then sometimes we have other versions that have like extra things put in there. So, this is a Arduino Uno. So it has 328 byte. So kilobytes of memory. So there's not a lot on there. And so it does kind of mean that, oh sorry 32 kilobytes I believe. Yes. So it's got 32 kilobytes, and that means that you don't have a lot of room. The good news is that the JavaScript that we're running never actually ends up on the device. So if the Firmata script that we flashed before successfully flashed to the device, then we know it's gonna fit. Obviously that matters when it comes to things like, if you have variables or it's trying to buffer a lot of the messages coming through on the device, you might actually see those difficulties as well. So when you're running your program you also want to leave enough room, or have enough good data structures in order to deal with the fact that there are a lot of messages coming through that the device has to hold onto for a little bit. So as usually with everything, it's always a balance. But that's a really good question, and just to remind you the JavaScript never actually goes to the device. The JavaScript script is simply just controlling the device instead. So the JavaScript is just sending op codes to the device so that we don't have to worry about that huge overhead of how big JavaScript would be to send to it. Cool. So the next thing we want to do is to plug the OLED screen in and start interacting with it. So, if I have the overhead camera sorry, we have a bunch of different wires. So actually let's go back and look at the documentation for OLED js. So I tried to document this as good as possible (laughs). But I'm always looking for port requests or issues if you find anything confusing. So the SDL, that's mentioned just over here, that's actually the data line and then you've got SCL which is the clock line. So I've been pretty clear about if you're using an Arduino Uno then these are the pins to use for each. The reset has to go to four, and then you've got your standard power and grounds which I usually don't document just because it's pretty easy to do a one for one with those. So I will actually show that being plugged in before we actually get started. So I have my Arduino here, and I have power, ground, reset, clock and data line. So that ends up being a total of five different cables. But it is actually still pretty efficient. It is still I think less cables than SPI, and that's just because the reset line is actually-- - [Dan] So, I hate to pause you but-- - [Suz] Yeah yeah go for it. - [Dan] But I think, I'm getting a message that maybe we could focus this camera a little better. - [Suz] Okay. - [Dan] So. - [Suz] So this is kinda the reset wire is not joined to the others so it's usually the easiest one for me to connect first. So it says in the documentation that reset has to go to pin four on the Arduino. So you might not be able to actually see this but these is a little tiny four numeral next to that little pin input, and so I'm literally just trying to connect each one to the correct one as listed in my documentation. So I like to use red for power and black for ground. So I'm gonna go ahead and plug them in 'cause they're always like super easy. Especially if you've done this a couple of times before. So I just plugged them into ground and power and that just leaves our clock, and our data line. So our data line is actually the brown cable. Our clock is the white. Again you can make up whatever convention you want but I like to use white for clock because it's just like my own little personal thing that I'll always remember. So the clock I believe needs to be pin A5 which is analog pin. And then, A4 is the data line. So the reason why we use A4 and A5 is because most Arduino boards come with I squared C capabilities built in but they use very specific pins to do that. So for an Arduino Uno the A4 and A5 pins are your clock and data lines for this particular board. So, it's not sort of arbitrary. This is kinda how the Arduino board is being set up. The reset pin was just an arbitrary choice by me. So, we have a lot of this code here already. We just need to write these middle bits here. And so we have to pars some options in to tell it what size screen we have. We have to give it the address of the device itself which can vary per screen. And then we also have to create an instance of our OLED screen. So we're just gonna go ahead and do that in the code now, in order to start sort of connecting to it. - [Dan] You're still using the overhead camera. - No. - [Dan] Yeah. - Thank you. (laughing) So I'm gonna show you that again. So it's just these lines here. We're just gonna be doing something very similar to this. But I'm just gonna walk you through it instead of copying and pasting. So, let's create, (typing) some options. And by the way, this is all documentation that's not using the most modern JavaScript. So we're still sort of using var and things like that. It's up to you if you want to request that. I sort of have just left it old so that people don't necessarily have to use trans filers to be able to use those new features. But it depends on what version of node they're using. I think most people are on version four at least now so that's good. (typing) Okay, so I needs to pars in options so that my screen library kind of knows how to control this device. So before I actually, put that in I'm gonna establish just some, some constant variables that are not gonna change. So I'm gonna call that width. So the width is gonna be 128 pixels. And the height is going, whoops. Is going to be 64, yes that's right (laughs). So got to be devisable by eight. So that's gonna be the size of the screen. I also want to establish something just ahead of time, called the tile size. And that's just because we want to be able to change this and have the algorithm kind of automatically adjust itself based on how big or small we want those tiles. So we're gonna start with a tile size of four and we're gonna see how we go. And then I can change that to let you know how that works later on. I keep trying to do my Bim shortcuts (laughs). It's like a, what's it called? Like a muscle memory. Okay. So now we can actually set the width to be width and a short hand of doing that, in more modern JavaScript is just to list these. (typing) And then we need the address. So I know for a fact that the address of this particular board is 3D. You can think of an address as an I squared C device as like phone number. So you can have multiple I squared C devices connected to those analog pins. And if they all have different phone numbers, it's not always the case. Sometimes it's annoying not that case, but you can have like, let's say five different screens connected, and if they all have a different address or phone number, you can actually kind of control them all without having to kind of like pull wires out and swap them around and stuff like that. So, just think of the address as us kind of like being very specific about which device we want to speak to that's connected to that I squared C bus. (typing) So now that we have the address, and I don't know why but I'm a semicolon person, so I'm gonna put some semicolons in. Once we have the options and we've said sort of, this is the minimum set of kind of properties you need to give to get this going, we're gonna create a new variable and let's call it screen 'cause that's actually easier to kind of reason about than OLED. We're gonna create a new OLED screen. I think that's what I called my dependency. Yes. And let's pars in the options. (typing) Cool. I kinda want to run that just to make sure I haven't completely screwed something up. (chuckling) Okay cool. So it couldn't get the height, and I actually know why that is. So I'm not actually using my library properly. So we do actually need to pars in a couple of other arguments. We need to pars in our board and our five instances. Because this is a separate thing to Johnny-Five we actually need to be able to give it those things so it can actually use Johnny-Five to communicate. So we're gonna go back to the code and we will pars that in. So I think it was board and then five. I hope that's right but we'll just guess. There's nothing like reading your own documentation. (laughing) Alright. So I'm glad I tested that because it definitely blew up. It looks like this is okay. So I'm just gonna stop this process and then we'll keep going. So we definitely want to, make sure first that the screen's working but then we want to clear the screen 'cause sometimes when you start the screen up it can have sort of some snow on it. Kinda like an old school analog TV. I guess you still get snow, just digital snow now on digital TV's. So one of the first commands that I want to show you for this is, is screen.clearDisplay(); (typing) And then we can call screen.update(); just to make sure that that actually gets sent to the device. So now if we run this, let's see if we can cross to the camera. So all I'm really doing is running the same file but if we look at the camera, you might be able to see there's a little bit of snow on there right now. You can sort of see that it, at least did a thin and then it's very very subtle. We might actually have to turn the-- - [Dan] Yeah. I'm trying to think so-- - [Suz] One of the lights out-- - Let's see, let's take a minute here, to see if we can make this a little better. - Yeah. Let me put something on the screen. 'Cause that was gonna be my next thing anyway. - Oh yeah, put something on the screen. - Screen.drawLine. I'm gonna do zero zero. This is a spoiler alert. (laughs) - [Dan] I think people see it. - 60. Yeah. And then I don't know 12 (laughs). - Yeah. So we're starting at zero zero and then it's going across a little bit and down a little bit. So the one here is just what color I actually want to do, and by color I mean the pixels either on it, it's like shining in a white sort of color or it's just off. So you can actually draw with like negative color, and you can just clear out parts of the pixels which is kinda cool. So just remember that one just always means the pixel is on. So I do actually want to change this library quite a bit because I did write it a few years ago. I would love to have an enom. So it would be colors.white or something. Or color.on or pixel.on pixel.off or something like that. I think that would be a lot more effective but I'm interested to get people's thoughts. Again raise an issue if you think that you have an idea on that. Another thing that I can do is I can basically tell it not to update the screen immediately. So we can do a lot of like manipulations first and then update the screen all at once. We're probably gonna do that today, 'cause there's no pint in drawing each line individually and kind of bottle necking the USB connection. I can show you that method as well. (typing) I think, drawLine. Yep draws in one pixel white line. And yeah you can say whether or not the screen immediately updates to the result. So cool. So this is literally all we need in our repertoire today in order to start doing this generative art. So we have everything else is kinda like more the algorithm, but this is definitely like the fastest way to get started with drawing on an OLED screen. So I'll just show you that one more time. There's the line there. So we're just gonna be drawing lines in different patterns across like invisible tiles on the screen. Cool. So we have our tile size and we have our width and height. So we're gonna be making heavy use of these. We're gonna be creating just a couple helper functions as well in order to kind of start drawing this. So the first function I want is to create a vector because we want a lot of things where we're dealing with XY coordinates and you don't really get that in JavaScript. I know that in like processing and things like that you get these really nice like classes right? Like vectors but we don't get that in JavaScript. So I'm not even gonna pars in arguments except the X and Y. I'm literally just gonna return an object that has the X and the Y set at zero. Like I'm just gonna go super simple today. I know this is not necessarily how you would always do it, but this is definitely gonna suffice just so that we don't lose time on creating this very fancy like very correct vector. So, now we can actually just get these objects that we can get the X and Y values out of. So a vector is really just trying to denote like a point on the screen itself. The next thing we want is to create a tile, so we need to be able to actually draw like either a forward line or a leaning back line. So that's the next thing that we're gonna do as well. So I think we might write this first I guess. We're gonna have another function that does a bunch of loops as well to draw the tiles. So maybe we can do just createArt() because that's what we're actually gonna create. So these are just my place holder functions, and then we can actually get started writing them. So as you saw on the whiteboard, all we really want to do is kind of split up each screen and the tiles and then just either, generate a random number and based on that we're either gonna do like the leaning line or the falling back line. So, maybe we could just write the function to create the tile. So what do we need to do with this? We need to have a random number right? So I'm just gonna call it num. And then in JavaScript I think we can do just Math.random(); and we're just gonna take like the Math.random number, because we can use this pretty pretty easily. So we need to kind of now create one of two conditions right? So we can just create our empty conditions at this point. So I'm just really saying if num is more, is greater than 0.5, we want to do a thing, otherwise we want to do another thing right? So let's just set up this rule. It's gonna be super arbitrary because it doesn't really matter which one you start with. Maybe this one is leaning, let's do leaning forward because that's a little easier to do for the first time, and then this L statement is gonna be falling back. I guess that's the easiest way to do it. Like how do you describe this Dan normally? Like leaning forward falling back? - [Dan] I dunno. I think forward slash and back slash. - Forward slash and back slash. - [Dan] Yeah. - Wow. (laughing) That's actually really simple, thank you. - [Dan] 'Cause that's what it originally was. (Suz laughs) So like on the Commodore 64 like-- - Oh on the Commodore 64. - [Dan] Just printing those characters. - Of course. That's so smart. So my first computer was a Commodore 64, so this is making me feel super nostalgic. Alright. So, what we want to do is we want to establish like two vectors right? We want to have like the start of the line, an X and Y and then the end of the line an X and Y. So I'm gonna create some new variables so we're gonna have start, no wait lineStart. Let's call it lineStart. (typing) I don't know what I'm doing. Okay. lineStar equals and then we're just gonna create a new vector. So we're gonna just like manipulate the X and Y afterwards. So now I just need an end line. Wait, lineStart, oh I'm getting so confused. Okay. lineEnd. So, we shoulda just copy pasted this line but it's cool. It's good to type stuff so you remember it. Okay. So now we just need to basically say, like we can set these new values depending on like what the random number was and then we're gonna actually draw the line. (typing) So I just realized that I'll actually need, an argument in here. So we're going to need to pars in the whoops, the screen instance so that we can actually like call a method on it. So you'll see why we need that later on but I'm just gonna do it so I don't forget. Okay. So, if the number is more than 0.5, we want to lean forward. So that means that our tile size is going to need to kinda come into play with this. So I think we actually need some more, variables to pars in because the tile needs to know exactly what tile it's actually on. So I'm gonna pars in a tile vector, so we're actually gonna make use of vectors later on as well. Now we can do something like just pretend that vector exists. We can have tile.X and tile.Y. And I want you to think of the tile X and tile Y as like the top left corner of that tile where it starts. So that kinda gives us our anchorage, and from there we can start generating lines. This is probably not the correct way to do it, as in the book but this is sort of how I'm gonna figure it out. So, I'm interested to hear in how you do it, but this is how I'm gonna do it. Okay. So if we have our line start and our line end vectors, we have our tile start, this is where we sort of want to start doing it. So, we want to maybe set up our line start first. (typing) So our line start x coordinate, if it's leaning forward, then it's gonna be like right in the corner right? So, I don't know how else to explain that but it's gonna be right at the start because the forward slash is sort of like yeah. The horizontal starts that way. So if you have a look at it this way, you can kind of see that it's starting right in the corner. So we can just set that to be the tile.x because that's the starting point of the tile. Then we want lineStart. y. Okay so this one is different this time because it's not the Y right at the top, it's actually the Y right at the bottom. So we're gonna do tile.y but then we're gonna add the size of the tile. So if the tile is a square, then we're gonna add the tile size. So we're gonna do tile size, and then because the X and the y of the tile, because it actually denotes the start of tile, it's actually inclusive. So I think we also need to take one away just to balance that. But we'll see if that's correct 'cause I did this like weeks ago in Australia after I met, after I saw Tim Holman's talk so, we're just gonna make this up. Okay. So now we need to do the line end coordinates. So the line end is gonna be like right towards the end of the actual tile itself because it's leaning forward. So we can just do tile.x and then we're gonna + the tileSize I guess. And then we're gonna do - 1 as well because it's inclusive. Stop me if this wrong. 'Cause I trust you Dan. You're much better at this stuff than I am (laughs). And then the line end is just gonna be, I think it's just gonna be the tile.y because it's sort of like ending at the top of the Y I guess. What am I doing? Line.End = tile.y. That should be it. - [Dan] Yes. - Okay. I'm hearing encouraging things from Dan right now (laughs). Okay. So, that's the leaning forwards. So let's do the leaning back. So the lineStart.x. So because it's, let's actually just like draw a little one here. So that we can actually kind of reference it. So, the lineStar.x, is it's still starting right at the start of the tile again so I feel like we can just do this. I feel like the tile.x, the lineStart.x is always like there. So we can like draw the line from bottom up, but we're just gonna do the line from the top down I guess. So there are different ways to do this because you can draw the line in backwards orders I guess. Okay. So, the line Start.y is going to be just the tile. The tile.y right? Because it's right at the top. So lineEnd.x, okay. So if the line ends like right at the far part because it's leaning back it's gonna be tile.x + the tileSize. I feel like I'm just writing exactly the same code as the other one. - [Dan] It should be, tilw.x + tileSize - 1 right? Because you're starting over. - Yeah that's what I feel. I just feel like this is, it just feels so repetitive but there's super subtle differences with it. - [Dan] Oh sorry, I'm behind. Like what I'm seeing-- - Oh, okay. - [Dan] What I'm seeing... - Oops. (typing) - [Dan] 'Cause that's, is this falling back? - Yeah it's falling back. - Oh yeah leave that then. - Yeah yeah yeah. - Yeah yeah yeah. - That's what I thought. Okay. Yeah, this stuff melts my brain. - [Dan] Yeah I know. - This is why I can't do it. Like, it's so funny 'cause hardware is like safe and comforting to me, and like this stuff is really scary 'cause it's so much, it's so much math and I'm really bad actually at spacial math. Like I just don't have a lot of good spacial awareness in my brain in general. It's just not how my brain thinks. So I really have to put in a lot of effort for this. Okay. So, it's gonna be at the bottom, so we need to + the tileSize again. - 1 inclusive. So, and then this is - 1. (chuckling) - [Dan] Yes. Yep, yep, yep that's right. (Suz chuckles) - Okay. (Dan laughs) (Suz laughs) Okay. So now that we have (sighs) now that we have that, it's the biggest anti-climax ever. It's just gonna be lineStart, I never do auto complete 'cause I'm not used to having it in Bim. lineStart. y right? And then it's gonna be line, this is gonna go on another line, lineEnd.x and then lineEnd.y, and then the color is 1, and then we don't want it to automatically update 'cause we're gonna be like drawing so many lines, we don't want to just like hit this device and sometimes it can actually overwhelm the devices and it doesn't break the device, but it does kind of just like bottle neck it and then sometimes the messages just don't get through. So that's a limitation of like using this way of doing things. If you did this directly on the device in C ++ you wouldn't actually see that issue. Okay. So that's a tile. Can we draw the tiles really quick? (typing) So that this stream doesn't go forever (laughs). Okay cool. So we want to create the art. Again this is a function outside of our screen. So we're gonna just pars in screen. Not screem. Ah! Okay. Okay. So, this is where we do our classic generative art like algorithm which is nested fallive right? So, we're gonna do let's, i = 0; and then i is less than the width of the screen. And then i is going to be += tileSize right? So it's gonna like jump in tile widths. Hopefully that makes sense. And again Dan will stop me if I'm going completely off the rail (laughs). - [Dan] I'm 20 seconds behind. - Okay (laughs). - [Dan] I can see through your audio. I can see your screen here. So. - Okay. So this is gonna look super similar, it's just like j is less than the height because now we're gonna go like tile downwards. So then we're going to do j += the tileSize again right? So we're really just like staggering this thing. So just can do all the tiles, stop when it gets to the end of the width and then like do the height, and then do the next row I guess. So it's doing it kind of row by row I guess. Sort of. No wait. Yes it is okay (laughs). Okay so now I think we can just, call oh we need new vectors. So we need to like generate what the tile start and is right? (sniffs) Whoops. So I'm gonna do tile = new Vector(); I feel like this has now become a speed code (laughs). Tile .x is = to i; and then tile., so you can see that if I actually had a proper vector function I could just pars in the X Y, so I realize that that was like something that wasn't so great when I created it but this is still pretty easy to actually fix. So tile.x = i, tile.y = j. Now we just need to create the tile, and then we pars in, what did we need? We needed, tile and screen. Oh that's it? Okay. That's easy. Okay. So we create the tile, we pars in our tile object and then we pars in the screen instance just so we can actually call things on it. I think that's, is that it? That's it. So after we've created the art we need to update the screen now. Right? So like we've sort of like manipulated the screens buffer, that's sort of what's happening under the surface, it's like frame of pixels. So now we do screen.update(); because then we're just manually updating it because when we were drawing our lines we were saying like don't immediately update. So I think that's it. I have no idea what I'm doing, but I think this is coming out alright (laughs). Okay. So, we need to call of these functions. Clearly. So I think we can just call 'em in here. So I'm gonna just whoops. I don't know my, this is a new keyboard so I'm still actually figuring out this keyboard too. (typing) Oh. It's just createArt right? (typing) Can I just create the art? I think I can just create the art. Is that it? Yeah. So we wrote a lot of code before we actually ran this. So (laughs), let's see if that actually runs. So I'm just, whoop let me go, so I'm just doing this. So I might just actually clear the screen, there we go. So I'm just running the same file and then like, let's see if it actually works. Oh my God. It actually worked the first go. So I'm gonna make this bigger because our tile size is really really tiny. - Cool. I'm sorry I just want to come in and look. - Yeah yeah come and look because like yeah that's-- - Oh Wow. Oh can you, oh you can see it there. It's just doing the scan thing - Yeah. - but I think people can see it. - Okay so let's just change - Wow the tile size real quick. - Change your tile size yeah. - Yeah because like, see Dan it's not scary at all. - No, I have so many questions. - It's exactly the same code, yeah. So the tile size, whoops. Oo what happened there? - I've never seen that happen. (Suz laughs) I'm trying to get out of the way but now I'm over here. - Okay. So let's do a new tile size. So I'm just gonna run that again. I'm so excited that it worked. Yeah! - Yeah! So if you wanted to animate something, you would just, are you continuously sending the same image or are you sending one? - Not right now. - So you could do that though? - So you could put this in a game loop and you might have a pretty limited frame size, - Yeah. - sorry frame rate just because of this USB bottle neck. - Yeah. - But if you wrote the - C ++ with the same kind of like thing, yeah you could do it. - Because something that's interesting that you can do with the 10 Print design, is you can change the probability, so right now it's 50%, - Oh. - this was versus that way. - Oh that's cool. - And so we could do it right now but like, you could actually since this is all JavaScript and connected you could - Yeah. - actually make an interface so you're like altering the probability in real time. - That's so cool. - So even like right now if you just go to, I'm standing in the way of course. - No you're fine, you're fine. - But if you go to where it's num's greater than .5. - Yeah? - I'm gonna come over here. - Yeah yeah. So if you just change that - just change it to like, - to like-- - Like .2 or something. - Oh I'm so excited. (Dan laughs) Okay. See this is where I'm like no idea what I'm doing. - I can come over and look. - So does that mean it will have more forward ones? - Yeah see? - Ah. - So it has a particular quality in that it's much rarer for it to go the other way. - Today I learned. - Yeah. So one question that I have, so to me it was interesting to watch this 'cause I'm so used to doing the programming to like generate a design like this, but I'm not used to doing the programming to put the design like this in something that isn't like, HTML 5 Canvas or processing the - Yeah! high level API. - Yeah. Totally. - In theory though it would be possible. I don't know whether it would be worth doing this or not, but with a display like this, there's no reason why you couldn't do drawing to like a canvas object with like a higher level API and then read the pixels of that canvas one at a time, and transfer them here. So I have this thing that uses Canvas where you can make your own fonts, for this screen. And it's actually using Canvas. So this is giving you the preview. - I'm gonna come stand over here just to be, - Yeah, yeah, yeah, yeah. Yeah, yeah. - out of the way of it for everyone now. - Yeah. So what this does is you can put in the font that you want to use. You can do like the size, and as you sort of change that it's changing, and this is literally a canvas. And then you change the threshold for what you want like the kind of smooth stuff to be. - Yes. - Right? And when you're happy with it, it goes through every pixel in the Canvas file and it gives you a font value down there. - Oh wow. - And then that converts it into like a frame buffer j song file that's compatible with my library. - Ah. - The next thing I want to show you is actually really cool. It's way cooler so I saved it to the end. But my friend Hexolan, do you know Hexolan? - I don't know if I do. - She's amazing. She's amazing. Oh she doesn't have it at quick. So it's called Oledjs-designer. So she took my library-- - Ah wow! So this is exactly what I was just talking about. - Yes. And like you're gonna lose it when you see this. It's like a thing where you can draw and you can download the image buffer. So that's like really really small. You can download the image buffer but what I did recently that I had on my laptop that I can't show you is I had Johnny-Five running in the browser and it sent it. - Ah okay. - So it's-- - Like web sockets? Or-- - No no no. In the browser. - Or in the-- - With Web USB. - Johnny-Five can be-- Oh. Oh I didn't know you could do that. - Well it's really hacky it's not actually officially supported 'cause you can't send a sig into the browser. So you have to like put it into a web worker and then. - Yeah. - But, you can also do it as a web socket. - Yeah. - So I could send that to my node process - Yeah. - and then update it. So, that's what she wanted to eventually do with it. And I've been, I've basically been forking this project to my own Git Hub and like messing around with it. - Right. - So I've gotten it working with Web USB with wifi via like NQDT and then also with web sockets. - That is wild. - So I wish I could show you but, Hexolan is awesome because she made this. - Well there's two things. One is you'll just have to come back and do another tutorial. - That would be great. I would love to. - Or, if you're doing follow up with any of this like coding that are trying more stuff on your Twitch channel, - Yeah. - I can like point the goal towards that. - Yeah totally. - Thanks for watching the edited version of live stream with Noopkat. I hope you enjoyed it. This is just a reminder, check out this videos description. Go and subscribe to Noopkat's Twitch channel. Check out her Twitter at Noopkat, or like I've been saying the last two years Noop kat. And thanks for tuning in. I'll see you in a future video. Bye! (upbeat music)
Info
Channel: The Coding Train
Views: 34,754
Rating: undefined out of 5
Keywords: live, programming, daniel shiffman, creative coding, tutorial, coding, challenges, coding train, the coding train, itp nyu, javascript hardware, javascript arduino, oled arduino, noopkat, guest coding train, suz hinton, arduino tutorial, arduino projects for beginners, arduino uno, arduino johhny-five, arduino project, arduino art, oled, oled art, oled screen, javascript oled, arduino js, guest tutorial
Id: Xtnitfj_e10
Channel Id: undefined
Length: 54min 51sec (3291 seconds)
Published: Thu May 03 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.