 So I'm going to be talking, my name is Greg, I'm going to be talking about Ruby Arduino Development, physical computing for everyone. So this talk is about, as you can see from the stuff up here, electronics, and as, you know, since you guys, most of you probably haven't done that much stuff with electronics before, I'm required by law to give you a condescending safety introduction. So electrical engineering is for experts. This isn't just programming, this is serious engineering. So like look at this guy, this is Lita Forrest, he invented the vacuum tube. He's got a bow tie, okay? He's bald, he's in black and white, he's in front of a chalkboard. This is serious stuff. You're not as smart as him. I don't see anyone here wearing a bow tie. This is for professionals only. No hard hats in the room, I don't see. You got to be really careful. This guy's in bright yellow. That's a lot of volt. This stuff is dangerous. If you ask an electrical engineer about a regular person or a programmer, that's you. That's how they see you. Your whole job is just plug it in, no questions. So thankfully, we're not going to be doing electrical engineering. We're doing physical computing. Physical computing is for everyone. For example, artists can do it. This is a pair of artists from New York, Jennifer and Kevin McCoy. They make these amazing animations by setting up these models that reproduce old movies and different things and then surrounding them with these lipstick cameras. And then they use microcontroller, which is what I'm going to be showing you today, to edit between the cameras on the live video feed to create the illusion of a movie. It's for idealists. This is an MIT fab lab in India where MIT sends students and professors to build these labs where they teach inventors all over the world to build anything they can think of using microcontrollers and computer-aided design and manufacturing. And it's for crazy hackers on the internet like this guy who built a cockroach-driven robot. So that's a live cockroach on top of that ping-pong ball there. And as the cockroach tries to run, it spins the ball, and the robot senses how the ball's spinning and moves around. So it's basically a cockroach amplifier. So physical computing is programming for stuff. Instead of programming data and files and the internet, boring stuff like that, it's programming for actual stuff. But it is programming. You read inputs instead of from data. You read it from your surroundings, and you modify your surroundings based on logic. So you sense the physical world, and then you use actuators and motors and electricity to modify the physical world based on the logic that you want to do. So in order to do computing, we need a computer, and we need one that can actually run things that can change the world. And I'm not talking in a fuzzy, headed way, physically change the world. And so that's a microcontroller is the word for that. A microcontroller has got logic, and then it's got the ability to translate that logic into electrical inputs and outputs. Brian Goodlad gave a talk yesterday about Ruby for embedded applications, and he had an ARM microcontroller he talked about in that talk. And I'm going to be talking about the Arduino, which is an open source hardware and software design that uses an AVR microcontroller. So for anybody who was in that talk, the board that he showed has 64 meg of RAM, and he ran Linux on it, this has 64k, so we don't run Linux. But it's got an AVR microcontroller, that's the chip there. It's got 14 digital IO pins. So those are pins that you can turn on and off, send 5 volts of electricity on or off from them based on the logic running on your microcontroller, and you can read in whether or not there's 5 volts coming into it from whatever you've got plugged in. There's 6 analog IO pins, so those can do not just high, low, 5 volts, yes, no. They can do a variety of levels, and they can read in things that vary in that way. You can power it via 9 volts. You can program it and also power it via the USB in order to talk to your big computer. And it's an open source hardware design, so lots of people make them, lots of people sell them. You can get them on the Maker Shed for 30 bucks. There's open source kits you can get that run as low as 5 or 6 bucks if you know how to solder or can buy a beer for someone who knows how to solder. This is what the software looks like for it. It's also an open source software library. This is actually most of the library here, and it's got library functions that correspond to those physical parts of the chip. You've got analog IO, digital IO, advanced IO, serial communication. You don't really need to worry about the details here, so I've put it up small. The point is that most of this is for sensing and controlling the physical world. That's what most of the software is about. So here's what Hello World looks like in Arduino's DSL there. Hello World in physical computing is blink and LED on and off. In all physical computing platform and work, that's Hello World. So here's Arduino's DSL. It's C++. It's not too bad. We declare an int LED13, which that's going to be the pin that we've got our LED plugged into. Then there's a setup function that runs once when our chip first starts up, and then we've got a loop which is going to run over and over again. In that setup, we do pin mode to configure the LED as an output pin, and then in our loop, we digital write that pin high. So turn it on, send 5 volts out through the pin, delay 500 milliseconds, write low, turn it off, delay another 500 milliseconds, wash or repeat. That's a blinking LED. And that's not too bad, but this is RubyConf and we're Ruby programmer, so we're going to immediately see problems here. You've got configuration that runs in this functional linear way, and you've got repetition. So you're doing digital write, delay, digital write, delay, digital write, delay. So when I started learning Arduino and writing C++, I was already a Ruby programmer, so the first thing that came into my head was what this should look like. This should look like this. Should look like a reprogram. It should have instead of all that configuration, it should be declarative. Output pin 13 as LED, and it should be object oriented. Declaring a pin like that should give us an object that we can call methods on. So instead of digital write on, digital write off, we'd say LED blink yourself with a 500 millisecond period there. So that's what started me down the road of wanting that to work in Ruby. So after some amount of work, we've got, this is running code in RAD, Ruby Arduino Development, which is what I'm going to be showing you for the rest of the talk here. So the first thing I'm going to do, oh yeah, so we've probably seen some live coding demos over the last day or so, but probably not any live hardware demos. So one big difference between live coding demos and live hardware demos is in live coding demos you're allowed to just sit quietly with your arms folded when they're done and appreciate whether it worked. But in live hardware demos, you're required to go, ooh, when it's over, to express your appreciation. So I want to salt a practice that once before we get into the demos here. So all together now. Ooh. Yeah, these guys have got the spirit of it here, so. Okay, so I'm going to show you the first demo here, which is just Hello World. I'm going to just blink the LED. So I've got a little view of a camera set up here so you can see my Arduino here. And Arduino actually even comes with a built-in LED. It's not blinking yet because I haven't written the code, but it comes with a built-in LED that is wired to pin 13 on it. And I mean, that's one of the great things about that is you buy your Arduino, you buy a serial cable, you use a USB device cable that you've already got, and you can do Hello World with nothing else. So I'm going to show you how this works in RAD. So RAD is, as you probably guessed from looking at that code, very inspired by Rails. So the first thing we do is we run the RAD command to generate a project, Hello World. And that's going to generate a directory for us with a bunch of files. It lets us know that we need a certain version of the Arduino library. It can actually install it for you if you haven't got it, but I do. So I'm going to move into that directory that I just made, open it up in TextMate here, and it installed a bunch of code that we need into that directory. And it also made this default sketch for us here. Can you guys all see that? And so it just has a loop method, which is the thing that's going to run over and over again that we have to have. And besides that, it's an empty subclass of Arduino sketch, which is how you get RAD's power to program your Arduino. So I'm just going to write that code we just saw, output pin 13 as LED, LED, Blink 500. So now that's written, I'm going to use now rake command, rake, make, upload. And that's going to compile my code down, and there it goes. It uploaded to the Arduino. And so now, if I go back over to the here, you'll see in just a second, you'll see the light come on and start blinking. The chip has to restart after it's been reprogrammed, but there it is. That's blinking LED. That's Hello World with Ruby. Very good. You guys don't even need my next slide here, which is, ooh. So how does that work? Hello World, it's very simple electrically. All it is, is all we're doing is sending five volts of electricity. Thank you. All we're doing is we're sending five volts out to our LED. In this case, it's on the chip. And then the LED is connected to ground on the chip as well to complete the circuit. So that when the pin is low, when it's not on, the LED is dark. And when it lights up, when we send five volts, the LED lights up. So let's talk a little bit how rad makes that happen for you. So at the top here, we've got your sketch. They call it a sketch because remember, this is just physical computing. We're not really serious. We're not electrical engineers. We're just sketching. We're not actually engineering. And then at the bottom is the Arduino hardware. But some stuff happened in between. And I'll show you what it is. It's just frightening black magic. Like any good framework, just magic. You don't need to know what's happening. But actually, I'm going to spend the rest of the talk here eliminating that black magic, explaining to you all of, as clearly as I can, all of what happens in the framework, how the framework gets from your Ruby class all the way to code running on the Arduino hardware. And the first couple of things we've already seen. So we saw that class methods for the declarative setup of the pin just right there. So that class method in Arduino sketch, the parent class, that's just doing string manipulation. You're just getting, it's keeping track of what you're telling it. And it is going to eventually write that set up method for you. And then for the loop method and for any other additional methods you might write, they get handed off to Ruby2C, which is a great gem written by Ryan Davis and Eric Hodel. It's great. It's terrible. It's great for my purposes. And it just takes your methods and turns them into C. So the loop method there is just going to get turned utterly naively in a terrible way into C. And hopefully, if we munge it enough and stick it in the right place, it'll work. So in order to dig more into the rest of this fighting black magic, I'm going to show you another, oh, right, there's another step I did. I showed you, which is the rake tasks. So after the class methods and the Ruby2C run, we're going to end up with C++. And that is then after passing through some more black magic, the rake tasks manage bringing it onto the Arduino for us, actually uploading it. So in order to clear up the rest of that black magic, I need to run a few more demos for you here. So the first one of those is Hello Drum. So Matt, we come up real quick and just handle the camera for me. So I've got a snare drum here that is, excuse me. So I've got a snare drum here that's got two chopsticks that are going to play it. And those chopsticks are epoxied to these tiny little servos. And the servos are plugged into my Arduino. And the Arduino is going to control those servos in order to move the chopsticks based on messages that I'm sending it over the USB serial connection from the computer. So first thing, I'll show you the code when we get back to the presentation. But first thing I'm going to just do is upload it to the hardware. So you'll see lights flickering there. That's the Arduino saying that it's receiving data. And then so in order to be able to send the serial messages from my computer over to the Arduino, I'm going to connect to it with screen. I don't know if you can read at the bottom there. I'm using screen. And then I'm just giving screen the dev TTY USB serial, which is my serial over my USB. And I need to give it 9,600, which is the rate here. And then so it's going to take a minute now that I connect to serial for the Arduino to start back up there. In my code, you'll see the light 13 will come on. OK, so that means it's listening. And so L and R. There we go. Yeah. Thank you, Matt. So that's hella drum. So again, we did very good. So how does this work? I described it a little while I was going through it. But the first steps are to get from your input to serial. So you type into screen, which communicates with your USB device as serial. And that sends over the serial the same USB serial connection that we used to program the Arduino. It's sending those characters one at a time to the Arduino. And then how does the Arduino move the servo? The Arduino moves the servo with something called a pulse width modulation position command. So the Arduino is going to tell the servo what angle to be at, which is a particular value. But the way it does it is with something called pulse width modulation, which means it uses one of the digital pins, but it turns it on and off really fast. That's basically all that pulse width modulation is just a fancy way of saying turn on and off really fast. So over a given period to give a particular value, you turn on and off that percentage of the period. So let's say your period was a second and you wanted to do 70, you'd be on 70% of the time and off 30% of the time. That's a simplification. But that's the idea of how pulse width modulation works. So here's the code. The first thing to notice here is we're doing output pin 7 and 11 as left and right. And we're setting an additional option that we saw in the Hello World example, which is device servo. So that's an example of a RAD plugin. So RAD has a plugin architecture which lets us wrap a lot of the existing C++ libraries and our own for new hardware in order to give them a good API for talking to devices like servos. So in this particular example, so here's another detail from the code here. The first thing, so we do val equals serial read. So that reads in the value from the serial connection. So that's from the computer to the Arduino. So if we type R, then we tell our servo right position is 90. So the plugin provides a method that turns that angle of 90 degrees that we want to move it to into the right on-off commands to do the pulse width modulation. And it's abstracting a C++ API that abstracts the hardware. So in the built-in Arduino, the commonly used servo libraries, it's not 0 to 180 like you want for degrees of motion. It's 254 to 24 something. And you have to tune it for your individual servo. And it's difficult. So we abstract all of that, and we just give it this really natural API of a position. So there's one additional note here that I want to point out about the serial read and the comparison, which is kind of a quirk, arguably a bug in RAD. So serial read returns an ASCII value. And in C or C++, a single quoted string is going to give you the ASCII value for that string. But in Ruby, single quoted string, double quoted string is the same. So we actually extend Ruby to C, in our specific case, to pass the single quotes straight through. So that's kind of an, I think, I'm not totally satisfied with that as an API choice. But because that is a somewhat surprising thing, as a Ruby, a single quoted string and double quoted string shouldn't make a difference to you. But that aspect of C is really natural for doing things like this, for comparing with those values coming across serial read. So that may stay, it may go. But I just wanted to point it out because we're doing Ruby here, we're higher level, we don't want to worry about too much of the guts of the C, C++. But it's important to be aware of what's underneath you and how these things are working in the trade-offs and what's actually going on. For me, Ruby Arduino is, in addition to letting me write Arduino programs easier and more effectively with Ruby, it also is a way to learn about this stuff. It's something to start from a place I know and move into something I know less about so I can learn more. So that's just a little bit of overview of what I was just saying, so in order we do, Ruby to C has a series of stages it goes through and is eventually going to produce that C++ output. So it is eventually going to be C++. And so things like that single quoted string become a factor. So then a little bit more detail here on how the rake task, we were seeing that serial communication. So the rake tasks that just rake make upload, all in one, is doing actually a number of things there. So once we've had C++ output, the rake tasks are going to invoke AVRGCC, which is GCC specifically for the AVR microcontroller, which is going to compile down to hex and then it's going to use AVRDude, which is just another client to actually program the Arduino over the serial connection. And we do have another rake task for just rake make compile and just rake make upload individually if you want to see the intermediate stages there. But rake, because of the dependencies of rake, we get the great advantage of you hit rake make upload, if your sketch hasn't been compiled, it's compiled and then uploaded. So my third example here is hello heat. And there's going to be another use of the servo, but with a slightly more sophisticated sensor. And I've got to do a little bit of moving around of things real quick. So what we're going to do is we're going to read the temperature using a digital thermometer. And then we're going to output it on the servo in the position of this giant red arrow here. So I've got this other, I'm just using a separate Arduino board here that I've pre-programmed with this code. So where's the thermometer? So you see if I go, if I cool it down by blowing on it, there's a broken tooth in my servo, so it gets flaccid sometimes. But then if I blow on it with hot breath, it'll slowly move up as I'm able to heat it up. You guys have got it now. Ooh, just did? OK. So how does this one work? So the first thing we're doing is we're reading value from the temperature sensor here. So you might think that a temperature is actually going to be an analog value, but in this case, this digital thermometer that I'm using here is a one wire device. So one wire is just a protocol for digital devices to send data to microcontrollers and to other digital devices. It's a bus that they can communicate on. So one wire actually sends the temperature reading as a series of bits in this protocol to our digital pin that we listen on. So even though we're getting a value which is of a two decimal plates, accurate temperature reading from the thermometer, we're getting it as a digital value. And then once we've got that digital value, we convert it to the angle for the servo using similar logic to what we saw in the drum example. So again, there's a lot of code here. I'm not going to walk through all of it, but I just want to zoom in on the loop method here because I think it demonstrates some of the beauty that you get from doing this stuff in Ruby as opposed to C++. So you can read this, and it's a recipe for how this works. So we refresh the servo to make sure we're still in communication with it. We do a temperature conversion, which is just a method that does that conversion from the bytes coming over in the one wire to the value that we need to position the servo, then we toggle the LED, blink an LED so that we know that we're working. And there's almost no physical computing project that can't be made better by the addition of more blinking LEDs. So that's a good design principle to keep in mind when you're doing this stuff. And then we actually read the temperature data. We print the temperature out to the serial, which is a debugging thing that didn't actually show you there. And then the last thing we do is we adjust the dial. So I'm not going to go through all this code. You can look at it in my slides or talk to me about it later if you are curious about the details of one wire or anything like that. There's just a few nice things about using RAD and programming the stuff in Ruby that I wanted to point out here. So one thing is hex literals. This is something that I didn't know about Ruby. But if you open up IRB and you type in 0xbe, you'll get an integer. It's a hex encoding of a number. So my temp there is just, again, that's an object that's created using the one wire plug-in. So that's the thermometer. And part of our communication with it, we need to send it a series of bytes in order to do command stuff to it to tell it to send us its data to talk to it. And so we get to do it really naturally with this hex literal there. And the one is just the address. It's an address on the bus. Another thing is bit manipulation. So in C, there's funky operators for doing bit manipulation that if you know C, you'll be very comfortable with. But if, like me, Ruby is of your primary language, then that stuff can be just strange to learn. Ruby doesn't have those because Ruby doesn't access things that way. So we've got some helpers that do that. So build int takes a high byte and a low byte and turns it into an int. We have bitwise and is going to do a mask with that byte there, the two's complement of a particular value. Again, it's details of what we need to do to communicate over the one wire protocol. But it's just nice to have these helpers that do these bitwise operations. And kind of a fun thing to be doing in Ruby, where you're normally not pushing things around at that level. So can we get rid of some more frightening black magic here? I think we can. So one step we need to do is assembly. So we saw how our class methods use string manipulation to fill out our setup method and how we used Ruby to C to translate the loop and helpers into strings. And then all that happens is those come together. We post-process the ugly output from Ruby to C to clean it up and fix some things. And then we jam it into this file, your sketch.cpp. And then that stuff gets compiled against the Arduino C++ library, which is what makes things like digital write, digital read, the serial stuff. They're really nice DSL work for us. And then, like we said, AVRGCC, AVRDude, the hardware. So that's the whole stack from top to bottom, looking like a nice pretty little cupcake there. And there's no more black magic. That's all the steps. And it's a little touchy, like it's complicated. There's some steps, but it's really not that bad. And it's less metaprogramming and less complicated than some other frameworks. So there's no more black magic. And so that means we get to have a little reward. So we've got one demo left here. And I'm going to bring up Matt Williams, who is a local Orlando Rubyist, who built this demo using Rad. And he's going to run it for you here. So what we're going to do is we're going to, Matt's written, he's programmed his Arduino using Rad to accept serial descriptions of drinks. And he's written a Ruby DSL to describe recipes for drinks, which I can show you anybody afterwards if they're curious. But he's just going to say things like one ounce. Yeah, here, go for it. So he's just saying things like one ounce, two ounces orange juice, one ounce vodka is a recipe for a screwdriver, which is what we're going to be making. And then that tells his Arduino to turn these relays, which I'm trying to reach out here. Or I can't reach it to see. So a relay is just a way of using a small amount of electricity, the five volts of DC that the Arduino uses for logic to control larger amounts. So he's using the relays to control car windshield washer pumps, which is what these are right here, that are in this bottle of vodka and this container of orange juice. And then so the Arduino turns those pumps on and off in order to complete his recipe. So you want me to grab the camera there, Matt? So you can get it running. So there you go. That's the vodka. Seems like a lot of vodka, Matt. Vodka or orange juice. There you go. So that's a screwdriver. So ooh. But when we're doing drinks instead of saying ooh, we say ah. And you're all welcome to come up and get yourself a drink at the end here. So just before we do that and before we start, Matt's going to start dispensing screwdrivers here. But I just want to summarize quickly. Physical computing is for everyone. Unlike screwdrivers, physical computing is for everyone. And you guys can do this. Even if you had no electronic experience, two years ago when I first started playing with Arduino, I had taken high school physics and I hadn't soldered since then. And I didn't know any electronics. And so if I can do it, you guys can definitely do it. So cheers. Be sure to come up and get a drink. And here's the info about where to get the gem. It's on GitHub. Anybody who has more experience with electronics or Ruby to see than I do, patches are more than welcome. And I just wanted to quickly thank JD Barnhart and Brian Riley. JD is here. He's part of Seattle RB Group speaking tomorrow. And he's responsible for 2 thirds of the code and the functionality of RAD. And Brian Riley is our great benefactor out in Vermont. Wolfden.org, his site, is a great place to get cheaper kits. It's called a really bare bones Arduino for soldering together your own Arduino hardware. And thanks a lot. Cheers. Enjoy the drinks. And I can answer any questions if people have them. Here in the front. He's asking if instead of as a replacement for the single quoted string for the ASCII literal, if I've thought about using the question mark operator of Ruby's to turn characters into their ASCII equivalent. And I thought of it because after we complained about that problem and Mitt fixed it the way I showed you guys on the mailing list, somebody else said exactly that. And that's totally the right solution. And I think that we're going to try to move to that if Ruby to C is hip to that, which people in this room could probably answer. Over here. Over towards you, because the candor was the sound of the drinks. Well, the one wire through the hole, you have to be careful about it. I mean, it's not like the problem through the hole, so you should not be talking about it. I'm sorry. If I get a different thermometer, can I still use your FBI or do I have to customize it to use maybe, I mean, our devices to think of one wire. So one more thing to say. Sorry, Heather. Any thermometer? Or is there something there? He's asking about how tied my code in that in the thermometer example is to the actual digital thermometer that I'm using. And one wire is a very common protocol for one wire and I squared C are the most common protocols for really simple bus based device communication like that. I'm not sure if other digital thermometers like that will use exactly the same communication over one wire. So in the parts of the code, I didn't really show you what I'm doing is reading the bits it's sending me and translating that into a high byte and low byte so I can make an integer out of it. And other thermometers might order those bits differently, but you could use our same one wire plug-in to get access to that, read out your bits and figure out what you need to do with it. Anyone else? Right here? The question is, AVRGCC is eventually going to take that C++ that gets output from RAD and compile it into Hex in order to have AVR to send it over to the Arduino. And is there any way we could just directly generate that Hex from Ruby? And that would involve writing a Ruby to Hex compiler. And I wasn't even willing to write a Ruby to C++ compiler. So I'm just mostly standing on the shoulders of Seattleites in order to do the hard work of generating the C++. So I honestly don't even know if that's possible. Evan over there and others who are more experienced of trying to write Ruby interpreters and compilers are more likely to be able to answer that question than I am. Yes? We're going to see and I think it's insane that it's probably just using it. And I think it's even more insane to consider writing something that goes to even lower the language. Can I mention it? So yeah, one thing I didn't talk about is that it's places to get hardware. I think it's actually quite a bunch of hard ones. SparkFun.com, SparkFun.com is a great place. Another place to look for hardware is something called the Beambot community, which Beambots are just really super simple, all solid state robots that do simple things. But there's a site called solarbotics.net that sells really good hardware, cheap. Radio Shack, which is terrible and overpriced and staffed by fools, but in a pinch it will do. There's probably one near you and it's probably open. Anyone else? So the question is, is the OneWire plug-in something that I wrote, or is it something that Arduino does for me? So in rad, plug-ins are a way of bridging between C++ code and Ruby. So it's a way of having some C++ code in a particular format somewhere that then rad can take in and use in its Ruby APIs. So the C++ code, in order to do the OneWire communication, like JD can probably answer that better than I can of where it came from, but. So OneWire is already in there. How do we know it just came out with a new board? Is that right? Do we have a new Nova? Yeah, that's right. So if you guys couldn't hear that, JD just said the OneWire is part of Arduino's library of plug-ins that they have. We, with that and both the servo JD, took those and in addition to integrating them into our plug-in system, improved them and submitted that code back to them. And so that's the answer to your question. Yes, it was talking about the wired article about Arduino which was very cool and featured some of the core Arduino guys. Are there any other questions? Right here. So the question is, he's wondering about other things that you can plug into your Arduino like GPS. That's the classic question. Everyone, as soon as you start doing this, if you wanna be able to plug everything into it. So GPS, you probably would use an intermediate board. There's oftentimes helper boards that will take directly from your GPS chip and translate that into a small number of pins or do some math on it to get it. Yeah, as Ben says, there are four super awesome GPS shields, all of them on SparkFun. Yeah, so Ben's saying that you can buy, for about 150 bucks, you can buy a shield which is the name for that thing, the board that helps get you from GPS chips output to something that Arduino can use. And for 150 bucks, you can buy one of those. It's got a GPS on it and that will plug into your Arduino. And we don't have a GPS plug-in right now but there's definitely Arduino GPS code out there and it's really quite easy to turn that code into a rad plug-in. Specifically what we tried to do is our plug-ins are really thin layer around the C++. So if you can find GPS or Arduino code on the internet to copy and paste, you can make a rad plug-in out of it. So the GitHub, more than welcome, if you end up trying that project to please talk to me, talk to Ben, he'll definitely be able to help you out there. There are also one wire GPS radios available. So let's speak that protocol, yeah. Are there any other questions? It's probably time to wrap up. So thank you, I'll answer your question afterwards. So thank you, everyone, and come up, be sure to come up and get a drink.