Low Power Arduino! Deep Sleep Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys welcome to another video on low-power design in the last video I showed you how to use a very simple latch circuit to completely kill power to the Arduino in this video we're going to leave the power on but instead configure the Arduino to enter a very deep sleep state and then of course we'll wake it up with a digital input or a timeout from the internal watchdog timer so this is where things get pretty cool and don't worry we're not going to be using any libraries or anything like that we're going to do all of this from scratch so let's take a closer look at what I got going on over here ok so here is the Arduino it's just a bare-bones standalone Arduino on a breadboard here we're using the 80 mega 328p - pee-yoo and this is running at 16 megahertz with a 5 volt input and in another video we'll talk about lowering that voltage and the frequency to reduce the power consumption even further the code running right now is just baseline code here to see what the current consumption is just running full tilt so we've got an LED hooked up to digital pin 4 we set that up as an output and then we're just blinking that and if you look up at the meter here when the LED is off you can see we're like 17 milliamps or so closer to 18 and then when it turns on it kicks up to 20 milliamps so one of the things that the datasheet talks about is is to write all of your digital pins either high or low when they're not used so let's go ahead and test that out okay so basically what I did here is just loop through all of the i/o pins and I'm just setting them all as outputs okay so pretty simple stuff here you do want to watch if you're going to do this if you have some some other device hooked up to those pins so you want to make sure they're driven either way they don't all have to be driven low they just need to be driven one way or the other you could even if you don't do this you could also just bias them with a pull-up or pulldown resistor and that'll do the same thing and surprisingly does save quite a bit of current so if we look at the meter now running when it's off we just went from 17 to 18 million now down to about 13 milliamps so I just wanted to throw that one in there because it's just something so easy that you can just basically just write that little piece of code and you can save a few milliamps in every milliamp counts when you're talking battery applications so there's that now let's get into actually putting the Arduino to sleep okay so let's first go over to the datasheet and they do a pretty good job of explaining the different sleep modes and the one we want to try out is the power down sleep mode and this is the deepest sleep you can put the Arduino into and you can see here from this table all the things that shuts down in the different ways you can wake it up so if we go down we want to see how you actually put this to sleep and I'm going to keep scrolling down and here is the sleep mode control register so we need to first set this up and we're going to set up the power down mode here so it's pretty simple you just need to make sure that the sm1 bit here is set and then there's also this SE bit there which is the sleep enable bit so it says that it's recommended to write the sleep enable bit to one just before the execution of the sleep instruction so what is the sleep instruction okay so just a few sections up they give you a little example here of the how to implement the sleep instruction and here you see the assembly code example and I've done this in other videos but what we're going to do is use inline assembler in our Arduino code to execute this instruction so let's go back now to the code and you can see here what we're going to do is go to sleep right after we turn that LED off so the first thing we do is set that power down mode remember the SM one bit needs to go high so we just take a one shift at over two places to that part of the register and then do an or equal so that's a nice clean way of setting only that single bit in that register and then we're going to go ahead and enable sleep which is only that first bit so just don't worry equal on that first bit and then this is how you do the inline assembler to execute that sleep instruction and again you might remember seeing this from some of my other videos so I've got this code running now and you can see here that actually I'm going to just cycle power there okay so the LED turns on and then it goes into the low-power state and you can see that we're getting about 381 micro amps 0.38 1 milliamps so that's that's pretty good that's less than a milli amp but we can do much better than that so let's let's keep moving on and of course right now there's no way to wake it up we don't have any interrupts setup we're not running the watchdog timer so we'll talk about that yeah in a little bit here but let's let's see how deep of a sleep we can get this into okay so the datasheet talks about different ways that you can reduce power consumption and one of the big ones is to turn off the analog to digital converter so we do that by going to the EDC control and status register a here and we just want to flip the bit here for the ADC enable so bits seven of that register so we just want to write a zero to that bit and that will kill the ADC so let's go ahead and do that so you can see here we've got the ADC sra and we're going to do an and equal now with the inverted with the inverted bit when we shift over one to the seventh place we're going to invert that make it a zero zero everybody else is a one and that's a nice clean way to clear bits out of a register and I did not preload this one so I have to program that real quick okay so I'm going to go ahead and power it up and watch the meter here so now we're at powered up and now when it powers down goes into that sleep state we went from about 380 micro amps now to 58 micro amps so that's a huge increase so that alone I mean now we're in good solid battery territory now with this setup but believe it or not we can do even better than that so let's try the next one okay so the next thing we're going to try out that the data she talks about to reduce power consumption is to disable the brownout detection unit while sleeping so to do this we scroll down to this MCU control register and this is kind of tricky actually it took me a couple tries to get this to work because it's a timed sequence and if you read this it's it's a little convoluted you know it's talking about you know to to to turn off be OD during sleep writing to the B ODS vid is controlled by a time sequence to disable it you need both be ODS am Bo DSE must first be written to one so you can see it's kind of confusing and then to set it you have to the B ODS bit has to be set to 1 and B ODS e must be set to 0 within 4 clock cycles and then to make matters worse it also says that the sleep instruction must be executed while B ODS is active in order to turn it off in okay so anyway let's and of course that needs to be it is automatically cleared after three clock cycles so this is all that all of this has to be done in order in fact I tried it several different ways and it didn't work but this way which that I'm about to show you actually does work so let me show you how I did that so right here so I moved up the sleep the sleep mode and sleep enable stuff up here and right here is the brownout detection disable code right here so what we're going to do is first set both the Bo DSMB OD SE bits at the same time so I'm just going to shift a3 over to the left five places in order that with the MC you see our register so basically what I'm doing is setting both of these bits here so I'm taking a three which is you know both of the you know two bits set shifting it over five places so it would set both of these bits here that's the first thing I'm doing and then the second part here which is the tricky one is we need to do both a set of the B ODS bit and a clear of the Bo DSE bit okay so the way I'm doing that is taking the MCU CR register and making that equal to the MCU CR register taking it back in and clearing the fifth bit which is the Bo DSE bit here the fifth one here and then setting oaring that with the sixth bit which is the B OD s bit here okay I know this all sounds pretty confusing but we're basically just setting this bit clearing that bit so the order is set both of the bits then set this bit again and clear this bit at the same time okay and that's all there is to it and I've got this code running take a look up at the meter let's do a power cycle here real quick so you can watch it okay LED kicks on then sleep mode wait a minute did we lose power no we didn't lose power it's just that it's just that low it's incredible look at that we're we are now running at point three to eight micro amps so remember when I thought that 0.33 eight milliamps was good well this is really this is the ultimate deep sleep okay so I think we can stop there there may be a few other things we can do to reduce that even further but I'm happy with 0.33 0.32 a microamps so now let's talk about how to wake it up from this deep sleep okay so this this deep sleep state can be woken up by any digital input that's hooked up to an interrupt so what I did here is hooked up a push button to digital pin 3 on here which is the which is interrupts 0 and I've got a pull-up resistor little 10k they're hooked up to the 5 volts to that pin so I've got a pull-up resistor and then and then on the other side of that push button we're going right to ground so it's going to be a falling edge interrupt and then over on the code side here I've just attached an interrupt to interrupt a 0 which is digital pin or sorry digital pin to sorry I said digital pin 3 it's digital pin 2 so I hooked that up the function we're going to call is just digital interrupts and it is going to be a falling interrupt and so I added in the function down here Void digital interrupts and the other thing we did here is when I route through all of those um all those pins now I don't want to set that interrupt pin as an output because now it's acting like an input so if it's not equal to 2 then this is kind of a clumsy way of doing that but it's ok for this for this test here so I've got that code running over here now and so we're in this deep sleep state you can see up there that our current is very low and when I press the button it wakes it up ok so it's as simple as that wakes it up the LED turns on and then it goes back into its deep sleep State ok so now let's get into some cool stuff let's let's implement the watchdog timer okay so let's talk about how to implement the watchdog timer and this is pretty cool this is a timer that runs on the part completely independent from the 16 megahertz clock okay so this is something running internally to the part so let's scroll down to the watchdog timer control register here and if you go down a little bit you can see the various modes and here is a table showing the times that this runt can run at and it's not very accurate so if you need a very accurate specific time interval that you need to wake up to you may want to implement an external real time clock which we may talk about in a future video but for now the max time we can set this to is 8 seconds and to do that you set the WD p 0 in the WD p 3 bit of that register and of course if you need anything longer than 8 seconds which I'll show you in a little bit here you just have to re execute the sleep instruction and of course it does wake up for that brief period of time but it's I mean it's it's hardly anything to wake up and then throw back in to sleep so you can get longer sleep times out of using the watchdog timer so let's go up here the funny thing about this is again it's a timed sequence and this took me a few try a few tries to get right as well so you can see the prescaler bits here the WD p 0 p 1 p 2 and then p 3 is all the way up here but to change those we need to first set the watchdog change enable bit now I found something kind of weird in this datasheet and if we go up here I'm just scrolling up here it's another timed sequence setting here so if you go up here to the where they talked about how the watchdog timer works they talked about this timed sequence here so I'm actually following it this way right a logic one to the change enable bit and ude okay at the same time and then it says a logic one must be written to the wde bit regardless of the previous value of the wde bit and then within four clock cycles then you can change the WD and watch scaler bits okay well we'll talk about that here it's like I know this is all confusing but I wanted to show you that in the datasheet as to the reason why we do it this way so basically what we need to do is first change flip the bit the change enable bit and then we can set up the watchdog timer configuration which needs to be in interrupt mode so we need to make sure that the wde bit is cleared and the WD IE bit is set okay and we're going to like I said before we're going to run this it at an eight second interval so let's go over to the code here here it is right up here and the first thing I do is set the entire register to 24 which is just setting these two bits the change enable and the wde bit and then right after that I'm setting just the pre scalars only so that's just the the WD p3 bit and the WD p zero bit so that sets it to eight seconds and it's also clearing the WD e bit and the wdce bit okay I know this is getting crazy okay so we set that up and then finally I just only set the WD ie bit okay which sets it up in interrupts mode and you don't have to do this every single time we can put this up at the at the setup as well and we can put a lot of this actually in the setup and maybe we'll do that here towards the end but anyway that's it so now we've got the code running here I'm going to do a power cycle okay so the LED turns on turns off for eight seconds okay we could time that out and then the LED should turn back on there we go so we know that it is actually running and we still have that digital input running as well so we can still wake it up and that doesn't affect the watchdog time either so as soon as I hit that button it wakes it up goes back into its deep sleep for eight seconds and then up at the meter here we are no longer pulling 0.3 micrograms now we're pulling about 6 micrograms so the watchdog does use some current I'm going to wait for it to to go back into asleep so we can zoom in a little bit on that oops okay so it's about seven micro amps okay so that's pretty good so that is the watchdog timer running okay so I said that we can extend that watchdog time out by simply executing that instruction the sleep instruction twice and basically that's what I've got here in the code I've moved all of the setup stuff up in the void setup function up here so we got the watchdog stuff up there we disable the analog/digital converter up there and we set up the sleep register up there as well again don't forget to re-enable your analog to digital converter if you are using that in your project so you want to do that after you wake up but down here what we've got is the loop here and I'm just looping through that twice now you still have to set up the brownout detection disables registers here so where you're actually going through and disabling that and then we execute the sleep instructions so now over here we should get double the time and I've been running this here for a little bit and the funny thing is is that up on the meter you don't actually even see the little blip you know the increase in current when it hat wakes back up and hat sets up these in strut or these registers so that's how fast it it is able to re execute those register those instructions to change those registers and then re execute the sleep instruction so let's just go ahead and check this out here with a stopwatch so we're going to power up and then as soon as the LED turns off we start it and we'll see and make sure that we do get the sixteen second watchdog time out so right now we are running at about seven micro amps all is good didn't see a blip up on the meter and there you what you have it so it was a little bit before 16 seconds but again it's not going to be that accurate but I did I did want to show you that you were able to get about you can double your time or triple your time or whatever you can put anything you want in this for loop so that's pretty much it there is one other thing we can look at but I might bring that up in another video and that is the oops that is the power reduction register and they talked about that in the datasheet a little bit and I probably passed it up but that basically allows you to disable various peripherals on the part while running I didn't talk about that in this video because that's more of a purist power reduction register and this allows you to disable various peripherals in the part so the reason I didn't bring this one up is because a lot of this stuff if you disable it you're going to break things in the Arduino so like you can't disable timer0 because you're using timer zero for your delays and then other timers control the PWM outputs and things like that and of course you know the use are zero there which is your serial port so you can use it you just put prr and you set all these two ones and that disables them and that will save you some reduce your current consumption and I did test that out it's pretty easy if this does nothing for you in a sleep state though because when you go into that deep sleep state you already are disabling all this stuff so this is more of a runtime while you're running type savings and I was able to get it down to about 10 milliamps running with disabling everything in here besides timer zero because I was using delays oh and that does uh that does bring me to one other point here so you know we have this little delay here this one-second delay you could actually reconfigure your watchdog pre scalers to one second and then just enable sleep mode there to save even further so you know if you're really if you're if you're really tight on your on your battery supply you could uh you can always implement you know sleep implement a watchdog tie out for every one of your delays so that's just another implementation you can use so anyway I'm going to make all this code available oh you know what I forgot one thing don't forget the is our watchdog timer vector interrupt down here okay you need that for the watchdog timer to work okay this is the interrupt that is called when it wakes up okay and I'm not putting any code or anything in there but you do need this because this is called when it wakes up can't believe I've almost forgot that but I'm going to make all this code available in the description below I might I may actually add a little bit more comments to it but you can pick and choose anything out of here you want to use notice that we didn't include any libraries or any of that crap so this is ready to go out of the box for you to use and that is how to get the arduino into a deep sleep state and wake it up with digital inputs and the watchdog timer hopefully that helps thanks for watching
Info
Channel: Kevin Darrah
Views: 118,637
Rating: undefined out of 5
Keywords: arduino, low power, battery, how to, tutorial, microcontroller, kevin darrah, energy, deep sleep, watch dog, brown out detector, BOD, power down
Id: urLSDi7SD8M
Channel Id: undefined
Length: 24min 13sec (1453 seconds)
Published: Fri Jan 22 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.