Here we provide the Python code required to operate the automated learning chamber and explain what each section of the code does. The full raw Python code can be found in the main.py file.
Required imports
There are 6 Python packages that are necessary to import for this project.
time
is imported in order to use the sleep()
function to pause between certain script commans.
picamera
is imported so that we can use functions which allow us to control the Raspberry Pi camera.
datetime
is imported so that we can display date and time stamps on the experimental footage.
pigpio
is imported for access to functions that allow us to control the LED lights
RPi.GPIO
is imported for access to functions that allow us to control the Raspberry Pi GPIO pings
random
is imported to create random numbers to randomly decide which side of the tank will have the light shine and food delivered.
import time
from picamera import PiCamera
import datetime as dt
import datetime
import pigpio
import RPi.GPIO as GPIO
from random import randrange
Feeder control
In the following chunk of code we are defining the feeder_activate
function.
def feeder_activate(rand_number):
""" " "
takes as input a random int either 0 or 1
depending on that, it will activate either feeder 1 or 2
0 corresponds to feeder 1
1 corresponds to feeder 2
" " """
if rand_number == 0:
feeder_pin = 16
print('Activating Feeder #1')
elif rand_number == 1:
feeder_pin = 37
print('Activating Feeder #2')
else:
feeder_pin = 0
print("Invalid option.")
return 0
GPIO.setmode(GPIO.BOARD)
GPIO.setup(feeder_pin, GPIO.OUT)
servo1 = GPIO.PWM(feeder_pin, 50)
servo1.start(0)
print('Waiting for 1 second')
time.sleep(1)
# Moving the servo
duty = 2
while duty <= 4:
servo1.ChangeDutyCycle(duty)
time.sleep(0.1) # just enough time for the wing to get there
servo1.ChangeDutyCycle(0) # then we set it to 0 so it stops
time.sleep(0.1) # time we want it to stop for
duty = duty + 1 # then continue to next iteration
# Wait one second
time.sleep(1)
# Turn back to 0 degrees
print('Turning back to 0 degrees!')
servo1.ChangeDutyCycle(2)
time.sleep(0.5)
servo1.ChangeDutyCycle(0)
servo1.stop()
print('Cleaning up...')
GPIO.cleanup()
print('All done!')
Camera settings
Here we will configure the resolution and image quality of the recording from the Raspberry Pi camera.
We start with the line print("Welcome to the automated chamber!")
to indicate that the script has started. Next, camera = PiCamera()
initializes a PiCamera instance and sets it equal to camera
. We then set the resolution, rotation, and ISO of the camera.
print("Welcome to the automated chamber!")
camera = PiCamera()
print("Passed PiCamera() line")
camera.resolution = (1640, 1232)
camera.rotation = 0
camera.iso = 800
print("Starting up the camera...")
# Waiting for automatic gain control to settle
time.sleep(2)
# Making camera values fixed
camera.shutter_speed = camera.exposure_speed
camera.exposure_mode = 'off'
g = camera.awb_gains
camera.awb_mode = 'off'
camera.awb_gains = g
camera.start_preview()
print('Previewing Now')
now = datetime.datetime.now()
dt_string = now.strftime('/home/pi/automated_chamber/training_videos/train%d%m%Y_%H%M%S.h264')
print('Date and time: ', dt_string)
Main script
Start recording first 3 minutes
First we start recording from the Raspberry Pi Camera by calling the start_recording
function from the PiCamera library. For documentation purposes we will want to annotate the top of the video frame with the date time and we want this to update every second so we run a for
loop which will annotate the camera background with the current date andn time every second.
camera.start_recording(dt_string)
print('Recording first 3 minutes: baseline before we trigger the lights')
for x in range(0, 180):
camera.annotate_background = True
camera.annotate_text = dt.datetime.now().strftime('%m-%d %H: %M: %S:')
time.sleep(1)
Activating lights
Next we trigger the lights and then the feeder. First we chose a random number, either 0 or 1 using the randrange
function so that we can randomly decide whether the left or right feeder and light will be activated for this session. Depending on the value we activate either the left or right light and then wait for 5 seconds.
# trigger lights 5 seconds BEFORE feeder
rand_Number = randrange(2)
pi = pigpio.pi()
print('Turning lights ON...')
if rand_Number == 0:
pi.set_PWM_dutycycle(22, 75)
else:
pi.set_PWM_dutycycle(6, 75)
time.sleep(5)
Activating feeder
Next we run the feeder activate function.
# trigger feeder now!
print('Activating Feeder...')
feeder_activate(rand_Number)
# turn off light
print('Turning lights OFF...')
pi.set_PWM_dutycycle(22, 0)
pi.set_PWM_dutycycle(24, 0)
pi.set_PWM_dutycycle(17, 0)
pi.set_PWM_dutycycle(5, 0)
pi.set_PWM_dutycycle(6, 0)
pi.set_PWM_dutycycle(16, 0)
pi.stop()
Stop recordinng
We will continue to anontate the video frame with the datetime for the last 3 minutes annd then stop recording.
print('Recording last 3 minutes: after light stimulus')
for x in range(0, 180):
camera.annotate_background = True
camera.annotate_text = dt.datetime.now().strftime('%m-%d %H: %M: %S:')
time.sleep(1)
print('Terminating program...')
camera.stop_recording()
camera.stop_preview()
camera.close()