Hardware with Arduino & JavaScript

Toggling LED from the Browser

Steve Kinney

Steve Kinney

Temporal
Hardware with Arduino & JavaScript

Check out a free preview of the full Hardware with Arduino & JavaScript course

The "Toggling LED from the Browser" Lesson is part of the full, Hardware with Arduino & JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Steve challenges students to write the code to toggle an LED from the browser. The code is then moved to a client-side application, and a button is coded to toggle the LED using a POST request.

Preview
Close

Transcript from the "Toggling LED from the Browser" Lesson

[00:00:00]
>> What I'm gonna challenge you to do is we would also love to send a post request to the server that turns that LED on and off as well. And once we have that in place, then we can go from browser all the way to Arduino, we can go from Arduino, or we can go from node to browser.

[00:00:18]
I think WebSockets will get us all the way there. But we'll kinda take a look at that full lifecycle. And from there, we can build on it with a bunch of really cool options as well. Awesome, yes.
>> I just have a quick question.
>> Yes.
>> And maybe this is a bigger one now.

[00:00:31]
I noticed in the Arduino IDE, it tells you how much memory you're using. And now that we're starting to bring in JavaScript libraries, is there a way to track that here? Or are we gonna run out of memory ever?
>> You're not gonna run out of memory because right now without, on the Arduino, the host computer is your laptop.

[00:00:54]
So I mean, you're gonna run out of memory but depending on the MacBook, somewhere between 16 and 120gb of memory. So we're not at this moment with this board bound by the memory constraints. For something like a Raspberry Pi, even these days on a modern Raspberry Pi, they're pretty impressive, like $30 computers, right?

[00:01:16]
And so it depends is the real answer. For the purposes of the Arduino, we are so limited that we are using a host computer, right? So, no because it's very much yes [LAUGH], right? We are so constricted that we're no constricted basically. Yeah, for a lot of these cases do need to be plugged in.

[00:01:37]
There are some that you might even choose, could we read system information and print it to an LCD screen? We could, right? But generally speaking, that would become more constrained when you have one of the boards that host a full node environment. All right, so the initial ask was that we can get an LED blinking along with it.

[00:02:03]
Now theoretically, we'll move to another example in a second what we do with a post request and stuff along those lines. But just as a sanity check, let's do it along, like when a get requests comes, let's toggle the light and then we'll kind of build on it from there.

[00:02:16]
So if we kinda go ahead. I took away the LED that I have. You might still have it, but I'm just gonna make it again. And I believe mine's on 11 still. So I've got that LED. And I'm gonna start with the simplest possible thing, which is to say led.toggle, when we get a request in.

[00:02:39]
Let's see how that goes for me. So then I will, All right, server's up. And so now, regardless of whether or not the button is pressed, when I visit the site, my LED should go on or off. So now I've got from the outside world in there. And one of the optional things to install was like ngrok so you could expose this computer to the Internet if you wanted to.

[00:03:08]
And now I could theoretically control this LED from my mobile phone. I mean, anyone could by visiting or not. And we've got this idea of now from the browser all the way to the board. We can turn that on and off. We can modify this a little bit with a post request, but just so that no one has to remember the syntax for curl, I have various different boiler plates set up.

[00:03:33]
There is one called Web with LED, I believe, Web to LED that we'll check out in a second. I just wanna show you a totally optional optimization that you can do if you want. If you do not want to do this, you do not have to. I will choose to do it, because that's the way I want to live my life, you don't have to.

[00:03:55]
Which is, for the most part, which I thought we do need to wait for the board to be ready before we interact with the board, which makes total sense, right? Which means that generally speaking, other than instantiating the board and maybe some other stuff, almost everything has to be inside this closure, right?

[00:04:16]
I am somewhat lazy and don't wanna live like that. So, an option, if you look over here, I have this little helper file in Utilities called create-board. No, that is far too far away. There it is, where I simply wrap this in a promise. Because I think in node, what is it, 18 and later, you have top level async await, right?

[00:04:42]
So by wrapping in a promise that resolves when the board is ready, I can do this instead, just at a top level and the rest of the code will execute once the board is ready. You can use the board on ready if that's simpler, it makes more sense to you.

[00:04:58]
Especially cuz I have a very increased font size right now, it allows me to kinda have better real estate there. But yeah, I just made a quick abstraction over that that I can create the board and then pause the execution until it's ready and then do everything kinda top level.

[00:05:13]
So I'll probably be using that from this point forward, but like I said, you do not have to, and if I did, if I needed the board object itself, that would work as well. It returns the board in this case once it's ready and it waits for it, so I don't have to set up that event listener every time.

[00:05:29]
If that's a helpful abstraction for you, great. If you don't wanna use it, that's totally fine, too, but just kind of full context. And you're like, yeah, there might be a bunch of other abstractions that you choose to make as well, but that is kinda the only one that I went for at this time.

[00:05:45]
So I'm gonna navigate, I've got just, and again, you could write this stuff by hand, to save the parts that are tedious for us. I've got this web-to-led, and we'll just take a tour of the code real quick. The server is basically the same that we had before, right?

[00:06:02]
I can pull in that, Johnny-Five. The only difference is this one starts out vite, to actually build some client-side assets too, so it's not just the raw stuff on the page. But it's the same basic setup that we had in the last example, in index.html, cuz nobody tuned in to this Nodesbots course to live watch me write HTML.

[00:06:26]
I mean, maybe you did. I don't wanna speak for you. So I can kinda navigate into that one as well. And it'd be cool to actually show just the flow with an Ajax page, for instance, right, of how would this work. And then, so basically the next few examples are, let's look at how do we trigger what we just saw with AJAX or net request or fetch request, post request, what have you.

[00:06:48]
And then we'll look at the WebSockets, and then I think things really kinda kick into high gear, cuz now we've got real-time two-way communication trigger in either direction, I think it's where things start to get fun. So, with that, let's dig into it. So if I go, I'm gonna just navigate out of that button-with-webserver and into web-to-led.

[00:07:09]
Sweet, and I will, node index.js, I'll just start that up real quick so you can see that now I've got something running at localhost. The server's running on 3000. The clients assets are on 5173, cuz that's the number that Vite shows. And so I have this button, ideally, clicking this button, I would like to make turn on that switch one way or the other.

[00:07:37]
So we get this working pretty quickly. It's an extension of what we just saw, but it kinda helps close the loop a little bit as well. So if we look at client.js, there's nothing in there, so we kind of navigate as we want. I'm gonna do the server side first because otherwise it's just gonna blow up.

[00:07:53]
So I'll kinda take you through some of the things. I have that create-boards. You can kinda see me implement that this time. We'll put up the post request that ideally should toggle the light switch in either direction. Great, so I can say const board = createBoard with the repl, we'll turn that off again.

[00:08:18]
I don't need the board on ready cuz, we gotta await it, right? So wait for the board to be ready. And when that's done, we'll do, let's get ourselves an LED, this one is still on 11. So we'll stick with that. And then I don't need the button just yet.

[00:08:39]
We could do something fun there. But now we can set up a post request instead, right? And we'll say post and we'll say api/light, yeah, let's do that. And when that comes in, very similar to what I had before. I'm just gonna do led.toggle, yeah, sure. We can set up that post request, and then in client.js, we've got that light switch, so we'll say, lightSwitch, addEventListener for a click.

[00:09:19]
And then I have all post is, any y'all ever tried to write a post, fetch is super easy for getting, you ever tried to write a post request without Axios or something like that, cuz you don't have too many libraries. So I did that exactly once and I don't ever wanna write it again.

[00:09:36]
So all posts does is it sends a post fetch request without me having to write all of this cuz I'm very lazy again. Live coding and live wiring is hard enough, I'm at least gonna give myself [LAUGH] a few niceties to make my life just a little bit easier there.

[00:09:52]
So that's what post is, it's nothing special, it's simply regular old fetch, either ready to accept JSON or not. So we'll do that post('/api/light'). I'm trying to think. Let's make this async just so we can see, we get better, So we'll kinda do that as well. And so now I've got that kind of full connection we're talking about.

[00:10:27]
I have a DOM element. I have an event listener, should verify that this works before I get too confident about it. But let's talk about my intentions. And then we'll see if my execution matches my intentions, right? So I've got a light switch. When it clicked, we're gonna send that post request to api/ light, which should go back to the server and toggle our LED on and off, right, and thus completing the circle as well.

[00:10:48]
All right, so just sending a post request, well console.log the response as well. So let's try that out, I do need to restart the server. You could try to get fancy with Nodemon and stuff along those lines, but between the client side server and the node server, and the Arduino board and memory leaks, I decided that wasn't worth it for me.

[00:11:12]
Tailwind hates me for some reason right now, but I'll fight with that later. It works, and I'll open the console up as well. So my light is going on and off from the web, through node, to my board. It's oddly satisfying. I've been doing this for a very long time, and I don't get a lot of that warm and fuzzies of the very first time that I made something change on a page.

[00:11:43]
And for some reason, making this tiny little three-cent light go on and off is mildly rewarding, [LAUGH] in a deep and satisfying way. We haven't really had to adjust our circuit. Now, again, we could theoretically do other stuff with the button. One example that, I don't think we will play with a little, but I left some fun little extensions in there.

[00:12:08]
There is one where you could theoretically wire up three of these buttons and have rock-paper-scissor in there, right? So you hit a button and then there's a little algorithm that randomly picks one and tells you if you won or lost. Listen, I pay attention during all of my meetings at work, and there's no way that I spend any time quietly playing rock paper scissor over on my other monitor while nodding, that never happened.

[00:12:34]
So, here's a bunch of little kinda stuff in there.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now