Well why wouldn’t you want a night vision camera. My first idea was to have a raspberry pi with a night vision camera but instead of a screen it would stream to a phone in one of these “virtual reality” headsets but I couldn’t find a setup that didn’t have too much lag.
I also didn’t want to make just another raspberry pi camera so that’s why I went with the night vision camera. What started as an “easy” project turned into a long list of problems to solve, that’s where the fun lies
- Raspberry pi zero W
- Night vision IR raspberry pi camera
- Xiaomi power bank board
- 3x push buttons
- Power switch
- 1200 mAh lipo battery
- ADS1115 analog I2C
- 3.2″ touch screen
- Aluminium enclosure
- Female USB panel mount
- Female micro USB panel mount
- 3x 3mm LED’s
- 3x 3mm LED panel mounts
Total cost £66.51
The power struggle
I thought this would be a relatively straight forward project untill I got into the details. One of the details was the power requirements. Its easy enough to power a raspberry pi but when you throw in a screen and the camera. What makes it even more difficult is that fact that the camera has 2 high power IR LED’s. While testing I tried a few power banks I had on hand. I found out that the raspberry pi, screen and camera were pulling about 1.5amp – 2amps with the IR LED’s on pull power.
I found that most power banks I had wern’t up for the task. I took a punt on Xaomi power bank board, It claimed to output 2amps. I tested the power bank when it arrived and sure enough I was able to support the Raspberry pi zero, screen, camera as well as the IR LED’s.
I was all set, Found a 1200 mAh lipo battery and give it an endurance test. With the IR LED’s on the whole time I was only managing 45 mins, This wasn’t terrible considering the whole setup was pulling 1.5amps. I went looking for a bigger battery and found a 2000mAh battery that was nice and slim, the problem with this battery was it couldn’t handle the high current draw from the power bank so I switched back to the 1200mAh battery. ideally I would use a Samsung 25r 18650 cell but there isn’t enough space. These battery’s are designed for high current draw and are often used in the vaping scene.
I know what your thinking, why would you add LED’s to a night vision camera. The first LED I always add to a raspberry pi project is to break out the ACT LED, This is so that when you shutdown the pi you can see the 10 flashes that tell you it’s finished shutting down and its safe to turn off plus it doesn’t hurt to see the activity of the pi.
The other 2 LED’s I added were broken out from the power bank board, On the power bank board there are 4 LED’s to indicate the battery level while discharging and charging. I only broke out the 1st and last LED’s so I would know when that battery’s getting low and when it had finished charging.
Where do I start with the software. While I was waiting for my 3.2″ screen to come I was using a 5″ HDMI screen. I got the camera up and running using pi camera. It wasn’t until I received the 3.2″ screen that my first problem cropped up, You see the pi camera using a hack where is basically pipes the camera to the HDMI output so when I was using the 5″ HDMI screen it worked find but the 3.2″ screen didn’t show anything.
To solve this I turned to pygame, This wasn’t a problem since I would be building my interface with this. I found this code that grabbed the output from the camera and put it into a frame buffer that was then displayed in pygame. This was great because it allowed me to scale down the stream to fit the 3.2″ screen.
My next problem was how was I going to access the photos from the camera. I first thought about turning the pi zero w into an access point and viewing the photos in the web browser on my phone, This seamed clunky. I finally came up with the plan to use a removable usb flash drive and hard coding the mount point into the code, This obviously has its down sides because only one USB drive would work with it. I found a really hacky way to find the current mount point on the pi. I basically using python to execute bash commands and read the output.
proc = Popen(["ls /media/pi/"], stdout=PIPE, shell=True) # Run comman and send it to stdout and stder out, err = proc.communicate() # Read data from stdout and stderr print out print eer
If you use this code it will turn the output of the command into a string so It can be used within python to define the paths to the mounted USB drive. This made it possible to watch for a drive to be mounted then write to that drive then if it was ejected it would save the photos and videos to the sd pi’s sd card.
Auto start pygame
So I wanted this project to be able to turn it on and it would auto load up to the camera python script, What I normally do is use the systemD systemctl scripts but this wouldn’t work with this pygame script. I searched high and low for a solution, I found that if you add a line to the file below
It’s just the same command as you would use to run your script
Analog Read, as easy as pi
So one fun fact about the raspberry pi is that it doesn’t have an analog read pin. So to read anything analog you have 2 chooses, You can ether use a MPC3008 or a ADS1115/ADS1015. The MPC3008 comunicates via SPI and the ADS1115/ADS1015 communicates via I2C. I went with the ADS1115 because the screen I was using used SPI. You can read up to 4 different channels at the same time but I only need one for this project.
The other problem with reading the battery levels is it needs to be isolated while the raspberry pi is off. Normally I use a single pole double throw switch(SPDT). The problem with these switches is there aren’t many to choose from and they tend to be bulky. At first I thought I could use a 2N7000 mosfet so it would be triggered when the pi was turned on by wiring up the gate to the power pin on the pi. For what ever reason I was getting leakage when it was off. I rewired it up so that the battery was isolated by the switch from the power bank board so it would be isolated from the ADS1115 board too. I don’t know why I didn’t think of this the first time round.
If you want just the basic code to read the battery level and turn it into a % then check out the link HERE
If you are looking to use the ADS1115 here is their github page
I have 3 push buttons, 2 buttons are for taking photos and recording video. The other one is connected to the button on the power bank, This is because the power bank needs its button pressed to turn it on after the battery has been reconnected, which is what the power switch does.
The 3.2″ screen I used came with 3 buttons down the left hand side, I decide to use 2 of the buttons for the take photo and video record buttons. I removed the buttons from the side of the screen so it would sit flush in the enclosure. When I wired up the buttons I wired them from the pins on the bottom of the raspberry pi, what I didn’t realise was that because I removed the buttons off the front that the PCB traces would still be connected so when I put it all together the buttons were acting weird. I had to take the camera all apart and cut the pins off the raspberry pi so it wouldn’t connect to the traces on the screen PCB.
I needed to break the OTG USB port on the raspberry pi w. I found a female usb panel mount, I cut the male end off the cable and soldered on one of these tiny USB OTG adaptors that normally slot into the male usb port. This made it really compact which is what I was looking for.
The screen I picked was a cheap and cheerful clone of the waveshare 3.2″ screen with buttons. With only a resolution of 320 x 240 it isn’t great but it’s not terrible ether. They can be found on eBay for about £8ish from china. I found the easiest way to get it set up was to use the drivers that requires internet access LCD-show-170703.tar.gz (download link) to install because this will install all the dependencies you will need.
If you plan on developing right on the screen its self follow my guild to get it setup to take advantage of the small screen real estate
Hardware walk through
Test footage in the dark
The base of my code came from this github link – https://gist.github.com/radames/f7b46828929c78bd66b5