 going to enjoy this talk a whole lot more. So I grew up doing a lot of web development and hardly any other development, but hardware was kind of always my hobby. But the big thing is that hardware is hard. It sucks. It's so hard that I couldn't even find a good picture for this slide because there was no picture that I could find out on the web that explained how hard it is to develop hardware. It feels like everything's against you all the time. So you come up with a cool idea. Like at one point in time I was going to build a heads-up display for my car. Who does not want a heads-up display on their car? Yeah, that's what I see no hands. So I got really excited. I had this idea and I'm like, I need to find all the parts. So I figure out what parts I need, some LED strips, just lay up on the dash and shine up on the window, and some controllers and things that hook into the car to tell how fast the car is going. And then I go to order them. And I'm super excited. And the thing that hooks into the car is out of stock. So, well, that's all right. That's all right. I'm still going to be excited. It'll probably be in stock tomorrow. I'll just sign up for that little email that says, we'll email you when it comes in. So the other thing is that a lot of times when you're doing hardware is money. So a lot of parts of hardware, whether you're doing it professionally or doing it as a hobby, are fairly cheap. But some of them get quite expensive or hard to find, like it's called an ODB connector that connects to your car. And so you sit and you wait and you wait and you wait some more and you wait. And you really do feel like this thing must be coming from Mars, the stuff that you order. Because sometimes it's coming from China and it has to go through customs. So you're super excited. And then eight weeks later, you get this email that says that it's touched the US border. And you're like, yes, four more days. And that's if you haven't decided to move on. Because if you're like me, waiting draws your attention away. We move on. I was excited about making a heads up display for my car. I still do not have an ODB connector to this day. That was like two years ago. So I got excited. I've ordered half of the parts. They're like sitting around my house or in my office. And the other half I've still never ordered. I've done like five projects since then. And it never gets better. You start to feel like maybe my idea was wrong. Maybe I wasn't that excited. Maybe it doesn't matter anymore. But either way, your excitement subsides. The butterflies come in. You find something else to look at. And you never get to that code. You've never even written a code for it. And then when that happens too much, I actually showed some of these slides. This is often how my wife looks at me whenever I say that I've got this great hardware idea I'm going to build. And somebody was like, you shouldn't badmouth your wife. And I'm not. My wife is an amazing person. She's the voice of reason and the reason why we can still afford a house instead of like just a big garage full of hardware that I'm never going to do anything with. So hopefully if you get into hardware, you have somebody who can be your voice of reason. It's super important to have that. Oh, I went backwards. And the next thing is deployment. So deployment was working against you too. So you get all excited. You've actually finally get some parts. And you write a bunch of code. And then you compile it and sometimes cross compiling. And it takes a while. I'm currently working in commercial doing embedded development in Elixir. And we have a project that takes like 10 minutes to compile. So you compile it all and it gets on an SD card and then you plug it in somewhere else or you have to SSH it over the files and restart your system. And so like 15 minutes later, you get all this together and you get it over on the system. And you accidentally return to OK as your state for your gen server instead of the struct that you were supposed to return. And so then you take out the SD card, plug it back into your computer. And you go through this whole process again and again and again. And it starts to get frustrating. The butterfly set in. You'd rather go outside. You'd rather build a heads up display for your car. I don't know. But it's tedious to find these errors. And then part of the errors coming in is our knowledge. So when you start working on hardware development, there are numerous ways that all the little sensors talk to each other. You have to learn a protocol. You have to read giant reams of documentation. This is for one tiny sensor that usually hooks to a system that you have multiple sensors. It's 27 pages long. I know that you probably can't see this very much. But don't worry, you wouldn't get much more out of it even if you were right next to it. So I don't even know what those graphs mean. And some of them are so cryptic that you don't even know what they're saying. But you still need to read them. And after a while, you get used to reading them. The other thing is I found is that our community is very inviting. And everybody's really nice in this community. But the people that are working in the hardware, if you go into the NERVS channel on Slack, they are the nicest people. Because they all know that you just got done trying to deploy on an SD card for the last 15 minutes. And it was your fourth time today because you had a bug. And then you realized that you don't understand I2C communication protocol. And you're about to rip your hair out. And you ask them a question, and they're like, oh, there'll be like five or six people. We have Connor Rigby up there from the NERVS core team. And I don't know how many times Connor has helped me. The other day I had a problem. It was just that the file that I had to get accidentally had .config.txt. And it wasn't supposed to have .txt when I downloaded it. So he spent way more of his time than he should have to help me out. That's true. I guess that's because everybody else in the hardware room is it needs butterflies too. So I just pulled you away from the real job. The other thing with hardware is you have to interact with the real world, right? So you have a sensor that's supposed to sense, I don't know, maybe lightning, right? So you have to wait for this real world event before you can test your software. That sucks. See, so Paul Lam, I think Paul's talking tomorrow. I don't know if he's here. He wasn't feeling too well. But Paul says you should start every great talk with a story. So all that other stuff I said, just ignore it. This is the beginning of my talk right here. Well, I guess I'll tell you who I am. It's me, Amos King. Everybody says that I look like 1010. So that's been my handle forever. Adcrons where you find me everywhere. I'm a binary noggin. I run an open source NERVS project called Grove Pi. Well, it's sports NERVS. You don't have to use NERVS. And then I have been in a host of a podcast called This Agile Life for about five years. But anyway, so does anybody know who this person is? All right. Anybody who doesn't know who this person is? Let me help you. Does anybody know who this person is? Oh, good. So Frank Hunliffe is the inventor of NERVS. NERVS is, for anybody who doesn't know, is a system of tools to build elixir run embedded devices. It handles everything from the Linux kernels that you have to deploy, all kinds of stuff. It's a whole set of tools, a whole community built around it. And a lot of people say like Jose is the nicest guy in the elixir community. No, I like Jose. Jose is a great guy. But Frank, Frank is amazing. So I met Frank last year at Elixir Days. I'm from a little town in central Missouri. It's about 4,000 people, about 100 miles outside of St. Louis. And I sit down at this table at Elixir Days and I start talking around and every single person at that table is from Missouri really close to St. Louis, including Frank, who now lives in like Maryland or DC or something. I don't remember exactly. And we started talking. Frank's a pretty quiet guy. But I got a little bit out of him about who he was and what he does. And then when I was on my way out, he's at the airport. And I like to talk a lot. And I see Frank sitting over by himself. And I'm like, Frank likes to listen. He doesn't talk much at all. So I run over and I'm like, hey, Frank, how's it going? And I'm into hardware. So I start talking to him about hardware and asking him questions and trying to draw Frank out. And Frank tells me about this project called GrovePie. And the GrovePie is a hat is what they call on the hook on top of a raspberry pie. And it has a bunch of sensors and a very common interface to those sensors that makes it a little easier for someone who's a beginner to work. It's really geared towards beginners. And Frank really wanted a GrovePie library in the nerves ecosystem so that it would get more people in. And he had already started. So he tells me about it. And before I got up from sitting next to Frank, I had already ordered the Starter Kit and like 70 sensors. And I should have asked my wife about it. But I didn't. And so like the next couple of months, I had a lot of free time. And I worked on this library a whole bunch to the point that Frank actually just transferred it to my GitHub account and said, you're in charge of it now. And but at the same time, Frank sent me acrylic cases that he had laser etched at home because he's got a laser cutter. That's what I'm telling you. The nicest guy in Elixir is Frank. He's like sending me stuff. I cracked it. And he's like, oh, that's cool. I'll send you seven more. But he also sent me a lightning sensor. And I was like, this is really cool. And he said, yeah, and and I start looking at it. And he's like, you know, it'd be really cool if we had three of these because it just tells it tells you the distance when lightning strikes how far away it was. And he's like, if we get three of these, we can triangulate and we can tell exactly where it is. And I start reading in the documentation. This thing right here says that the range is 63 kilometers. And I don't know about you guys. I live in the middle of Missouri. And Frank is in Washington, DC. And I'm not sure how we can even get someone somewhere in the middle that will allow us to triangulate after 63 kilometers. I think that his math is a little off. But I told Frank it's been like a year and I've been talking about working on this lightning sensor. And I said, Frank, I have a really good idea. And he's like, okay, what's that? I said, I can't test for lightning. Like, it takes forever. And I'm not excited. Like, I have to get some code to be excited. And then I can't wait for lightning forever. So I'm going to submit a conference talk. And I'm going to implement all the code for the lightning detector for the conference. And Frank, here's the thing. I'm not actually going to run it on hardware until I'm standing on stage at the conference. And, you know, Frank is like, you should do that. I totally respect you. You're nuts. But I respect you. So if everybody could could pull out their Twitter account, everybody who has one that's available and send one of these two things to Frank right now, that would be fantastic. He's expecting this today. He said that he couldn't make it. But basically, the top one is, I'm right. Or no, Frank is right. I'm always right. Frank's not right. Frank is right. And I am crazy. So if you think I'm crazy for waiting till I'm on stage to even test the software and the hardware, let Frank know that otherwise, my phone's going off like crazy. Somebody's doing it. Otherwise, do the bottom one and tell Frank that no way, this is awesome. And I'm not crazy. I'm completely sane. I personally think that the top one's probably right. So before we get too far, we really need to need to come up with some facts. So I went on to weather.com, which, you know, facts, I use that loosely when we're talking about weather, especially weathermen and weatherwomen because they never seem to get it right. But it says on there that there are 25 million lightning strikes in the United States every year. Now, again, it's according to weather.com. So it's probably just a guess. There are then I went on Wikipedia, you know, the next more accurate site on the internet. And they said there are 9.8 million square kilometers in the United States. And I already said that my my sensor has a 63 kilometer range. So let's do some math. Okay, so with 25 million kilometers, our strikes at 9.8 square kilometers, that's 2.55 strikes per square kilometer per year. So we divide that by 365 days. It's 0.007 strikes per square kilometer per day. We figure out the area of our sensor, 12,500 kilometers, roughly. That means we have 87 strikes a day. So if we keep going through our math and going down there, we see that we should have a lightning strike about every 17 minutes. That's perfect. I mean, this talk, how long is this supposed to be? 40 minutes? We have plenty of time. We can probably get two lightning strikes if we're lucky. We all know that that's how this works, right? Lightning happens every 17 minutes. Like you can say you're watched by it. The great thing about this is even if this is true, and we do get get the SD card put in, plug it in, run our software. Holy crap. It actually started up. Our GIN servers started up. It didn't crash. Let's hope we don't have a bug. If we have a bug, now we have 17 more minutes. We're up to 34 minutes, and that's just with one bug. I don't know about you, but every software I work on has a lot of bugs. I would hate for it to be the one right around detecting lightning because then we're like 34 minutes out. If you're doing this for a client, they really don't want to pay you to sit around for 17 minutes. But I just go skateboarding or something like that for 17 minutes, come back, why not? But I mean, we all know this isn't how lightning works, but bear with me. So documentation. This is out of all of this documentation, I thought about just putting all 27 pages of this up on these slides and just stepping you through each one of them because it's super exciting. It's like a Tolstoy novel mixed with Old Man in the Sea. So this is actually the communication. Somebody said that I have a moving around microphone. Okay, well, I'll just try to talk from over here. So this is the registers that you read. So this is a chart of all of the bytes that you're reading out. Every row is a byte whenever you're trying to read. So the first row, anything that says reserved, you can basically ignore because it's something inside of this device that you don't care about, can't change, can't do anything with. So on the first three bytes there are settings that we can change. The important one today is that AFE, GBA, it's gain. So gain is amplification. So how this lightning sensor works is that it has an antenna on it. And when lightning strikes, it creates radio frequency, some radiation that is detected by this antenna. And it actually says in the documentation that this device can tell whenever it's man-made or not. I think we can try to fool it, but I'm not sure. And it will, so it reads this RF and it looks at the power of the RF and can tell you how far away. And the great thing is that RF moves at speed of light. So it's instantaneous, even if it's the 63 kilometers away or right on top of the device. So this gain allows you to set this for indoor or outdoor. It only has two settings. So indoor it has a higher gain because you're detecting lightning that's outside and the RF gets blocked by the walls of the house. Outdoor has a much lower setting because the lightning is not blocked by near as much. So basically this whole device works by FM. Does anybody know what FM stands for? Frequency modulation, that's a great guess. It's actually Freakin' Magic. This thing works by Freakin' Magic. I was pretty amazed when I was reading all about it. And I used to do communications in the Air Force, like I fixed radios. So it was kind of awesome to realize that I could have used a radio to detect lightning. Who knew? So I took this chart and I wrote some code. So I read the first eight bytes. After that I don't care. So I only read the first eight. So zero to seven is the registers. The other things that we're interested in is on register three, the far right side is INT that's interrupt. An interrupt is an event that should stop you and cause you to see what's going on. The interrupts can be none, lightning, disturbance detected, which I think is like man-made. It never actually explains what it is. I'm guessing. And the other one is noise floor too high. There's so much radio frequency in the room that I can't read the lightning strikes radio frequencies. And then in register eight, so 0x07, the far right of that has distance. And that's going to be a number between zero and 63. Actually it can go up to 64. So zero, it's going to say overhead one to 63 is going to be an integer. And then at 64 it's going to say out of range. So apparently this can detect further than 64 kilometers, but it doesn't tell you. So I don't know if you realize this, but in order to test this, if I was going to write tests for this, so eight bytes, eight bits per byte that's 64, so I have to do two to the 64th tests. I hired an intern this year. That'd be a good job for him. So I talked to Nathan. He's my intern. I was like, hey, you should write these tests for me. And he said, yeah, no. He's a much smarter college student than I expected. So instead, let's go off the code. So it's binary. We talked about that. And we need, I used, I wish this was easier to, this is hard to do backwards. Nope, not that one. Don't look at that one. That's a secret yet. Hey, here we go. This is perfect, right? Perfectly readable. So actually, I was taking somebody through my slides and they told me I should never show more than 20 lines of code in an example. So if I can zoom in somehow here, there you go. 20 lines. Perfect. So I decided to use stream data and property-based testing using execute properties to actually generate all of this. This is the worst part of all of this code. It's not that complicated to understand, but there's a lot of it because two to the 64th test, I have a lot of data hidden in there. So basically, I'm trying to generate some data here on line nine. Well, you'll see like line six is interrupt. So that's the interrupt field that I was talking about. And line nine is tuple, constant, none, and then OB, zeros, all zeros. I could have put just a zero in there, but the documentation is based on binary. So I wanted it to look like the documentation, so it's easy for me to compare back and forth, which helped me catch a lot of mistakes where I type pro. So basically the constant on the left is what I want my parser to return to me. And the constant on the right is what the binary is that I read out. So this is just generating one little piece of that binary. And actually, this is just generating some data that we're gonna build our binary response. So we have the same thing with game. That there's the end door and outdoor that I talked about and their respective numbers. I don't know why it uses so many bits there when it's only two choices. Like why not just use one bit? I have no idea. I'm sure there's some like amazing engineering, electrical engineering choice that they made that this was the best thing to do, but I have no idea. And then we have distance. There's our online 29. There's our out of range with all ones. Line 39 is overhead if it's all zero. So this is actually made to tell you the distance a storm is away by averaging out lightning strikes. Cause apparently the very front edge of a storm, I don't know, apparently you can tell where it is by lightning. And then the middle one is a known distance. So if it's one to 63, which I pass in later. So okay, so that was just little pieces of the input. Here is the entire input being generated. I'm gonna, a lot of these are the other little blocks in that diagram that you saw. And then I need to put them together into a binary. So like lines 48 to 52 is the very first set of that binary. So the zero, so this is a two bit field. It's value is zero. This is one of the reserve fields. I don't care what it is. So I just set it to a constant because I'm never gonna read it. I'm never gonna care what it is. There's our gain that we talked about indoor or outdoor, but it's gonna be the binary. It's five bits long and then our power down, which this was one part of the documentation that I wasn't really clear on. I think you're supposed to tell this thing when you're gonna turn the power off, if what I'm not sure. So if we add those up, five, six, seven, eight, that's one byte and the next byte. And I'm sure that you guys don't want me to actually step through every single one of these. So just to generate the property, we're down to 81 lines. But I think they're fairly readable. It's easy to follow. You can compare it to the documentation pretty well. If I had run the formatter on it, it would probably be even easier to follow. And then here's our test. So I have gain and gain results. So the reason why I returned the tuples up above is that when I'm generating these tests, I originally had a bunch of ifs in my test saying, well, if the value of the gain was this number, then it needs to say indoor, otherwise this. And Chris Keithley, who spoke today, I actually reached out to him and said, hey, Chris, you do a lot of generative testing. Can you look at my tests? And he said, oh, generate the value that you want as your output with the generation of the input because it makes it a whole lot easier to change later whenever you see problems. And then it feels really good whenever your properties don't really change and you only have to change your input data. And I was like, you're weird, but okay, I'll try it. And he's right, like it feels really good whenever you don't have to change the meat of your test. So we generate all of these gain interrupt, known distance, known distance is used to get us a distance in case it's zero or 64. That's what the known distance integers there in that range are. And then we generate an input off of those. So those are the ones we care about. So we pass them into the input and then let the input come out. Line 91, we take the input, we parse it, we get an output. We assert that our output's distance is equal to the distance result from 87. So it'll be overhead, out of range, or one to 63. Our gain, so it's gonna be input or output and our interrupt result. So lightning, disturbing detected, noise, or none. I think that's all four. And so the test itself is fairly simple. It's the generating of all of that data that was the complex part. But I took it away. Now when I run my tests, all these property tests go and it doesn't run every possibility, but it picks like a random set of possibilities and runs like 100 of them every time I run my tests. So over time I build up a big confidence that this thing is working correctly. I promise that that is the most intense part of this whole thing. Now if I can find my, hey, there it is. All right, so that's not the only testing we had to do though. So I wanna say 2014 or so. Does anybody know who Sandy Metz is? I know a lot of this probably came from the Ruby community. Shh, don't say that. It's not cool in the Elixir community to say I did Ruby anymore. But Sandy Metz gave a talk about the magic of testing. And I really thought that this works with our gen servers and things like that too, is that there's really, I changed her graph slightly here, but not much, I'll get to that. So we have different types of messages is that when we want to query something in the gen server, it's pretty simple to test that, right? It already has some data. We query that data and assert that the data is what we expect it to be. It's usually like a line or two. The test is really simple. Then we have commands. All of our stuff falls under a query or a command. If anybody has anything else that is not a query or a command that they're doing in their software, please show me because I would love to see what this other thing is. I spent some time trying to think about this and I can't come up with anything. So a command. A command is where you're telling that server to do something. And a lot of times it will change some state inside that server. So you tell it to do something and you assert a public side effect to that. So in our case, I set the gain to outdoor. It was indoor. Now when I now use my query command to assert that it is set to outdoor. So I have a public change in my data. Boomerang is a name I gave it. I don't know what she calls it send to self. Basically, if you're calling anything internal to yourself, it should probably be a private method. But even if it's public, you don't need to write a test for it if it's only used internally. And then the bottom. So outgoing query. So if I ask another database or a sensor in this case for some data, I don't really need to test that. I'm actually testing the query of that result. But so that's where she just had ignore there. And I added stub. So a stub is where you fake out a response. So anytime this is called, I'm gonna return this. It's just stubbing. And I'm using the mocks library from Jose Valin and actually to mock this stuff out. And then outgoing commands. So these are important because a lot of times like we talk to an external system and it may not tell us anything. We just tell it to do something, right? You tell the sensor to change its setting to outdoor. And it just, you don't know like, hey, did it work? The only way to figure that out is to query it again. But we actually want to make sure that whenever we call that function that we really do tell the sensor in this case to change its state or do something. Even if it was like turn on this light, like he had the stop lights, you could test out. Like I sent the right message to turn on a light. And a mock is a lot like a stub except for a stub can be called or not called. It can be called 500 times. A mock is an expectation of this will be called at some point and at least this many times during this test which I'll get to an example of that. So let's go back to incoming query. I said this was simple, right? So we have an incoming query. I ask, I call it subjects is the lightning sensor. So I ask it for its gain and I get indoor. I use subject because I grew up like working a lot with RSpec and so sorry for anybody who hates RSpec but so I just, it's really like, there's not much to talk about here, right? Anybody feel like we need to beat a dead horse with this? Okay, good. So we'll go back. So next, so that was the query. That was pretty simple. Now let's go to the command. We have a serving some public side effects, right? So it's very similar. I'm gonna use the game. So here's where I do the command. I tell the sensor, hey I want you to set your gain to outdoor and then we assert that it is now outdoor. Was indoor, we saw the default last slide. Now it's outdoor. That's pretty simple. All right, so now we'll talk about the boomerang stuff. Okay, now that we're past that. Outgoing queries, so a stub. So this is using that library and the library mocks requires you to create a behavior. So I created a behavior for the board. Let me pull out the board here. So this is the actual Raspberry Pi zero board, that the Grove Pi. And what I'm doing is I'm stubbing out all calls to this board because I want to be able to run this without the hardware. It hasn't showed up. It's stuck in customs. It's out of stock, whatever reason. But I want to keep my momentum and my excitement going so I keep writing. So we're going to stub out the board and say that when we read, read is the function that you're stubbing. And here I'm saying the address. So I was talking earlier about this using I2C communication. So I2C communication is where you have a single line, well it's more than one line, but you can only talk to one device at a time and every device has an address. Most of them are hard-coded into the sensor whenever you get it. You might be able to change it by one or two by soldering some wires on there. In our case, the sensor is set up to be address three. So I'm actually in my stub saying it must be address three because I don't want my code to accidentally say address four. And then the eight is the number of bytes that I want it to return. And then the output there is that sensor output from the parser. So I'm faking that too. I'm using a generator, whoop, a generator up there at the top where, and so now I've stubbed out this method to return output. And so now we go ahead and we make our read. This read bang doesn't read anything. It's cache, it actually forces it to talk to the sensor and then I assert my results that I actually got my expectations based off of my output. All right, outgoing command. This is gonna look really similar, but not quite. And you'll see. So we have our expected gain. So the gain earlier in the system, I have it that if I tell it to set the gain, I just assume that it's set. And I changed my internal state and idea of what the sensor is to go ahead and say outdoor. Next time it reads, it'll update if it didn't. So that's why I was able to do the test earlier without the mock. This test, I want to make sure that whenever that board, when we call write, and then I have number of calls over the underscore calls, I just put there for explanation purposes. It's not required, but that's the number of times this write can be called in this test. If it's called more than that or less than that, I'll get an exception raised. Again, we're checking that the address is three and then I'm changing the gain to that expected gain from up above. That's my expectation that I want to send to my device. I have a little parser that changes that into binary and sends the whole first byte to the sensor to change its setting. Write always returns okay. This is where I was saying that we write to it and it's like, I hope that worked. And then so I try to set the gain to the expected gain and then this verify right here, just make sure that that mock was called the correct number of times. That's actually the assertion. So we're kind of asserting a side effect a little bit. All right, so somewhere over here. Hey, there's my test. Okay, so this is the really exciting part. We're gonna run some tests. And there are property tests, so they take a little time because they're testing hundreds of different tests. Crushed fingers, let's hope this passes. Yes! So I have three properties and three other tests. And they all pass. So hopefully it'll work on real hardware, right? Because all my tests pass, of course it will. Okay, so what I did was I created a little program that uses the library. And really all it is an application that starts up and this is a gen server. It's subscribed for three different events. The light, I don't know how easy that is to read. The line 10 is subscribing for a lightning event. If it detects lightning, it's gonna get a handle info. It's subscribed for a customer, or customer. Disturber detected, which is man-made disturbance. Or noise floor too high, is that what it says? And then all we do is I'm gonna output this. So somebody, I think it was Connor asked me why I didn't put a web front end on this. And it was like, Connor. I'm gonna run this code for the first time up on stage. I want this to be the lowest level of complexity possible because it's probably already not gonna work. But we'll see. So that's basically the code that we're gonna run. So when we run this demo, this is gonna be, we gotta tweet Frank one more time. And tell him either I was crazy or I'm still crazy or it failed or it passed. Because I'm sure he's waited with bated breath after all the things that he already got. So we'll go back over here. He's probably what? Probably is eating dinner. He is on the East Coast. All right, so we're gonna get out. This is the Raspberry Pi Zero. I have an SD card. I wasn't completely honest about not testing this before I got here. Okay, so I deployed it just to make sure everything started up. I didn't actually wait the 17 minutes that I need to wait for lightning. I just plugged in, saw that it started up without crashing and then unplugged it because I'm not completely crazy. So there's the Grove Pi Zero and here's our lightning sensor. And I know nobody can see this but there's a little antenna right here on the side of it. So I'm gonna go ahead and plug it in. If anybody wants to do any light reading I can drop off the documentation for them. Okay, so that's starting up. We're gonna use screen and connect to this. This is connecting over a serial port and we should see an IEX console soon. Oh, it's starting up. Hey, yeah, all right. Oh, whoa, whoa, it's going off. Man, I didn't expect it to go off that much. Whoa, now it's, this may not be good. Well, let's find out. So now we just wait 17 minutes. Maybe, nobody told me that. No, we did the math earlier, Johnny. No, 17 minutes. Hopefully we're close to that 17, probably a minute. All right, I'll be right back. Does anybody know what this is? It's called a Vandegraaff generator. So in the tube that goes from the bottom to the top is a black rubber band. In the very bottom there is a brush that touches that rubber band. And so the rubber band goes around rubbing on that brush, picking up static electricity. Just like me, when I rub my feet on the carpet right before I touch my son's ear, I'm a great father. And it goes up into the top of this ball and in the ball there's a little bitty metal piece, I'll show it to you before I start it, that catches all of the static and distributes it over that ball. The size of the ball depends on the voltage level you get. This will put out about 350,000 volts. So I'm gonna need a volunteer to touch that to make lightning. Brian, you wanna do it? Or I could use this ball here and just discharge it or you could do it with your finger. Yeah, that's what I thought. So let me go get started. Here, let me restart this before you touch that thing. Can you feel it though, when you're around it? Yeah, that's nice, John. So I'm gonna restart this thing. Oh, that's not a good sign. Why is it got question marks? Oh, okay. I don't know what those are, it doesn't know either. All right, you ready? It says noise level too high, but we'll see. Go ahead, try to touch it. What? So I would definitely call this a success, especially if I had to tell Frank whether it worked or not, right? So if, I mean, if you guys could flood Frank, that would be awesome, but I know that some people are like, I don't wanna get on my phone, it's too hard. I don't blame you. We have phones. Everybody should be on their phones. Man, I gotta go touch this ground because my head is full of static right now. It doesn't matter, we've got the whole stage full of static. I probably can't bring this out tonight. So, oh, I was gonna show you guys the inside of it. Does anybody want me to open it up and show you the inside of the top of it? Just out of curiosity, okay. 15,000 volts, you can get about an inch away, but here at Denver, since it's so dry, we can get a lot further away. But down in the end of here, you'll see a little, so this is the black, because amperage killed, you're not going to vote. But I did tease my son. I was like, you know, there's 120 volts in that outlet, and there's 350,000 volts on that. I'm gonna put my face on it. I'm like, ah, ah, ah. He knows better now, he's just looked at me, he's like, whatever, go away. I have five kids, none of them cared that they thought I was getting electrocuted. They were like, mm-hmm, walk away. All right, so, is everybody done with that? All right, so, my next steps, I only supported one sensor setting here, so I want to support all of them. I have a lot more documentation to read to get that done, and just like adding a web interface to it, I didn't want to support all of the settings and then get here and really mess it up, because it was a lot easier for me to focus on one. Test with actual lightning would be awesome. Although spring's coming up, and I live in the middle of Missouri, and we have thunderstorms all the time, so I'll probably get a lot of testing in on it. And then I thought it would be really cool if I could get a website up that other people could buy these sensors and then run some program, some elixir on there, that would connect to that website, and then we could see lightning all over and get everybody's information. But I'll probably never get to that because I might actually build the car heads-up display. Here's the slides are available at that top. I don't even know if you can read that. It's pretty hard to read, and it won't zoom in. I have no idea why. Come talk to me, I can give that to you. The Grove Pi library is actually out on Hex, and this lightning sensor will be added to the Grove Pi library, and whenever I finally get it added, it'll probably be in the next week. I will put a link to where you can buy the sensor if you want to, and then there's a link to Sandy Mett's talk, which is really good talk. You should read it, but really the big thing about all of this is that I wrote this completely without hardware. I had the hardware sitting in a box, but I didn't try it on hardware. I never once plugged it in, but I was able to do this all with testing. So it's important, and I can make small changes and test them in 30 seconds, instead of having to wait 15 minutes by the time I get everything built and get it deployed to hardware and hope that I actually hooked my cables up correctly, because the sensor over here, I don't know if you notice, it's got four separate wires that I have to put in the right place, and I have messed it up, and that's really frustrating too to debug, because you're like, what did I do? And you're looking at everything and it looks right, but you messed two colors, you swapped. I'd like to thank the St. Louis Elixir Group. They let me give this talk on Monday night, and I took them all the way up to the demo point, and then I said, but I can't show you, because I'm awesome like that. So I didn't show them. We did pull that out and play with it. I just didn't plug any hardware in, and it was a good time. I'd like to thank Frank for sending me a lightning sensor and for being so confident in my abilities up here today, and Connor, Connor has helped me out a lot in my nerves questions, so bug him if you have nerves questions, and Elixir Days for having me back again. I had a really great time. This is the legal part, all the images I got on Flickr. Next time I think I'm gonna hire somebody to make my slides, because this is the worst part. So I had to display this, according to their terms of use. So there's all the images if you care. And finally, come talk to me tonight. I'm super introverted, so if you just like to listen, that's cool. I'll talk your leg off, but I can shut up and listen too. So if you have questions, or you wanna get involved with the Grove Pie Library, there are hundreds of sensors and more coming out all the time that we would love to support, and I would be willing to sit down and pair with anybody, pair remotely, whatever you wanna do. Thank you.