Wednesday, July 26, 2017

Filming Birds with a Raspberry Pi (Part One)

I had recently purchased a camera module for the Raspberry Pi, mainly just out of curiosity, and a desire to learn how to use it.  In the back of my mind I had been working on an idea to build a birdhouse and use a Pi to film the birds, but I was currently working on several other projects, so I was in no hurry to start a new one.  One evening I was working at my desk in my shop, and I heard some chirping outside the window.  I pulled back the curtain to find a Carolina Wren's nest with baby chicks inside chirping away.  How fortuitous.  Suddenly my project to film birds with the Pi moved to the front of the list.  With little knowledge of how to use the camera, I bent a piece of 12awg copper wire into a makeshift camera stand, hooked it up to the Pi, and set it in the window.  A quick Google search told me that I could enable the camera module using the raspi-config menu, and then operate the camera from the command line using the following commands for pictures and video respectively:

raspistill -o birdpic.jpg

The above command takes an 8 megapixel image and outputs it to a file named birdpic.jpg.

raspivid -o birdvid.h264 -t 10000

The above command takes a video and outputs it to a file named birdvid.h264.  The -t specifies the length of the video in miliseconds, so -t 10000 takes a 10 second video.

It worked.  I sat there for a little while amusing myself taking video of the birds every time they started chirping, because that usually meant that it was feeding time.  The video through the window was decent, and I managed to edit together a short video.





Obviously, this was far from an optimal set-up.  The video through the window was OK, but it could definitely be better, and the whole thing was dependent on me sitting there listening for the chirping and hitting a button.  It was time to take this to the next level.  I had some IR motion sensors lying around, and some leftover 1/2" plywood from a previous project, so I whipped up a quick little box with a hinged lid and a removable front panel with holes for the camera and motion detector.  I decided to store the video on a 16 GB usb thumb drive.  The other options would have been to save it
to the SD card, which would only wear out the card faster, or stream it via wifi to my server.  I decided against wifi in case I wanted to use this project for filming something else that was too far away from the house for wifi.  The USB drive turned out to be an adequate solution.  I made sure to leave plenty of room in the box, and air gaps at the top to deal with the heat produced by the Pi and the USB stick.  To mount the motion detector and camera on the front of the box I simply used electrical tape, since this was more of a prototype or proof-of-concept than anything else.  I was pleased with my little box, considering I made it on the fly in just a little
 over an hour.  The IR motion sensor I used was a HC-SR501, which runs off of 5V, but conveniently send a 3.3V signal when motion is detected, so I could hook it up directly to the Pi using only three pins without having to use a level-shifter.  With that, the hardware was complete.  Now all I needed was a little code to automate the whole process.  Back to Google.

It turns out, as to be expected, the Raspberry Pi Camera Python module is located in the Raspbian repositories, so it can be installed with a quick:

sudo apt-get install python-picamera

I don't want to get too in-depth on how to use this module, so I will just point you to Raspberrypi.org's documentation here.  The code is simple.  All I am going to do is to  monitor the GPIO pin that the motion sensor is connected to.  When motion is detected I am going to start recording.  After 10 seconds, I am going to check the motion sensor again.  If there is no motion, then the clip is over.  If there is still motion after 10 seconds then it will wait another 10 seconds and check again.  This results in a minimum size clip of 10 seconds, with no maximum size as long as motion continues.  To prevent video files from overwriting each other, each clip will contain a time-stamp in the file name.  I could have gone a little more advanced with the code, but I was in a hurry to get this up and running, so I kept it simple.  Here's the code if anyone would like to use it:

 #!/usr/bin/env python  
   
 import RPi.GPIO as GPIO  
 import picamera  
 import time  
   
 MOTION_PIN = 4  
 camera = picamera.PiCamera()  
   
 GPIO.setmode(GPIO.BCM)  
 GPIO.setup(MOTION_PIN, GPIO.IN)  
   
 def take_video():  
      timestamp = time.strftime("%y-%m-%d-%H-%M-%S")  
      print 'recording started' # for troubleshooting only  
      camera.start_recording('vid%s.h264' % timestamp)  
      camera.wait_recording(10)  
      while GPIO.input(MOTION_PIN):  
           camera.wait_recording(10)  
      camera.stop_recording()  
      print 'recording stopped' # for troubleshooting only  
   
 # Begining of Program  
   
 time.sleep(2)  
 while True:  
      print 'waiting for motion' # for troubleshooting only  
      GPIO.wait_for_edge(MOTION_PIN, GPIO.RISING)  
      print 'motion detected' # for troubleshooting only  
      take_video()  

As always, we need to make the file executable using sudo chmod +x /home/pi/motion-vid.py.  I want to have this script run on start-up, so we need to add this file to the /etc/rc.local file, but before we do that, we need to think about the USB flash drive that we are using to store the video.  When a USB drive is inserted into the Raspberry Pi, it is not automatically mounted as it is in many other operating systems, so we need to make sure that the Pi also mounts the USB drive on start-up.  To do this, we must first determine the name of the drive, and of the partition on the drive.  Typically the first USB drive you insert in the Pi will be sda, but in the interest of being thorough we will double check just to be sure using the command ls /dev/sd*.





As you can see above, it returned two values.  sda is the name of the drive itself, and sda1 is the name of the partition on the drive.  We want to mount the partition.  Next we need to look to see if we have a place to mount the drive.  Navigate to /mnt using cd /mnt, and see if you have directories there.  If not, create a directory named usb (the name is arbitrary) using the command sudo mkdir ./usb.  We can now mount the usb drive using sudo mount /dev/sda1 /mnt/usb.







So now that we know how to do it, let's tell the Pi to mount the USB on boot and run the camera script.  Open up the /etc/rc.local file using your text editor du jour (i.e. sudo vim /etc/rc.local)and add the following lines to the file:

# The following line mounts sda1 to /mnt/usb
sudo mount /dev/sda1 /mnt/usb

#The following lines runs the script that takes video based on a motion sensor
cd /mnt/usb
sudo /home/pi/motion-vid.py &

And that's it.  I put the box on the windowsill next to the birds nest and plugged it in.  The first day I got just under 400 video clips, which took up about 3.5 GB.  That means with a 16 GB USB drive I would only need to swap out the drive every four days or so.  At any time I could log into the Pi over wifi to make sure it was still working, and view any of the clips I chose.  And of course, I had to make another bird montage:



And now for the sad conclusion of this project.  After a little less than a week of watching the birds, and admittedly becoming a bit attached to the little guys, I was working in my shop when I heard a commotion at the window.  I figured the birds were getting active, so I logged into the Pi and pulled down the last video clip.  Horrified I watched as one of the neighbor's cats pounced onto the nest and pulled it, and the baby birds, off of the window ledge.  C'est la vie.  It is nature after all, and cats will be cats.  I can't be happy they keep away the mice and snakes, and then fault them for eating the birds.  It wasn't the smartest place for the Wrens to build a nest anyway, 2 feet off the ground.  At least I got to watch them for a while, and it gave me a good starting point for this project.

So what did I learn, and what's next.  Most importantly, next time I film baby birds they will be in a bird house where they will be better protected from predators.  My code could also use a little bit of improvement, and next time I will probably just stream the video to a server instead of using the USB drive for storage.  I am already working on a design for a bluebird house that will have an internal camera and an external camera, and will be able to conceal the electronics in a separate compartment from the birds.  The biggest hurdle to overcome with that project will be powering two Pi Zeros and two cameras, but I'm sure I can come up with something.  Until then, stay safe, and keep building.

Sunday, July 9, 2017

Watering the Garden with Raspberry Pi

If you've ever planted a garden or grass seed in the spring, you know that watering can be a time consuming task, and going out of town for a weekend can be disastrous for your new plants if the weather is hot and no one is around to water them.  More importantly, I just like to build things, so why not scratch that building itch and create an automated hose bib that can be scheduled to turn on and off using a Raspberry Pi?

My original approach to this project involved a watering system located near the garden, but I ran into several complications during the design phase.  The first issue arose trying to power the Pi as well as the electronic solenoid valve that would control the water flow.  Running wires across the back yard was not an ideal solution, and battery power was going to require frequent recharging.  I was also going to have to find a way to protect the electronics from the sun's UV rays as well as moisture, while at the same time allowing enough air-flow to let heat escape.  It occurred to me that locating all of the electronics inside the house and using them to control a hose bib on the side of the house solved both of these issues, and also added the flexibility to allow me to change the location of my automatic sprinklers or drip-watering-systems whenever necessary.

With this basic concept in mind, I broke the project into three segments: electronic hardware, plumbing hardware, and control software.  For the electronic hardware, I would need to be able to switch on and off a 12V fused power source that would supply an electric solenoid valve that would control the water.  This could easily be done by controlling a relay with a GPIO pin on the Pi.  For the plumbing hardware, I would need to tap into my water line and run it through the electric solenoid valve, and from there outside to a hose bib.  I would also need to be sure to include a check valve to prevent the back-flow of water from the outside, and there would need to be a way to drain any outdoor pipes to prevent freezing in the winter.  The control software would be the easiest.  All I needed was a short start-up script to set-up the GPIO pin, and then the timing of opening and closing the valve could be done with cron jobs.  With a plan in place it was time to get building.

Electronic Hardware

For this project I purchased a 12V / 3amp normally-closed brass solenoid valve to control the water flow.  You can buy a plastic one cheaper, but I had reservations about connecting a plastic water valve to my plumbing.  Basically all I needed to do was to connect a GPIO pin from the Pi to a relay that could then switch on/off the 12V power supply to the valve.  I went with a 4-channel relay module since I already had plans for future projects that would require additional relays.  I had a 12V / 30 amp power supply from previous projects on hand, which will provide more than enough current for this project, as well as anything I might need it for in the future.  The only thing left to plan was a fuse for the power to the valve.  For most people a simple in-line fuse holder would solve this problem, but I just so happened to have an old DC fuse panel lying around looking for a job to do, so I put it to use.  Here is the schematic for the final design:


In the above schematic I also drew in the relay board.  Obviously if you use the same relay board that I did, you don't need to build any of this, but I wanted to include it so that anyone using a different relay could adapt the circuit to their own needs.

Regarding the switches, I added the first switch to cut the 12V power so I don't have to pull the fuse every time I want to make adjustments to the set-up.  This particular switch has an LED that is powered via the same 12V that it switches, so I had to add a resistor to the ground leg on the switch to limit the current for the LED without limiting the current to the valve.  This was done by simply cutting the wire and adding the resistor in-line.  I also added a second switch to bypass the relay and open the valve without involving the Pi.  This is a standing "request" from my wife that anything I automate must still have a manual switch for operation.

One last, but very important note, when I finally had the whole set-up finished, I tested it out.  As soon as I sent power to the solenoid, my Pi emailed me that my smoke detector was alerting and gave me an audible alert that it was preparing to shut down.  What!?!?  These are all separate systems that should have nothing to do with each other except that the same Pi controls them all!  Well, since I had run my 12V lines along the same path as the jumpers for all of my GPIO pins, as soon as I switched the solenoid on, the electrical noise on the 12V lines interfered with the signals on the other GPIOs, causing a moment of havoc for the Pi. This could have been solved by rerouting my wires, or by trying to smooth things over with capacitors, but I happened to have some ferrite core noise suppression filters lying around, so I tried one out.  After testing several times, I can verify that this does in fact solve the problem.  With the noise filter there are no issues, without it the Pi goes a little nuts.  So keep this in mind when determining your cable management, or invest in some filters to solve the problem after the fact.

Plumbing Hardware


I hate plumbing, but it's a handy thing to know how to do.  I know just enough about it to make me dangerous, but that probably applies to a lot of things.  I won't go into too much detail here, because everyone's plumbing situation is going to be different, so there is no one-size-fits-all solution.  I am going to try to focus on the few components that will be universally required, and then just skip to the final result.  If you are not completely comfortable with altering the plumbing in your house, then you may want to look into another way to do this project.  Plumbers are expensive, so mistakes could be costly, not to mention messy.  You've been warned, so I accept no responsibility if you choose to proceed and accidentally flood your house.


Above is the basic set up for the plumbing piece.  Starting on the left, the first piece we need is a cut-off valve.  If my improvised plumbing leaks or brakes, or my Pi goes all Superman 3 on me, I need to have a way to cut off the water from it's source.  Next comes the solenoid valve that will be controlled by the Pi.  After that we need to use a check valve to prevent the water from the hose from draining back into my water pipes (this is probably required by code in most places).  Finally, I used a T-junction and another cut-off valve to allow for draining the outdoor pipes.  This valve will stay closed during normal operation, and will only be opened at the end of the season in order to drain the outdoor pipes so they don't freeze.  The outlet for this valve will lead to a sink basin in my shop so that I don't have to mess with sewer lines and traps.


So that is the basic design.  To the right is the fully installed product.  To tap into the waterline I opted to slice into one of my newer Pex waterlines, which is much easier than trying to mess with 70 year old galvanized water pipe.  For the line that continues outside I opted to use galvanized steel water pipe because I wanted something more rigid to support the solenoid valve, and because you can't run Pex outside.  If you do something similar and use steel pipe outside, be sure to paint it to keep it from rusting.


Control Software

With everything in place, all I needed to do was to write a couple of short scripts to control the solenoid valve.  This is the easy part.  Here are the two python scripts called water-on.py and water-off.py:

 #!/usr/bin/env python  
   
 # water-on.py  
   
 import RPi.GPIO as GPIO  
 from time import sleep  
   
 RELAY_PIN = 26  
   
 GPIO.setmode(GPIO.BCM)  
 GPIO.setup(RELAY_PIN, GPIO.OUT)  
   
 GPIO.output(RELAY_PIN, 0)  
 sleep(1200)  
 GPIO.output(RELAY_PIN, 1)  

 #!/usr/bin/env python  
   
 # water-off.py  
   
 import RPi.GPIO as GPIO  
   
 RELAY_PIN = 26  
   
 GPIO.setmode(GPIO.BCM)  
 GPIO.setup(RELAY_PIN, GPIO.OUT)  
 GPIO.output(RELAY_PIN, 1)  

For the water-on.py script I added in a 20 minute timer before automatically turning the water back off as a fail-safe.  As always, once the scripts are created using a text editor, they need to be made executable by using

chmod +x water-on.py
chmod +x water-off.py

I need to make sure that the GPIO pin that controls the relay isn't floating when the Pi reboots, so I need to run the water-off.py script on boot.  I am going to do this by adding the following line to the /etc/rc.local file:

sudo /home/pi/water/water-off.py

This time I am also going to make the file executable without having to specify the whole path to the file by copying it to the /usr/bin folder like so:

cp /home/pi/water/water-on.py /usr/bin/water-on
cp /home/pi/water/water-off.py /usr/bin/water-off

Notice I dropped the .py when I added the file to /usr/bin.  This is not necessary, but in Linux land file extensions are not required, and it saves me a little bit of typing.  So now the water can be turned on with a simple command.

water-on

But the point of this was not to be able to turn on the water by typing a command, we could do that more easily by flipping a switch.  The goal is to be able to schedule the water to turn on and off automatically.  For this we will use Linux's built in scheduling system called Cron.  To add a task to the cron table we use the following command:

crontab -e

 The first time you edit the cron table you will be prompted to pick a text editor.  I prefer vim, but it's purely a matter of personal taste.  When the file is opened for the first time there is nothing but lines of comments explaining how Cron works.  Since the directions are built into the cron table, I won't go into too much detail here.  To turn the sprinklers on for 20 minutes every morning at 6:00am you would add the following two lines to the end of the cron table:

00 6 * * * water-on &
20 6 * * * water-off

Remember that I added a fail-safe to the water-on script to have it shut off after 20 minutes, so the water-off isn't 100% necessary, but it seems like good practice.  If you wanted to run the sprinklers for more than 20 minutes you could either edit the sleep line of the water-on script, or just add another line to the cron table to turn the water back on after 20 minutes.

So that's it.  Now every morning my Pi will wake up at 6am sharp and take care of my watering for me.  Sure you can buy an off-the-shelf product that will do the same thing, but what's the fun in that?  If anyone needs any help adapting this walk-through to your own projects just let me know in the comments and I'll do my best to help.


Monday, June 26, 2017

Adding a Soft Shutdown Switch to Headless Raspberry Pi

Recently I had to pull one of my Raspberry Pis out of service to make some hardware changes to it.  Because this Pi runs headless, in order to avoid potentially corrupting the SD card I had to log into the Pi from another computer and issue the shutdown command.  While this is only a minor inconvenience, it occurred to me that I could write a short script to shutdown the Pi when a button was pushed.  Since I already had the soldering iron out and the Pi on the bench I decided to run with the idea, and have a little fun with it while I was at it.

The basic solution to this is actually very simple, but I prefer to take simple things and make them unnecessarily complicated and over-engineered.  It's just my nature, but I realize not everyone shares my prerogative.  So in the interest of making this post as useful as possible, I am going to briefly explain the easy way first, and then I'll show you the solution I ended up using.

The Easy Way


All we really need to make this work is a momentary-on push button switch wired to a GPIO pin and a short Python script.  I used a typical pull-up resistor configuration for the button.  If you have never done this before use the diagram is to the right.  The Python script will use the RPi.GPIO module to set edge detection on the GPIO pin, and then use a threaded callback function to initiate shutdown.  To do the actual shutdown I will use the Python module os to interact directly with the operating system.  The code is short and sweet.  Feel free to copy or republish it. Here it is:

 #!/usr/bin/env python   
     
 import RPi.GPIO as GPIO  
 import os  
 from time import sleep  
   
 def initiate_shutdown(channel):  
   os.system("shutdown now -h")  
   
 BUTTON_PIN = 21  
   
 GPIO.setmode(GPIO.BCM) # Sets GPIO pins to BCM numbering  
 GPIO.setup(BUTTON_PIN, GPIO.IN) # Sets pin to input  
 GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callback=initiate_shutdown, bouncetime=500) # Sets edge detection on pin  
   
 # infinite loop  
 while True:  
   sleep(60)  

So now, when the button is pushed, the Raspberry Pi will execute a soft shutdown, just as I set out to accomplish.  But what happens if the button is accidentally pushed, perhaps I should add in a short delay before shutting down with a way to abort the procedure.  But this machine is headless, so I would need to devise a way to alert someone that the button was pushed, probably using light or sound.  And I don't want to waste any more GPIO pins than would be absolutely necessary.  It was becoming clear to me that this project needed to be tweaked a bit, so I went back to the drawing board and came up with a solution that fit my situation much better.


The Fun Way


In the end I decided to use a button with a built in LED that would stay on when the Pi was up and running.  I used a second GPIO pin wired to an NPN-transistor to control the LED in the button (once again a very standard way to control an LED, but the diagram is to the right if you need it. *EDIT: Not pictured in the diagram to the right is a current limiting resistor between the GPIO pin and the transistor.  I used a 1k ohm resistor, which limited the current draw from the GPIO pin to 2.5mA.  Thanks to Dan Koellen who pointed this out in the comments.)  When the button is pushed the LED will flash for 30 seconds to show that the shutdown procedure has begun, and it will go off when the Pi has shutdown.  To abort the shutdown procedure I will use the same shutdown-button so I don't waste a third GPIO pin.  When pressed the second time, shutdown is canceled and the LED goes back to always-on.  I also decided that I needed to have an audible notification, and a voice could be more fun than a simple beep or buzzer.  There are plenty of text-to-speech websites that allow you to download the voice as an MP3 for free, so I found one that I liked and recorded soundbites for shutdown-initiated and shutdown-aborted.

For the Python script, I thought I could use the same threaded callback design that I used in the code for the easy solution, but for some reason I couldn't get event detection to work inside the callback function.  Instead I went with a slightly less elegant, but just as effective solution of putting an if statement inside an infinite loop to test for event detection.  There are plenty of ways to play audio using Python, but since I had already imported the os module to shutdown, I decided to use command line functionality to play the mp3.  For this I had to install mpg123 using apt-get install mpg123.  If you do something similar and use a different method to play the audio file, just be sure to background it or run it in a different thread.  Otherwise your program will stop and wait for the audio file to finish playing.  Anyway, enough blathering about the code.  Here it is.  Fell free to copy it if you like, and leave any questions in the comments if you have any issues getting it to work for your specific situation.

 #!/usr/bin/env python   
     
 import RPi.GPIO as GPIO  
 import os  
 from time import sleep  
   
 def play_audio1():  
   os.system('mpg123 -q shutdown30.mp3 &')  
   # print 'playing audio1'  
   
 def play_audio2():  
   sleep (1)  
   os.system('mpg123 -q aborted.mp3 &')  
   # print 'playing audio2'   
   
   
 def stop_audio():  
   os.system('pkill mpg123')  
   # print 'stoped audio'  
       
 def initiate_shutdown():  
   
   GPIO.remove_event_detect(BUTTON_PIN)  
   GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, bouncetime=500)  
       
   play_audio1()  
       
   for x in range (1, 30):  
     GPIO.output(LED_PIN, 0)  
     sleep(0.5)  
     GPIO.output(LED_PIN, 1)  
     sleep(0.5)  
     if GPIO.event_detected(BUTTON_PIN):  
       break  
   else:  
     os.system("shutdown now -h")      
   
   stop_audio()  
   play_audio2()  
   GPIO.remove_event_detect(BUTTON_PIN)  
   GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, bouncetime=500)    
   GPIO.output(LED_PIN, 1)  
   
 # Begining of Program  
   
 BUTTON_PIN = 21  
 LED_PIN = 20  
   
 GPIO.setmode(GPIO.BCM)  
 GPIO.setup(BUTTON_PIN, GPIO.IN)  
 GPIO.setup(LED_PIN, GPIO.OUT)  
   
 GPIO.output(LED_PIN, 1)  
   
 GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, bouncetime=500)  
   
 while True:  
   sleep(1)  
   if GPIO.event_detected(BUTTON_PIN):  
     initiate_shutdown()  

And that is that.  The soft shutdown button is now functional.  Here is the end product (the button is on the right hand side):


And here is a short video of the button in action.  Sorry it's a little shaky.  I either need a tripod for my phone or less caffeine:



EDIT:  I'm adding the following link for anyone interested in learning more about using the RPi.GPIO module in Python to interact with the Pis GPIO pins: https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/

EDIT: One thing I forgot to mention is that in order to have the script run on start-up I added the script to the /etc/rc.local file.  If you use this method be sure to use the full path to the file, and run it using sudo so that it can control the GPIO pins.  Also be sure to add an ampersand to the end of the line to background the script since it uses an infinite loop.  The line in my rc.local file looks like this:
sudo /home/pi/soft-shut/soft-shut.py &

EDIT: When I first ran this script with the audio files I noticed that the volume was really low.  Initially I thought it was the result of buying the cheapest little speakers I could find, but it turned out that by default the volume for the Pi's audio-out is not turned all the way up.  This is easily remedied with the following command that only needs to be run once:

amixer set PCM -- 100%

Wednesday, June 14, 2017

Email Smoke Detector Using Raspberry Pi

     Many years ago I built a device that would monitor the signal wire in my home's interconnected smoke detectors, and send me an email and text message when they sounded an alert.  I used a WRT54GL Linksys router that I re-flashed to run an open-source Linux based operating system, and hardware hacked to add an SD card for added storage space, 5 GPIO pins, and two serial ports.  One of the serial ports was used as a console, and the other was used to interface with an AVR microcontroller that did the actual monitoring of the smoke detectors.  It was over engineered and unnecessarily complicated, but it worked, and it introduced me to Linux scripting and microcontroller programming.  It was probably the first electronics project that I fully engineered from start to finish, and I still look back fondly on that project.

     Recently, as I was pondering on what I could do with the various Raspberry Pis I have acquired, it occurred to me that the Pi, with all it's free GPIO pins, would be perfect to revisit and re-engineer my old smoke detector email device.  In fact, this project would take so few resources that there is no reason I can't use the same Pi for several other "smart home" type tasks.  With that in mind I designed the basic layout of this project to be modular and expandable.  I used a piece of 3/16" thick acrylic sheet and some scavenged motherboard standoffs to mount the Pi and the other circuit boards.  I drilled holes in the acrylic slightly smaller than the threads on the standoffs, and just used the standoffs to tap threads into the acrylic.  It actually worked pretty well, and made for a very stable structure.  I bought a breakout board for the Pi's GPIO pins with a ribbon cable to allow for an easy disconnect point and mounted it on a perf-board with pins to provide a test point when all the cables were connected.  I made sure to leave room on the acrylic sheet for future expansion.


     The basic concept for this project is based on the fact that when one of my smoke detectors activates, it sends 9 volts down a signal wire to let all the other smoke detectors know that they also need to sound in order to alert people in all areas of the house.  If I can detect this 9V signal then it's just a matter of writing the code to send the email.  Since this is the case, the project can be broken into two parts, hardware and software.  For the hardware side, I need to determine how to take that 9V signal and convert it into a 3.3V signal that the Pi can receive on one of it's GPIO pins (more than 3.3V could seriously damage the Pi).  On the software side I need to program the Pi to detect the level change on one of it's GPIO pins and send an email when it receives that signal.  Overall this shouldn't be too complicated.  So, let's get to building.

The Hardware

     The hardware side of things ended up being a little more complicated than I expected due to the electrical noise present on signal wire from the smoke detector.  For the sake of documentation I'll go through the failure of the initial design first, but if all you are looking for is the final solution you can skip to the end of this section.
     I started the design with the idea that all I needed to do was convert the 9V signal from the smoke detector into 3.3V for the Pi's GPIO pins.  There are several ways to convert 9V to 3.3V, but I decided to go with a simple voltage divider circuit, since all it would take are a couple of resistors that I already had lying around.  This is how it works:



For the circuit above, the following formula applies:



Since I am trying to convert 9V to 3.3V, all I need to do is find two resistors in my collection that will make V(out) about 1/3 of V(in).  A little bit of math tells us that R1 needs to be about twice the value of R2.  I settled on an 8.2 kohm resistor for R1 and a 3.9 kohm for R2, since that is what I had readily available.  I built the circuit on a breadboard and tested it with a 9 volt battery.  The battery measured 9.7V across it's terminals, and I measured 3.1V for V(out), which is enough to pull the GPIO pin to high.  A little more math said that at 9V even V(out) would be 2.9V, and according to the following website, the voltage really only needs to be >2V in order to pull the input pin to high  (http://www.mosaic-industries.com/embedded-systems/microcontroller-projects/raspberry-pi/gpio-pin-electrical-specifications)  I thought I had a quick and easy solution, but once I had everything soldered and connected, I was surprised to find that the Pi was sending out multiple false alarms.  It seems that the signal wire for the smoke detector circuit was picking up electrical noise and that was translating into false alarms.  I tried to smooth it out with capacitors, but to no avail.  I decided it was probably better this way, being forced to isolate the smoke detector circuit from the Pis circuitry would protect both the Pi and the smoke detectors, so I went about trying to find the best way to do it.

  I thought about using a relay to isolate the Pi from the noisy electrical system, but there is not enough current on the signal wire to power a relay.  A transistor would probably be just as susceptible to the noise as the Pi, so that solution was out as well.  I brainstormed and researched for days trying to find a solution to this problem, until finally I came across the website of Dr Edward Cheung (http://www.edcheung.com/).  He is a very fascinating man, and I recommend taking the time to look at his web page if you have a chance, but what was of particular interest to me was a project he did in 2004 where he tied the signal wire from his interconnected smoke detectors to his homemade home automation system (http://www.edcheung.com/automa/smoke_det.htm).  In order to do this he used an optoisolator to act as the relay between the smoke detector system and his home automation system.  An optoisolator, also referred to as a photocoupler or an optical coupler, activates a light source, typically an LED, when voltage is applied across one half of the circuit.  A receiver coupled with a transistor on the other side of the circuit detects this light and closes the circuit on that side of the optoisolator.  This electrically isolates the two sides of the circuit. That was exactly the solution I had been searching for (Thank you Dr Cheung).  With this new found idea I quickly ordered some optoisolators and sketched out a circuit design.  I settled on a PC817 for the optoisolator due to it's low cost and quick/free shipping from Amazon.  Here is the datasheet if anyone is interested: http://www.farnell.com/datasheets/73758.pdf   And here is the final circuit:
When it was finally put together it worked perfectly.  A couple of notes regarding the design, I got the idea of using redundant resistors on the smoke detector side of the circuit from Dr Cheung's website as well.  The idea is that if one of the resistors failed it would not interfere with the smoke detector's operation, so the value of R1 and R2 had to be such that just one resistor would be enough to allow for proper operation of the smoke detector, and the sum of both resistors would not be too high as to prevent the optoisolator from sensing the current.  I expected to do some trial and error here, but it turned out that my first try with 680 ohms worked perfectly with one or both resistors.  R3 is just a pull-up resistor to keep the GPIO high until the circuit is closed and it is pulled low by the ground.  The switch on the Pi side of the circuit is to allow me to test multiple iterations of my script without having to set off the smoke detectors every time (my dog hates the sound).  Basically closing the switch simulates the optoisolator closing the circuit due to the smoke detector's activation.


When it came to actually building the circuit on a circuit board instead of the breadboard, I wanted to use a socket for the optoisolator in case I ever needed to change it out.  Unfortunately the only sockets I had lying around were for 16-pin microcontrollers, which were 4 times too big.  I decided to turn this inconvenience into opportunity, and wired the circuit board up to accommodate 4 optoisolators wired to four different GPIO pins.  This way if I ever decide to monitor any other systems with this same Pi, the circuitry is already built.

The Software

While there are many ways I could have approached the software side of this project, I have always wanted to learn to program in Python, so that is what I did.  A couple of Google searches and YouTube tutorials later I was ready to start.  Since this is not a Python tutorial I will just paste the code below.  If anyone would like to use the code to do a similar project of your own please feel free to copy it.  If you republish it, all I ask is to give me credit, and possibly post a link to this blog.  If you are having problems getting the code to work for your own project, please feel free to leave questions in the comments and I will do my best to answer them.  First I am listing the modules that I will be using, as well as providing a link to the Python documentation for each module.

time (used to allow the sleep command to pause the script)
datetime (used to timestamp emails and events)
RPi.GPIO (used manipulate, set, and read GPIO pins on the Raspberry Pi)
email (used to format email messages)
smtplib (used to send email messages)
https://docs.python.org/3.5/library/smtplib.html


And here's the code (obviously email addresses and passwords have been removed):


 #!/usr/bin/env python  
   
 import RPi.GPIO as GPIO # Used to interact with GPIO pins  
 import time # Used for sleep and to timestamp the email  
 from email.mime.text import MIMEText # Used to compose email  
 import smtplib # Used to send email  
   
 # Create a function to run when pin state changes  
 # When this function is called, all it does is send an email  
 # based on the state of the pin  
 def send_alert(channel):  
   
   # Set variables  
   gmail_user = 'address@gmail.com'  
   gmail_pass = 'password'  
   sent_from = gmail_user  
   send_to = 'address1@gmail.com, address2@gmail.com'  
   
   # Create Timestamp  
   timestamp = time.strftime("%m-%d-%y %H:%M:%S")  
   
   # if statement to determine which email msg to send  
   # If the pin is low then the alarm is sounding  
   # Boolean vale of pin when high is true, low is false  
   if GPIO.input(12):  
     subject = 'Smoke Detector Stopped ' + timestamp  
     body = 'Sorry to interrupt you again, but your smoke detector has stopped sounding. It is possible that there is no fire, but it is also possible that the fire has shorted out part or all of your elecrical system. Thank you for your time. \n\n   Sincerly,\n Pi-Server'  
   else:  
     subject = 'Your House May be on Fire ' + timestamp  
     body = 'Sorry to interrupt you, but it seems that your smoke detector is sounding. It is possible that your house is on fire. Thank you for your time. \n\n   Sincerly,\n Pi-Server'  
   
   # Compose the email  
   msg = MIMEText(body)  
   msg['From'] = sent_from  
   msg['To'] = send_to  
   msg['Subject'] = subject  
   
   # Send the email  
   try:   
     server = smtplib.SMTP_SSL('smtp.gmail.com', 465)  
     server.ehlo()  
     server.login(gmail_user, gmail_pass)  
     server.sendmail(sent_from, send_to, msg.as_string())  
     server.close()  
   
     if GPIO.input(12):  
       print 'All-clear email sent!'  
     else:  
       print 'Alert email sent!'  
   except:   
     print 'Something went wrong sending email...'  
   
   
 # Beginning of Program  
   
 GPIO.setmode(GPIO.BCM) # Set's GPIO pins to BCM GPIO numbering  
 INPUT_PIN = 12 # Set's the variable representing the input pin to 12  
 GPIO.setup(INPUT_PIN, GPIO.IN) # Sets the input pin to be an input  
   
 # Wait for the input to change states, run the function send_alert when it does  
 GPIO.add_event_detect(INPUT_PIN, GPIO.BOTH, callback=send_alert, bouncetime=2000)  
   
   
 # Endless loop to keep the program running  
 var = 1  
 while var == 1:  
   print 'smoke detector is being monitored'  
   time.sleep(60)  
   
   

A couple of quick notes here.  In the example above I have only sent the alert to two email addresses.  It is also possible to send a text message using email.  For Verizon, you use the full 10-digit phone number followed by @vtext.com  The advantage of using text message is that it tends to get pushed to your phone faster, since most email just polls the server periodically.  The limitation of using text messages, at least with Verizon, is that to send it from email you are limited to 140 characters including the addresses.  Since I am already sending this to two email addresses, adding two more text message addresses to the message pushes the total over 140 characters, and the message doesn't go through.  The solution to this is simple, I just need to create a second email message that only sends a short message via text.  This is not difficult, I just haven't done it yet.

Whether you've written your own script or used mine above, don't forget to make your file executable:

chmod +x filename.py

If you want to be able to run the script using only the filename without referencing the location then copy the file to /usr/bin, although this is not really necessary in this case since I will just be running the script automatically on boot.

cp /home/pi/filename.py /usr/bin/filename.py

Finally, I want to make the script run when the Pi boots so that I don't have to log in and run the script every time the power flickers.  There are several ways to do this, but the method I used was to edit the /etc/rc.local file.  Use whatever text editor you like, I prefer Vim.

sudo vim /etc/rc.local

Add the following line under the comments, but before the "exit 0"

sudo /home/pi/filename.py &

Don't forget the ampersand at the end to tell the script to run as a separate process.  Since the script is an endless loop, if you leave off the ampersand the Pi could get hung up in the loop and never finish booting.  Also note that this script must be run as root due to accessing the GPIO pins, hence the "sudo".

And that's it.  Connect all the wires, reboot the Pi, and now the Pi is monitoring the smoke detectors.


So What Next?

At the time of writing this blog I have had this project done for about a month.  It has been running 24/7 and tested periodically with both the smoke detectors and the test switch.  No problems so far, and only one false alarm that happened during a lightning storm.  I'm planning on putting this project along with my file server and network equipment on a UPS, so that should stop any power fluctuations from causing false alarms.

So what other uses can I come up with for this Pi?  I'm up for suggestions.  I'm considering a temperature and humidity sensor in the shop, because heat and moisture are bad for both woodworking and electronics.  I'm even considering putting wireless contact sensors on the windows and doors so that the Pi can act as a home security system.

Currently, I'm building a system to allow the Pi to control water flow to a hose bib so I can schedule the sprinklers hooked up to that faucet.  It combines a little plumbing with a little electronics and results in a fairly interesting project.  As soon as I get it up and running I'll post an overview for anyone interested in building something similar.  Until then, stay safe and keep building.

Monday, June 5, 2017

Raspberry Pi

An Introduction

I have several projects that I am currently working on involving Raspberry Pis, and every time I start to write up a blog post I realize that many people might be lost from the beginning without knowing what a Pi is, and how to do the initial set-up for it.  In addition I have some links to information that I need to store for future reference, and this seems like as good of a place as any.  So, let's get started.

What is a Raspberry Pi?


I once told a friend that was stopping by that I was working on a Raspberry Pi, and he was disappointed when he arrived and wasn't offered a slice for dessert.  The Raspberry Pi is a great little single board computer that can be purchased for around $35, depending on the model.  It can do almost anything a modern desktop computer can do, albeit a little slower.  Not only is it inexpensive, but its small size and low power consumption make it ideal for a variety of projects.  It's biggest drawback is that it uses an ARM based processor instead of an X86/X64 processor, so it is limited in that it can only run operating systems that have been developed for or ported over to work on ARM based processors.  That being said, there are many flavors of Linux that have been made to run on the Pi, such as Ubuntu, Kali, and Rasbian (which was written specifically for the Pi), as well as other specialty Linux operating systems such as Kodi (media center), OpenWRT (routing), and Retropie (old video game emulator).  Even Microsoft has made an Internet-of-Things version of Windows 10 that runs on the Pi.  I could make an entire post about the Raspberry Pi and it's capabilities, but so many others have already done this that I will suggest that anyone interested in learning more about the Raspberry Pi let Google be their guide down that rabbit hole.  I have put just a few links below to get you started.

Specs: http://elinux.org/RPi_Hardware
Lots of info from the people that make them: https://www.raspberrypi.org/
More Information: http://elinux.org/RPi_Hub

I have a Raspberry Pi, now what?

Once you have a Raspberry Pi you will need to provide it with an operating system.  The Pi does not come with a built-in hard drive, but instead uses a micro SD card (sold separately) as it's hard drive.  Eight GB should be plenty of space, but I typically use the 16 GB cards since there is not much difference in price.  It is also advised to stick to reputable brands and get a class 10 card for faster write speeds.  The nice thing about using an SD card as a hard drive is that if you want to experiment with different operating systems, switching from one to the next is as easy as swapping out the card.

Now you will need to decide which operating system to use, which all comes down to what you want to do with your Pi.  If you are new to this, and just want to see what the Pi is capable of, I suggest starting with Raspbian, which is a Debian based Linux distribution designed specifically for the Pi.  You can use Raspbian with or without a GUI (called PIXEL), but for new users I would definitely suggest using PIXEL.  If you are a more advanced user, or if you have a specific application in mind, you may want to try a more specialized operating system.  For example, maybe you want to build a portable penetration testing rig, in which case you would want to use Kali Linux.  If you want to build a media center computer then I would recommend LibreELEC or OSMC which are both based on the Kodi Media Player (formally XMBC).  Below I have listed the operating systems that I have tried, and a link to where you can download them.  More comprehensive lists can be found here: https://fabiololix.blogspot.it/2016/05/raspberry-pi-distribution-list.html

Raspbian (Linux Desktop Specialized for RPi):  https://www.raspberrypi.org/downloads/raspbian/
Ubuntu MATE (Ubuntu Linux ported to work with RPi):  https://ubuntu-mate.org/download/
Kali (Linux Desktop specialized for Penetration Testing):  https://www.offensive-security.com/kali-linux-arm-images/
LibreELEC (Media Center):  https://libreelec.tv/downloads/
OSMC (Media Center):  https://osmc.tv/download/
Retropie (Classic Video Game Emulator):  https://retropie.org.uk/download/

For anyone asking "What about NOOBS?", I'm not a big fan, so I intentionally left it out.  If you are interested you can find more info here:  https://www.raspberrypi.org/downloads/noobs/


Installing the Operating System

Once you have decided on an operating system and downloaded the disk image you will need to verify the image and write it to your micro SD card.  This will have to be done from another computer.  If you are using a Linux machine then it can all be done from the command line.  You can find information on that here:  http://elinux.org/RPi_Easy_SD_Card_Setup#Using_the_Linux_command_line
If you are using a Mac then I know nothing about the world you live in, but you can find info on how to do it here:  http://elinux.org/RPi_Easy_SD_Card_Setup#Flashing_the_SD_card_using_Mac_OS_X
The only computer that I have with an SD card slot is a Windows machine, so I will give brief instructions here on how to set up the SD card using Windows.

When a file is downloaded from the internet, typically an SHA1 or MD5 checksum is provided.  The purpose of this is to verify that the file was not tampered with prior to downloading and that it was not corrupted during the download.  I have had success using the following two tools to verify SHA1 and MD5 checksums in Windows.  FCIV (Microsoft File Checksum Integrity Verifier) is a command line utility that is easy to use if you are comfortable with using a Windows terminal.  It can be downloaded from here:  https://www.microsoft.com/en-us/download/details.aspx?id=11533.  Once installed, read the readme.txt document that comes with it for further instructions.  If you would rather use a graphical tool then I recommend Igorware Hasher.  It  is a free utility and can be downloaded here: http://www.igorware.com/hasher

Once you have computed the checksum and compared it to the checksum provided on the download page to verify that your disk image is not corrupt, you are ready to write the image to the SD card.  I use Win32 Disk Imager, which can be downloaded here:  https://sourceforge.net/projects/win32diskimager/
It is pretty simple to use, just select the operating system disk image that you have downloaded for your Pi, select your SD card as the destination, and click "Write".  Just be 100% sure that the drive letter that you select is indeed your SD card, or you could end up overwriting a partition on your computer.

And that's it.  With your newly minted SD card containing the operating system for your Raspberry Pi you are ready to boot it up.  Don't forget, you will need to have a keyboard, mouse, and display in order for you to do the initial configuration on the Raspberry Pi, even if you plan on setting it up for headless operation or remote connectivity.  Below I'll go through some basic hardware options for the Pi, the initial configuration for a Pi running Raspbian, and some basic information regarding the GPIO pins.

Raspberry Pi Hardware Options

I won't spend much time on the Hardware options, just because there are so many of them, and new hardware is being developed all the time.  As I mentioned earlier, you will need a USB keyboard and mouse, as well as a monitor and HDMI cable to do the initial set-up on the Pi.  Depending on the function of the Pi, you can opt to run it headless after that, and just connect to it remotely via SSH or VNC.  If you are building a media center computer then your TV will be your monitor, and I would highly recommend a wireless keyboard/mouse combo with a USB dongle.  You will also need a 5V micro-USB power supply that can provide a minimum of 2 amps.  Most non-Apple phone chargers will work for this purpose, just check the rating on them and make sure that they provide at least 2 amps of current.  If you don't have one handy they can be purchased fairly inexpensively.


The only other piece of hardware that I would consider necessary is a case for your Pi.  Because the circuitry is exposed on all sides, you really want to have something to protect it from coming into contact with anything conductive while it is running.  I've tried many different cases, and I've even made my own.  From my experience the case made by CanaKit is the best, but there are plenty of other good ones out there.  If you are looking to buy a Pi, you can get a kit from CanaKit with the Pi, case, and power supply included, as well as a couple of heat-sinks for your processors.  This is the current link on Amazon for the kit:  https://www.amazon.com/dp/B01C6EQNNK/ref=wl_mb_recs_5_title



As far as other hardware, they sky is the limit.  The Pi has a dedicated camera socket which can be used to connect a camera for high definition pictures and video.  There are also plenty of small touchscreen monitors marketed for the Pi.  If you want to play with the GPIO pins there are breakout boards and cables made specifically for the Pi.  For additional functionality, a wide variety of "HATs" have been developed for the Pi.  These HATs typically connect to the two rows of GPIO pins, making them sit directly on top of the Pi, like a hat (hence the name.)  These can be used for a wide range of things, from driving motors and servos to reading analog sensors, and even adding a GPS module.  If you are interested, take a look at Adafruit's selection of Pi Hats at the following link:  https://www.adafruit.com/category/286
If that's not enough, just Google Raspberry Pi HATs or Pi accessories.  There are new accessories being developed for the Raspberry Pi every day.


Raspbian Initial Configuration

OK, I got off on a little bit of a tangent there regarding the hardware options.  Lets get back to actually using the Pi.  So you've got your Pi, your case, your power supply, and a micro SD card with an operating system installed on it.  What next?  Hook-up your monitor, mouse, keyboard, and Ethernet cable for internet (if you have to use Wifi, that's not a problem, but I won't be covering that here.)  Go ahead and insert the SD card and lets power this baby up.  For the purpose of brevity (if it's not too late for that), I'll only go over the initial set-up for Raspbian.  Other operating systems will likely be similar, and will probably have their own documentation regardless.

If you have installed Raspbian-lite you will be booted into a terminal.  If you have installed Raspbian with Pixel (the graphical desktop interface) you will boot into a desktop environment, similar to Windows.  Either way, you will have to log in. The default user is "pi", and the default password is "raspberry".  Once you are logged in we will need a terminal window, so if you are in the desktop environment click on the black square icon for the terminal in the upper left hand corner of the screen.  Once you are in the terminal, type the following command "sudo raspi-config".  This will bring you to the Configuration Tool.  Typically I'm an advocate of doing everything directly from the command line, just to stay familiar with the Linux terminal, but to keep things easy we'll use the built-in tool.  Below is the main menu for the configuration tool.


As Raspbian gets updated, this menu changes from time to time, so if your menu doesn't look exactly like this don't worry, you should still be able to find the options you need.

The first thing we need to do is to change the default password for the user "pi" (option 1).  This is done for security reasons, so that anyone with knowledge of the default login can't gain access to your system.  Personally I like to go in and create a new user with root permissions, and then delete the user pi altogether, but this is a bit more complicated and not completely necessary, so I won't be covering that here.

Option 2 allows us to change the hostname, which is how the Pi will identify itself on the network.  This step is optional, but I like to make a habit of giving all machines in my network unique hostnames.

The next thing we need to do is set the localization options.  By default the Pi assumes you are in Great Britain, because that is were the Pi originates.  If you are from the other side of the pond in the States, like I am, you will need to notify the Pi.  Select option 4, and proceed through all the sub-menus in order.  For the first menu item, "Change Locale", you will be looking for something like "en_US.UTF-8 UTF-8".  Once you have highlighted this option, use the space-bar to select it, then hit return.  The rest of the menu options, Change Timezone and Change Keyboard Layout, should be fairly self-explanatory.

Option 5, "Interfacing Options," has several sub-menu options, but the only ones I will address here are "Enable SSH" and briefly "Enable VNC"  Both of these options will open the Pi for remote connectivity.  SSH is a protocol that will allow you text-based terminal access from another network computer.  If you are turning the Pi into a server, or you just don't want to leave the keyboard and monitor connected, you will want to enable SSH access.  If you are using a Linux machine to connect to the Pi, you can do it from the terminal command line using the following command: ssh -l <username> <ip.address>  If you are using a Windows machine you will need to use a terminal program like Hyperterminal or Putty.  Putty is the most commonly used terminal program and can be downloaded for free from here: www.putty.org  If you want remote access and are not comfortable having only a text-based terminal, you can turn on VNC server here as well.  VNC will give you remote access to the desktop environment by using a VNC client like RealVNC's VNC Viewer (downloadable from: https://www.realvnc.com/download/viewer/).  Another good option is TightVNC found here: http://www.tightvnc.com/download.php  Unfortunately I have found VNC to be a little slow and laggy on the Pi, so I recommend leaving the keyboard and monitor hooked up if you want to use the desktop environment, and only use SSH for remote connections.

The last thing we need to do is to "Expand the Filesystem" to allow Raspbian to use the entire SD card.  This option is in the sub-menu under "Advanced Options".  Once selected the filesystem will automatically be expanded, and then you should be prompted to reboot.  Once you have completed this last step and rebooted you should be finished with the initial configuration, and be ready to explore the world of Raspberry Pi.

Additional Configuration

I started to include a few other things here, like terminal-based network configuration, changing the root user, and mounting USB drives from the terminal, but I decided this post was already long enough, and the information would not be necessary for all Pi users.  Instead I decided to create a separate post for additional Linux configuration options.  It will be coming soon, and I know you are all very excited.

Raspberry Pi 2B/3B GPIO Pins

The last thing I will touch on in this post is the GPIO pins available on the Raspberry Pi (General Purpose Input/Output).  On the Pi models 2B and 3B there are 40 GPIO pins accessible via the two rows of male header pins.  These pins can be used to connect the Pi to external sensors, or use the Pi to control other electronics.  Really your imagination is the limit.  Just keep in mind that the Pi's GPIO pins use 3.3V logic, so if you are communicating with something using 5, 9, or 12V, you will need to use a level converter of some kind in order to not damage the Pi.



The image above is the layout for the pins on the Raspberry Pi models 2B and 3B.  It was borrowed from the following website, where you can also find the pinouts for other models of the Raspberry Pi:  http://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-header-and-pins/

For additional information regarding writing Python scripts utilizing the GPIO Pins see the following links:


So that is where I am going to stop for now.  In the future if I run across any useful links regarding general information on the Raspberry Pi I will post them below, just for reference.  If anyone can think of any other basic information that I have omitted please let me know and I will update this post.  

Tuesday, May 30, 2017

Experiments with Lichtenberg Figures on Hardwood

     In one of my earlier blog posts on Lichtenberg Figures I made the observation that they did not work well on hardwoods.  However, after continuing experimentation and my success with the mahogany tealight holders, I decided that I simply had not perfected the technique required for burning figures into hardwood.  When I finished the tealight holders I decided to do a little more experimentation before retiring the Lichtenberg machine back to the shelf.  I chose four species of wood: red oak, mahogany, ambrosia maple, and walnut.  I used two pieces of each species, and in an attempt to be as scientific as possible, I planed and cut all the pieces to the same dimensions, approximately 10" x 3-1/2" x 3/8".  For the electrolyte solution I used 1-1/3 tablespoons of baking soda to 1 cup of hot water.  It seems that the trick for getting hardwoods to work is to make sure that they are thoroughly saturated with electrolyte solution, so two coats are necessary before burning, and then additional coats are required throughout burning as the heat from the procedure dries out the wood.  I presoaked all of the pieces by brushing on a liberal amount of solution while avoiding the edges of the pieces.  I did the second coat of electrolyte immediately before burning, concentrating more solution around the area where the electrodes will connect.  In the video below you can see that in almost all instances the pieces will dry out around the electrodes first and will require constant re-wetting throughout the process.



     Now that all of the pieces are finished, it looks like red oak turned out the best (upper left in the picture below), followed by mahogany (upper right), then walnut (lower left), then maple (lower right) respectively.  By best I mean they had more detail, and less thick, deep burns.  This is subjective of course, and other people might be looking for a different effect.


     My hypothesis was that the harder the wood, the more detail would show up, and the softer the wood, the deeper and thicker the burn would be.  While this seems to be generally true (pine and MDF burn thicker and deeper with less detail than hardwoods), between hardwoods there seems to be other factors effecting the pattern.  Confirming my theory, Red Oak is the hardest of the woods I tested, and it did have the most detail.  Maple is the softest, consequently having the least detail.  Walnut, however, is harder than the Mahogany by a significant degree, but it burned decisively deeper lines with less detail than the Mahogany.  Further experimentation along with additional research into the characteristics of the woods will be necessary to determine what factors other than hardness effect the burn patterns on various species of wood.


     Now that the experiment is over, and the Lichtenberg machine has been relegated to it's spot on the shelf, I am once again left with a bunch of wood panels with neat designs but no real purpose.  This time I decided to do something with them.  I was not overly impressed with the Maple, so I set it aside and proceeded to finish the other panels with four coats of polyurethane.  With some brass hooks and eyelets, and a length of brass chain, I connected the panels together to create a simple wall hanging.  I think it turned out nicely.