 That should be like full HD. That was not full HD. Yeah, there we go. Full HD. Okay. All right, I'm just going to use my laptop. Hello, everybody. I'm just getting started. I'm Ian Nash, and I'm going to be talking today about embedded JavaScript microprocessors and how I found running JavaScript on microprocessors actually makes sense and is possible and cost effective today. I am a software engineer in New York City working at Oscar Health, which is a health insurance startup there. And in college, I studied computer engineering, but now I mainly do software. And in my free time, I like to tinker with hardware, which means that I don't have university labs accessible to me anymore and I have a very limited set of parts at home, but I still like to tinker and buy random things and then figure out once they come in the mail what to do with them. And it's nice not to have any deadlines or pressure or expectations and just kind of mess around with things. In high school, I built a pick human aware like foam missile launcher. It just started like little darts, and it was a program I did with a college with a lot of structure and I had a professor actually helping out with a lot of the code and I would have had no idea where to start or what to do without most of the stuff already solved. And that project took about, I would say, 30 hours to complete in a group of three. And then my latest microcontroller project is a live heart rate and motion streaming sensor. It's almost like a Fitbit, but it gives you updates every 10 to 50 milliseconds. I'm trying to optimize that a little bit. And a lot of the control code for that is actually written in JavaScript and it's a custom microcontroller with some sensors soldered on and a battery pack. So it's really cool to see like, I don't need an oscilloscope for that. I just needed like a soldering iron and just ordered parts that came in the mail and just kind of assembled them together. So yeah, this is a reference of what I started out with. It was a big project that had a lot of electrical components and a lot of moving parts and wires. That was fun. Now it's just a little board with everything all soldered together. So I'm going to go over a little bit about my journey and where I kind of started working with microprocessors in JavaScript and what brought me to something that kind of works. And then I'm going to go through a step-to-step guide on actually how to make this possible and to build a JavaScript project on ESP32. I have a demo here. It's probably not going to work. I took a lot of screenshots. If it works, great. You guys will see a Wi-Fi network and you can get the temperature. If it doesn't work, well, you won't see a Wi-Fi network. So yeah, we want to show the current temperature on a web page. That's kind of going to be the goal in the tutorial project I'll go through. Raise your hand if you've worked with Arduino before. Who's heard of Arduino? Okay, awesome. So about half of you guys. Arduino is a library and IDE around the Atmel Mega. And the Atmel Mega is a hobbyist-friendly open-source chip. And it's one of the first easily accessible hobbyist chips that really take off in popularity. And it started a huge microcontroller maker movement. And it's great. You buy a board. You plug in it over USB. You download an app and you can just start writing C code. And it's much, much more intuitive than previous tool chains where you'd have to go to a vendor's website. You would have to download a huge toolkit. You would have to know how to run compilers. And you would have to write custom flashers in certain cases. So it really lowered the barrier to entry. And raise your hand if you've ever worked with an ARM SDK or any sort of microcontroller SDK before. Cool. Okay. Just curious. So yeah, this is kind of in my journey. In high school I started with PIC and college I did a lot of Arduino work and then did a lot of bare metal ARM and some more technical microcontroller stuff. But I think what I studied and what I do for fun with microcontrollers are actually two different areas. So a lot of this technical stuff I learned I don't use because other people have kind of figured that out and I can just build the fun parts, mainly in software. So this is a bit of an example of what PIC code looks like. And if you see here, it's pretty incomprehensible what all this stuff is and there needs to be some comments. And then here there's actually an entire bit mask. So you have to know the actual architecture of the chip and you actually have to calculate how many microseconds it takes for each clock cycle of the CPU. So just measuring that out and calculating it takes a lot of time. Arduino makes it a lot easier. This is a still C code, but you can say pin mode, trig pin output instead of TRSC 5 equals 1, TRSC 2 equals 5, TRSC 2, 5 equals, etc. And then in the loop here, you can just write delay microseconds and then you can get pulse in, which will give you a variable of the distance between you and the object. And this is in reference to that missile launcher where it's going to spin around and then when it sees someone coming to range, fire a little foam target. And now this is an imaginary JavaScript API which you can make real with some of the stuff that will be going through in a couple minutes. So here you can just call a method to get a configuration pin. You can require a pre-built module, initialize it with the pin. And you can use event-based programming instead of loops. It's because you need to manage timing and events really carefully with a single core processor. But with these newer processors, they're hundreds of times faster than the, say, the Arduino so they can actually multitask to where you can say, I just want to do this on a timeout of 10 milliseconds, and the processor will figure out how to give you that real-time signal on its own. So the ESP8266 is a chip that a lot of hobbyists started using with the Arduino. And it's a little microprocessor board. It's like a couple of dollars. And the problem is, is developing on it, you have to download tools from the vendor. You have to work with a custom compiler and read through a lot of C code and write a real-time operating system plug-in to even just use the libraries that were there. So one of the benefits, a developer came out with a tool called ESPRINA, which is a JavaScript interpreter to run on these devices and really interact with the low-level signaling and real-time operating system. So you don't have to manage all the C code. And it's an interpreter. So you load the firmware on the device and then you send your JavaScript code over a serial port, over to the board over USB. And then your board will run the JavaScript. You don't need to download any custom tool chains. You don't really need to do any sort of complex compilation. But I really wanted to get started working with that. And a new chip came out that people are talking about. It's the ESP32. It's an expressive 32 model. And it is a low-cost, really rich interface chip that includes a Wi-Fi radio, a Bluetooth radio, a dual-core processor, and a kind of open development tool chain that made it easy for hobbyists to go in and write extensions or rebuild previously existing tools to run JavaScript on microprocessors, targeting this microprocessor. And the other cool thing is there are tons and tons and tons of development boards with different bells and whistles, such as batteries or screens or different voltage pinouts where you can really find a board that suture needs to develop something and not have to build much custom hardware. And you can really just start plugging in sensors to a degree. So the board I'm working with and the board I have up here is the Lowland 32 by Waymos. It's one of the original, I think it's the second board, and there are spin-offs of spin-offs of spin-offs. So you have to be pretty careful when you're buying boards to find a developer that's made a name for themselves with designing their boards. The design of this board is pretty good for development, and one of the great things is you can just plug a battery into it and you don't have to run it over USB or build a custom battery control. It has all the battery control and charging and safety chips already built in. And it also has four megabytes of RAM to load your programs. That's actually a separate trip from the microprocessor. So it's 3-0. It comes with a little IDE. If any of you are familiar with the JavaScript IDE or any sort of like learn-to-code IDE, it's really similar. On the left, you have a repo, which is a read-eval-print-alooop. So you type commands, it'll say output. You can run this code here and it'll output the console of the code just like Node.js or the Chrome Web Inspector. So it's a really familiar interface. You click here to connect to the board over USB and you write code. This code here, it sets up a data bus using two wires on pin 17 and pin 5. And then it requires a module, connects to the display, and in this function it prints out a message on the display that's just hello world and then writes the display memory to the actual screen. Because here it's like Canvas where you draw stuff onto a canvas and then you need to print the buffer and load the canvas onto the page. Sprino is full stack JavaScript. And a problem with that is a lot of the lower level libraries that communicate, for instance, to the screen are actually doing all of the underlying calculations to draw the image and to send the commands to the string to the screen in JavaScript. And that causes a performance penalty and it really hits the limitations of some of these chips where you really have barely enough processing power to do that. And I was looking for an easier way to do this where you could just work with modules and write the drivers in a lower level language and then have a higher level language on top of that, very similar to React Native. And there's an OS for these boards, which I was really surprised about. Like it's an OS that does all these things but it seemed too good to be true. And it's called Mongoose OS. And Sprino was pretty frustrating for me where it was a limited environment. It was sometimes unstable. It kept crashing. I was trying to make a demo today and then I used a newer version of what I had before and it started crashing. And when one of these processors crashes, it crashes. It prints out its entire memory buffer and then just says abort and restarts the program from the beginning. So you have to read the memory and it's not worth it. So it's easier to just try to fix the crash and comment out the lines of code until you find where that crash happened and then kind of dig into it. But it's really time consuming and it happens a lot. So it made me sad. Mongoose OS though is a toolkit that combines IoT cloud integration and it's pseudo commercial to where if you want proper security, if you want over there updates, you have to pay them for that. But it also is really good for... Most of their stuff is open source and it has a really good developer environment and it's much more solid than what's volunteer community driven because it's actually a commercial product that they're selling. So if you build something with it, you need to publish your code. That's the GPL license. But for hobbyist projects, that's fine. And you can bolt on any of the stuff they have on your own too if you really want to do that. So setting up a simple environment for development, you need to set up a serial port, match voltages on your sensors, and assemble the boards and make sure you choose the right board. So this is kind of the prerequisites to even getting to software is to buy a board. My recommendation to get started with this stuff, I'll get back to what board to buy and some more of the specifics, is just to build many simple projects. So instead of trying to start something where you build a Wi-Fi web server that shows you the temperature and has a display for it, that's three or four components and so many different types of protocols and modules that can fail. It's easier to just start with building a temperature sensor. That's it. Print it to the screen. Copy and paste the demo code. See if it works. Plug in all of the sensors. Check the connections. And that way you won't get frustrated with trying to do everything at once. And in hardware it's harder to debug and see where things break. So really becoming familiar with the sensor, the protocol, and how to wire it is pretty helpful. Then for instance you could go at a heart rate sensor or at a motion sensor. And one thing to be aware of when you're buying sensors is protocols. A lot of sensors will give you an analog protocol, but most sensors these days have a three or four wire interface that has a digital protocol that's much easier to interface with and all of the really finicky analog and electrical engineering type. We have a signal and we want to get that signal to have some meaning. Happens on the sensor, not on your board. So you can just talk to the board and say what's the temperature. And it'll tell you number in Celsius instead of what's the temperature and it'll give you a range of numbers in an analog format. So three of the things that the Mongoose OS provide me that we're going to cover for this temperature sensor project are RPC calls. Raise your hand if you're familiar with what an RPC call is, a remote procedure call. Great. So remote procedure call is just a really fancy way of calling a function that doesn't actually run from where you're calling that function. So you can write a function or write a bit of a program that runs on a server and then call that from a client just like you would call a function on the client. So it's a layer that allows you to communicate between devices in a fairly natural way. And then Sesanta is a web server for microcontrollers. It serves web pages. It serves RPC calls. And it integrates all of this stuff together in a really easy to use format. I'll cover soon. And the last thing is MJS. It's a microJS interpreter for Mongoose. And one of the things that makes MJS different from Esprino is MJS doesn't try to do all of those low-level calculations in driver rights. It delegates very quickly to a C API. So it's going to hit the board with a command that says, get the temperature. And then it'll respond back with Celsius instead of Esprino where it'll send a message to the board saying, give me device 10 on this bus. Give me the device 10 initialization voltages. Give me the device 10 temperature range. Set temperature range. Set temperature. And the problem with that all happening in JavaScript is it has a lot more overhead. And if you can do that in C and have a lot more control of each cycle of your processor, which still matters, even with the faster processors, then it's easier to test that code. So if there's an issue with your JavaScript runtime, it'll come out more frequently if you're using the JavaScript runtime for all the operations instead of using a C runtime. Mongoose, another thing that's great. It's really easy to install. It's just like installing NPM. It runs great on Max Linux. I'm sorry I don't work with Windows. I would tell you it runs great on Windows if I've tried it. And you can just add a Ubuntu repository, and it'll install. Or you can run a Bash script, and it'll just install on your computer. If you're on Linux, no need for any drivers to interface with these boards. If you're on Max, you have to download a driver from the manufacturer. But it's really easy. And it brings you into this interface in Chrome, which is a web browser interface, where it gives you a step-by-step on how to initialize the board. And when I first got these boards, I plugged it in, and I tried to talk to it. And I tried to talk to it at different speeds and protocols, and it just started giving me gibberish. And then I finally figured out, OK, I'm talking to a Python interpreter. And then at one point, it's like, OK, well, what if I don't want the Python interpreter it comes with? And then I had to download another program called ESPTool, which lets you flash it, but it's a command line program. And it's very tedious to set all the parameters correctly and make sure the flash goes correctly. This just does it for you. There's a console down here that tells you all the details, unless it fails, which it sometimes fails, but it's not too often. You can debug it. But it gives you a really nice step-step-step into entering the environment and setting up your board. And you can get to that within five minutes. It also gives you an environment to write code and to save it onto the board. So you write your code here, and then you can save it onto the board, and then it'll run it just right there. So an example of code that you can write in the Mongoose environment is this is a very simple piece of code that will create an RPC handler to turn on or off an LED based off arguments coming in. So here is GPIO set mode. This is very similar to a lot of the other libraries that I mentioned earlier, and I don't think I covered this too well. So what I'm going to do is I'm going to project the board and kind of explain some of the different components. Give me one second. This may or may not work. I'll give it a try here. Thanks, Apple, but no. I didn't think it would be this hard. No, I don't. OK, fine. All right. So this chip right here is the ESP32 processor. It's kind of the guts of this whole thing. Let's see if I can zoom in a bit. Here we go. And it is a processor, and it has all the Wi-Fi architecture in it and all the Bluetooth. And below is Flash. This is the memory that's going to need to store the program you write. So when you write a web page or JavaScript, it's going to get stored into Flash, along with the parts of the JavaScript runtime. And the Mongoose libraries and a lot of the other JavaScript interpreters handle that for you. And then this chip right here is the USB interface chip. So it's going to interface the board to your computer, because the processor doesn't really talk the same language or voltage as your computer talks in. And this will create a USB driver that will give you a really low level communication to the chip that's a standard for a lot of this stuff. Really important buttons, the reset button. In many cases, if a chip's finished, you can just mash it a bunch and it'll go back to the last program. And then here are the battery charging circuits, as mentioned before. One thing to be careful of with these chips is a lot of the pins are numbered, but they're numbered in the way as an engineer would. So the chip has pins that start 9 to 45, 44, 12, 13, 10, 11. It makes sense when you lay out the chip. But when you're actually connecting things and you're like, oh, pin 9, and it's next to 32, you're like, what? So these aren't very developer-friendly boards. And unfortunately, that's what you get for using cutting-edge beta stuff. It'll be better soon. There's already really good documentation to make it better. There's a vendor in the US called SparkFun that has developed a slightly nicer board. And even if they didn't really develop a slightly nicer board, they developed a slightly nicer guy. Now, this is really overwhelming, I understand. But if you want to work with this stuff, you kind of have to learn, get some pieces of it. But the great thing is with these boards, a GPIO means General Purpose IO. And a lot of these pins on the board can do lots of different things. And these libraries will figure them out for you. So you can plug in a sensor as long as the voltage is correct. If it's 3.3 volts, you can plug it in as long as you don't plug in the power backwards. And plug in a pin and just see if it works and move it and see if it works. And the software will say, you can't use pin 34 for a DAC. And it'll just tell you that. And then you can look up the documentation and say, oh, I want to use a DAC. I'll put it on pin 26. So there's really better documentation coming out. But unfortunately, it's still work in progress. It's not completely solved yet. So for this, I'm just going to cover how this temperature sensor hooks up really quickly. If you see here, there are only three pins. It uses an interface called one wire. One wire is what it says. This is data, output. That's going to be the temperature. Positive, that's going to be power for the module. And negative, that's going to be ground for the module. I know this is a lot of electrical engineer stuff. But if you want to get started with this, this is kind of the direction to go. And there's a lot of tutorials out for Arduino on this stuff. So if you look here, I've color-coded the wires. 3.3V, that's going to be our power. 16 is going to be our data. And you'll see where that comes in in a second. And then in this mess of things at the very bottom, there's the ground. So you can connect it directly to the board. And you don't need to make your own power supply since the board has all the power supply circuitry already built in. Let's see here. OK. The one wire protocol, if you're trying to debug a protocol or learn how this stuff works, the best study resources are actually in universities, I've found. A lot of university tutorials and intro labs are better laid out than Wikipedia. And then if you try to look at the manufacturer's website, it's so highly technical, it's something else. So that's a really good way to get started with a lot of this stuff. What I want to do right now is go through the JavaScript side of things. And if you have any particular questions about how to hook it up and the wiring and a lot of the electrical engineering, look up our Gino tutorials. I'll have my contact information at the end. And if there are any specific questions, I'll be glad to answer them. This right here is going to GPIO set mode. So this is what I was talking about earlier, where those pins can do lots of different things. This line of code will actually figure out that pins.led, which is going to resolve to 22 in this case, it's going to tell it that it wants an output pin, a really simple type of pin for the LED. And it's going to set it and figure that out. And if it fails, it'll give you a message, which is really good because a lot of stuff before never really did that and never really gave you the perch for that. rpc.addhandler setled. This is going to listen for a message called setled. And then once it gets set to LED, it'll run this code, which will write to this LED that we've set up here if it's going to be offer on based off an argument to the function. So it's a pretty simple function in JavaScript to turn off around the LED based off of a remote call. Now we're going to get to the code that is running right now on the board for getting the temperature. It's a little more complex, but it really has the same type of structure. So at the very beginning, we're setting the pin to 16. And 16 is actually the number that corresponds to the board. A lot of other development environments and boards don't do this where you have to look up giant tables and figure out the internal versus external ports. Thankfully for this, the boards are labeled in a way that makes sense so you can just use it right in the code. And then here, this type of sensor is a DHT22 model. And DHT is a built-in library that will allow you to interface really easily with the DHT model sensor on the one wire protocol. So all of that protocol spec I showed before, it's all handled on the board hardware level. And then all of the communication like messages descend and different back and forth is handled on the driver level. So it's really great to have all that figured out for you and you can just call it with a really familiar JavaScript API. And there are tons of different modules out there that have been developed for heart rate sensors, LED displays, LCD displays, motion sensors, error quality sensors. And if you can't find one, you can find one and change it a little bit usually. So a lot of that really difficult legwork has been done tons of times and this will just let it be easier for the next time and let more people really access this sort of hardware. So the get temp handler, it's going to call the DHT sensor and the get temp method, the get humidity method. This will return two numbers. If we don't get a number, it's going to just return null to the user. If we do get a number, it'll actually just put it right in the response. So this is actually going to give us a JSON response, the key of temperature, the value of a float that's a temperature, humidity, and then value of h that's a temperature. So when I call this get temp handler, it will return to me either null or numbers for the temperature on the client side. And the way you interface with that is really simple JavaScript and HTML. Let's see if I still have it up here. OK, I don't have it here, but it just calls a post URL and then gets JSON back. It's a fairly simple web API. I'm sorry I messed up the slides. I copied and pasted the wrong chunk of code. OK, I can skip this. All right, one of the cool things about the Mongoose toolkit is it allows you to create configuration for your project. So you can rely on other libraries by including them just like NPM modules. You can put in a schema for your configuration, and it will automatically come up with a different configuration and load in all the modules. And there's even an incredible button, which if you've ever done firmware development before, it's kind of amazing. It sometimes works because it requires an external server. It takes a little while, but it usually is consistent. So you'll write an entire project. And when you click this rebuild app firmware button, they warn you it's slow. What it does is it'll call into Mongoose OS, runs this data center that will compile all of the libraries you want into a firmware. And then you click a button, it'll upload the firmware to the device. And these are the low-level C libraries that I was talking about. You have to build toolkits for. They do all the toolchain stuff for you. So you just include a bunch of dependencies. You build the firmware. You load it on the board. And then you can just start writing JavaScript. So it really, really lowers that barrier of entry, just like React Native does in many ways. So an example is in the Mongoose OS libraries, you can see that there are tons of libraries available. And they're all in GitHub. So let's take a look at one of these libraries. And something that's fairly interesting is it has a source folder. And this source folder includes the C driver code, which is fairly low level. It's not that bad, but it's pretty low level. It has to deal with timing delays and protocol level stuff. And then there's another file in here, which is what the magic of MJS is. And this is a JavaScript bridge. So this is the JavaScript portion of the API. And one of the really cool things about Mongoose is it does a really seamless transition between writing that C driver code and then writing that JavaScript driver code, which is pretty cool to see low level driver code, JavaScript code next to each other, a nice web UI, and it just works. And one of the really cool things you can do here, let me just plug in the device. So I'm going to hook up the device right now, actually, and go through the connection. So right here, device setup. You can see the first part's done. It found that I plugged in the board. I just plugged it into the USB port. And then it's going to try, let's see if it has access to the internet. It's going to try to load the code on that board right now. So if we go here, it's going to load the files from the board. OK. Nope. I'm going to restart server. Don't worry. I'm not going to spend too much time as it doesn't work. All right. So I'm going to go here. Yeah. So it worked this time. So it discovered that I've already loaded the demo JS project. That's the firmware for the ESP32, which is the board. And if you just install the software, you can get to this point. Installing software, plugging in the board over USB. It's quite easy. And then this last step I'm not going to do because I don't want to connect to the Wi-Fi network here. I want to make a Wi-Fi network. So I'm going to click done. I'm done with a little setup wizard. And then you can look here at the device configuration. And this is where all of the files running on the board will let you set up different servers. And this is the beauty of the Mongoose OS, is it will let me set up a web server. And all I have to do to set up a web server is in the Wi-Fi section, I enable an access point. Access point, enable true. You set the SSID, the password, and all of those things. And it will just create a wireless network for you. And it'll serve up HTML files that will then be able to call RPCs. So does this look kind of familiar in terms of you create a network, you load an HTML file, and then you call a JSON URL? Raise your hand if that seems pretty doable. OK. Let's step back a bit. Create a web page to call a JSON URL to return data. Does that kind of sound more in the scheme of things for JavaScript land? OK. So this is that interesting bridge where you can run an embeddable web server and you write JSON configuration. And this stuff here is actually the defaults. This file is my override. So these are the only things I had to change from that giant configuration. So this is a Wi-Fi connection from a host that shouldn't be there. And this is the access point. So the SSID is temperature and the password is how hot is it? And it'll use the 16 pin to connect to the temperature sensor. So if I hop on. Yes. OK. Yeah. Close this out. Yeah. So that's all I have. Go forth and create. I know that was a lot. What's the URL for the JSON thing? So the URL is if you go to 192.168.4.1 on that Wi-Fi network. I think I'm on the wrong network. Does it work? I think the wire got loose. So that's an error because I didn't handle the edge case of it not connecting to the temperature sensor. So it was able to serve the web page and it was able to ask for the temperature. But I never wrote the error case for if the temperature sensor didn't return temperature. Yeah. You connected this thing right here. So if you connect to the temp Wi-Fi network, we'll see how long this lasts before it crashes. Yeah. Any questions? How's it doing the web server? So the web server, this is actually the configuration for the device. I think it's connected. Yeah. It's connected. So right here it's getting an HTTP URL. It's not Node.js. It's all custom high-performance low-level C code. But it's easily configurable. So yeah. You guys are hitting get temperature. You're running into an error state. And hey, you're loading a web page from a $6 chip powered over USB talking to my computer. So yeah. Any questions? So you say that it's a better way. So technically, I can actually look like a customized web page on there. Yes. There are limitations. You have four megabytes for everything. So no images. No crazy JavaScript frameworks, guys. Like this is very low level. Yes. Why use JavaScript? OK. Because C is pretty finicky. One of the nice things about JavaScript is with a temperature sensor demo, I could just put a call back there. And all of this stuff eventually hits C. It's very similar to when I'm conceptualizing something. I have this high-level code. I can write out that high-level code in JavaScript. And these processors can handle JavaScript. They're already running a real-time operating system. And JavaScript's really just coordinating all of the C low-level code. So it lets you think more about the thing you're assembling instead of all the little bits and pieces. It's like when you use a JavaScript framework that just gets a URL from a server, which of all the particular getPost URL headers and cookies, all that's really managed for you. And that's the idea here, where you can write 20 lines of JavaScript, maybe a C module, or just grab C modules from other people, and get up and running in an hour instead of eight hours. Or in many cases, when I've written custom C, I have copied the wrong timing constraint from another file. And just somebody's trying to DDOS this. What are you guys doing? Oh, yeah, the RP. There's no security on this. You guys can log in and change the password and the network. And I think you can actually load JavaScript on this. Extra points to anybody that does that. But I mean, if you guys break into this and try to take over the world, just unplug it. Yes. What about callbacks? Sorry. Yeah. You can use most ES5 features. What you can't use are any features. So most all language features for ES5 are supported. But what you can't do is you can't use Canvas. You can't use, like, Ajax Request. You have no access to any libraries that a browser would give you. It's very similar to Node.js, where you have to require things to do most everything. So you have to require all the libraries you need to do most everything. I don't think generators and yields are implemented, but a lot of features are there. It's not that hard to write a pretty decent JavaScript interpreter. The hard part is how do you make a interpreter connect to that hardware and work with the board? Yeah. Yes. What does it basically look like? There's a jealous case in this byte code in Java. JavaScript is not actually becoming byte code. When I was editing that file right there, if I click Save, it would actually send the JavaScript as is to the board. And the board is running in Live Interpreter that will go through the code, parse it, and run it all in real time. So there's no compilation, no byte code, no translation. It's just running that exact file on the board. So when I go to this view here, the device files, it is what it says it is. These are the files on the board. Oh, here's my horrible HTML if anyone's interested. So now we could see the full error, and then maybe you could add a sad face to it. And then if I click Save and Reboot, it'll put it onto the board, reboot it. This is the board rebooting. It is an operating system, so it prints a lot of stuff. And yeah, so that file I just changed got uploaded to the board as is. It's not compiled or packaged or changed. What's the get temp supposed to return? Get temp is supposed to return an object with the temperature in Celsius and the humidity that looks just like this. So it's supposed to return JSON. It worked earlier. The wiring quality is not high. So I think the connection is loose or something. Well, what I could do is this. I think that's valid. Yeah, it looks like it lost connection with the device. OK, now it's back up, reconnected. Any other questions while we're monkeying around with this thing? Can you do what? No, you can't run a Node.js server. So the server you guys are seeing and connecting to is a C low-level high-performance server. In some ways, Node.js acts as an interpreter, and MJS is an interpreter. It's just a different interpreter, but I don't think you could run full Node.js. There's really no reason to, because it's designed for a different environment. So Node.js, in this particular case, is MJS. Yeah? So MJS actually means it's part of the firmware. It's not something that you load in after the fact. Right, so MJS is a part of the firmware. It's an interpreter written in C. So the firmware is going to be an interpreter of all of the C-level libraries. And then the HTML and JavaScript and stuff, that gets loaded on after the fact, on to the memory in Flash. Is there a timeout? Yeah. So there's an error state, and if it hits a timeout, it'll call the error state of that callback. I just didn't implement any error states for the sake of clarity and laziness. And please don't ask me how to test this. I have no idea. Any other questions? Cool. Any more questions?