Hey, in this video I'm going to show you how to hack the default firmware that we left off with, in the first video, to create your own modes from scratch. So this is the endpoint that we're going to reach in this video and you can see it's a pretty neat effect where you have the LED is growing along each side and then shrinking away. Let's get started.
Just picking up where we left off in the last video we've programmed a very fast rainbow mode and I'm just going to copy all of that code from the previous video into a new particle app so select all of the control and copy. Then go to code and I'm going to create a new app and this time I'm going to spell infinity correctly and I'll call this infinity hack and we can give it a description if we like let's make a mode and I'll choose to paste all that code in, go back to the top and I should be able to have to enter on that. Okay so now we have a new particle app with exactly the same code as the last sketch. Now, remember I do have to include that neopixel library so we'll just go to the libraries select neopixel and include in the project and we're going to include it in infinity hack and confirm that. So of course particle has been kind enough to drop in that include statement I already have it begin so I'll just remove that, just to remove the redundancy and we're ready to go.
Now remember to get your infinity kit to connect to Wi-Fi you have to press that setup button at the moment and that's handled by this line of code here. So semi-automatic means that the Infinity tip will basically work straight away without any Wi-Fi connection but because we're going to be uploading code to it a few times in this video going to change this to automatic which means it will always connect to Wi-Fi and in fact it won't run the onboard sketch that we arrived at the onboard application that we write unless a Wi-Fi network is present but that'll just streamline things for this video.
All right without housekeeping out of the way we're finally ready to create our own mode from scratch. So I'll just scroll down from there and the first thing that we have to do is say that the state exists this line enum State Bar this is basically our way of telling the photon on board these are some states that exist. I'm going to use this the word state and mode interchangeably. So we can see that these look kind of familiar we have rainbow we have comet something called solid and scroll. So these are the existing modes or States that are built into the Infinity and if we want to add our own we just need to give it a state variable or a state constant here, so I'm just going to include a new line and call this state 'edge' because you know we're lining up edges in sequence. For want of a better name edge will do for now so that's that way of saying hey this state exists what a numb does is it enumerates a number for each of these names so rather than refer to same mode 1 2 3 & 4, because we're humans we want to refer to them by you know meaningful names and this is a way of attaching a name to a constant number when we don't really care what the number is we want to refer to some constant number some arbitrary number by a name. You'll see what this means later on.
I'm just going to gloss past the remaining Global's global variables they're not super important for now and just going past the set up routine, this is code that's run only once to set up the Infinity kit we can see that something called strict beginners being called that's basically initializing the strip of LEDs and then update is turning this is updating the state of all the LEDs and because they haven't been set yet they're just being initialized to an off state so that's that's just the start up housekeeping.
Moving down to the loop this is code that runs continuously so let's take a close look at what's going on here because this is what drives the Infinity kit, we have a user color so we can select our user color with that that color scrolling mode that's basically kept in this user color variable, so it just needs to be initialized and it gets initialized to some value of a color wheel. We run a function called Wi-Fi or connect Wi-Fi on button press so that's the the pressing of the setup button is this is what handles connecting to a Wi-Fi when that setup button is pressed now this is the important part we have some some variable called state get set by a function called get state and and that is being passed our potentiometer so looking at it from a thousand yards moving the potentiometer affects the output of this function get state and get state sets the variable state so when we come down to our switch the switch case statement we're switching off state and state is being set to something, what's it being set to it's being set to those predefined values that we saw in the enum call so these are these this is how we determine what state we want to go into we set state to one of those variables or one of those values sorry. So let's um let's flush this out a little bit just to illustrate, our new state is called state underscore edge so we can just create that that declaration in the state machine here by saying case state edge that means that if get state returns state edge and it gets written into the state variable this is the part of code of the code that's going to be called and what we can do here is just call some function that doesn't exist yet but we're going to write it very shortly. So we can call our new mode and you made up we're just calling edge so I'll call some function called edge and we'll pass in the user color and then break just following the pattern basically following the pattern of the existing States we have if state is equal to state edge then run the edge function and break so now we have with we've made some some stable mode exist and we can actually enter it in this state machine what remains to be done well of course we have to create our mode for one we have to you know write the functionality for it and we also have to update the get state function so that it can actually return state edge. So let's do that next just going to scroll down into the functions area and you'll find probably the second function down is the get state function so what is actually happening here well again looking at it from a thousand yards we've got this if if-else chain and we're basically comparing value, which is some something to do with the reading the potentiometer value and we're just saying if it's less than a certain amount. So what's happening here is that we're reading the value of the potentiometer and then dividing it by essentially the maximum number that could be returned so what that means is Val is going to take on a value between zero and one and that just describes the the fraction of turn that you've put on the pot. So one being all the way to the right and zero being all the way to the left. Rather than try to expand this if-else chain for now I'm just going to have the edge function replace the Komet function so we'll essentially be swapping it out so what I'll do is comment out that line after I've done that the UM the hotkey way I've pressed ctrl and then slash and that's how you can quickly comment or uncomment lines but you can comment it out just by inserting those two slashes and instead of retaining state comment for between 75 and 95 percent of the pots arc. I'll return state edge. So what have we achieved so far we can we can return the state that we want to get at a certain point in the pots revolution which is super important because now the only thing we have left to do is to build the functionality of our new state.
Now we need to actually write our new mode, we need to give it that functionality so remember, from this switch case statement we're going to call a function edge and we're going to give it a value which is the user selected color this is something that's common to a lot of modes because we want to be able to select a color and have that be used for lots of different modes if we wish. So I'll come back down to just under the get state and we'll put out a new function here for now. So we're going to our function is going to return nothing it's going to it's going to be a void edge and what's going into it is this unsigned integer 32 bit we're passing in some colour. Now if you take a dive through a lot of the other states you'll see this thing called state current equals and then we're setting it to whatever state we're inside. That sounds that's just a good bit of housekeeping so that you can quickly update so that the photon knows which state it's currently in at any given time and that's that's a little bit important because for when we have say these long loops I'm looking at the comet state as an example when we have these long loops we can insert a check that basically says is the pot still pointing to a region that's inside that state and that way if we didn't have that then we'd be able to move the pot and we'd have to wait for some long loop to finish before it would leave the state. If you haven't somewhat I can't really follow along with that don't worry just suffice to say that including state current equals state edge is a really good idea. Okay so what do we what do we need to do we want to light up all four edges of the mirror kind of grow them on and then and then shrink them off I suppose so we're going to need to know first of all how many LEDs are there per edge so let's create a variable for that. I'm going to say int edge length equals and this is where we can invoke this strip property. So I kind of glossed over it before but at the top of the code we initialized the LED strip and it created some object called strip. Now we initialize that LED strip with some number of LEDs there are 44 LEDs so we could refer to this variable as the nut the total number of LEDs but I'm going to pull it off the strip object itself, so I'll say strip num pixels that are added for its built-in functionality and that's the 44 LEDs that make up the entire infinity kit so because that we have a square mirror it stands to reason that if we divide that by 4 that is the number of LEDs per edge which should be 11. So what comes next we're going to work off a single edge and then kind of replicate it across all four because once you have the functionality for one edge it's really simple to get it working on all four edges so just thinking about one edge we need to grow along that edge and then shrink along that edge and we can do that with a for loop for I'm going to create a loop index the int I equals zero and then I is less than edge length that's the number of LEDs that we care about we're going to increment I. So what do we want to do in this live we basically want to set the Ith LED each time it iterates and then push that change to this to this drift so we're going to call the set pixel function we're going to set the Ith Pixel and we're going to give it the user set color. I haven't really gone into how this works yeah but suffice to say the first argument is the the index of the pixel you want to set and the color you want to set it to. Remember this color is coming in as the user-defined color that's being passed in so we want to update that led. Now setting the pixel doesn't actually make that change appear on the strip to make that change appear we have to call something called update. This means that we can set as many pixels as we want in you know in whatever order we want and then once we hit that update function that's when the changes get pushed to the LED strip and so things don't get a crazy how about we delay for 50 milliseconds. All right we've come a long way so let's just let's just hit that flash button making sure our Infinity kit is connected. Hit that flash button and we'll see what happens.
But just before we proceed one thing that I forgot to include was something useful debugging tool which is the clear strip function. So all we're doing in this in this function is updating pixels but we're actually clearing any which means that any residual pixels that are left over from any other function I'm just going to remain static, so we need to include that just to give us like a blank canvas to work off. So once you've included that then you can keep the clear strip functionally the flash button sorry. Let's see what effect that code change had so here's our very first rainbow mode and if we move across we then have I guess that's the color scroll mode and then the next one would have been the comet but now we have that growing edge remember we've only entered the code that makes the edge grow but making it shrink is also really easy we're just rather than setting the LED to a specific color we now just set it to off. So the the the shrinking along one edge is also really easy to implement let's implement that and see how it works.
What we can essentially do is just grab this for loop that we've written for the growing a single-edged and copy it and paste it in because we're going to do a very similar operation but rather than write it to some user-defined color, in this case, it was a purple because I played around with the that used that color scroll mode. What we can set it to here is strip dot colour that's without a U and then now we have the red green and blue values that we want to sew to which is zero zero zero because that's going to turn the ID off. So with that simple change let's just hit the flush button to make sure that we have everything working for a single edge all right so the photon has rebooted so it's gone to that default color that it starts up with which in this case is green you might remember it comes from the color wheel zero but we can see along a single edge this is the zeroth led to the xi or tenth I guess if you're indexing from zero we're growing and then shrinking so that's one loop running and then the other want to turn them on and then want to turn them all off and you can see that because we only did it for I is less than edge length is only doing it for this first edge. Now it turns out to get this behaviour to mirror across all four edges is a really really simple addition. This may not be the most elegant way to do it but it's certainly very clear. So if we take this one line copy it and paste it let's work on as if we're setting the second edge that's like saying we want the I led off the second edge to work and because the LEDs are addressed as one long string that's just like offsetting by edge length and then if we wanted to do this same thing for the third and fourth edges we could say we want to offset by two times the edge length and no points for guessing correctly here three times the edge like so we're basically doing that same edge operation just offset by the length of a single edge, so we're offsetting around all four edges now I'm very quickly that change in the second loop as well and now that all that is complete we don't really need this clear strip routine we technically don't need that because we're kind of clearing all the LEDs ourselves so everything looks okay here let's hit that flash button. Of course, this isn't the most elegant or programmatically correct way to do this you can see that there's quite a lot of duplicated functionality this could be very easily achieved with another loop but it's also really easy to see what's going on.
Okay that codes flashed and you can see that the behavior of one edge has been replicated across the remaining three edges and that completes writing our own mode completely from scratch now.
There are a few really big things that I glossed over very quickly and just trying to get this video to an endpoint where you can kind of copy the existing structure and hack it to create your own notes if you want to. For the finer points definitely, refer to some of the written material for this tutorial about the more exact function of each thing we just covered and don't forget to like you know to look through the comments of the code as well because it can it kind of leaves this trail of breadcrumbs for you to follow.
And there's one last thing that I forgot to include and we kind of set the groundwork for it before but if you take the mode knob off this mode just as it starts it has to actually complete both of those loops before it will respond which can be a bit confusing for the user. So we're just going to update that and you might remember that at the very start of the edge function we set the current state to state edge and this is for the functionality that we're about to include. So I'm just going to scroll down to comet because the line is actually an exact copy if we grab this last line that says if and in English this is kind of what it means if the current state that the pot is set to be not equal to the state we're in then believed the state. So this is this is what we can drop into our loops and it kind of polls that potentiometer to just check if we actually want to exit this loop prematurely because we don't need to be in VN anymore the user is requesting to be offered so it doesn't really matter where exactly this goes you can see in what I've put it above the delay and the other I've put it below it doesn't really matter where it goes it kind of makes sense to put it in I guess towards the bottom, so I'll do that here. But if you include those lines then you should get instant feedback when you leave that state with the knob.
So there you have it creating your own mode from scratch now I'd love to see what you their creative internet community comes up with so if you come up with your own mode absolutely we'd love to see posts and code for it in the forums or even upload a little demonstration video that would be awesome to see. I'll catch you next time [Music] English (auto-generated)