Monday, June 17, 2013

Friday, May 10, 2013

Automatically taking photos of the sunrise over Mt. Rainier

The view from my bedroom window
I wish I had done this earlier and not when I have 2 more weeks left in the house before I move to a place that does not have a perfect view of Mt. Rainier from the master bedroom window. I've connected this shutter release cable for the 5D to an opto-isolator chip which is then connected to one of the GPIO pins on my pcDuino. Whenever I want to wakeup the camera I set the GPIO pin high for 500ms to wakeup the camera. Then I use gphoto2 to capture the image. The following script will be run at sunrise every morning.
#!/bin/bash

function wakeup {
        echo waking up camera
        #half-press of the shutter button to wake the camera via optoisolator chip connected to shutter release port of camera
        /home/ubuntu/sample/core/gpio_set 7 1
        #hold the button for 500ms
        /bin/sleep .5s
        #release the button
        /home/ubuntu/sample/core/gpio_set 7 0
        #wait for the camera to wake up
        /bin/sleep 2s
}

function takephoto {
        echo taking photo
        /usr/bin/gphoto2 \
        --camera="Canon EOS 5D Mark III" \
        --folder=/store_00010001/DCIM/100EOS5D \
        --capture-image
}


#write images to card
#/usr/bin/gphoto2 --camera="Canon EOS 5D Mark III" --get-config /main/settings/capturetarget
/usr/bin/gphoto2 --camera="Canon EOS 5D Mark III" --set-config /main/settings/capturetarget=1

#loop 90 times and sleep 120 seconds between each photo
x=1
while [ $x -le 90 ]
do
        echo Taking photo $x of 90
        wakeup
        takephoto
        echo Sleeping for 120 seconds
        /bin/sleep 120s
        x=$(( $x + 1 ))
done

#write images to ram
/usr/bin/gphoto2 --camera="Canon EOS 5D Mark III" --set-config /main/settings/capturetarget=0
The output looks like this:
/usr/local/bin/camera.sh
Taking photo 1 of 90
waking up camera
taking photo
New file is in location /store_00010001/DCIM/100EOS5D/3Q1A2080.CR2 on the camera
New file is in location /store_00020001/DCIM/100EOS5D/3Q1A2080.CR2 on the camera
Sleeping for 120 seconds
Taking photo 2 of 90
waking up camera
taking photo
New file is in location /store_00010001/DCIM/100EOS5D/3Q1A2081.CR2 on the camera
New file is in location /store_00020001/DCIM/100EOS5D/3Q1A2081.CR2 on the camera
Sleeping for 120 seconds
Taking photo 3 of 90
waking up camera
taking photo
New file is in location /store_00010001/DCIM/100EOS5D/3Q1A2082.CR2 on the camera
New file is in location /store_00020001/DCIM/100EOS5D/3Q1A2082.CR2 on the camera
Sleeping for 120 seconds
Taking photo 4 of 90
waking up camera
taking photo
New file is in location /store_00010001/DCIM/100EOS5D/3Q1A2083.CR2 on the camera
New file is in location /store_00020001/DCIM/100EOS5D/3Q1A2083.CR2 on the camera
Sleeping for 120 seconds
Taking photo 5 of 90
waking up camera
taking photo
New file is in location /store_00010001/DCIM/100EOS5D/3Q1A2084.CR2 on the camera
New file is in location /store_00020001/DCIM/100EOS5D/3Q1A2084.CR2 on the camera
Sleeping for 120 seconds

Monday, March 25, 2013

How to sync the contents of your old Linux server to your new one

Make sure that both systems are running the same version of the same Linux distribution. Shutdown any processes that are not necessary on both servers(everything but SSH). Then run this command as root on the new server:


rsync root@oldserver.jasongarland.com:/ / -av --exclude '/proc/' --exclude '/etc/hosts' --exclude '/etc/fstab' --exclude '/etc/mtab' --exclude '/etc/network/' --exclude '/dev/' --exclude '/sys/' --exclude '/var/run/utmp' --delete


Note: This will erase anything on the new server that doesn't exist on the old one. Also note that I have only tested this method with Debian and Ubuntu.

Tuesday, February 19, 2013

Laser cut Nixie Tube clock powered by Arduino





http://www.thingiverse.com/thing:52252



I bought all the goodies to make a nice Nixie clock from Taylor Electronics, but I didn't have a nice case for it. It took me about 6 hours to design, cut, and re-cut parts until I had something I was happy with. I disabled the I2C master on the first TES 1361 SmartNixie board and replaced it with an Arduino Nano board connected in the unused RTC connector on the bottom of the backplane board. I poll the GPS RTC board via I2C to get the time and then send command over the I2C bus to the SmartNixie boards to display the digits.





Laser cut parts from 1/8 acrylic (The stuff I bought from Home Depot ended up being 2.2mm thick and not 3.175mm(1/8") so this drawing was designed for 2.2mm, but that isn't hard to change.)


Order these parts from http://www.tayloredge.com/storefront/index.html


1 x 1392 - 6 Digit IN18 Clock Backplane

6 x 1361 - SmartNixie IN18

1 x 1375 - SmartNixie GPS RTC

1 x 1364 - SmartNixie HVPS-H

1 x Active GPS Antenna

1 x Power Plug



I ordered my IN-18 tubes from super-gene on ebay: http://myworld.ebay.com/super-gene/

6 x IN-18 tubes



12V power supply and Arduino Nano can be ordered from Amazon here:

http://www.amazon.com/Wall-Adapter-Power-Supply-12VDC/dp/B006GEPUYA
http://www.amazon.com/Arduino-ARD-NANO30-Nano-v3-0/dp/B003YVL34O



Arduino Sketch:

Saturday, January 21, 2012

Download all of your images from Smugmug

I cheated and used wget to grab the files. This could be done using a perl module if you wanted.

You will need to have the WWW::SmugMug::API module installed for this script to work. All of the others should be standard stuff.




#!/opt/bin/perl

use warnings;
use strict;
use Data::Dumper;
use WWW::SmugMug::API;
use File::Path;

my $APIKey='your_key';
my $username='your_login_email';
my $password='your_password';

my $dest_folder='/share/jgarland/Photos/Smugmug';

my $sm_api = WWW::SmugMug::API->new(
 {
  sm_api_key => $APIKey,
  secure     => 0
 });

$sm_api->login_withPassword(
 {
  EmailAddress => $username,
  Password     => $password
 });

&get_images;

$sm_api->logout;
exit;





sub get_images {

 my $albums=$sm_api->albums_get();
 foreach my $album (@{$albums->{'Albums'}}) {
  my $images=$sm_api->images_get(
   {
    AlbumID => $album->{'id'},
    AlbumKey => $album->{'Key'}
   });
  foreach my $image (@{$images->{'Images'}}) {
   my $image_info=$sm_api->images_getInfo(
    {
     ImageID => $image->{'id'},
     ImageKey => $image->{'key'}
    });
   download($album, $image_info);
  }
 }
}


sub download {
 my $album=shift;
 my $image_info=shift;
 my $album_folder=$dest_folder . '/' . $album->{'Category'}->{'Name'} . '/' . $album->{'Title'};
 my $image_file=$album_folder . '/' . $image_info->{'Image'}->{'FileName'};

 unless(-d $album_folder) { mkpath $album_folder or die; }

 if ( -e $image_file ) { return(); }
 
 my $command='/usr/bin/wget -c -q \'' . $image_info->{'Image'}->{'OriginalURL'} . '\' -O "' . $image_file . '"';
 print "$command\n";
 my @results=`$command`;
 my $errlvl=$?;
 print Dumper(@results);
 if ( $errlvl == 0 ) {
  return();
 } else {
  unlink($image_file);
  die("errlvl=$errlvl\nDeleting $image_file\n");
 }

}

Thursday, October 13, 2011

What do I do with this core file?

Use this script to generate a useful backtrace from the core file.

#!/bin/bash

corefile=$1
outfile=$1.gdbtrace.log

function getprocess {

        commandstring=$(gdb -c $corefile \
                --eval-command='set pagination off' \
                --eval-command='bt' \
                --eval-command='quit' \
                |awk '/Core was generated by/ { split($0, a, "`"); split(a[2], b, "'\''"); split(b[1], c, " "); print c[1] }')

        echo $commandstring|awk '{print $1}'
}


if [ -a $corefile ] ; then
        process=$(getprocess)
else
        echo You must provide a core file as an argument
        exit
fi

if [ -a $process ] ; then

echo Core was generated by $process

gdb $process \
                -c $corefile \
                --eval-command='set pagination off' \
                --eval-command="set logging file $outfile" \
                --eval-command='set logging on' \
                --eval-command='bt' \
                --eval-command='bt full' \
                --eval-command='thread apply all bt' \
                --eval-command='thread apply all bt full' \
                --eval-command='quit'

echo "Trace written to $outfile"

else
        echo "Can not find $process. This script my be broken, or the file disappeared."
        exit
fi

Tuesday, March 22, 2011

German exit signs

I've made my way to Frankfurt, Germany. Tomorrow I will be taking the train to Regensburg. I will post all of my photos on my photo sharing site later here.

All throughout the airport I've seen these exit signs and they reminded me of the signs you see inside the game Portal.

Here is a picture of one of the signs. (I didn't take this picture. I can't get my memory card reader to work right now.)


And here is a logo for the game: