- 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)