Programmable Wildlife / Security / Timelapse Camera Projects with an ESP-32 CAM

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hi, I'm Alastair and in this video I'd like to  teach you some projects you can create using one   of these esp32 cam boards. Now, what is this?  Well, this is a board that has a tiny digital   camera sensor on the top there, it also has an SD  card reader, and it's powered by an esp32 chip.   Now that's a programmable microprocessor - very  similar to an arduino if you're familiar with   those - it's actually a little bit more powerful  than most Arduinos because it also has built-in   wi-fi and built-in bluetooth and it has touch  sensors and also a number of gpio pins as well,   so that means you can add on additional inputs  and outputs that adjust how the camera behaves.  So the camera itself is not that great quality:  it takes pictures at a resolution of 1600 by 1200   pixels - that's probably slightly less than  the camera in your mobile phone, for example.   It can also take low resolution videos as well,  but what makes it interesting is the fact that,   because you can upload custom  code onto that esp32 chip,   you can totally change its behavior and the way it  functions. So, for example, let's say you've got a   pir sensor this is something that detects heat  movement and you can have that connected to one   of the gpio pins when movement is detected  it triggers the camera to take a photograph   and perhaps you want to set this up outside  somewhere so this whole module will run off   a single 3.7 volt lipo battery like this one  so with that combination there for example you   could set that up outside a bird box in your  garden and every time movement was detected   you could take a photograph of whatever birds are  visiting your garden or maybe instead you want to   create some sort of security system so i've got a  pressure pad here this is effectively a very big   switch that gets activated when someone steps  on it well if you connected that to one of the   inputs instead you could cause the camera to  start a video stream and it could also email   you to say that um you know the pressure plate  had been stepped on log on here to see a live   video of what is being recorded at the time or you  could set it to a time lapse camera for example   so set it to wake up every minute every hour every  second however often you want and save a stream of   images to the sd card on board there um and then  you know you could create a video at the end of   all of the shots that have been taken so there's  loads of nodes you can do that it's really really   powerful it's not very expensive this only cost  about five pounds um the only difficulty with   them is is because there's a lot of functions  packed into them they are a little bit tricky   in places to get to work they're not quite as  straightforward as working with a typical arduino   i've been using them for a couple of months  now and i've used them in a couple of different   projects so in this video i'd like to both explain  the projects i've created and also some of the   pitfalls and the problems i encountered on the way  and explain how to overcome them so that you can   use these in your own projects as well so to give  you an example of it in action here's the bird   table in my garden and i've pointed the camera at  it to be triggered by a little pir sensor at the   top there it's about 50 centimeters away and i'm  actually really surprised that the quality of the   photos it took you can see this blue tip here and  the the depth of focus in the background as well   then at the base of the bird table i  noticed a little crop of dandelions growing   so i set the camera to a time lapse mode to  automatically take a photo every 30 seconds   and then as the sun came up in the morning you  can see the sequence of images as the petals open   and if you've been following my channel for  a while you'll know that i'm building an   escape room in a box and one of the new  features i've just tried adding to that   is one of these cameras here in the top half  of the board so this is actually triggered by   one of the arduino controllers which is running  the game and that sends a high signal down this   cable here to the gpio pin on the esp32 and that  can trigger a photograph to be taken of players   um when the game starts or when a  puzzle is solved or for any game event okay so let's talk about the hardware and what you  probably find when you buy one of these modules   is that it comes supplied without the camera  connected to it this is normally just sort of   floating around in the back separately so the  first thing you're going to want to do is to   actually connect them together so to do that there  is this connector in the middle of the board here   and you pull down slightly on this lever on the  top and that exposes just a row of contacts on   the bottom and on the reverse of the camera ribbon  you'll see that there's a row of contacts there   as well so we're just going to gently push the  ribbon cable of the connector into that slot   you see this is a bit fiddly to do there we  go and you want it to be lined up nice and   straight it doesn't go in too far and then you  simply clamp that shut in position there and   what that should do is that should create a nice  secure connection with the contacts to the camera   you'll notice that the actual lens itself  though is still quite wobbly so what i've   normally done now is just to put a little blob  of sticky fixer or blue tack or something like   that just to hold that camera back and keep  it secure against the back of the board there   now you might find that your module was also  supplied with an external aerial like this one   but it might not have been i found about half of  the units i bought came with an external aerial   half of them didn't um now it doesn't  matter too much because the board itself   does have an internal wi-fi aerial  that's built into it like this one here   but it also has a little ipex connector  here that's this round socket and that is   for connecting this external aerial if one was  supplied which in theory will give you a better   wi-fi strength now the thing is though it's not  quite as simple as simply plugging the external   arrow and if you want to use it and pulling it  off if you want to use the internal one instead   there's actually a tiny tiny little selector  at the bottom here and what it is there's three   contact points and there's a zero ohm resistor  that needs to bridge between two of them and   that selects whether you want to use the internal  aerial or the external error if you've got one   now one of the things you might have noticed  from looking at this chip is that it doesn't   actually have any usb connector on it anywhere  so in order to be able to upload code onto it   we're going to need another piece of  external hardware and one popular option is   an ftdi programmer like this one so this has  a usb mini connector at one end it then has   a clip here which is a usb to serial converter and  it has a row of output pins that we can plug into   the gpio pins on the esp32 cam board and what  this will do is this will effectively take   usb data input convert it into serial data output  and it will use that to program the board here   now um these are actually very handy little  boards and you can use them to program lots   of chips not just esp32s like this one and they  can program both 5 volt and 3.3 volt devices   so before using one the first thing you need to  do is to make sure that it's set to the correct   operating voltage as you can see there's three  pins here and there's a little jumper so this   one the top is 5 volts the one at the bottom is  3.3 so i'm just going to put the jumper across   those two pins there to make sure it's set into  3.3 volt mode um because esp32s run at 3.3 volts   and then you'll see that i've got the wires  already plugged in here via a cable and what   i'm going to do is i'm going to plug the vcc  output into the 3.3 volt pin here i'm going to   have ground going to ground and then i've got a  receive and a transmit data line and those are   going to go into the transmit and receive pins on  the esp32 like this so um the way this is going to   work is we are now going to plug the programmer  through this usb connector here into the pc   we can go into our arduino ide or whatever  other development environment you're using   select the target board and upload data through  the programmer here onto the esp chip it's kind   of like a pass-through that will convert  incoming usb data into a serial connection   we'll connect to the serial pins here and then  back again we'll take serial data back into usb   um obviously the serial connection you need  to make sure that you connect the transmit   pins from here to the receive pins on the esp32  and the transmit from the esp go to the receive   on the converter and then back to usb and once  you've uploaded code onto the board you can then   uh pull this off again and the code will  be saved on the chip and you can now   power this however you want through the five volt  pin here or through the 3.3 volt pin at the top now this is an alternative which i've only  discovered more recently and this is essentially   exactly the same thing as the ftdi programmer  just in a slightly different form factor   and the point here about this board is that it'll  actually slot directly underneath the esp32 cam   module like that it like the ftdi thou acts as  a programmer so we can connect to the usb micro   socket here connect that to our laptop and upload  code but also it's a really handy way to actually   supply power to the device as well so  while we talk about power you'll see i   demonstrated in the videos earlier  one of these lipo battery packs   so this takes a single 3.7 volt lipo battery  but there's some circuitry on the back that   will step that supply up to 5 volts with a 4 amp  output and also outputs 3.3 volt output at 1 amp   and it has a charger circuit as well so you can  actually recharge the lipo battery while it is   still in place through this connector here and  then it has an output at the top which is for   the five volt output so um one of the really handy  things about this particular board is not only can   you use it to program the esp but if i now just um  plug into the connector at the bottom here that's   actually a really convenient way of powering it as  well from the 5 volt output of the device here now   just to clarify i said that the esp chip runs at  3.3 volts which it does however i'm supplying 5   volts and letting the on-board regulator drop that  down and the reason is because the lower voltage   output from here only supplies one amp and i found  that that's not enough current to actually drive   um the wi-fi and the camera and the sd card all of  these devices at once use quite a lot of current   um so i found it's better to actually supply a  5 volt supply even though that's kind of more   than it really wants but then let the voltage  regulator here drop that down to 3.3 volts   that's the way i've found to get more reliable  performance without risk of brown out errors   and things like that now obviously the wiring is  going to depend exactly on how you want to use   this module so rather than show you a complete  wiring diagram what i'll show you is some   snippets of how to wire individual components  together that i used in those projects there   so firstly is how to wire the ftdi controller to  the cam board in order to be able to upload code   onto it and i kind of demonstrated this in the  video earlier but i just wanted to reiterate it so   you have a selector switch normally on these  boards which you set either 5 volt or 3.3 volt   and you want that to be set to 3.3 volts and then  you connect the receive line on the programmer to   the transmit pin on the esp32 which is this  one here then you plug transmit into receive   connect the grounds together and vcc goes to the  3.3 output here now one thing to note however   is that different programmer boards from different  manufacturers come with different pin outs so   these two images i've got here these are actually  photographs of two boards with exactly the same   functionality they've actually got the same clip  on them basically except notice that uh in this   one we have starting from the top ground cts vcc  tx0 rx and on this one we've got exactly the same   pins but literally listed from bottom to top  so we've got ground cts vcc transmit receive so   do be very careful when you follow the wiring  that your pins may be in a different ordering   um the only other thing to notice here as well is  that when you want to upload code you need to put   the esp32 into a kind of programmer state and  to do that you connect gpio pin 0 which is here   to ground so i've just plugged the little cable  in there and having done that you hit the reset   button on the board once that will put it into  programming mode where you can upload code to it   once you've uploaded the code through the  programmer you can then take this off again   reset once more and it will start running the  code that you just uploaded if you're using one   of those modules which i showed the programmer  modules that kind of happens automatically or   at least it should happen automatically  anyway so you won't need to manually do   that but you'll you'll need to insert that cable  there if you're using a programmer of this style now in terms of using sensors or other inputs  to trigger the camera that's not quite as   straightforward as you might think either you  can see that there's a number of gpio pins on   the esp32 board but actually as it turns out a lot  of them aren't available for use because they are   shared functionality with either the camera  sensor or the sd card but um using the code   which i'll show you later on it is possible to use  pins 12 and 13 on the board here as either inputs   or outputs so with the example of the camera that  was triggered by a pir sensor what i've got here   is a pir sensor which has got a 5 volt supply  which is wired to the 5 volt pin here it's also   got ground and it's got an output in the middle  and that output line goes high when movement is   detected by the sensor now um you'd think that you  would be able to plug the output of that directly   into one of these two pins here like that then but  when i tried to do that i found actually that the   whatever reason the output signal from this was  not enough to reliably be detected as a high input   on the pin here so what i've done instead is  i've used an npn transistor so this is a bc   547 transistor which is a very cheap common  component it literally costs a penny you   can buy them in bags of thousands and what that  does is it means that when a very small current   is applied at the base leg of the transistor it  allows a potentially larger current to flow from   the emitter which is a pin here to the collector  so what i've done here is it's a little bit you   can think of it a little bit like a relay where  you use you know a small load on one side of a   relay to trigger a bigger load on the other but  rather than being electromechanical it's purely an   electronic component um so what we're going to do  here is we've got our pir sensor which is powered   by 5 volts that's going to give an output through  this 2 kilo ohm resistor here into the base   of the transistor and so when this kind of this  weak signal here which i found that wasn't strong   enough to be detected directly on a gpio pin but  it is strong enough to turn the transistor on and   that's going to allow the 3.3 volt pin here which  is connected to the emitter that's going to allow   current from there to flow into the collector  here and into the pin so i found that um was just   a way to get the detection of these pir sensors  much more reliable than um just plugging them in   directly which i'd sin used in some other circuit  diagrams but just didn't work for me at all   okay so here's the code now even though this is  written for an esp32 you'll notice i'm using the   arduino ide still because that's an environment  that i know a lot of people are familiar with   and if you've come from an arduino background you  can carry on using it to program esp chips as well   the only thing you need to do is go into file  preferences and where you see this line here that   says additional board manager urls you need  to include the package that defines the esp   boards which is this one here once you've done  that you can then come into your boards here   and you'll see that you have in addition  to the arduino boards listed at the top of   the screen here i've got a ton of other boards  as well i've got some esp8266 boards and i've   also got some esp32 boards here and assuming  you're using exactly the same hardware as me   the one i am using is called the ai thinker  esp32 cam so you select that as your target board   and from then on you can carry on using the ide  just as normal as if you were using an arduino   so all my code listings i start at the  top with some includes so these are   external libraries that we're going to make use  of now all these ones at the top are actually   defined as part of the esp development kit so  you don't need to download any of these extras   but they do define kind of additional features  on top of the core functionality of the chip   so just to talk through what they are obviously  this is the the core functionality we then load a   library that lets us access the camera we're going  to save photos onto the built-in sd card so we   both have the sd library itself and also a library  to access a file system on the sd card we're going   to make a couple of changes to the way the system  behaves in regards to its power functions so   that's what these three libraries are uh we're  going to save some data onto the eeprom as well   so the sd card that's kind of like a storage for  data which is where we're going to save our images   eeprom is like a very small amount of erasable  flash memory and we're going to use that to keep   track of the number of photos we've taken so  that we can increment a file counter each time   we are also optionally going to use a wi-fi  network if it's in range we're going to use that   to download the current time and also to send an  email with an attachment to the photograph on it   and the time function here will let us actually  work out the time stamp at which each photograph   was taken now this one here this is the  only third party library we were going to   use so this is the one that lets us send  emails and there are several similar   sounding libraries so um i will show you the  one it is if you go to manage libraries here   and it is the one that is called esp  mail client i simply search for that   uh you'll see it is this one here confusingly it  is not the esp32 mail client that's actually an   older version of the same library you just  want the one that's called esp mail client   and that works for esp32 and esp8266 so  we're going to install that as well you only   need that if you are want to use the the email  functionality but i've included at the top here   okay and then we get some defined so these are  kind of uh constant values that we're going to   replace in our code that's going to alter the  behavior slightly so with each of the lines here   you'll see i've commented some of them and i've  left some of them uncommented so this is up to you   to change to to alter the behavior that you want  the code to have and what features you want to   include so the first one this is what i mentioned  about um the eeprom saving the number of pictures   that we've taken so you'll have like pick one pick  two pick three and if you want to do that then you   keep this line here uncommented we've got option  to use the timestamp as well now the esp32 though   it's got a lot of onboard functions doesn't have  any ability to actually keep track of the current   time it doesn't have a battery-backed real-time  clock on it anywhere so if you want to record   the timestamp at which the photograph was taken  which is a pretty useful thing to want to know   we're going to connect to an internet time server  to get the current time that obviously requires   a wi-fi connection however so if you're talking  about setting this camera up somewhere you know   in the middle of a woods or at the bottom of  the garden where you don't have wi-fi that's   not going to be an option so i've left this as an  optional inclusion if you want to use a time stamp   which is retrieved from an internet time server  but that does require a wi-fi connection to work   likewise clearly sending an email of the  photograph is going to require a wi-fi connection   as well and then we've got two different modes  that will actually activate the camera to take a   picture so you only want one of these uncommented  if you uh use this one for example you want to   comment the other one out so in trigger mode this  is where one of the gpio pins so i'm using gpao   pin 13. when that is set to a high signal so that  could be as a result of a button being pressed   or a sensor which is reading a high value or  that could be another arduino for example which   is sending a high signal when that happens on that  pin 13 the camera wakes up and takes a photograph   and it does that every time that rises from low to  high or alternatively timed mode this is where the   camera wakes up automatically on a given schedule  so every uh 50 seconds 100 seconds a thousand   seconds however long you want um it will wake up  and so this is for sort of time lapse photography   basically and then we've got some more defines  here so this is only relevant if you want to   send an email and these are the credentials that  you're going to use to um to log on to your email   account under send that email so we've got first  of all the network that you're going to connect to   and the ssid and password and then you want  to define the mail host now i'm using a free   outlook address here i would recommend that you  don't use your primary email account because   if something goes wrong in your code let's say  that you set timed mode activated and you send a   you set a photograph every two seconds let's say  and you email every two seconds a new photograph   to your account you'll probably find your  email is going to get blacklisted quite   quickly as being a spammer so what i did  was i signed up for a free email account   a hotmail account basically at outlook.com  and i'm using that to send my photographs from   so that literally takes you know 30 seconds  to sign up for a new outlook.com email address   and if you do that this will be the  address of the mail server that you   need to log on to you can have a gmail  account instead or any other email account   you'll just need to change the address here  to whatever the smtp server is for your email   okay then we get on some constants so the  constants are variables which are going to   stay the same throughout the duration of  the code and the first section here this   is where i actually define some of the gpio  pins that are going to be used in the code   so um although it looks like the  esp32 camera has quite a lot of   pins in practice not that many of them are  actually usable because quite a lot of them   already have functions attached to them so the  camera itself and the sd card uh and then there's   various leds attached to them so um first of all  here i've got an led pin and this is a a red led   pan that's on the back of the board near the reset  button and we're going to use that just to show   when the board is actually activated and doing  something so that's attached to gpio pin 33   but we'll refer to it in the code as led pin  on the front there's another led but this is   a much brighter white led and this is the one  that we're actually going to use to create   a flash if we want to take uh photographs in  low light and that's attached to uh gpo pin 4   and then so these are both output pins then the  trigger pin this is going to be an input pin   because this is the pin which we're going to use  to take a photograph if we're in trigger mode up   here it's when this pin gets sent to high signal  and it's pin 13. that's where we are we're going   to to take a photograph with the the camera  that'll be our trigger uh we also define uh a   flash power so if you want to use the flash that's  at the front here it's actually surprisingly   bright for quite a small led so you can set it to  any brightness you want between 0 and 255 but even   if you don't want the flash on you might find  it quite helpful to set it to a very very low   value that's what i've done here i just set it to  1 out of 255 because then it will kind of act as   an indicator to show that the photograph is being  taken it won't really illuminate the scene at all   but it will just show that the camera is on and  doing something so that's uh that's quite a useful   way of doing that i found um then if you are  not in trigger mode but if you're on timed mode   so this is where we're taking a photograph every  regular number of seconds this is how many seconds   to wait in between taking a photograph each time  uh so i've put 30 seconds here but you can put   one second you could put like 10 000 seconds  depending what it is you're you're trying to take   a photograph of basically um now here i've put a  delay time in milliseconds this is something you   might need to tweak yourself later um i'll explain  exactly how that's used later but essentially   when the camera first wakes up it does some  kind of automatic initialization and calibration   routines um so there's an auto exposure mode  for example but that exposure only works   if it's had a bit of time to actually measure  the light in the scene and things like that so   normally when the camera's triggered you obviously  want to take a photograph as soon as possible   after the trigger to capture whatever it is but at  the same time if you take the picture too quickly   you'll find that the camera hasn't had enough time  to properly configure itself so i set this to uh   three thousand milliseconds so three seconds after  the trigger first gets detected before it takes a   photograph and i found that worked pretty well but  you might want to adjust that up and down to get a   quicker response um but if you take it too  small you might find that the auto exposure   doesn't work but i'll talk about that in a bit  more detail when we get to the um the exposure   and the sensor settings later um now we have  a couple of globals so this is the um picture   number that we take and like i say this is going  to get incremented every time we take a picture   and if you choose to number the files according  to the latest picture then it will get saved as   part of the file name on the sd card and then  this is a path object which we will use to save   the latest photograph taken to the to the file  system that will be the part that gets sent us   um if we are sending an email if that's one  of the functions that we've chosen to do   uh we'll also create a global variable for  the session that we connect to the smtp server   and we define a callback function so a  callback function is a function that gets   called unsurprisingly when a certain event happens  and in this case that event is sending the email   so um this callback at the top here what we do  basically just it's like a status report after   we've attempted to send an email so this will be  called automatically by the email sending function   it will print the status of the um the  smtp request basically whether it was   a success or a failure and some details about  if it was successful who the email was sent to   uh the subject and the date time it was sent and  things like that um now that is the only callback   now we have one other uh interesting function  here and this is a sleep function now to kind   of explain why this is here i'm just going to  jump ahead a little bit first so normally in most   esp or arduino code you're probably familiar with  having a setup function which is run once when the   code first starts up and also a loop function  which is something that loops round and round   while the code is running well one thing you might  have noticed as i scrolled very quickly down here   is that in this particular program almost all  of the code is contained in the setup function   and there's actually nothing at all in  the loop function we still do have to   have it there because otherwise the code  won't compile but actually nothing happens   and you kind of think well hang on a minute if  there's nothing in the loop function what is   it that makes the camera do these functions  what is it that triggers a photograph to be   taken uh or to send the email or to wake up when  this high signal is received or the sensor goes   and the answer is we're going to use an esp  feature called deep sleep now this is really   really useful for when you're creating battery  powered projects particularly it's less important   if you're running on mains power but if you're  creating any kind of portable kind of project   and you want to reduce the current consumption as  much as possible when it's not doing anything and   the way to do this is to sort of create this low  power nearly hibernating state of the chip and   it shuts down all of the non-essential functions  so you know the bluetooth the wi-fi all of this   gets shut down and the only thing that will wake  it up again is a very specific um sort of signal   that you define before you send it to sleep so um  to talk through when it when it wakes up again by   the way what it does is calls the setup frontal  again just as if it uh had been turned on for the   very first time so uh the way that arcade here is  going to work we're going to have the device wake   up when it first gets turned on perform all the  setup actions then it's going to go to sleep and   it's only going to wake up again when a trigger  occurs and calls set up again so we never really   get into the loop function that never happens um  so the the sleep function this is this is what   happens when we go to sleep so we'll have a look  what we do the first thing we do is we define the   trigger pin and i'm defining that as an input  pull down now this is another feature which uh   if you're used to arduino coding you may be less  familiar with on an arduino you can define any of   the gpio pins as either an input or an input pull  up so an input means it is just floating signal   it has no particular state an input pull up well  that means it uses one of the on-board resistors   to pull that signal up to a high value and what  you then normally do is you have something like   a button which connects it to ground instead  that pulls it down low well if you're on an esp   you do have pull up resistors but you also have  pull down resistors on certain pins at least   and in this case we're going to use the pull down  on the trigger pin what that's going to do is it's   going to keep the when we do a digital read on  this pin if there is no input to be detected there   it's going to make sure it reads a low signal  it's not just going to be an arbitrary floating   signal it's actually going to pull it down to  ground to low and only when that gets pulled   up to 3.3 volts that's when we'll record a high  signal on that input instead so that's the first   thing we do before we go to sleep we'll we'll  make sure that the trigger is set as a pull down   the next thing this is a bit complicated as well  so uh this it holds the setting holds the pin mode   of a gpio pin while it's asleep remember i said  that when it goes into sleep mode the esp kind of   enters this very low power state and it turns  off all its non-core functionality and that can   actually cause it to kind of um forget the  settings that you'd assign to certain pins   they restore back to their defaults if you don't  want that to happen if you want it to remember the   state that you set a certain pin to while it's  asleep you can call this hold function here so   what we're going to do is we're going to hold gpo  number four which is our flash on the front we're   going to hold that in the state it was in so that  we don't accidentally get the flash turning on   when we go to sleep or something like that i will  also turn off the led on the back of the board as   well now confusingly this is an active low led so  to turn it off we actually write a high signal to   it so this is all kind of getting getting ready  for bed we'll we'll put the trigger in the right   state we'll make sure it remembers the flash on  the front we'll turn the led on the back off and   then what we need to do is we need to basically  set our alarm clock what are we going to do   to wake up again well we've got two choices here  if we want to use the trigger mode to wake up   that's where we are listening to our depo  number 13 pin and we've got two options here   um we might want to wake up when that goes high  and this is the line of code which i'm using in   all of the all of the projects that i've actually  built this is the way i'm using it so if you're   using a pir sensor for example that typically  goes high when it detects movement so uh if you're   using a pir that signal line is uh connected to  power number 13 you want to wake up when that   signal goes high similarly if you are going to  write a high signal from another arduino or from   a button or something like that you want that  alternatively you could uh comment that one out   and have this one instead so this will be exactly  the same but this is where it goes low now the   only thing to note here is if we're waiting for  the the pin to go low then we want to have this as   a pull up instead so this normally keeps the state  of the pin high but then we wait for it to go low   or alternatively you want it the other way around  we normally keep it low and instead we'll wake up   when it gets high so they're just two different  ways of setting the same logic basically but you   probably want it to be this way round certainly if  you're using a pir sensor that's how you want it   um alternatively maybe we want to set our alarm  clock to wake up after a certain amount of time   so in that case we call this funnel instead  so we call the sleep enabled with a timer wake   up rather than with an external wake  up and when do we set our time for well   it's the time lapse interval which we defined in  our constants at the top of the code here now we   gave that value in seconds because i just  found it more convenient to type in seconds   um but the timer wake up function expects that  to be in microseconds so we have to multiply by   a million to get that in the right interval there  so we specify our alarm clock and the final thing   we do is we actually tell the device to go to  sleep so having chosen our way of waking up   making sure that if we are using a trigger pin  that we have set that to the right mode as well   we've turned the lights off now we actually  go to sleep and what will happen then is that   the when either of these two events that  we chose here wakes the esp up it will go   into the setup function so that's where  we now look okay so we have looked at um   the constants the mail callback the sleep function  all the things literally all of the rest of the   functionality of this device absolutely everything  else it does is in this setup function here   now some coders will say that that's not a  particularly elegant way of doing it if you've   looked at some of the examples that come with the  esp32 camera you'll see that they actually come   with lots and lots of different uh files that you  know subroutines and modules that divide all the   functionality into different files and arguably  that is a better way to arrange complex code but i   think in terms of explaining what's happening it's  actually easier to see just this um you know it's   slightly monolithic but it literally follows it  in order the steps that happen uh in chronological   order all in one place so i'm i'm going to keep  it like this because i think this is actually   easier to explain all the different steps involved  none of them individually are that complicated   so it's just a matter of stepping through  them and explaining what they do so here goes   once again we start up with a very simple visual  education that the device is doing something so   we'll turn on the led that's on the back so  this is the little red led on the back and   remember i said it's an active low led so we  actually write a low value to it to turn it on   now this one here is slightly complicated  remember i said at the top we were including   some uh system settings libraries these ones  here so this uh particular project the camera   uses an awful lot of uh power so um anything  up to about two amps i think peak power and um   you know the esp is only a tiny little chip it's  very powerful but it it uh you know only so much   it can really provide and if it senses that too  much or not enough current is available rather   for the esp and that can happen when the camera  is drawing too much power from your power supply   it kind of shuts the esp down it's a it's a  safety feature and it's a very good safety feature   i'm going to be a little bit naughty though and  disable it because i found it's a little bit too   eager to shut itself down so as soon as you try  to actually activate the camera the first thing   that happens is the esp shuts itself off um  because the camera is drawing all the power   so there i've written a caution here just to be  aware of what this line of code is doing because   effectively i'm overriding a safety feature  that comes in the esp that is designed to   stop it from experiencing a brown out if  there isn't enough power to supply it but   i found that it was necessary um and it hasn't  caused any damage whatsoever to any of my esp   chips when i'm running on battery power otherwise  it was just always shutting off all the time i   think it's just a little bit too eager effectively  the safety protection so i'm going to turn it off   um i've created a serial connection just as  completely standard there so that we can get some   debugging information and now we're going to  configure the camera hardware now if you're   using the um the ai thinker esp32 camera like  i am you don't need to change this at all um   i've just included it here because there are a  couple of slightly different boards available   and if yours is wired differently then you'll  have to change so this is the pin on the esp32   chip and the corresponding pin on the camera and i  mentioned earlier that although the esp has got a   lot of gpio pins lots and lots of them are being  used by the camera already as you can see here   so pins 5 18 19 21 36 22 0. all of these pins here  are being assigned to some function on the camera   and that generally means we can't use them for any  other function in our codes there's actually not   that many pins available but um yeah if you're  using the same camera as me you don't need to   change those at all but i've left them there so  you can configure them if necessary now these   things you might want to change however so this  is the the configuration really of the quality of   the photograph we're taking so i'm specifying  uh that we should take a uxga which is the   highest um highest resolution photograph that the  camera is capable of that's 1600 by 1200 pixels   um now that's only possible though if your  board supports something called sudo ram   which is like an extra uh an extra tip of  ram that's on the board that enables it to   work with these higher resolution images if your  ball doesn't have that what we'll do is we'll   default down to a lower quality and a lower  resolution picture instead um and here's some   of the alternatives you can specify say qvga  vga svga um but if you're capable of doing it   i suggest this is the largest resolution and you  can also select the the quality settings as well   okay so that's the camera configuration now what  we do is we configure the flash on the front   and because we want to be able to vary the power  of that flash we need to attach it to the led   driver the pwm driver for leds on the esp  so what we do here is we um we specify uh   pwm channel seven with a um refresh hertz of  5000 and 8-bit resolution so this is setting up   the pdm controller again this is a little bit  different than if you're used to using an arduino   on an arduino you simply call analog right on  an esp it's slightly different you've actually   got different pwm channels which you can assign  to different pins what we're going to do here is   we're going to assign this sort of pdm pwm driver  that we've just here to leave open four it's all a   bit complicated if you haven't seen that before  and it's not very well explained apologies for   that but what it then means is that we can then  finally call ledc right and instead of writing   the pin directly that we want to do a pwm  signal to what we do is we write the channel   of the led controller and that channel has  previously been attached to the pin here so it's   kind of one more step removed from the pin than  you might be used to but what we'll do is we'll   specify the flash power so that might be anywhere  between zero to have the flash off and 255 for   maximum brightness like i said i quite like using  a very low power of just one or two just to light   the led up and show that a picture is being  taken uh then we will have a little pause here   now this is the first of a couple of little  pauses that we're going to introduce into the code   um remember the what i said at the top was about  the auto exposure settings of the camera well   this one is to make sure that the i squared  c interface has initialized before we try to   turn the camera on if in your code you  get some error about something like   um camera model not supported or camera not found  or something like that what it probably means is   that you're trying to initialize the camera  too soon after the code has started running   so this delay here this is just a quarter of a  second delay just to make sure that the interface   is up and running before we try to turn the camera  on uh assuming that's successful though um we will   then have access to the the camera here if  it's not successful what you notice here is   we just go back to sleep again so this was the  sleep function that we defined up here and this   will go back to sleep and then try to wake up  again whenever the trigger is next detected   but so every time we fail in the code instead of  just crashing out or giving up or something like   that what we say is okay we're going to go  to sleep and try again next time essentially   um but assuming that it was successful so we've  waited a bit for the ice cream c interface then   we turned the camera on then what we can do is we  configure some settings about the image itself now   i've included all of the different settings you  can configure here but i've put these as their   default values for now so in practice you could  actually comment out this entire section it would   have absolutely no effect because all i'm doing  is overwriting all these different settings with   what they were default set as anyway but i've  included them because i wanted to demonstrate   the different things you can say and actually  there's a surprising amount that you can   configure um so we start at the top with  things like the gain the exposure the   exposure correction and the white balance now  by default these are all set to automatic mode   so this is automatic gain this is  automatic exposure automatic white balance   if you want to specify a manual gain the  first thing you'll need to do is to disable   the automatic gain like that and instead let's  say you could now put a a manual gain value here   so somewhere between norton 30 but you do need  to disable the automatic gain first you can't   just set a manual value here otherwise what  you'll do is you'll find it will be overridden   again by the automatic the value here so we've  got gain exposure we've got some white balance   and then we've got brightness contrast saturation  there's even a handful of built-in special effects   so if you want a sepia effect or grayscale or  negative things like that you can put them here   you can flip the image over vertically or  horizontally that's quite useful if the way   that you actually mount the camera is not the way  up you want the photograph to be taken for example   there's two at the bottom if i'm totally honest i  don't even know what those do i just found them in   the esp camera library so if you happen to know  what those do uh do let me know that would be   great um but these are all the values you you can  set if you want to um uh correct the image and um   uh yeah again i said here that what we do now  is we actually wait a little bit of time before   grabbing an image from the camera and the  reason for that is because by default we   are using the automatic settings if you were to  set these to manual instead and to explicitly   set again an exposure and a  white balance level you want   then you can delay your startup time here because  that's the thing that takes the time to happen is   is configuring the the values of the automatic  settings um anyway so either way you've done that   what we do is we now we initialize uh some memory  for the frame buffer so the in-memory uh picture   that we're going to take that's in the frame  buffer then we wait this bit of time just to   make sure that the um the sensor has grabbed the  automatic exposure settings and then we actually   tried to take the picture so oops i've just  commented that out this very innocuous line here   amongst this entire you know sea of code this  is the one that actually takes the picture um   doesn't it look very plain and not really like it  does very much at all but that's the important one   and then what we can do is we can uh check the  result of that to make sure that we actually   got some data from the camera if we didn't once  again we'll say okay go back to sleep try again   next time um but assuming we did get some uh data  from it we can carry on we go on to the next step   so whether we had the flash on uh you know  as bright as possible or whether we only   had it on a tiny bit before carrying on we can  definitely turn it off now so we will write a zero   value to our seventh pwm channel and  that's the one that's controlling the flash   and then what we're going to do next  is we're going to start building up the   file name that we're going to use  to actually save our brand new   photograph too so at the moment it's still only  being held in memory we've got this frame buffer   uh sort of which is just a series of bytes in  memory and we're going to save it out to the   sd card but before we do that we need  to decide what we're going to call it   so if we are using incremental file numbering this  is where we just have a value that increases every   time we take an effect graph and we use that to  name the file so to do that we are going to use   four bytes of uh eprom memory that should  be plenty to store a big uh number in to   save our photos unless you're gonna take a  huge amount of photos that should be plenty   uh if there's already a value there then  we'll grab it and we'll increment it by one   and then what we'll do is we will build up  our path we've already got a forward stroke   pick and then we'll put the new picture number  after it's been added by one on to the end of it   and then we'll save the um the new value  back to eprom so we grab whatever was there   increase it by one use that to name our file  and then we save it back again um i have used   eprom a few times before in my different projects  probably not as much as i could actually it's very   very useful if you want to persist small pieces  of data on a um on an esp or an arduino as well   um just very very small values it can't be used  to store you know center readings and lots and   lots of data but things like configuration values  it's actually really useful and the way you do it   is you kind of create this uh copy in memory of  what the eprom value is and then you write it back   once you've finished using it so you do have to  remember to commit back to eprom because this put   command here doesn't actually save it back it just  alters the kind of in memory value and then this   actually saves it back so important to remember  to to commit once you're using any e-prompt data   okay so that uh that has modified our file  path or it might have modified our file path um   the next thing we need to do is we need to turn on  the wi-fi if we need it so if we want to grab the   timestamp now at which the photograph was taken  or if later on we're going to send an email in   either of those cases we're going to need the  wi-fi activated so here we've got some fairly   standard code on an esp to connect to a wi-fi  we'll define that we are a acting as a wi-fi   station so we're not a hotspot we're going to  be a client connecting to an existing a wi-fi   network and we'll give ourselves a name in this  case this is the camera i set up on my bird table   outside so i call it bird feeder cam and we have  a counter of the number of attempts we've made to   connect to the network and then we actually try to  connect so wi-fi dot begin with the specified ssid   and password and then what we do is we wait  basically to connect now if you've got a good   wi-fi signal this sometimes gets through on  the first count sometimes it takes a little   bit longer but this will basically loop round and  round until either it gets connected or it exceeds   ten iterations uh through this loop um and like  i say if your wi-fi network is a bit slower to   respond you might want to increase that number  there so it gives it a longer timeout basically   but in between each time it waits  half a second and then tries again   if in that time it did get connected successfully  then we'll just dump some information out to the   serial monitor to say the ip address that we got  assigned and also the strength of the wi-fi signal   if we didn't get to connect to the wi-fi  network but we wanted to because we were   using one of these features then again we say  okay go back to sleep try again next time okay   so we've reached this stage now this stage here  what we know so far is that we have successfully   taken a photograph we have successfully accessed  the picture number on the eeprom if we wanted to   we've successfully turned on the wi-fi if we  wanted to so now if we want to grab the uh current   time to append that onto the end of the file name  that's what we do in this section here um so i am   in the uk so my offset from gmt time is zero and  also we're not currently got any offset from you   know if you have daylight saving time or something  like that as well you can define an offset here so   this will be uh you will need to customize this  wherever in the world you are and whether you   are currently observing daylight savings times or  not you can enter values here which are in seconds   different from gmt so they might be quite  big values depending on where you are   and because the time server that we now  specify so we're going to call this config time   function we'll pass in our two offsets and we will  grab a time from i'm using pool.ntp.org you could   also use one of these alternative servers  instead so time.windows.com or time.nst.gov   there are other ones as well so these are servers  which exist on the internet and their only purpose   is to tell you what the time is um very useful  little things as it happens so we'll um we'll   try to configure the time and then what we'll do  is we will create a structure to hold that time in   and that will let make it easier to kind of grab  the different components of it so rather than just   being a total number of seconds since the epoch  in 1970 or whatever we can grab bits of it um so   we'll try to grab the time and put it in this time  info structure if we fail guess what we go back to   sleep if we succeed though what we'll do is we'll  output to the serial monitor what the current   time is and these little um kind of placeholder  values here these specify the elements of the   time uh that you want to show so here i'm  showing the day name uh the month and the day   of the year and the hours minutes and seconds  that's what i'm writing to the serial monitor   but for the purposes of naming the file what i'm  going to do is i'm going to write the year then   the month then the day then the hours minutes  and seconds and i'm going to append that onto   the path that we've got already so we may uh  already have appended to our path if we were   choosing the incremental file numbering we  might already have a picture number one we   but we might not we might just be looking at pick  at the moment either way what we'll do is on to   the end of uh that we will add on a time stamp  that is the year month day and you can format this   differently if you want so i've i've given an  example that shows some of these other formatters   here that you can use to retrieve elements of a  time stamp uh and put them on the file name there   now that we've finished adding elements to our  path we'll add the file extension on the end as   well so we'll just slap a jpeg extension  on the end of it that is the file format   that our frame buffer is in so when we come to  save this file it is actually going to be a jpeg   file we'll give it the right extension to make  that clear okay so we finished setting our file   name now we need to save it to the sd card so to  do that we're going to call the sd begin method   now this is a bit confusing because um i'm calling  it on the mail client object you'll remember that   mail client was something that we imported  up here which allows us to send emails   but those emails allow you to include attachments  that were sent saved on the sd card rather so so   um in order to let the mail client access  the sd card i'm calling the sd begin method   from the mail client object itself  rather than from the sd card library   so that's might seem a little bit confusing  but it just makes sure that it sets up that   kind of link from the mail client to the sd  interface basically uh the sd library itself also   defines a begin method but we're not going to call  that one we're going to call the mail client one   and these are the pins which the sd card uses so  as if we hadn't already assigned enough pins when   we were talking about the camera set up here  so all these pins are defined by the camera   we're now also going to find a load of other  pins which have to be used to access the sd cards   we're using 14 2 15 and 13. but hopefully that's  alright again these are the correct values for   the board i'm using which i'll include a link to  your board if you're using a different model or   manufacturer might be slightly different  but hopefully they're the same um if we   can't uh access the sd card with those settings  uh then we print an error message and we go back   to sleep but assuming we can we carry on so now  we try to access the file system on the sd card   so we create a new file system object and we tell  it that we're going to be using the sd format   to do it we will try to uh open the file at the  path that we have built so this was the the path   remember was all that thing where we we started  with pic and then we added an extension or we   added a timestamp then we added the jpeg extension  what we're now going to try and do is save the   file to that path so to save a file you actually  call the open method but pass in the file right   sort of parameter at the end there and assuming  that was successful um what we will do is we will   then write the contents of our frame buffer  into that file that we opened for writing   um i'm not even going to say this anymore  but if if it was in successful at writing   we go back to sleep um but yeah so what we  do here we we um we access the file system   tell it that we're using the sd card we open the  file that we have created so the the unique path   for this version that increments every time  we open it with the right mode and then we   write the buffer values and the length  of the buffer we write into that file   and then we just put a little message to say  hooray we saved the file and then we can close it and now that we've finished working  with the camera as well we've saved the   the frame buffer we had we can also release that  from the esp cam so all this up to now we've just   been holding in memory the whole time the bytes  of our image data but now that we've successfully   written it to the sd card we can release all  that memory that we've been hanging on to   that's been holding onto that image so we can  release that and we can take a little breath   phew that's just to let everything stabilize  that probably doesn't even need to be there but   i just like the idea of the esp  needing to breathe at that time   okay so we've written it to the sd card and maybe  uh that's all that needs to happen but um if you   chose that you want to get the email sent to you  now with that attachment as well then we will need   to step through this bit again it's not too hard  it's just a bit of a base there's lots of it um   so smtp where you set debug mode on you don't  actually need to do that but i find it's pretty   helpful it gives you a lot of output um because  there's sort of various steps involved here and if   any of them fail it's useful to see uh what what  happened particularly when you are sort of first   trying to get this to work um so you uh first of  all we define a session so there's kind of various   nested uh objects within the the email client  functionality and the largest one of these is   the session and the session relates to the host  and the port and the author email so this is our   account from which we're going to send the email  um so we define a session object and we configure   those values most of which were defined in the uh  the top of the code here as well at the top of the   code then what we do now that we've got a session  well now we need to create a message within that   session so we set the name of who this message  comes from and also the email that comes from   we set the message subject and we add recipients  who are going to receive this message as well   and you can add multiple recipients you can  also add ccs or bcc's to your email as well   and we add whatever the text content we want to be  to your message so i've just got some plain text   here but you could make this more interesting if  you want and we specify the encoding format that   the message comes in so all this here this is just  like what you do when you open up gmail or hotmail   or whatever and you type your new email to someone  these are the basically the fields that you would   enter when you're writing an email to someone and  then we define the attachment that we're going to   add to the message which is part of the session so  the attachment well this is going to be the file   that we've just uh saved onto our sd card isn't  it so we'll define an attachment we'll call it att   we'll give it a file name and a mine type so  it's going to be binary data so octet stream   and then this is the important one because we need  to tell the mail client where it's going to find   the data to include as part of this file and it's  going to be the path again so this path that we've   been using all along we built it up we called  it here when we saved the file to the sd card   so we're going to call exactly the same thing  again to tell the male client where to find it on   the sd card we'll just use exactly the same value  and then it's on the sd it is encoded in base 64.   and then this line here adds the attachment  to the message above it so we now have a   message containing an attachment and what  we need to do is to send that to the session   so we've got two steps here first of all we try to  connect to the uh smtp session with the variables   that we defined up here and then if that is  successful what we then do is we then try to   send the mail so again we pass in uh a reference  to the smtp server and a reference to the message   that we've just created up here which remember  contains the attachment as part of it now   and hopefully that's successful but if not guess  what we go to sleep we go to sleep and then we   finally get to the end of the code so this is  the the last line that we need this send mail   send them out so now we've finished all of our  wi-fi functionalities we can disconnect from   wi-fi if we're using it we can turn the wi-fi  off and for the final time we can go to sleep   and so whatever actions were taken  depending on what features you chose   right at the top of the code here remember half  an hour ago whenever it was i was talking about it   so you can define these different functions  up here and depending on which ones you have   commented and uncommented out different  sections of this code will be executed from   top to bottom but essentially they they literally  just follow through the code in order we configure   the camera settings we turn the camera on we  take the photo and then we either get the new   file number to assign the photo or alternatively  we connect to a time server and get the time   and then we save the file to the sd card and  then we send the file from the sd card via email   and then we turn the wife off and then we go to  sleep and every time we go to sleep again remember   we looked at this function before uh what we do  is we just specify the conditions on which we   want to wake up again so we make sure we've got  the pins in the right state and then we either   wake up when that pin goes high or when it goes  low or after a certain amount of time has elapsed   and uh then we go to sleep here and this will  now put the board into a very low power state   all of that functionality would turn off it  would only wake up when these events happen   at which point it will run through this whole  setup code again and take another picture so hopefully this video has given you an insight  and let me pass on some of the things i've learned   from using these little esp32 cam boards like  i say they're not going to win any prizes for   best photograph competition but they're they're  so small and they're so cheap i mean i literally   bought a box of i think five of them for about  20 pounds um that you can just play around with   them and try using them in different projects  so whether you want to create a wildlife camera   in your garden or maybe you want to create like a  smart doorbell system that takes a video of anyone   that comes to your door or like me whether you  want to try to put them as part of an escape room   prop or puzzle that takes a photograph of players  when a certain game event happens hopefully i've   been able to give you the idea and some of the  knowledge that you'll need to be able to kind   of run those kind of projects i'll copy the  code i've used and the wiring diagrams and   things like that i'll probably put them onto my  github account later so you can see them there   i'm only able to create these videos with the  support of my patreon donors so i'd like to say   all thank you very very much for continuing  to support me i know normally the videos i   make a slightly more escape room puzzle focus  than this but i hope you felt that this was   similar enough that there is a kind of knowledge  that you can use here and and take it into an   escape room context in my next video i will  probably be going back and maybe even finishing   off the escape room in a box i've been making uh  which has been going for a little while now so   if you're interested in finding out more about  what's gone into that please do follow along   and i will look forward to seeing you  in that video next time okay cheers bye
Info
Channel: Playful Technology
Views: 34,939
Rating: undefined out of 5
Keywords: ESP, ESP32, ESP 32, ESP-32, Camera, ESP32 Cam, Arduino, Wildlife Camera, Timelapse Camera
Id: FmlxC0goKew
Channel Id: undefined
Length: 71min 37sec (4297 seconds)
Published: Mon Apr 26 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.