 Hi, and welcome back to another episode of Visual Studio Toolbox. I'm once again with my friends, Suze Hinton. Hi, Suze. Welcome back to Visual Studio Toolbox. It's very good to be back. Awesome. Well, we're doing an IoT series together. This is our third episode in. Yeah, I think so. I think so. It's a good track. It's funny. It's not that many, but it does happen. So we're doing a series of these and the whole point is to make Windows IoT development kind of demystified show folks from the very beginning. So if you missed previous episodes out there, take a look at them because they allow you to see the first episode we did was the very basic stuff, like what is this hardware? How are we going to work with it? We didn't even start Visual Studio in that first episode. We broke the core rule of Visual Studio Toolbox, and you got to show Visual Studio. It was running in your machine. That's as far as we got. But that was important. We needed those for 15 minutes or so to give you the foundation as a viewer. Episode two, we actually showed basic sample. A sample you can just download, something really simple. Now we're graduating to the next level up, right? Yeah. Now we're running custom code. This sample wasn't available before. Right. You're going to show it, you're going to describe it. So let's jump in and you can tell us what you're going to show us today. Sure. Yeah. I'm proud that we graduated from Blinky Academy. Blinky Academy, I love it. Blinky Academy was our last episode. So I wrote a custom app that could be seen as maybe like a smart home device, and so it's a little bit more practical than Blinky. But I'm going to tell you a secret that you might not have known which is like, this is my first ever UWP app. You've actually never written UWP or C-Sharp before? Is that even as far as I can go or have you done C-Sharp? So I've done a little bit of C-Sharp, but the last time I wrote heavy amount of C-Sharp was 10 years ago. That's a long time. Yeah. And so I'm used to writing this stuff in C. And that's why I was so excited to come and talk about this stuff because it was a way better experience than usually when I'm writing C stuff where it's really hard to debug and the languages are obviously not as approachable as well. So yeah, I had a really great time writing my first UWP app. So I'm going to actually show you some of my code. And if you've got any kind of suggestions for improvements, I would absolutely love a pull request because this will be publicly accessible as well. Yeah. Yeah. The sample is meant to be very reproducible, right? Yeah. We talk a lot about the hardware. They get a pre-poll list exactly the stuff you need to build. If you want to reconstruct this at home, because that was like when we were planning this series, right, my pet thief was, I keep finding stuff and I can't reproduce it. I don't know which board they were using or which sensor. All these assumptions were made and I said, let's make a series that starts in the beginning and I'm going to ask you a lot of questions. So I'm excited. Let's jump in and take a look at the details of this. Yeah. So this is a little bit more complicated than our Blinky sample. We want to kind of step it up a notch. So as you can see here, there are a few more wires, which might look scary. And instead of just an LED, we have two little devices and we call these breakout boards. And we call them breakout boards because they usually feature one or more sensors on them. And then we break out the connections into an easily accessible format, which means that they're breadboard compatible. So you have these little kind of header pins that are soldered and you can then just pop that straight into the breadboard and start hooking that up to your Raspberry Pi, which is really cool. Yeah. So I'm going to raise a bunch of like, hey, I'm new to this. I want people to kind of hear from that experience. Like when you're looking at this diagram here, this is like a representation of the physical board that's lying to your left. So if we zoom in on that board and take a look at folks, what that looks like. So it matches pretty much to what you were showing. And if you missed previous episodes where we talked about it, this board has a series of numbers and letters, right? Going vertically horizontally that lets you understand which pins that we have put this stuff into. So you can really reproduce this 100% and there really are two sensors like that. And the sensors themselves, like you can't see it maybe in the video feed, but if we actually go back to the diagram behind us, they have names on the sensors. And like when I got my first pack, I actually opened up all the plastic covers on all the sensors. Every sensor came in a little plastic thing. So I laid them all out. Then I'm like, oh, the plastic thing had the name of the sensor on it. So I panicked at first. I was like, now I won't know what the sensor is. But the name of the sensor typically in most kids is written on the sensor itself. So take a look at that if you're new. And then again, there's diagrams like this on the internet you can find to often tell you how to hook it up to a breadboard. Absolutely. Or there's other ways, right? You can connect some of these straight to the pie using the pins on the pie that we've covered up because we put the big wire in there. That's the GPIO port, right? Yeah, so sometimes you can get away with not having a breadboard at all. Like those pins that are on the breakouts, you can actually just find wires that kind of have like inputs on both ends. And so you can plug one end into the physical pin on the Raspberry Pi. And then the other end just goes straight to, you know, and slides on to the pin on the breakout too. We're doing the breadboard just because it's like more stable and like there's less room for error. But you can absolutely do this and it's kind of really doing the same thing. Awesome, all right. Well, let's jump in to show people what we're actually gonna show them. Yeah, absolutely. So what we're actually gonna be doing today is we're gonna be using two different sensors. So there are a couple of sensors on each board but we're concerned today about temperature and we're also concerned about proximity. So they're two values that we want. And so the breakout boards we have here today, one of them is a climate sensor. So it's known as the BME 280. Thanks, Nate. Yeah, it sounds like one of those kind of old school like, you know, like marketable titles. The BME 280 is so advanced. Yeah, definitely. And I've learned that some of these sensors actually come with revision numbers. Sometimes it's the BME 280 revision, one versus revision two. So you'll find that as you start hacking but usually that stuff is written again on the sensor. Totally. Somehow identifiable. And the BME 280 actually comes in that static kit that I mentioned in the previous episode. So if you were interested in playing with this climate sensor immediately, like getting that pack is the easiest way to do it. Yeah, I strongly recommend that for getting started. If you can afford that pack, buy the pack, but you can actually buy sensors one sensor at a time. Yeah, absolutely. You can buy replacement sensors for them. Let's say you break them, let's say you burn them out or step on them and your cat runs away or whatever. Whatever may happen to your sensor, I've had a few incidents, but they're fully replaceable. They're pretty cheap, right? A couple of bucks typically and the kid makes it easier because it gives you a bunch of range of stuff to play with. And let's take a look at what we're going to do with these two. Totally. Yeah, so this BME 280 does temperature, humidity and I believe pressure. And then the proximity sensor does both like ambient, so like lighting in the room, but it also does like how close like objects are to the breakout board as well. And so what we're going to do is we're going to put together like a smart home app that is a little more practical than the Blinky app in that we actually are going to have like a proper foreground app running that's displaying useful information. So it's going to tell you what temperature it currently is, which is cool. And then there's like a little magical thing where it's going to be so smart that it can recognize who is standing in front of it and it can greet you by name, which is pretty cool. That's awesome. Let's see how that works. Absolutely. So I've provided this sort of this breadboard diagram so that you know how to plug them in. But the main overview that I'm going to give before I dive into the code and everything is that these two devices use a communication protocol called I squared C, which I've mentioned in previous episodes before. And so they plug in very similarly and then they also have similar ways of like communicating with the pie. And so sometimes you can find packages for these that have already been written that you can start using. And we're talking about like Nuget packages, right? Yeah, totally. That net developer is very familiar with. You can find them from the community or the manufacturer sometimes. And at the time you just find code that people expect you to run to get this to work. And you can demonstrate actually both kind of variants of that for these two sensors. Yeah, so I picked the proximity sensor today because it didn't actually have like a package in Nuget already to use. So I wanted to demonstrate that you can write less than a couple of hundred lines of code and you can be driving this once you sort of like start reading up on things like I squared C and how devices work. Right, so we're not gonna go for like the details of how to learn how to code that. Maybe that's another mean tell us in the comments that's maybe what you wanna see as well, but let us know. But I think what's important here is not to scare, like to me it's kind of scary sounding. I'll just speak for myself and not for my audience. Hundred lines of code to write a driver. Oh my God, I'm terrified. But this is C sharp, we'll show that. And also there's probably people like you and other pretty examples out there. I know from experience I found one of those and I got it to work. So you have to just kind of pay some classes and just start working with the thing. Absolutely. There's a great hacker community out there and once you get the events and if you can like you write it yourself and there are some great motivations for that. This platform to me is about flexibility and some flexibility has a cost and that cost is you have to learn sometimes more advanced things than just your normal like I'll just download a package and run and you get package and run it. But there's options for both and we'll take a look at that some extent. Yeah, it's super exciting to like write C sharp in a context that you've never written it in before. And then it was exciting for me to write a hardware app in a context such as C sharp that I'd never done before as well. So I think there's some really cool parts about this project in general. So I should probably demonstrate the device. Let's take a look. Yeah, let's take a look at how the hardware and the software works together and then we can jump in the code and take a look at how it actually works. Awesome, okay. So what we actually have is we've showed the breadboard a little bit and it has the devices that are plugged in. And so what our app does is it constantly monitors the temperature and the proximity and it shows the temperature on the screen. And then when you wave your hand in front of this proximity sensor right here, that's how it knows that you're sort of present. And we also have, I didn't show it but actually have this webcam here as well. So that webcam is just plugged in via USB. It is just one of the Microsoft lifecams which is compatible with Windows IoT. And so that's what's actually gonna take a photo of me but I have that tucked onto my laptop. So that's sort of how I'm doing that there. So I'm gonna run the app and just give a demonstration of it and I'll sort of talk through exactly kind of what's happening as I'm running it. So- You terrified me just a second ago. What do you mean? You put the camera over the power button of the device. Oh did I? I think so. And I was like, oh my God, no, no, no. It's not touching, it's okay. It's like, oh, here's our demo and we turned the demo off using the camera. So-called IoT expert right here. It's amazing what you can do when you're just plopping a camera on this. I've done it to it. I wish the power button on the surface had a cap or something on it. Honestly, that would be my friend. Yes, I just forget it's there all the time. I haven't used this laptop in a little while so totally forgot about it. Yeah, that's awesome. But a couple of things I want to point out is the differentiation of sensors that we're using. Like the lifecam is just a USB device, right? So it's just plugged into the pie using the USB. If we can switch to the device view for a second here. This is just, that's all it is. Like it's just plugged in over USB. Other stuff is plugged into the breadboard which is over that big cable of the GPU cables connecting back. So you can mix and match how things are working. If there's a driver in Windows IoT Core already, it's there to go. If you have something for the breadboard which has a NuGet package or code that you want to write, you can get that to work. Very flexible platform. Just wanted to point that out because sometimes people might say, oh, I need to buy a particular camera type. No, there's actually things that might work. Documentation actually has a list of what device they're supported out of the box, which ones you need packages, the NuGet packages for, and which ones you need custom code for when you just don't find it. That's when your third option comes in. Yeah, that's a really good point. So I actually did do my research before I decided what parts to use. As I said, like I wanted to pick one that wasn't supported but I also didn't want to have to write like everything. So I definitely looked up like temperature sensor and then Windows IoT Core and it was the BME280 that came up as a NuGet package. So you can kind of, you know, if you know what you want to achieve but you don't know what to buy sometimes that can narrow it down by just seeing if someone has already implemented it. Yeah, sometimes when people do the work for you. So good. So good. Let's run this app, let's see how it works. Yeah, so I have the application that I wrote. It is just open as a solution in Visual Studio. So I'm going to do exactly what I did with the Blinky and I'm going to run it remotely. So that's going to start up debugging. Yeah, in the previous episode we talked about how this is now building it locally as an arm. So it runs on the pie because the pies are arm and it's deploying to the pie and it starts it on the pie. So that's the experience. Go up to the previous episode. If you missed that kind of instruction that's why we're skipping it. IP address based deployment and gives us some filler talk while this takes a few seconds. It does take a little bit because it is finally yet and then it has to copy it over and then the app has to start up and I actually have a lot of other kind of secret things going on that we're going to talk about other episodes. So it does take a little while to start up. We're kind of building the sample up, right? We're going to show particular parts of it in this episode and the future episodes are going to come back and talk about some other things. So you might notice some code as you're watching that we don't talk about. We will talk about it. Yeah, I tried to hide them in other files but you might already be looking at the solution explorer and going, what's that? But yeah, we're going to get to that. So my app has actually started up. So we're actually going to go and have a look at the hardware again because I do have the app which is very simple and in design, running on the screen. So if I lift this up I've chosen purple as my background so I think it's a pretty rad color. I love the Visual Studio. Thanks you for the purple. You picked our color. Oh yeah, that's true. You didn't even think about that. I did not. Visual Studio Toolbox solutions. I'm just going to pretend that that was the plan all along. Plan, yeah. We plan everything with you on Toolbox. So you can see here that it says the temperature is currently, and what's the value? It says 74.5. So I'm going to prove to you that this is actually the live temperature coming from the sensor. I'm actually going to get my finger which I'm hoping is a little bit warmer than the room temperature and I'm just going to place it over the temperature sensor. As long as you're alive I think we should be able to demonstrate. I hope so. I mean my hands are pretty cold. Okay, but you can see it's 73.6. So usually if I've got a heavy sweater on it we'd probably be going up to 79. I've seen people use lighters and stuff to show this. I probably wouldn't want to slide anything on fire in the studio. They get mad at Channel 9 when you set the studio on fire. That's what I've heard. Yes, totally. That would not be recommended. You can also cheat and you can just breathe on it, like breathe warm air and that's also how you can trip off the humidity sensor if you were using that particular one as well. Awesome, and a few will show like the code that's running behind us. We just want to demonstrate this is working. Totally. And then we'll jump into the codes. Now you also have a sensor for detecting motion, right? That's right. Yeah, so proximity sensors are really awesome. You can get them in sort of various sensitivities. So I got one that sort of required you to be close so that you don't have like, you know, you cattle your dog walking by and tripping it off every time. And so you do have to sort of like have this sort of magic wave at the sensor. Waves are cool. Yeah, I feel like it's very like 70s sci-fi to be like, to activate something. I would love to wave at something when I got home and they would tell me things. I think this is the future. Waving is the future. Okay, so yeah, we're going to start a thing. We're going to start a thing with wave. Well, we have gesture-based navigation now, right? Wave-based devices. I think you're branding for it. I'm going to stop. That's awesome. Okay, so I'm going to demonstrate that part of it. So what's going to happen is I'm going to place my finger sort of near the proximity sensor and I've set a threshold. So once it crosses that threshold, it's going to take a photo of me on the webcam. And if you imagine that this device was sort of packaged into like a tablet-looking thing, that webcam would be like on the top of it and it would all be lined up. So this thing would be in front of you, wave at it, the picture would be taken and then stuff would happen. Yeah, so I'm just going to place my finger just like over the top of it. And I'm actually just going to zoom in on the hardware really quickly while I do that. So I'm going to hold this screen up and because it takes a little while to recognize it, I also sort of put a status on the screen. So my finger is going to just come over to this proximity sensor and I'm going to get closer and closer. And see how this is recognizing? I've got to come over and have to be photographed by the webcam so that I think I got away with it. And then if we come over, oh, it didn't recognize me. So I don't think I was fast enough. So what I'm going to do is I'm going to do the same thing but I'm just going to like actually stand right in front of the webcam so it gets a photo of me this time. Okay, so hopefully that worked. Oh, and it did. So you see that? It says greetings soothed. So it actually recognized who I was. Okay, let's try it. Let's try it. I'm going to go. It's going to be my turn. Okay, okay. Because like I just want to prove that that's not how I'm going to do it. And I'm going to stare at the camera. Okay, so I'm going to touch it and do we have recognition of Dimitri or not? Ah, it says greetings friend. Awesome. So why is that? How come it recognized you but it didn't recognize me but not recognize you? Right. So you're using a particular service in Azure to do this, right? That's right. So I'm using the Face API which is one of our like Microsoft cognitive services. And what I did ahead of time before we made this series was I like created like a, created a subscription key to the Face API. And then I trained my particular subscription on my face. And so I used some API calls to send a few photos and sort of identifying who I was. There was some example, sample app that you found that the service provides that you train it. So we don't have to build everything for this demo out of the box. So good. Yeah. So you train like a person with a person group and then let's say you had all of your family and they were using the smart device. You could train it on all of them so that it learns how to like greet everybody. You could have built that code into your app. So your app could have been both trainable and detecting. Totally. But this is a demo. Yeah. We're trying to keep things simple. Keep it simple for you. So there's kind of like a here's, here's like the cake that we prepared earlier kind of thing for that. Yes. But we'll link to everything in the GitHub repo so it'd be easy to find. Awesome. So this is sort of like what, what some of the app does, it does other things but that's sort of what we're focusing on today. It shows the temperature from the sensor but it also uses a different sensor to know when to then react and do something else. Which is a thing that sensors to use super commonly for in electronics is not just kind of like showing telemetry but also like reacting based on like input and things like that. Awesome. Let's take a look at some of the code behind it and again, we kind of had I think a mix of things we talked about that certain things were SDKs, certain things were NuGet packages from the community, certain things were code and certain things were drivers. So let's just walk people through that. Awesome. Yeah. So the first thing that you might see is that I'm using a special package here that isn't system or windows. And it is built Azure IoT, Adafruit BME 280. Yes. This is the community one that somebody wrote. Totally. You just added it via the NuGet. It is the best because it's really easy to use. So I can actually show you the literal lines of code that that's using when we scroll down. Let's do it. So let's do that. So we're still using our GPIO because we still want to make use of that for other things which I'll go into in a second. But let's just call out just the BME 280 sensor first because that's the one that has the library. And so here on line 27, I'm just instantiating a new sensor. And that's really as easy as it is. It automatically goes out, it speaks to the GPIO pins and it actually finds where that is. Oh, that's cool because in the past when I've used stuff like this, I had to give it in the constructor or something, the pin. Totally. This just finds that that's awesome. And because this is IceBread C, it's always plugged into the same pin. And because this is a breakout board that is manufactured at scale, it always has the same kind of address, which is something we won't go into. But that's as easy as it is. And from there you can start, you can initialize it and start reading things from it, which is really, really awesome. So how do we read from this sensor? Yeah, so let's go back down and let's just cover really quickly. We have a very similar main page. So we have our timer, which is gonna read values every, whoops, I've got a mistake there, so let's fix that. It's gonna read values every thousand milliseconds. I didn't want to be too crazy with that. And then we have this measure timer tick, which I'm gonna expand. But we need to initialize our devices first. And that's where we actually, I think, initialize our BME sensor. Yeah, so I have a task here where I'm actually initializing both sensors. And I promise I will go into the sensor a little bit later on. But I'm calling BME 280 sensor initialize. And what that does is it just talks to the device, it might send some calibration settings to it. And then once that's done, because it's an asynchronous task, we know immediately that we're ready to start sort of calling more of the user-friendly commands on it. Yeah, it's a nice async approach here. So we're just waiting for everything to get initialized that we're moving on. Totally. And you'll see a couple of other little secrets like connections to IoT hub and stuff like that, which we're gonna cover later. Then we start the measure timer to actually start taking that telemetry. So I'm gonna show you what that is. So I've just got some regions just to make it easier for me to move around. So our measure timer tick, which I felt was descriptive of what it's doing, it's measuring things. We're just creating a new double variable, and then we are BME sensor dot read temperature. Easy. And then we get a double back. Awesome. And that's literally the temperature. But the only snag is we live in North America. The North America issue, yes. Yes, so I'm not from North America. I don't know if you're from North America. I was originally born under the Soviet Union. So I was born in a thing that doesn't exist anymore. Oh, wow. But I'm in New York, I like you. So I live here. Are you more comfortable with Celsius or Fahrenheit? Fahrenheit, I grew up here. Okay. Yeah, so I didn't grow up here. Where'd you grow up? So I grew up in Australia, in Melbourne, and we use Celsius. You basically could've said basically the rest of the world, so. I know, I mean I was very careful about North America. Yes. I think there's one other country too, but I forgot which one it is. Yeah, there's a short list, but we appreciate you calibrating yourself. Yeah, so spoiler, if you've never had to convert Celsius to Fahrenheit before, it's a nice formula. I have to do it in my head a lot when I'm seeing things out and about. So you take the Celsius temperature, you multiply it by 1.8 and you add exactly 32. And that gives you the Fahrenheit. So that's what I'm displaying on the screen there. I can do the same with proximity, but I based the class that I wrote for the proximity sensor on the BME 280 because I thought that NuGet package had a really nice API. So you'll see that there's very kind of similar signature there. Then, because this is just a UWP app, I can actually, I have like a text node called temperature status, and I'm setting that as a string. And you can see here that I'm just kind of like making it just like one decimal point and then putting the nice little degrees Fahrenheit, sorry, on the end. Awesome. That's really all that that specific part of it is doing. Yeah, really easy. It initializes, it reads every 100 milliseconds, and then it just updates that text node so that when I put my finger on it, you could see it was live updating every second or so. Awesome. So that was the NuGet package part of it. Maybe we can take a look at the thing you wrote now, at least at a high level. So to make that sensor work, so again, you have these two classes you initialize here, but that sensor, the VNC, easy name, VNCL4010 sensor did not have a driver, it did not have a NuGet package, but you chose it for that purpose. That's right, yeah. So I wanted to see how hard it would be for me and my first UWP app to write a driver for it, right? And so I've written drivers for hardware in other languages like C, and I've even written them in JavaScript. So I thought, how hard could it be? I remember you laughing the same way when you were first like, yeah, I think I can do it. Probably, I'll let you know, and then you built it. So awesome, let's take a look at it. Yeah, I was really excited to show you that. So the one little important detail that I will tell you is that you can just read proximity values on this, but you can also set what's called an interrupt. And the interrupt is my threshold. So I can tell the device, like if I get a certain distance like close, then I want you to actually tell me on a certain pin on my Raspberry Pi. So kind of in the way that we had our Blinky as like pin five, and it was an output, this time this pin is actually going to be an input because the device is actually speaking back to the Raspberry Pi, right? So I've decided arbitrarily, completely arbitrarily on pin 16 because I wasn't using it and it was close to the proximity sensor. And I'm basically saying that pin is going to be my little messenger. So when it goes beyond the threshold, it's going to actually pull that pin value to low. And that's how I can actually attach handlers in like normal events to be able to react whenever that pin value changes, which is what Windows IoT Core gives you out of the box. Maybe let's zoom to the hardware for a second and take a look at the pin magical pin 16. Yeah, absolutely. Again, I want people to kind of visualize like the wire that's going. So that blue one, right? Yeah, so this blue one here. Yeah, and there's an actual number 16 that probably people can't see very easily on the video here. But like you can identify it, right? That little strip that's going out there has a 16 on it. The blue is going to a 16. The code has 16 in it. That's all the magic is, right? There's nothing else. You could have made a different decision once you know enough about how the boards work. So that's all I wanted to point out. I had no idea what I was doing. I just saw that there was a pin on there, the sensor that said int, which is interrupt. And then I read the data sheet to make sure it wasn't interrupt. And then I was like, I don't know pin 16. That'll do if it doesn't work or try another pin. So it's very a guess and check even for me, right? Because like this sensor is very new to me. So yeah, that's a really, really good point. So that's that special thing there. You could, if you wanted to, read the temperature and then have a conditional in your code if you wanted to saying, oh, I'm sorry, read the proximity. So you could just, every time it reads, every second, you could actually, if you wanted to, just like compare the value to some kind of chart. You could make a programmatic decision or you could have made a hardware sort of decision. There's probably pros and cons in the real world of this. For now, this will work. People try it. That's the most important. Totally. I think I was just looking for the extra challenge other than doing a programmatic. Maybe I was more scared of C sharp than I was of the hardware. Of the hardware. There you go. So let's just go with that. But yeah, feel free to do it programmatically because not every sensor has an interrupt pin, right? So I was just lucky that I had one. So that's really all that's happening. And when I first initialized my devices, I sort of wanted to show you this. Trying to find it now. Initialized devices, where is that? Yes, okay. So you can see here that on line 96, I have interrupt pin, which is my pin 16, dot value changed. So as you can see there, I'm actually adding a handle to that. Just pushing it on. Interim pin, is that a class you wrote or is that part of the GPIO? That's all part of the GPIO. So my interrupt pin here is just, it's very similar to the Blinky pin before. We're opening a pin and that's pin 16. And then my drive mode is actually different this time. Right. So instead of an output. And by this time we mean like in the previous video we showed that we had, and I asked the question, like what is this GPIO pin drive mode? And this was about the read and write thing. So, and this always is the context of the app. So the app is either reading something or getting data back, input output. Yeah, so with an LED, right? That's known as like an output because it makes light. So you want to write to it? Light. Yes, as an output. Light. Exactly. Here it's like, sensor going off. Sensor going off, if it detects, so it makes sense. Yeah, so we make it an input. I won't go into any detail really on what pull-up is. But it's, sometimes you need to have a, what's called a pull-up resistor, which like the pie actually kind of supports on board. Just to be able to like. Our viewers are like. Yeah, there's like. Let's just skip it. What are you talking about? Yeah, let's just skip it. Will this work? But if you're interested, you can Google like pull-up resistor or pull-up like circuit. And it gives you a little bit of information. It's literally just tied to how the device uses the interrupt. So it is dependent and the data sheet will actually tell you that. So there was literally a line saying, you need to use a pull-up resistor. And I was like, oh cool, I'll just put it. Yeah, so what's great about internet, it's sort of things like Windows IoT Core is that you can just do that and you don't even have to use a physical resistor. So it's kind of amazing. That's really cool. But the main guts that we need to know about is that we have configured Pen 16 to be an input so we can listen to changes on it, right? So that's really important with IoT Core. But this is all built in. I mean, you can see here that this is a class, right? And so it's really, really, it's really, really low effort to be able to use all these things because they've been done for you. So before, I mean, I'd love to look at how it actually recognizes you using the face API and the webcam, but like, let's take a look at the class that you built that is at a high level because there's still a thing you initialize to make the device work. And that's that class that you have there. If you can just open it up and give people a sense of like, what did it took you to write it? Yeah, is this the sensor class? Yes, yes, the sensor class. This is the scary code, right? This is the scary code, yeah. We're not gonna teach you how to write this code. We're not gonna explain to every detail, but wanted to show you that, in fact, the Windows IoT platform has a set of classes that enable you to do this in C-Sharp. Yeah, I was so... Not a Sambler, not C++, not something else, right? Exactly, I was so excited when I saw this here, like Windows.devices.iScorezT. I was like, all the abstractions have been done for me, right? So I'm not like flipping pins or anything like that. I'm just like, I know this device speaks I-squared-C. I know that Windows IoT Core is capable of giving me those abstractions. So as you can see here, we won't go into too much detail, but you can see I'm creating a new I-squared-C device, which is my sensor, right? This is the address that we touched on briefly here, but when you initialize it, we're just getting the I-squared-C connection settings and we can do things like setting how fast we communicate. You can see these are all based on existing classes that are given to us straight from Windows IoT Core. Right. So you just have to basically build the logic around them to make the sensor do what you need to do, and then you have this automatic hardware trigger to that magical 16 location and the board and everything just starts working together the proximity is detected. Totally. And you could have gone more advanced if you wanted to with code. Yeah, I didn't implement the entire sensor, you know, where you can read ambient light and things like that. I just did the little bits that I needed and that's kind of nice stuff, the freedom to do that too. And to be honest, I pretty heavily referenced the BME 280 library because they had done a lot of this kind of initialization stuff already. So I was just able to copy paste it, which was awesome. So that's why we're showing you this because if you want to get started with a different device, so if you want to add the light properties or whatever to this, then you can basically base it off people's existing code, which is awesome. Awesome. Yeah, and then I just have a couple of methods, you know, such as read proximity and some stuff to do with the interrupt as well. But all of this I got from the data sheet, which I've linked in there. So if you're not already feeling terrified, you can click on that link and just kind of see how I was able to write this based on the information that the actual devices manufacturer provided me. Yeah, and folks should feel free to, you know, send you a question on Twitter. I know you're active there. They can leave a comment on the show and all the source code and all the hardware specifications we're making all available on GitHub. Totally. In the repo link. So we're really, again, the goal of the series is to make sure you can reproduce this at home. If you wanted to learn all the details. Yeah, it's real. Yeah, and we wanted to show you that it's still C sharp. So even on this low level, you know, level where I'm actually like throwing bytes around and stuff. Yeah. You know, you can see here, this is like sending 20. It's real, and it actually happens, which is really cool. Yeah. Cool. So we had, you know, the both the sensors are operational, but then we had this magical camera part, which actually did facial recognition using Azure Cloud Services from a little ARM device. So how did you make that work and how did you work with a webcam considering it's plugged in over USB? So it's not in the breadboard. Totally. This is that driver-driven thing that the platform shouldn't fear your support, right? Yeah, so this was a relief to work with, you know, because it's USB. Yeah. And there's a lot of conveniences already put in. So you can see there's no scary, like, you know, GPIO stuff here. We're using Windows Storage, we're using and Windows Media, right? And so I have just a small set of class here that really just has, you know, one main async task here and it is take photo. Yep. And so you're going to recognize this from, like, probably code you've written before, right? Yeah, very familiar to anybody who's on this. It looks super similar. Again, if there's a better way to do this stuff, please pull request me because this is where I'm, like, not as versed in it. Yeah. But I'm using just my local data folder and that's so that I don't have to have extra, like, you know, folder capability permissions and things like that. And yeah, I'm just sort of creating a JPEG and then I am saving it to the hard drive so that I'm able to then go and send it to the FACE API. So that's really all that that class is doing. The FACE API is doing most of the heavy lifting. Like, once we've taken that photo, we need to send it to the cognitive services, right? And this is where you're referencing the Oxford namespace because, again, this is a NuGet package based on something you've already trained, using a sample application we talked about before. So you set up the cloud portion of it. Totally. This video isn't about that, right? So we're not going to demo how to set it up. If you guys want to see a video on that, put a comment in the show notes in the show, we'll get back to maybe doing more episodes. But it's just going to work based on, again, C-sharp code based on NuGet packages and recognition. I just copied, I'm not going to lie. I copied a lot of this. I mean, I sort of changed it into sort of more my style of writing things. But this is just copy and paste from, you know, some of the cognitive services, C-sharp samples that are out there. Yeah, they have great samples. And it works. You know, it understands how to use all the network libraries and everything like that to send the requests and everything. And I literally didn't have to do anything to make this part of it compatible with, we know it's IoT, the UWP. Awesome. Yeah, so that's how that works. It sends it off. And then once it actually gets the viewer's name, you know, the person who is viewing the UWP app, that's sort of why I named it that, it will return either friend or it will just return the person's name it got back from the Face API. Awesome. And then once we're actually in our class, back in our sort of main page class, this is where we sort of recognize and greet viewer. Where, you know, we have a placeholder to tell them something's happening. We take a photo using our webcam set at class. We get the viewer name. And then from there, because we're in like a task, we have to jump back to the main thread, update that message by greeting them. Then we do this thing where we, once you sort of trigger the interrupt, it waits for you to reset it. So this is just a nice little method that I made so that you can do that from the main thread, which is kind of cool. So, if you kept like waving, it wouldn't do anything until this finished running, because we had to finish the first request coming in. And this is why it kind of failed the first time you tried it, because you weren't in the view and there's no like advanced logic to say, is there a person in the picture before we send it? Like you could have added so much more code, we could have had a lot more UI, we could have shown your face, you know, there's cool stuff you can do. This is simple by design. Yeah, just so that you can get a feel for exactly what it's doing, then add your own complexity, obviously add your own exception handling, of which like there is not a lot in here, just to keep things simple. So let's keep it exciting, we'll just crash it later. Yeah, so that's sort of what I'm doing, then I'm trying to be a good citizen and sort of like not fill up the limited hard drive space on the pie, so I then just delete the photo. But that clear interrupt flag is really handy, because it means that you don't get stuck in a loop of, and this actually happened to me before I made the clear interrupt, it just kept taking photos and photos and photos and photos, and then it was crashing my app because it was making too many requests to the face API. So that was really good to know that I shouldn't clear it immediately, that I should wait. The challenges between the software like Visual Studio and the keyboard are meant sometimes, we cause ourselves a lot of problems. I've written code which, yeah, this is very normal. Totally, so yeah, so the recognizing great viewer is actually what happens when the interrupt triggers as well. So I'm trying to find where that is in my code, I think it's in my handle list. Yeah, so on interrupt means that the value of that interrupt pin changed. Right, so that's the swipe being detected that's a little swipey thing. And then, so this falling edge and rising edge just means that when you reset the interrupt, the pin goes back to high, and then when you actually trigger the interrupt by waving in front of it, the pin gets pulled down low. So I'm making sure that the event is only for the low part because I got stuck in a loop there too. Right, because when you reset it, it sends again a signal. Yeah, it's like, oh, there's someone again and I'm like, no, I was just telling it to reset. So that's why I put that there, you don't wanna trigger it for both because then you get stuck in an endless loop. So yeah, so that's really it. Like a lot of this stuff is like, you know, patterns that you've seen before, you're just kind of listening to a slightly different, you know, I guess input rather than an API response or something like that. You're just like listening for a change in a pin. Awesome. Was there anything else? I'm trying to think of it. I think that was everything I wanted to show in this particular episode. And I know you have more kind of in the sample and we're gonna dive a bit deeper and I think this is a great start. So, you know, once again, thank you all for being in yet another episode of Visual Studio Toolbox and thank you folks for watching. We hope you enjoyed this series. Again, this is a series of episodes. We're hoping if everything goes well, make about six of them and then we can add more based on your feedback to let us know what you wanna see. We had a few episodes before this go live so you can see the more introductory ones and this is the more advanced ones. We try to cover everything we can in every episode but some things we just wanna skip. We don't wanna get bugged on the basics. By the next video, I don't think I'll be showing the fact that the board has like letters and numbers on it. Like that sort of stuff. I think we can stop doing but definitely let us know what you think and thank you so much for watching Visual Studio Toolbox. We'll see you again next time. Take care.