Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Roman KellenbergerCarlos A Lugo
Published © GPL3+

Variable-Time Camera for Monitoring Plant Pollination Events

This is a Raspberry Pi Zero-based time-lapse photo / video camera to monitor plant-pollinator interactions in the field.

BeginnerWork in progress2 hours2,172
Variable-Time Camera for Monitoring Plant Pollination Events

Things used in this project

Hardware components

Raspberry Pi Zero
Raspberry Pi Zero
×1
ZeroCam - Camera for Raspberry Pi Zero
For camera version 1
×1
Flash Memory Card, MicroSD Card
Flash Memory Card, MicroSD Card
We used cards with 32GB capacity from various manufacturers with mixed success. The best result was obtained with cards from SanDisk
×1
AUKEY 5000mAh Power Bank
The Pi zero requires 5V input. A 2200 mAh / 5V / 1A power bank allowed to take 2345 photos, and a 5000 mAh / 5V / 2A power bank allowed to take >5000 photos in an interval of 10sec.
×1
USB-A to Micro-USB Cable
USB-A to Micro-USB Cable
×1
Transparent clip box 6x16x11cm
For camera version 1
×1
Ultratape Double Sided Foam Tape
×1
Dummy CCTV camera
For camera version 2
×1
Pimoroni Camera Module for Raspberry Pi Zero – 160° variable focus
For camera version 2
×1
Pimoroni Raspberry Pi 3 Heatsink – 6mm
For camera version 2
×1
5V cooling fan
For camera version 2
×1
Adafruit BME280 I2C or SPI Temperature Humidity Pressure Sensor
For camera version 2
×1
arduino 4pin oled i2c 128x64
For camera version 2 We don't know exactly where ours comes from, but there are many very similar ones out there that work in an identical way.
×1
Pimoroni Mini Breadboards & Jumper Jerky
For camera version 2
×1
Maker Essentials - Mini Breadboards & Jumper Jerky
Pimoroni Maker Essentials - Mini Breadboards & Jumper Jerky
For camera version 2
×1

Software apps and online services

Raspbian
Raspberry Pi Raspbian

Hand tools and fabrication machines

Multitool, Screwdriver
Multitool, Screwdriver
For camera version 2
Soldering iron (generic)
Soldering iron (generic)
For camera version 2

Story

Read more

Code

Camera script

Python
This script is used to take a series of pictures or videos using the Pi zero W system and assuming no access to a wireless network. It of course should work in most Pi's with a recent Raspbian version.
Picture series or video are captured over several predetermined intervals in the field and variable duration. The script is executed after booting the Pi zero.
The name of the script is fr.py and it should be located at the folder Camera. i.e. ~/home/username/Camera/ where username changes depending of each user instalation. In our case it is the standard user pi. So the script is located in ~/home/pi/Camera.

In order to execute the script after boot, the lines:
cd Camera
./fr.py &

need to be added to the file /etc/profile
#!/usr/bin/python3

import os
from time import sleep
from datetime import datetime
import picamera
import glob

##############
VID=False #Boolean for pics or video False is pictures, True is videos
NP=2000  #Number of pictures
PWT=10  #Time bewteen pictures in seconds 
VWT=5*60  #Video length in seconds
NV=3    #Number of videos
NPX=1      #Number of picture series
DT=10*60    #Interval between videos in seconds
DTP=0    #Interval between picture series in seconds-0 one series
##############
def picts(wt,M,PTH,N):

	crot= 270
	cres=(1024,768)
	camera=picamera.PiCamera()
	camera.rotation=crot
	camera.resolution=cres
	for i, filename in enumerate(camera.capture_continuous(PTH+'/'+str(M+1)+'-'+'image{timestamp:%H-%M-%S}-{counter:04d}.jpg')):
		sleep(wt)
		if i ==(N-1):
                	break

	camera.close()

###############
def vids(ST,M,PTH):
	camera=picamera.PiCamera()
	ts=PTH+'/'+str(M+1)+"-"+datetime.now().strftime("%H-%M-%S")
	camera.start_recording(ts+'.h264')
	camera.wait_recording(ST)
	camera.stop_recording()
	camera.close()
	print("DONE VIDEO")
##############
def wrtrun():
	with open("NR.TXT","w") as f:
		f.write(str(0))
##############
def main():
	nrl=glob.glob("*.TXT")
	if len(nrl)==0:
		wrtrun()
	

	with open("NR.TXT","r") as f:
		for row in f:
               		nk=int(row)
	NF=nk+1

	with open ("NR.TXT","w") as f:
        	f.write(str(NF))

	PTH="BOOT"+str(NF)
	os.mkdir(PTH)
	
	if VID==False:
		sleep(50)
		for np in range(NPX):
			picts(PWT,np,PTH,NP)
			if DTP>0:
				sleep(DTP)
			else:
				pass
	else:
		sleep(50)
		for nv in range(NV):
			vids(VWT,nv,PTH)
			sleep(DT)
	
	with open("NRLOGS.TXT","w") as f:
		f.write(PTH+" process completed without interruptions")

	os.system("sudo shutdown -h now")  
##############
main()

Wireless camera calibration stream.

Plain text
The second version of the camera has an adjustable lens to modify the focal point on the fly. In order to adjust the focus for a particular set up we provide this simple command which generates a live stream of the camera to a remote device such a mobile phone, another raspberry pi or a computer. Once you start this stream It will be available for a period of time so you will be able to adjust the lens according to your needs.
If you are an Android user we recommend the application Rpi Camera Viewer:

https://github.com/ShawnBaker/RPiCameraViewer

It works with this stream out of the box and it is well documented. The key argument -t 60000 means that the stream will last one minute.
raspivid -n -ih -t 60000 -w 1280 -h 720 -b 1000000 -fps 15 -o - | nc -lkv4 5001 

BME 280 sensor and 128x64 OLED graphic display script.

Python
The second iteration of the camera was equipped with an Adafruit BME280 Humidity + Barometric Pressure + Temperature Sensor Breakout and a display.
This python script is used to collect measurements and display the readouts in the screen. It uses CircuitPython and the packages Adafruit CircuitPython BME280 and Adafruit_CircuitPython_SSD1306 to handle the breakout and the display respectively.
Detailed instructions on how to install all the above can be found in the following sites:
CircuitPython:

https://learn.adafruit.com/circuitpython-on-raspberrypi-linux

Sensor breakout:
https://github.com/adafruit/Adafruit_CircuitPython_BME280

Display:
https://github.com/adafruit/Adafruit_CircuitPython_SSD1306

In our setting the display operates via I2C, whereas the sensors are wired using the SPI configuration.

If you wish your code to be launched automatically as in the case of the camera script just add this file to the Camera folder and edit the profile folder adding the name of this file after the camera script:

./infop.py &

Notice that with all these scripts you can now combine the sensor, camera and display into a single script in order to log environmental data alongside pictures and videos. This of course is entirely up to your custom needs.
import time
import subprocess
from board import SCL, SDA
import busio
import adafruit_ssd1306
from PIL import Image,ImageDraw,ImageFont

import board
import busio
import digitalio
import adafruit_bme280


spi = busio.SPI(board.SCK,MOSI=board.MOSI,MISO=board.MISO) 
cs = digitalio.DigitalInOut(board.D5)
bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi,cs)


i2c=busio.I2C(SCL,SDA)
display=adafruit_ssd1306.SSD1306_I2C(128,64,i2c)
display.fill(0)
display.show()

width=display.width
height=display.height
image=Image.new("1",(width,height))
draw=ImageDraw.Draw(image)
draw.rectangle((0,0,width,height),outline=0,fill=0)
padding= -2
top=padding
bottom=height-padding
x=0
font=ImageFont.load_default()
while True:
    draw.rectangle((0,0,width,height),outline=0,fill=0)
    
    cmd="hostname -I | cut -d\' \' -f1"
    IP= subprocess.check_output(cmd, shell=True).decode("utf-8")
    draw.text((x,top+0),"IP: "+IP,font=font,fill=255)

    T=("T: %0.1f C" % bme280.temperature)
    draw.text((x,top+8),T,font=font,fill=255)
    
    P=("P: %0.1f hPa" %bme280.pressure)
    draw.text((x,top+16),P,font=font,fill=255)
    
    H=("Hum: %0.1f %%"%bme280.humidity)
    draw.text((x,top+25),H,font=font,fill=255)
   
    cmd = "df -h | awk '$NF==\"/\"{printf \"Disk: %d/%d GB %s\", $3,$2,$5}'"
    Disk = subprocess.check_output(cmd,shell=True).decode("utf-8")
    draw.text((x,top+33),Disk,font=font,fill=255)

    display.image(image)
    display.show()
    time.sleep(.1)
print("DONE")

Github code repo.

The picture/video collection script and a timelapse video creation script can also be found here.

Credits

Roman Kellenberger

Roman Kellenberger

1 project • 1 follower
Carlos A Lugo

Carlos A Lugo

1 project • 2 followers
Theoretical Physicsist very interested in low-cost automation and physical computing applications to research and fun.
Thanks to Boris Delahaie and Allan Ellis.

Comments