My 'Bot has developed a bit of emotional instability. Or instability anyway. It runs for a while and then without fail loses it's network connection. It seems to have started with the introduction of the LCD...but...the LCD is connected to the Arduino not the RPi! I have also added another GPIO function but the network crash seems to happen with or without the GPIO functioning.
I have started a series of tests to try to narrow down the source of the problem. So far I have tried running with and without the GPIO functionality and with and without the LCD functionality. I have also let the RPi run without my Python code but with the camera and some other processes running. In the former two cases we had a failure in the latter we were stable.
Sunday, February 24, 2013
Friday, February 22, 2013
Robot Kill Switch - GPIO
Now that the robot starts auto magically it seemed like it would be a nice idea to have a way to abort that auto start or to stop the robot...without a terminal or web session. Since I have already exposed the GPIO bus it was easy to implement this desire.
The picture shows the hardware. The push button is wired to pin 14 of the GPIO bus (blue wire). A 10k resistor connects that lead to ground (brown wire). The 3v power supply is connected to the other side of the push button. If the button is depressed during start-up the 'Bot will abort prior to starting any of it's modules. If it is pressed any time while the 'Bot is running it will shutdown cleanly.
Here is the code for the abort of start-up:
The picture shows the hardware. The push button is wired to pin 14 of the GPIO bus (blue wire). A 10k resistor connects that lead to ground (brown wire). The 3v power supply is connected to the other side of the push button. If the button is depressed during start-up the 'Bot will abort prior to starting any of it's modules. If it is pressed any time while the 'Bot is running it will shutdown cleanly.
Here is the code for the abort of start-up:
# *****
# Abort startup if the kill switch is pressed
# *****
GPIO.setmode(GPIO.BCM)
GPIO.setup(intercom["pins"]["startRobot"], GPIO.IN)
GPIO.setwarnings(False)
if GPIO.input(intercom["pins"]["startRobot"]):
logger.critical("Aborting startup - kill switch pressed")
sys.exit(1)
# Abort startup if the kill switch is pressed
# *****
GPIO.setmode(GPIO.BCM)
GPIO.setup(intercom["pins"]["startRobot"], GPIO.IN)
GPIO.setwarnings(False)
if GPIO.input(intercom["pins"]["startRobot"]):
logger.critical("Aborting startup - kill switch pressed")
sys.exit(1)
Robot Auto Start
Now that I have an on-board status display I wanted the 'Bot to automatically start on boot. To make this happen you need a script located in /etc/init.d that follows certain conventions. My script is shown below and is based on this post.
Make the script executable
The above is pretty much the most basic of scripts for my purpose. Note that zzCommand.py is a short command line way to put commands that would normally come from the web interface into the 'Bot's execution queue. This causes the 'Bot to stop in a controlled fashion. My first version of this script used a killall python...not so eloquent!
Once the above script is written it can be executed as shown below and/or added to the list of scripts that will be started auto magically:
Start the program
Stop the program
Register script to be run at start-up
To register your script to be run at start-up and shutdown, run the following command:
#! /bin/sh
# /etc/init.d/noip
### BEGIN INIT INFO
# Provides: robot
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts the robot
# Description: A simple script based on one from www.stuffaboutcode.com.
### END INIT INFO
# If you want a command to always run, put it here
# Carry out specific functions when asked to by the system
case "$1" in
start)
echo "Starting the robot"
cd /home/pi
./xxr -lD
;;
stop)
echo "Stopping the robot"
cd /home/pi/Robot
python zzCommand.py --command=Shutdown
;;
*)
echo "Usage: /etc/init.d/robot {start|stop}"
exit 1
;;
esac
exit 0
# /etc/init.d/noip
### BEGIN INIT INFO
# Provides: robot
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts the robot
# Description: A simple script based on one from www.stuffaboutcode.com.
### END INIT INFO
# If you want a command to always run, put it here
# Carry out specific functions when asked to by the system
case "$1" in
start)
echo "Starting the robot"
cd /home/pi
./xxr -lD
;;
stop)
echo "Stopping the robot"
cd /home/pi/Robot
python zzCommand.py --command=Shutdown
;;
*)
echo "Usage: /etc/init.d/robot {start|stop}"
exit 1
;;
esac
exit 0
Make the script executable
sudo chmod +x /etc/init.d/robot
The above is pretty much the most basic of scripts for my purpose. Note that zzCommand.py is a short command line way to put commands that would normally come from the web interface into the 'Bot's execution queue. This causes the 'Bot to stop in a controlled fashion. My first version of this script used a killall python...not so eloquent!
Once the above script is written it can be executed as shown below and/or added to the list of scripts that will be started auto magically:
Start the program
sudo /etc/init.d/robot start
Stop the program
sudo /etc/init.d/robot stop
Register script to be run at start-up
To register your script to be run at start-up and shutdown, run the following command:
sudo update-rc.d robot defaults
Thursday, February 21, 2013
'Bot Status Display
I have added one of these displays to the 'Bot as you can see from the picture. This version of the display requires a LOT of pins from the Arduino but I had them available (and I am running out of room for anything else anyways)!
The wiring instructions that I used can be found here. I am probably going to move the display somewhere as it hangs over the edge of the treads now!
Writing to the display is very simple as shown by the below Arduino code:
Initialize the LCD
Write to the LCD
The wiring instructions that I used can be found here. I am probably going to move the display somewhere as it hangs over the edge of the treads now!
Writing to the display is very simple as shown by the below Arduino code:
Initialize the LCD
// Include and initialize the library for the LCD
#include <LiquidCrystal.h>
LiquidCrystal lcd(11, 12, 3, 4, 2, 5);
String lcdMessage = "";
#include <LiquidCrystal.h>
LiquidCrystal lcd(11, 12, 3, 4, 2, 5);
String lcdMessage = "";
Write to the LCD
// Set the size of the lcd and say hi
lcd.begin(16,2);
lcd.print("HW Interface up");
lcd.setCursor(0, 1); // Next write to position zero of second line
lcd.print("P2A:Waiting");
lcd.begin(16,2);
lcd.print("HW Interface up");
lcd.setCursor(0, 1); // Next write to position zero of second line
lcd.print("P2A:Waiting");
Monday, February 18, 2013
'Bots Eye View
Webcam Struggles
I have been struggling to implement a reliable webcam on the 'Bot for a while now. I think I have finally gotten there but it has been, well, a struggle. My requirement is to stream images in as close to real time as possible but while using a minimum of processing power.
My original idea was to capture images in Python using cv per this example. I worked on this for quite a while and finally gave up as I could not get it to be stable. Invariably, while it would work for a while, it would finally die (webcam would come unbound?). I thought that it might be the cheap webcam that I am using and tried another with the same results.
My next attempt was to try ffmpeg which is a powerful command line utility that can do a lot of image related functions...many more than I need. It does, however, have the capability to capture images from a video stream and save them with a unique time stamped file name. It drove me nuts. I still do not know why but it would save an image from a point back in time...! I thought that it was my code that was the problem as I do have some latency with my message queing and the like but I finally determined that it was ffmpeg. I strongly suspect that it was user error but did not take the time to prove this as I found an easier solution.
In any case, I am now using another command line utility called fswebcam. It is simpler than ffmpeg, but more importantly, it does what I want it to do! It runs in a little script that is spawned when the 'Bot starts running:
while [ 1 != 999 ]
do
FILE="/var/www/stream_$(date +%H%M%S).jpg"
fswebcam -r 320x240 -S 1 --jpeg 95 --save $FILE -q --timestamp %H:%M:%S
done
My original idea was to capture images in Python using cv per this example. I worked on this for quite a while and finally gave up as I could not get it to be stable. Invariably, while it would work for a while, it would finally die (webcam would come unbound?). I thought that it might be the cheap webcam that I am using and tried another with the same results.
My next attempt was to try ffmpeg which is a powerful command line utility that can do a lot of image related functions...many more than I need. It does, however, have the capability to capture images from a video stream and save them with a unique time stamped file name. It drove me nuts. I still do not know why but it would save an image from a point back in time...! I thought that it was my code that was the problem as I do have some latency with my message queing and the like but I finally determined that it was ffmpeg. I strongly suspect that it was user error but did not take the time to prove this as I found an easier solution.
In any case, I am now using another command line utility called fswebcam. It is simpler than ffmpeg, but more importantly, it does what I want it to do! It runs in a little script that is spawned when the 'Bot starts running:
while [ 1 != 999 ]
do
FILE="/var/www/stream_$(date +%H%M%S).jpg"
fswebcam -r 320x240 -S 1 --jpeg 95 --save $FILE -q --timestamp %H:%M:%S
done
Sunday, February 17, 2013
Robot Status Display
I have a hankering to add one of these displays to the 'Bot. It is the same device that is used in this Arduino shield less the shield. I am currently using an LED to signal some limited status messages but this would give a lot more options. Have ordered one just in case...!
Monday, February 11, 2013
Distracted Again!
I keep getting distracted. This time not with doing stuff that needs doing around the house but with our back garden. I have never actually had a back garden before, or at least not in the any recent decade, and certainly not one with visiting wild life.
Granted below pictures don't qualify as very exciting wildlife but I am hoping that my setup will allow better shots as spring arrives.
Take a garden, a table, and a fat ball. Add a Canon DSLR, an A/C power adapter, an iMac running DSLR Assistant, a long powered USB Cable, and an iPad as an extra viewing screen (so I can still be doing something useful), and you have my BirdCam.
Now if only I had some more interesting birds.
Granted below pictures don't qualify as very exciting wildlife but I am hoping that my setup will allow better shots as spring arrives.
Take a garden, a table, and a fat ball. Add a Canon DSLR, an A/C power adapter, an iMac running DSLR Assistant, a long powered USB Cable, and an iPad as an extra viewing screen (so I can still be doing something useful), and you have my BirdCam.
Now if only I had some more interesting birds.
Sunday, February 10, 2013
I am now officially back to working on the 'bot. Unfortunately somewhere in the process of moving and configuring my new office I whacked my install and had to reconfigure the SD card...
...and I am still trying to get back to where I was before we moved! Backups you ask? Didn't I write about backups?
Whatever.
Back with more later.
...and I am still trying to get back to where I was before we moved! Backups you ask? Didn't I write about backups?
Whatever.
Back with more later.