Monday, February 24, 2014

Raspberry Pi Makerbot Cam

We've been using our new Makerbot 3D printer quite a bit since we got in in December in our school. I've been the one learning how to use it and training some students to use it. So it's taken quite a lot of my time watching the results from printing different projects under different conditions. Not every print comes out successfully and sometimes you need to cancel a print because you can see that something is going wrong. And sometimes a spool of filament is running low and you're not sure there will be enough to complete a print. Rather than having to check on it every so often, I wanted to set up a streaming Makerbot cam with my Raspberry Pi and the new Pi Cam I got for it so I can oversee prints wherever I am.
The Pi Cam produces very nice quality still and video images and there are some very good tutorials on making it do lots of different things.
I like to do things a little at a time, so in this post I'm outlining the steps toward the eventual goal of streaming video and some of the hurdles on the way to getting there.

Getting the camera working

Getting the camera plugged in and snapping pics and video was easy and fun. The Raspberry Pi folks have put this information together here: Raspberry Pi Camera setup. In the process I wanted to start using the Raspi in "headless" mode to make it easier to get the photos off. My email client doesn't really work on it and plugging in a USB drive to copy files takes time. 

Remote access to images

From a Mac I use Terminal to log right in to the Raspi. Get the Raspi's IP by typing ifconfig on the Pi (connected to a monitor with peripherals), then use that to log in with SSH:

ssh pi@ipAddress
Now I'm at the pi prompt and can type the camera commands to take pictures and video. But the files are saved on the Pi. To get them off, log out of the ssh session. I used SCP to copy them to my Mac:

scp pi@ipAddress:image.jpg Desktop/image.jpg

puts the image right on my desktop.

Streaming video to a website

Miguel Grinberg has a great method of setting up a constant stream of images to the web from a Raspi Cam here. The idea is not to stream video, but to take stills in rapid succession, each new one replacing the previous, and stream those with MJPG-Streamer. So far it's pretty choppy for me, but I haven't played with the framerate yet. I can probably tweak it to get a smoother stream. Here is a sample:
There is a point in Grinberg's tutorial where he provides an update on installing MJPG-Streamer. Definitely follow it. The information is crucial to getting it to work successfully. I found a couple Linux command line tools useful. To stop the raspistill process before it's finished, first log out of the SSH session (the trailing & allows you to log out without killing the process), log back in and type:
$ ps aux | grep raspistill
That shows the raspistill process ID. Then you can kill it with:
$ sudo kill 2314 
(or whatever it's process ID is)

Running the streamer from button input

So I don't want to have to log in to the Pi and run this line of code every time I want the Pi to stream Makerbot footage:
$ raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &

What I need is a button I can press on the Pi that starts taking pictures for an hour or two. So I've ordered this setup from Adafruit--a GPIO ribbon and breakout board--to which I'll wire a button. The MJPG Streamer is always running, so all it needs is the pictures to dump into the streaming folder. This took some time to figure out. Here is the wiring below, which includes wiring for a momentary switch and an LED that will stay on as long as the camera is taking stills. The LED on the camera would work were it not for the camera enclosure I printed, which covers up the LED. I know, I could have drilled one or put it in the design, but a little more wiring is fun. Some tips on this setup follow:
Note: LED is on because switch has just been pressed.
To figure this out, I mostly used these two resources; buttons and switches and blinking LEDs. Initially the switch did nothing because I made the mistake of having the GPIO ribbon reversed. Heed this advice and make sure the single different colored wire on the ribbon--in my case, white--is oriented so it is towards the outside facing end of the Pi, not towards the middle. And on the topic of GPIO pin numbering, I am using BCM mode, which is a confusing topic for beginners like me and well explained here (down the page at A Word About GPIO Pin Numberings). The concept of pullup and pulldown resistors is still a little fuzzy to me, despite having dealt with it before with Arduinos, but I am pretty sure I have a pullup resistor here because there is no resistor between the button and ground. I need to attend a pullup/pulldown workshop, clearly.
So for the programming I used Python, which is typical on the Raspberry Pi. I made one Python program that 
  • configures the GPIO pins, 
  • turns on the LED when the button is pressed, 
  • runs a shell script that creates the /tmp/stream directory (for some reason it keeps disappearing) to store the images, 
  • starts the raspistill command, 
  • starts MJPG Streamer (if it's not already going), 
  • then turns off the LED when those finish. 
Note the trailing & after the MJPG Streamer command. That allows raspistill to start even though the MJPG Streamer process hasn't been stopped. The omission of & at the end of the raspistill command forces the LED to stay on until it has finished, though. The original program in the buttons and switches tutorial had prev_input = 0, but I had to change it to prev_input = 1, or the program would run without being pressed the first time, I think because my switch is being pulled high when open (not pressed), so ((not prev_input) and input) was initially true when prev_input was initialized to 0.
Here is startcam.py:
And here is the shell script startMBCam.txt:
I tried to get startcam.py to run at startup like is shown in the buttons and switches tutorial but MJPG Streamer would not run. I could tell the camera was snapping images but nothing was accessible at the streaming IP.
UPDATE: I got the program running automatically when the pi boots! I added the startCam.py program to the /etc/rc.local file to run it on startup, and included the full path to mjpg_streamer in the startMBCam.txt file: /home/pi/mjpg-streamer-code-182/mjpg-streamer/mjpg_streamer 
I also soldered a pretty sweet board for the button and LED, and connected them to the GPIO pins without the ribbon, just directly with female header connectors.




Creating a box for the camera

For this part I found a nice Raspberry Pi Camera case design on Thingiverse and used Tinkercad to modify it a little. I moved the ball connection to the bottom of the camera case front and flattened the ball socket.

The next and final step will be mounting the whole apparatus near our Makerbot with power and ethernet attached, but that will have to wait until after break.