├── README.md └── picamcorder.py /README.md: -------------------------------------------------------------------------------- 1 | # picamera 2 | Raspberry Pi Action Cam based on Alex Eames' [PiCamCorder2](http://raspi.tv/2013/raspicamcorder-2-standalone-raspberry-pi-camcorder-with-buttons-screen-and-dropbox-capability) and updated to work on the new 40 pin headers. 3 | -------------------------------------------------------------------------------- /picamcorder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | # script by Alex Eames http://RasPi.tv 3 | # needs RPi.GPIO 0.5.2 or later 4 | # updated to work on the A+ 5 | 6 | import RPi.GPIO as GPIO 7 | from subprocess import call 8 | import subprocess 9 | from time import sleep 10 | import time 11 | import sys 12 | import os 13 | 14 | front_led_status = sys.argv[-1] 15 | if front_led_status == "0": 16 | print "front LED off" 17 | front_led_status = 0 18 | 19 | GPIO.setmode(GPIO.BOARD) 20 | 21 | # GPIO 33 & 25 set up as input, pulled up to avoid false detection. 22 | # Both ports are wired to connect to GND on button press. 23 | # So we'll be setting up falling edge detection for both 24 | GPIO.setup(33, GPIO.IN, pull_up_down=GPIO.PUD_UP) 25 | #GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP) 26 | 27 | # GPIO 35 set up as an input, pulled down, connected to 3V3 on button press 28 | GPIO.setup(35, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 29 | 30 | # Set up GPIO 5 for camera LED control and rear LED control 31 | GPIO.setup(5, GPIO.OUT) 32 | GPIO.setup(22, GPIO.OUT) 33 | 34 | recording = 0 35 | vid_rec_num = "vid_rec_num.txt" 36 | vid_rec_num_fp ="/home/pi/vid_rec_num.txt" # need full path if run from rc.local 37 | base_vidfile = "raspivid -t 3600000 -o /home/pi/video" 38 | time_off = time.time() 39 | 40 | def write_rec_num(): 41 | vrnw = open(vid_rec_num_fp, 'w') 42 | vrnw.write(str(rec_num)) 43 | vrnw.close() 44 | 45 | def start_recording(rec_num): 46 | global recording 47 | if recording == 0: 48 | vidfile = base_vidfile + str(rec_num).zfill(5) 49 | vidfile += ".h264 -fps 25 -b 15000000 -vs" #-w 1280 -h 720 -awb tungsten 50 | print "starting recording\n%s" % vidfile 51 | time_now = time.time() 52 | if (time_now - time_off) >= 0.3: 53 | if front_led_status != 0: 54 | GPIO.output(5, 1) 55 | GPIO.output(22, 1) 56 | recording = 1 57 | call ([vidfile], shell=True) 58 | recording = 0 # only kicks in if the video runs the full period 59 | 60 | #### Quality VS length ### 61 | # on long clips at max quality you may get dropouts 62 | # -w 1280 -h 720 -fps 25 -b 3000000 63 | # seems to be low enough to avoid this 64 | 65 | def stop_recording(): 66 | global recording 67 | global time_off 68 | time_off = time.time() 69 | print "stopping recording" 70 | GPIO.output(5, 0) 71 | GPIO.output(22, 0) 72 | call (["pkill raspivid"], shell=True) 73 | recording = 0 74 | space_used() # display space left on recording drive 75 | 76 | def space_used(): # function to display space left on recording device 77 | output_df = subprocess.Popen(["df", "-Ph", "/dev/root"], stdout=subprocess.PIPE).communicate()[0] 78 | it_num = 0 79 | for line in output_df.split("\n"): 80 | line_list = line.split() 81 | if it_num == 1: 82 | storage = line_list 83 | it_num += 1 84 | print "Card size: %s, Used: %s, Available: %s, Percent used: %s" % (storage[1], storage[2], storage[3], storage[4]) 85 | percent_used = int(storage[4][0:-1]) 86 | if percent_used > 95: 87 | print "Watch out, you've got less than 5% space left on your SD card!" 88 | 89 | # threaded callback function runs in another thread when event is detected 90 | # this increments variable rec_num for filename and starts recording 91 | def my_callback2(channel): 92 | global rec_num 93 | time_now = time.time() 94 | if (time_now - time_off) >= 0.3: 95 | print "record button pressed" 96 | rec_num += 1 97 | if recording == 0: 98 | write_rec_num() 99 | start_recording(rec_num) 100 | 101 | def flash(interval,reps): 102 | for i in range(reps): 103 | GPIO.output(5, 1) 104 | GPIO.output(22, 1) 105 | sleep(interval) 106 | GPIO.output(5, 0) 107 | GPIO.output(22, 0) 108 | sleep(interval) 109 | 110 | def shutdown(): 111 | print "shutting down now" 112 | stop_recording() 113 | flash(0.05,50) 114 | GPIO.cleanup() 115 | os.system("sudo halt") 116 | sys.exit() 117 | 118 | print "Make sure you have a button connected so that when pressed" 119 | print "it will connect GPIO port 33 (pin 16) to GND (pin 6)\n" 120 | print "You will also need a second button connected so that when pressed" 121 | print "it will connect GPIO port 35 (pin 18) to 3V3 (pin 1)\n" 122 | #print "You will also need a third button connected so that when pressed" 123 | #print "it will connect GPIO port 25 (pin 22) to GND\n" 124 | 125 | # optional for when you're at the terminal 126 | #raw_input("Press Enter when ready\n>") 127 | 128 | # when a falling edge is detected on port 33 my_callback2() will be run 129 | GPIO.add_event_detect(33, GPIO.FALLING, callback=my_callback2) 130 | 131 | # when a falling edge is detected on port 25, my_callback() will be run 132 | #GPIO.add_event_detect(25, GPIO.FALLING, callback=my_callback, bouncetime=500) 133 | 134 | # check rec_num from file 135 | try: 136 | directory_data = os.listdir("/home/pi") 137 | if vid_rec_num in directory_data: 138 | 139 | # read file vid_rec_num, make into int() set rec_num equal to it 140 | vrn = open(vid_rec_num_fp, 'r') 141 | rec_num = int(vrn.readline()) 142 | print "rec_num is %d" % rec_num 143 | vrn.close() 144 | 145 | # if file doesn't exist, create it to avoid issues later 146 | else: 147 | rec_num = 0 148 | write_rec_num() 149 | 150 | except: 151 | print("Problem listing /home/pi") 152 | flash(0.1,10) 153 | GPIO.cleanup() 154 | sys.exit() 155 | 156 | try: 157 | while True: 158 | # this will run until button attached to 35 is pressed, then 159 | # if pressed long, shut program, if pressed very long shutdown Pi 160 | # stop recording and shutdown gracefully 161 | print "Waiting for button press" # rising edge on port 35 162 | GPIO.wait_for_edge(35, GPIO.RISING) 163 | print "Stop button pressed" 164 | stop_recording() 165 | 166 | # poll GPIO 35 button at 20 Hz continuously for 3 seconds 167 | # if at the end of that time button is still pressed, shut down 168 | # if it's released at all, break 169 | for i in range(60): 170 | if not GPIO.input(35): 171 | break 172 | sleep(0.05) 173 | 174 | if 25 <= i < 58: # if released between 1.25 & 3s close prog 175 | print "Closing program" 176 | flash(0.02,50) # interval,reps 177 | GPIO.cleanup() 178 | sys.exit() 179 | 180 | if GPIO.input(35): 181 | if i >= 59: 182 | shutdown() 183 | 184 | except KeyboardInterrupt: 185 | stop_recording() 186 | GPIO.cleanup() # clean up GPIO on CTRL+C exit 187 | --------------------------------------------------------------------------------