eBook Raspberry Pi Project Ideas

85
10 PROJECTS FOR THE RASPBERRY PI A RESOURCE FOR BEGINNER AND INTERMEDIATE-LEVEL MAKERS

description

10 "Do-it-yourself" projects with the Rasperry Pi board

Transcript of eBook Raspberry Pi Project Ideas

  • 10 PROJECTSFOR THE RASPBERRY PI

    A RESOURCE FOR BEGINNER AND INTERMEDIATE-LEVEL MAKERS

  • See what happened.Real-time data streaming from your Raspberry Pi with just one line of code. It's that easy.

    Interactive data visualizations.Visualize and mine your data in waveforms, stacked line graphs, and statistics. Data logs streamed in less than 1ms!

    Rest easy, your data is secure.Every data stream is secured by enterprise-grade SSL encryption from the millisecond you stream it. While many of our user share their data with friends and coworkers, others choose to work privately.

    About Initial State

  • Welcome to the Raspberry Pi community!

    Developed in the UK by the Raspberry Pi Foundation with the intention of promoting the teaching of basic computer science in schools, the Raspberry Pi was released to the public in February 2012.

    In two years, about 4.5 million boards have been sold around the world.

    The Raspberry Pi is a hacker or maker's dream device, a credit card-sized Linux computer with enormous educational and DIY/hobbyist possibilities.

    From adding and using temperature sensors and LED lights to building a hamster fitness tracker, weve outlined a few of our favorite beginner and intermediate Raspberry Pi projects.

    Enjoy!

    So, You Own a Raspberry Pi

  • 1. Getting Your Monitor to Work

    2. Taking Control of Your Keyboard Layout

    3. Pressing Buttons to Light Up LEDs

    4. Pressing Buttons to Make an LED Blink

    5. Using Pi-Plates to Add Functionality

    6. Streaming Temperature

    7. Baking a Turkey

    8. Running a Shutdown Button Script at Boot

    9. Building a Mobile GPS Streamer

    10. Building a Hamster Fitness Tracker

    Project Chapters

  • 1Getting Your Monitor to Work

    CHAPTER

  • New toys are exciting. Every moment not spent unpackaging and getting your toy ready for action is a moment wasted. Thats exactly how I felt when I got my hands on my first Raspberry Pi. Initial States ever-generous leader had provided me with everything I needed to get started an HDMI monitor, a Bluetooth keyboard and mouselife was looking pretty good.

    I made sure everything was hooked up properly, turned on my monitor and then powered up the Pi. Andnothing happened. Instead of the beautiful Raspberry SVG popping up on my screen, I saw a No HDMI Input Detected message. I was confused. I checked the HDMI cable. I checked that the Pi was actually on. Everything was good. But everything was not good because the most important slice of my Pi was refusing to cooperate.

    Come to find out, Initial States leader wasnt overly generous the monitor was probably as old as HDMI itself. And after a bit of research, I realized that Pis tend to have widespread issues not working with older monitors. But Im an engineer, and I wasnt going to let that stop me. When rebooting failed, I turned to Google and found out about a very important config.txt file that was the answer to my problems.

    Why Wont My Monitor Work?

  • The problem with NOOBS is that, while it does have lines in its code to help your monitor recognize the Pis HDMI signal, the key presses (1 for HDMI preferred mode and 2 for HDMI safe mode) never worked for me. And since I couldnt see the NOOBS interface since my monitor wasnt working I couldnt access the config.txt file that way.

    Fix:I decided that the OS I wanted was Raspbian. So I went and downloaded just Raspbian (this will work for any other OS too). When I unzipped the file, I now had access to the config.txt file! If you open it up, youll see that the entire file is commented out:

    Problem #1:The monitor is not working with the Raspberry Pi.

    Change the config.txt fileFix:

    Problem #2:NOOBS, Raspberry Pis out-of-box software that came preloaded on my SD card

  • # For more options and information see # http://www.raspberrypi.org/documentation/configuration/config-txt.md # Some settings may impact device functionality. See link above for details # uncomment if you get no picture on HDMI for a default "safe" mode #hdmi_safe=1 # uncomment this if your display has a black border of unused pixels visible # and your display can output without overscan#disable_overscan=1 # uncomment the following to adjust overscan. Use positive numbers if console # goes off screen, and negative if there is too much border #overscan_left=16 #overscan_right=16 #overscan_top=16 #overscan_bottom=16 # uncomment to force a console size. By default it will be display's size minus # overscan. #framebuffer_width=1280 #framebuffer_height=720 # uncomment if hdmi display is not detected and composite is being output #hdmi_force_hotplug=1 # uncomment to force a specific HDMI mode (this will force VGA) #hdmi_group=1 #hdmi_mode=1 # uncomment to force a HDMI mode rather than DVI. This can make audio work in # DMT (computer monitor) modes #hdmi_drive=2 # uncomment to increase signal to HDMI, if you have interference, blanking, or # no display #config_hdmi_boost=4 # uncomment for composite PAL #sdtv_mode=2 #uncomment to overclock the arm. 700 MHz is the default. #arm_freq=800

  • I went through and uncommented these lines to cover all of my bases:

    # uncomment if you get no picture on HDMI for a default "safe" mode hdmi_safe=1 # uncomment if hdmi display is not detected and composite is being output hdmi_force_hotplug=1 # uncomment to increase signal to HDMI, if you have interference, blanking, or # no display config_hdmi_boost=4

    Result:

    The new uncommented lines worked like a charm. My monitor recognized the Pi as soon as I booted with the newly formatted SD card.

    Now you can play with your new toy!

  • 2Taking Control of Your Keyboard Layout

    CHAPTER

  • Alright, so you followed my last tutorial to get your ancient (which is only 4 or 5 years old nowadays) monitor working with your Raspberry Pi. Once you got over the initial excitement of seeing the Pi boot, you mightve gone into the terminal and noticed something funky going on your keyboard was not working! How on earth can you be expected to do anything at all without a pipe* key?!

    This little guy |. Dont worry, I didnt know what he was before terminal, either.

    Not to worry, I can tell you whats wrong and how to fix it.

    Note: We love Great Britain they gave us the Pi, after all!

    My Keyboard Layout is Funny

    Problem #1: Keyboard is not working when you boot Raspbian

    Fix: Raspbians default keyboard layout is British! We need to change it to the U.S. layout.

  • Fix:

    This is easy-peasy, mainly because no pipes are involved. First, check to make sure you have Nano. It is an amazing text editor that works directly in your terminal.

    sudo -s apt-get install nano

    If you dont have it, get it. Its awesome and will let you do this next step. Just type in:

    sudo -s nano /etc/default/keyboard

    Now we can see this little line in your keyboard layout file that says:

    XKBLAYOUT=gb

    That stands for Great Britain and Unattainable Pipes. Change it to:

    And save (Ctrl-X -> Y). Now before you start spamming the backslash key and getting angry, let your Pi know that you want it to drop the accent:

    Once the system is back, you can enjoy your proper keyboard layout! If youd like an example script to type on your newly formatted keyboard, try our Performance Monitor you can see how hard youre making your little board work!

    XKBLAYOUT=us"

    reboot

    Problem #2:

    I have no idea how to change the keyboard layout

  • 3Pressing Buttons to Light Up LEDs

    CHAPTER

  • Ok, so youve installed the Initial State streamer, you ran our little example code, and now youre ready to learn more about streaming and internet-enabled development platforms!

    I chose to use a Raspberry Pi for my project, but the basics can be applied to other single-board computer platforms like BeagleBone Black, PandaBoard, MinnowBoard, and UDOO, or even Gumstix COM and Arduino if they have been outfitted to access the internet and can run Python.

    In this little tutorial I show you how to do a couple things:

    Setup a hardware circuit with LEDs and buttons

    Communicate between software and hardware using Raspberry Pis GPIO pins

    Write a python script that translates button presses into LED events

    And most importantly.

    Use the Initial State streamer to debug and monitor your code!

    Pressing Buttons to Light up LEDs

  • The Raspberry Pi has power, ground, and programmable GPIO pins. These GPIO pins are how we are going to communicate button presses and when we want the LEDs to turn on or off. In the graphic below, you can see my breadboard connections (everything is crowded at the bottom of the board due to the interface board taking up the top 20 pins). Connection to any GPIO pin will work, but I will use my numbering for the examples.

    Raspberry Pi B+ w/ Raspbian loaded SD card HDMI cable + HDMI Monitor (some way to see your Pi) WiFi Adapter/Dongle (can use ethernet cord for hard connection instead) Breadboard 40-pin GPIO Ribbon Cable (can use 5 individual male-to-female jumper cables instead) 40-pin T-Shaped GPIO to Breadboard Interface Board (not necessary if using jumper

    cables) 2 Push Button Switches 3 LEDs (I used Red, Green and Yellow) 3 220 Ohm Resistors (to use with the LEDs; 180-2K Ohms is generally a safe range) 2 10K Ohm Resistors (to use with the buttons; 5K-100K Ohms is generally a safe

    range)

    My Supplies

    I used a Canakit so all of these pieces minus the monitor were included:

  • One row of Button 1 to GPIO 23 (pin 16) and a 10K resistor; the other end of the resistor should be connected to ground

    The other row of Button 1 to the voltage source (3.3 V)

    One row of Button 2 to GPIO 24 (pin 18) and a 10K resistor; the other end of the resistor should be connected to ground

    The other row of Button 2 to the voltage source The short leg of the red LED to GPIO 4 (pin 7) The long leg of the red LED to a 220 resistor; the

    other end of the resistor should be connected to the voltage source

    The short leg of the yellow LED to GPIO 17 (pin 11) The long leg of the yellow LED to a 220 resistor; the

    other end of the resistor should be connected to the voltage source

    The short leg of the green LED to GPIO 27 (pin 13) The long leg of the green LED to a 220 resistor; the

    other end of the resistor should be connected to the voltage source

    You want to connect:

    The Raspberry Pi has power, ground, and programmable GPIO pins. These GPIO pins are how we are going to communicate button presses and when we want the LEDs to turn on or off. In the graphic below, you can see my breadboard connections (everything is crowded at the bottom of the board due to the interface board taking up the top 20 pins). Connection to any GPIO pin will work, but I will use my numbering for the examples.

  • The first thing were going to want to do is import some libraries:

    import RPi.GPIO as GPIO ## Import library that lets you control the Pi's GPIO pins from time import sleep ## Import time for delays

    Sleep is a command that ignores inputs for the specified amount of time. Youll see how it can be used in a few lines.

    As you saw earlier, making the Initial State streamer usable is as easy as:

    from ISStreamer.Streamer import Streamer

    Now we want to tell it where to stream:

    ## Streamer constructor, this will create a bucket called Double Button LED## you'll be able to see this name in your list of logs on initialstate.com## your access_key is a secret and is specific to you, don't share it!streamer = Streamer(bucket_name="Double Button LED", access_key="Place Your Access Key Here")

    Every time you run a script with a bucket name a new bucket will be created, even if that bucket name already exists in your log shelf. You can append to the same bucket by adding the bucket_key parameter (see below). Any stream with the same bucket_key will go to the same bucket regardless of bucket name.

    streamer = Streamer(bucket_name="Double Button LED", bucket_key="double_button_led", access_key="Place Your Access Key Here")

  • GPIO.setwarnings(False) ## Disables messages about GPIO pins already being in use GPIO.setmode(GPIO.BOARD) ## Indicates which pin numbering configuration to use GPIO.setup(16, GPIO.IN) ## Tells it that pin 16 (button) will be giving input GPIO.setup(18, GPIO.IN) ## Tells it that pin 18 (button) will be giving input GPIO.setup(7, GPIO.OUT) ## Tells it that pin 7 (LED) will be outputting GPIO.setup(11, GPIO.OUT) ## Tells it that pin 11 (LED) will be outputting GPIO.setup(13, GPIO.OUT) ## Tells it that pin 13 (LED) will be outputting GPIO.output(7, GPIO.HIGH) ## Sets pin 7 (LED) to "HIGH" or off GPIO.output(11, GPIO.HIGH) ## Sets pin 11 (LED) to "HIGH" or off GPIO.output(13, GPIO.HIGH) ## Sets pin 13 (LED) to "HIGH" or off

    Its time to set up the GPIO pins. The first phrase keeps the terminal from alerting us about GPIO pin use (since we know were using them!). GPIO.BOARD tells the Pi that you will designate pins by their placement (i.e. the number in the circle) instead of their name (i.e. GPIO 3). If you want to use the latter convention, simply replace BOARD with BCM.

    GPIO.setup lets the Pi know which pins you are using and whether they will receive input (buttons) or giving output (LEDs). We will set the LEDs initial states to off.

    Now comes the fun part! We need to initialize some of the parameters well be using later:

    ## state - decides what LED should be on and off ## initialize to 0 or all off state = 0 ## increment - the direction of states ## initialize to 1 or increasing inc = 1 ## Set prev_input's initial value to 2 prev_input=2

  • ## This while loop constantly looks for button input (presses) while True: ## When state toggle button is pressed if ( GPIO.input(16) == True ): ## If increment is increasing, increase state by 1 each press if (inc == 1): state = state + 1; ## If increment is decreasing (0), decrease state by 1 each press else: state = state - 1; ## Reached the max state, time to decrease state if (state == 3): inc = 0 prev_input=1 ## Keeps a reset button phrase from executing when state shifts down to 2 streamer.log("prev_input",prev_input) ## Stream prev_input when changed streamer.log("increment", inc) ## Stream increment when changed; "stream name", value ## Reached the min state, time to increase state elif (state == 0): inc = 1 prev_input=2 ## Makes all reset button phrases executable streamer.log("prev_input",prev_input) ## Stream prev_input when changed streamer.log("increment", inc) ## Stream increment when changed ## Define state 1 if (state == 1): GPIO.output(7, GPIO.LOW) ## LED on GPIO.output(11, GPIO.HIGH) ## LED off GPIO.output(13, GPIO.HIGH) ## LED off prev_input=2 ## Makes all reset button phrases executable streamer.log("state",state) ## Stream current state streamer.log("increment",inc) ## Stream current increment streamer.log("prev_input",prev_input) ## Stream current prev_input## Define state 2 elif (state == 2):

    And start our While loop! The code within this loop executes whenever a statement is True. So the first If statement will execute if GPIO pin 16 (or button 1) receives input (is pressed). The increment variable designates whether the LEDs will turn on or turn off one-by-one. The state is indicative of how many LEDs are on currently. We also begin to insert streamer statements!

  • GPIO.output(7, GPIO.LOW) ## LED on GPIO.output(11, GPIO.LOW) ## LED on GPIO.output(13, GPIO.HIGH) ## LED off prev_input=2 ## Makes all reset button phrases executable streamer.log("state",state) ## Stream current state streamer.log("increment",inc) ## Stream current increment streamer.log("prev_input",prev_input) ## Stream current prev_input## Define state 3 elif (state == 3): GPIO.output(7, GPIO.LOW) ## LED on GPIO.output(11, GPIO.LOW) ## LED on GPIO.output(13, GPIO.LOW) ## LED on streamer.log("state",state) ## Stream current state streamer.log("increment",inc) ## Stream current increment streamer.log("prev_input",prev_input) ## Stream current prev_input## If the state equals anything other than 1, 2, or 3 (0) else: GPIO.output(7, GPIO.HIGH) ## LED off GPIO.output(11, GPIO.HIGH) ## LED off GPIO.output(13, GPIO.HIGH) ## LED off streamer.log("state",state) ## Stream current state streamer.log("increment",inc) ## Stream current increment streamer.log("prev_input",prev_input) ## Stream current prev_input streamer.log("button_1", "pressed") ## Stream which button was pressed sleep(0.2); ## Wait 0.2 second before looking for another button input

    This next if statement executes whenever GPIO pin 18 (or button 2) is pressed. It will either turn all of the LEDs on or off depending on their current state.

    ## When reset button is pressed if ( GPIO.input(18) == True ): ## If 1 or 2 LEDs are on if (state == 1 or 2 and prev_input!=1): GPIO.output(7, GPIO.LOW) ## LED on GPIO.output(11, GPIO.LOW) ## LED on GPIO.output(13, GPIO.LOW) ## LED on prev_input=1 ## Keeps this phrase from executing when all LEDs are already on state=3 ## Change state to 3 inc=0 ## Change increment to decreasing streamer.log("state",state) ## Stream current state streamer.log("increment",inc) ## Stream current increment streamer.log("prev_input",prev_input) ## Stream current prev_input#streamer.log("phrase",1) ## used to see when each phrase was executing

  • ## If no LEDs are on elif (state == 0 and prev_input!=0): GPIO.output(7, GPIO.LOW) ## LED on GPIO.output(11, GPIO.LOW) ## LED on GPIO.output(13, GPIO.LOW) ## LED on prev_input=1 ## Keeps this phrase from executing immediately after the state is set to 0 state=3 ## Change state to 3 inc=0 ## Change increment to decreasing streamer.log("state",state) ## Stream current state streamer.log("increment",inc) ## Stream current increment streamer.log("prev_input",prev_input) ## Stream current prev_input#streamer.log("phrase",2) ## used to see when each phrase was executing ## If all LEDs are on elif (state == 3 and prev_input!=0): GPIO.output(7, GPIO.HIGH) ## LED off GPIO.output(11, GPIO.HIGH) ## LED off GPIO.output(13, GPIO.HIGH) ## LED off prev_input=0 ## Keeps this phrase from executing immediately after the state is set to 3 state=0 ## Change state to 0 inc=1 ## Change increment to increasing streamer.log("state",state) ## Stream current state streamer.log("increment",inc) ## Stream current increment streamer.log("prev_input",prev_input) ## Stream current prev_input#streamer.log("phrase",3) ## used to see when each phrase was executing streamer.log("button_2(bullseye)", "pressed") ## Stream which button was pressed sleep(0.2); ## Wait 0.2 second before looking for another button input

    And finally we need to safely wrap up everything with a closing statement:

    streamer.close()

    Now we can run the code! Pressing Button 1 should light the LEDs up one at a time, while pressing Button 2 should turn them all on if 0, 1, or 2 LEDs were on or all off if all 3 were on.

    You can also go to your Initial State account to see your new Double Button LED bucket! After pressing my buttons a few times, this is what I had to look at:

  • If you like the idea of streaming your data directly from your device but dont have an Initial State account yet, sign up for free here.

  • 4Pressing Buttons to Make an LED Blink

    CHAPTER

  • A while ago, I showed you how to configure three LEDs and two buttons using the Raspberry Pis GPIO pins. Once youve gotten the hang of buttons and how programmable pins work, there are all sorts of cool applications.

    Just to show you another neat thing youre now capable of, Im going to walk you through setting up an LED that starts blinking when you press a button. Learning how to start and stop an action with button presses and make something alternate states on its own is great for tackling more complex projects!

    Start and stop a blinking LED with the push of a button

    Use Initial State to broadcast a message when the button is ready to be pressed and then register each time the LED goes on and off before the button is pressed again.

    Use Button to Make an LED Blink

    Here Im going to show you how to

  • Raspberry Pi B+ w/ Raspbian loaded SD card HDMI cable + HDMI Monitor + Bluetooth Keyboard/Mouse WiFi Adapter/Dongle (can use ethernet cord for hard connection instead) Breadboard 40-pin GPIO Ribbon Cable (can use 5 individual male-to-female jumper cables

    instead) 40-pin T-Shaped GPIO to Breadboard Interface Board (not necessary if using jumper

    cables) 3 Breadboard Tie Lines 1 Push Button Switch 1 LED (I used Blue) 1 220 Ohm Resistors (to use with the LEDs; 180-2K Ohms is generally a safe range) 1 10K Ohm Resistors (to use with the buttons; 5K-100K Ohms is generally a safe

    range)

    I used a Canakit so all of these pieces minus the monitor, keyboard, and mouse were included:

    You want to connect:

    One row of the button to GPIO 23 (pin 16) and a 10K resistor; the other end of the resistor should be connected to ground

    The other row of the button to the voltage source (3.3 V)

    The short leg of the blue LED to GPIO 4 (pin 7) The long leg of the blue LED to a 220 resistor;

    the other end of the resistor should be connected to the voltage source

  • Now for the software part! If you havent installed the Initial State Streamer yet, its super fast and easy.

    Instructions

    1. Create an Access Key in your Initial State account (can do on the landing page under Streaming Access Keys). If you dont have an account you can sign up at https://www.initialstate.com/app/#/register!

    2. Turn on your device and make sure you have an internet connection.

    3. Type this command into the command line:

    \curl-sSL https://get.initialstate.com/python-o-| sudo bash

    4.Follow the prompts if you say Y to the Create an example script? prompt, then you can designate where youd like the script and what youd like to name it. Your Initial State username and password will also be requested so that it can autofill your Access Key. If you say n then a script wont be created, but the streamer will be ready for use.

    5. Either use your example script to get your Access Key or create one from scratch and start streaming!

  • Run a while loop to check for button presses and either blink or stop the LED when it detects one. Note that the sleep sometimes causes button presses not to register while the LED is blinking. Pressing and holding the button for 1 second should do the trick.

    import RPi.GPIO as GPIO ## Import library that lets you control the Pi's GPIO pins from time import sleep ## Import time for delays from ISStreamer.Streamer import Streamer ## Import the Initial State streamer

    Designate the name of your stream and which Initial State account it should go to.

    ## Streamer constructor, this will create a bucket called Button Blink## you'll be able to see this name in your list of logs on initialstate.com## your access_key is a secret and is specific to you, don't share it!streamer = Streamer(bucket_name=Button Blink", access_key="Your Access Key Here")

    Setup your GPIO pins and initialize some variables.

    GPIO.setwarnings(False) ## Disables messages about GPIO pins already being in use GPIO.setmode(GPIO.BOARD) ## Indicates which pin numbering configuration to use pinNumLED = 7 pinNumBTN = 16 GPIO.setup(pinNumLED,GPIO.OUT) ## Tells it that pinNumLED will be outputting GPIO.setup(pinNumBTN,GPIO.IN) ## Tells it that pinNumBTN will be giving input ## Initialize btnOn and prev_inputbtnOn = False prev_input = 1

    Stream your first message!

    ## Stream a message when the button is ready to press streamer.log("msg","Press the Button!")

    Import the GPIO library, time, and the streamer.

  • while True: try: input = GPIO.input(pinNumBTN) if ((not prev_input) and input): btnOn = not btnOnprev_input=input sleep(0.05) ## When the button is pressed, start toggling the LED between ## HIGH and LOW with a 0.5s interval between if btnOn: GPIO.output(pinNumLED,GPIO.HIGH) streamer.log("LED","Off") ## Stream that the LED is Off sleep(0.5) GPIO.output(pinNumLED,GPIO.LOW) streamer.log("LED","On") ## Stream that the LED is On sleep(0.5) else: GPIO.output(pinNumLED,GPIO.HIGH)

    Pressing Cntl-C will exit the while loop and stream the final message. streamer.close() makes sure that all of the logs are streamed before the script finishes.

    except KeyboardInterrupt: break ## Stream a message when the loop has been broken streamer.log("msg","Finished!") streamer.close()

    In Initial State you can see when the button was first pressed and when the LED turns on and off.

  • If you like the idea of streaming your data directly from your device but dont have an Initial State account yet, sign up for free here.

  • 5Using Pi-Plates to Add Functionality

    CHAPTER

  • If you thought that Raspberry Pis were cool, just wait till you see all of the things you can add to them to expand their functionality. And if you already knew about all of the things you can add to them, just wait till you see this one!

    Pi-Plates are stackable Raspberry Pi add-on circuit boards that come with all sorts of goodies. The one I have pictures of here is the ppDAQC board, and it comes with 7 digital outputs, 8 analog to digital inputs, 8 digital inputs, 2 analog outputs and 7 indicator LEDs. My other favorite features are the programmable pushbutton and bicolor LED (but thats just because Im easily entertained).

    Using Pi-Plates

  • To show you how easy it is to set this bad boy up, Im going to tell you how right now. The Pi-Plate just stacks on top of the Pis GPIO pins. It makes use of the Pis SPI feature, so make sure that its enabled by entering:

    sudo nano /etc/modprobe.d/raspi-blacklist.conf

    And commenting out blacklist spi-bcm2708.

    If you had to comment it out, reboot your Pi (sudo reboot). spi_bcm2708 should now be listed if you enter lsmod in the command line.

    If you dont already have the SPI and GPIO libraries, youll need to update and install them:

    sudo apt-get update sudo apt-get install python-devsudo apt-get install python-rpi.gpio

    And now we want to make the ports accessible in Python:

    mkdir python-spicd python-spiwget https://raw.github.com/doceme/py-spidev/master/setup.py wget https://raw.github.com/doceme/py-spidev/master/spidev_module.c sudo python setup.py install

    sudo apt-get install python-pip sudo pip install http://pi-plates.com/downloads/pi-plates.tar.gz

    Now lets run a Hello World! The guys at Pi-Plates provide a nice beginner script that outputs Hello World in ASCII through the built-in LEDs. I thought this was pretty neat, so I also inserted some streamer statements so I could see the ASCII values of each letter. Want to try out Initial States data streamer? See how to install it below.

    Finally, the ppDAQC module needs to be installed. It uses pip, so if you dont already have that, be sure to run the first line:

  • 1. Create an Access Key in your Initial State account (can do on the landing page under Streaming Access Keys). If you dont have an account you can sign up here!

    2. Turn on your device and make sure you have an internet connection.

    3. Type this command into the command line:

    \curl-sSL https://get.initialstate.com/python-o-| sudo bash

    Instructions:

    4. Follow the prompts if you say Y to the Create an example script? prompt, then you can designate where youd like the script and what youd like to name it. Your Initial State username and password will also be requested so that it can autofill your Access Key. If you say n then a script wont be created, but the streamer will be ready for use.

    5. Either use your example script to get your Access Key or create one from scratch and start streaming!

    The script is very simple we just import the ppDAQC module, the ISStreamer module and time. Then we set up the streamer and a while loop that converts each letter in Hello World into an ASCII value that is output to the Pi-Plates LEDs.

    ## Import the Pi-Plates ppDAQC moduleimport piplates.ppDAQC as ppDAQC## Import time for delaysimport time## Import the ISStreamer modulefrom ISStreamer.Streamer import Streamer ## Streamer constructor, this will create a bucket called Computer Performance## you'll be able to see this name in your list of logs on initialstate.com## your access_key is a secret and is specific to you, don't share it!streamer = Streamer(bucket_name="Pi-Plates Hello World",access_key="[Your Access Key]")

  • msg='Hello World' msgLen = len(msg) ## This will run until you interrupt it (Ctrl-C) while(1): for i in range(0,msgLen): value=ord(msg[i]) streamer.log("Letter",msg[i]) ppDAQC.setDOUTall(0,value) streamer.log("ASCII value", value) time.sleep(.5) streamer.close()

    The while loop will run until you interrupt it with Ctrl-C.

    You can see the Pi-Plates built-in LEDs lit up in the top left corner of the board. On the right you can see how ASCII value changes with each letter inside of Initial State.

    Now youve made your board light up! Lets use my other favorite built-in feature the programmable button. The Pi-Plate makes it very very easy to turn this button into the one thing I always wish my Raspberry Pi had a shutdown button!

    First you need to install a program that runs in the background of your Pi called ppPower. This is easy to do with these commands:

  • wget http://pi-plates.com/downloads/ppPower-1.00.tar.gz tar -xzf ppPower-1.00.tar.gz cd ppPower-1.00 sudo ./install-ppPower

    import piplates.ppDAQC as ppDAQCppDAQC.enableSWpower(0)

    Now you just need to reboot your Pi (sudo reboot), and associate the button with this program. Enter Python with sudo python and enter the following lines:

    Aaaaaaaand it was that easy to set up a functioning shutdown button! It will work every time you turn on your Pi with the Pi-Plate attached from here on out. The Pi-Plate even provides a convenient LED indicator that turns orange while the Pi is shutting down and red when it is safe to remove the power.

    To read more about the button and what this particular Pi-Plate can do, be sure to visit this users guide.

    Thats all for now on the Pi-Plate, but be on the lookout for future tutorials this little guy is waaaaaay more powerful than what Ive shown!

    Here you can see the magical blue button

  • 6Streaming Temperature

    CHAPTER

  • Hello World! This is likely the output of the first program you ever wrote when learning how to code. Setting up a device to stream temperature data is quickly becoming the de facto Internet of Things (IoT) Hello World! project. If printing Hello World! the first time was a long, frustrating task, you might have never written another program. Your first IoT project should only put a big ol smile on your face. This fun, easy project will introduce you to the wonderful world of IoT data streaming.

    A video tutorial of this entire project can be found at http://youtu.be/HMqPbfvCshs.

    An internet connected Raspberry Pi or your single-board computer of choice. A DS18B20 temperature sensor (https://www.adafruit.com/product/381). A breadboard for wiring up a simple circuit (in the Adafruit Pi starter kit). A 4.7K to 10K resistor (also in the Adafruit Pi starter kit).

    Stream Temperature from Your Raspberry Pi

    Here are the supplies you will need

  • The DS18B20 temperature sensor works well with the Raspberry Pi because it has a digital output, and the Pi has no on-board analog to digital convertors (ADC). Raspbian includes an interface to read the output of the sensor. We just have to write a little code to grab and parse out the temperature. Adafruit has a great tutorial here (and here for the PDF version) for using the DS18B20 that we are simply going to follow and modify to stream the temperature instead of just outputting it to the screen.The hardware setup is simple. DS18B20 red wire to 3.3V. Black wire to GND. Blue wire to a pull-up resistor and to GPIO pin 4 of your Pi.

  • To start the temperature sensor read interface we need to run two commands. Go to a command prompt on your Pi or SSH into your Pi. Type the following commands:

    sudo modprobe w1-gpio sudo modprobe w1-therm

    cd /sys/bus/w1/devices

    The output of your temperature sensor is now being written to a file on your Pi. To find that file,

    In this directory, there will be a sub-directory that starts with 28-. What comes after the 28- is the serial number of your sensor. cd into that directory. Inside this directory, a file named w1_slave contains the output of your sensor. The contents of this file will look something like this:

    a2 01 4b 46 7f ff 0e 10 d8 : crc=d8 YES a2 01 4b 46 7f ff 0e 10 d8t=26125

    The number after t= is the number we want. This is the temperature in 1/1000 degrees Celsius (in the example above, the temperature is 26.125 C). We just need a simple program that reads this file and parses out that number. Lucky for us, Adafruit already created a Python script for us that does just this and outputs the temperature to the screen. Create a new file on your Pi (e.g. temperature.py) and copy-paste the following code in.

    import os import glob import time os.system('modprobe w1-gpio') os.system('modprobe w1-therm') base_dir = '/sys/bus/w1/devices/' device_folder = glob.glob(base_dir + '28*')[0] device_file = device_folder + '/w1_slave' def read_temp_raw(): f = open(device_file, 'r') lines = f.readlines()

  • f.close() return lines def read_temp(): lines = read_temp_raw() while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw() equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 temp_f = temp_c * 9.0 / 5.0 + 32.0 return temp_c, temp_f while True: print(read_temp()) time.sleep(.5)

    Run this script (sudo python temperature.py) to see the output of your temperature sensor on the screen.

    This is the point where we deviate from the Adafruit tutorial. Sending temperature to the screen is boring. We want to stream this data to somewhere we can see not only the current temperature but a history of captured temperature data (plus, who wants to read a bunch of temperatures as text; we want a pretty data visualization). First install the Initial State streamer to give our temperature measurements a destination to go to (go here for instructions on setting up the Initial State streamer; it is super easy and takes less than two minutes). We are going to modify the script above to stream the temperature to our Initial State account instead of outputting it to the screen. Here are the modifications:

    import os import glob import timefrom ISStreamer.Streamer import Streamer streamer = Streamer(bucket_name="Temperature Stream", access_key="PUT YOUR ACCESS KEY HERE")

  • os.system('modprobe w1-gpio') os.system('modprobe w1-therm') base_dir = '/sys/bus/w1/devices/' device_folder = glob.glob(base_dir + '28*')[0] device_file = device_folder + '/w1_slave' def read_temp_raw(): f = open(device_file, 'r') lines = f.readlines() f.close() return lines def read_temp(): lines = read_temp_raw() while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw() equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 return temp_c while True: temp_c = read_temp() temp_f = temp_c * 9.0 / 5.0 + 32.0 streamer.log("temperature(C)", temp_c) streamer.log("temperature(F)", temp_f) time.sleep(.5)

    You will need to copy+paste the access key associated with your Initial State account in between the quotes on line 6 where it says PUT YOUR ACCESS KEY HERE. You can find your access key under your account settings or on the landing page once you log into your account.

    These are the modifications we just made: On line 4, we imported the Initial State data streamer module. On line 6, we created a new bucket called Temperature Stream and associated it with our account via our access key.

  • On line 30, we modified the read_temp() function to only return the temperature in Celsius. On line 34, we converted the output of read_temp() to fahrenheit. On lines 35 and 36, we streamed the two temperatures.

    Run the modified script (sudo python temperature.py or if you want to set this to run uninterrupted for a long time, you might want to use the nohup command nohup sudo python temperature.py > tmp.txt &). I put my temperature sensor on ice then warmed it back up again in my hand to test it out. Go to your Initial State account and a new log will show up in your log shelf called Temperature Stream. View this in Waves or Lines to see your data streaming in real-time. Here is what my data looked like in Lines.

    Now that you can capture and stream temperature data, you have the tools to stream anything you can capture sensor outputs, software variables, hardware events, button presses, doors opening, your heart rate, gps data, your hamsters activity, anything.

  • 7Baking a Turkey

    CHAPTER

  • Since everything is getting connected to the Internet of Things, it is time for your turkey to get in on the IoT action. In this simple tutorial, I will show you how capture the temperature of your bird as it cooks in the oven and stream it to a data visualization in your web browser. Hi-tech turkey!

    Use a Respberry Pi Help You Bake a Turkey

    Here are the

    supplies you

    will need

    An internet connected Raspberry Pi or your single-board computer of choice

    Vernier Go!Temp USB temperature probe

    Thermal shield tape

  • The Vernier Go!Temp probe has a temperature range of -20C 115C (-4F 239F), convenient since we want our turkey to reach an internal temperature of 71C (160F). However, you do not want to expose the plastic base or cord of the Go!Temp probe to the ovens high temperatures. This is where the thermal shield tape comes in. Thoroughly wrap all of the probes exposed plastic that will be inside of the oven in the thermal shield tape to keep it safe. The wrapped, shielded cord and Go!Temp probe are the only things that will go in the oven with your turkey (please do not put your Raspberry Pi in the oven).

    Plug your Go!Temp probe into your USB port and start your Pi. At a command prompt, type lsusb to verify that your Pi sees the probe:

    pi@raspberrypi ~ $ lsusbBus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 001 Device 003: ID 08f7:0002 Vernier EasyTemp/Go!TempBus 001 Device 004: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter Bus 001 Device 005: ID 046d:c534 Logitech, Inc.

  • One of the devices connected should say Vernier EasyTemp/Go!Temp. Once connected, your Go!Temp probe is going to write data to a file, /dev/ldusb0. Verify that file is present (type ls -l /dev/ldusb0 at the command prompt).

    That completes the hardware setup. For the software setup, first install the Initial State streamer (instructions previously laid out in this eBook) to give your captured temperature readings a destination to go to. Create a new file on your Raspberry Pi (e.g. turkey_temp.py) and copy+paste the code below into it. You will need to copy+paste the access key associated with your Initial State account in between the quotes on line 6 where it says PUT YOUR ACCESS KEY HERE. You can find your access key under your account settings or on the landing page once you log into your account. The code below is all of the code that you will need.

    from ISStreamer.Streamer import Streamer import time import struct # Streamer constructor, this will create a bucket called Turkey Temperature streamer = Streamer(bucket_name=Turkey Temperature", access_key="PUT YOUR ACCESS KEY HERE") # Stream message streamer.log("Turkey Says", "Gobble Gobble") targetTemp = 160 targetReached = False while True: # Set sample interval to 5 seconds time.sleep(5.0) # Read 8 bytes from ldusb0 and unpack them # little endian format # data 0: 1-Byte Sample Count # data 1: 1-Byte Sequence Number # data 2, 3, 4: 2-Byte Temperature Samples ldusb = open("/dev/ldusb0") raw = ldusb.read(8) ldusb.close() data = list(struct.unpack("

  • Line 6 sets up the destination bucket for our data stream. We will name the bucket Turkey Temperature. Every time you run this script, a new bucket named Turkey Temperature will be created under your Initial State account (identified by your access key), and all data generated from that script run will be contained there. Line 9 streams the first message to the newly constructed stream.

    Reading the temperature from the Go!Temp probe (lines 16-32) follows the guide given at http://finninday.net/wiki/index.php/Vernier_Go_Temp_USB_device_in_Linux. Every five seconds, eight bytes are read from /dev/ldusb0. Within these eight bytes are three 2-byte temperature readings from the probe. However, these readings need to be converted to Celsius/Fahrenheit. After testing the conversion equation given in the finninday.net tutorial, I realized that my Go!Temp required a bit more calibration tuning to be accurate. I tested the reading on a few different temperatures and empirically determined the readings were off by a factor of 1.16 (hence the adjustment on line 32). I recommend doing similar tests on your Go!Temp probe and adjusting the conversion accordingly.

    Streaming the calculated temperature happens on line 35. If you want to change how often the temperature is captured and streamed, change the sleep time on line 16.

    # Average together the three temperature samples and apply transform: C = Average/126.74 - 5.4 cel = (data[2] + data[3] + data[4]) / 3 / 126.74 - 5.4 fahr = (9.0/5.0 * cel) + 32.0 # Adjusted temperature factor determined empirically fahrAdj = fahr * 1.16 # Stream it streamer.log("Temperature(F)", fahrAdj) if fahrAdj > targetTemp and not targetReached: streamer.log("Turkey Says", "I am cooked!!") targetReached = True

  • We are ready for a test run. A good test to run is to capture the temperature change inside your oven when you preheat it. This will ensure that everything is working before you mess with your turkey. Set your preheat to something less than 115C (239F). Do not preheat more than 150C (302F) or you will damage your Go!Temp probe. Be careful to only put the thermally wrapped and shielded portion of the probe in the oven and start the preheat cycle. Run the python script at the command prompt (type sudo python turkey_temp.py).

    Log into your Initial State account and a new log will pop up in your log shelf called Turkey Temperature. View this in Waves or Lines to see your temperature changes. My test run is shown above when I used my ovens fast preheat option. It took my oven 6.58 minutes to reach 256F where it then settled back to the target 240F. I found it Interesting that this option overshoots the target then settles back down. I decided to do a second test run using my ovens normal preheat option for comparison. This was a much more surprising result.

  • I learned that my oven is a liar. After 11 minutes, my oven beeped to tell me that it was preheated to 240F. The temperature reading was only 184F. For the next 10 minutes, it continued to preheat until it stabilized at 230F. Huh? I have a hard enough time cooking as it is. I do not need any additional help from my oven to sabotage dinner.Once everything is working, you are ready to cook. You will want to place the Go!Temp probe in the thigh of the turkey but do not touch the bone (b/c the bone heats up faster than the meat). A nice guide on exactly where to place a meat thermometer in a turkey can be found at http://karyosmond.com/where-do-you-stick-thermometer-turkey. Use a small knife or something sharp as a guide for your probe. Did I mention that the only thing that should be in the oven besides your turkey is the thermally wrapped portion of your Go!Temp probe and not your Raspberry Pi? Please dont kill a perfectly good Pi. You are ready to cook and stream. Once you see that your turkey has reached its target temperature (160F to 175F depending on whose advice you take), your bird is cooked. Bon Apptit**Note This tutorial pushes the Go!Temp probe to its temperature limits. If you cook your turkey at an oven temperature higher than 150C (302F), your Go!Temp probe may die. Follow all directions and restrictions listed in your Go!Temp probes instruction manual.

  • 8Running a Shutdown Button

    Script at Boot

    CHAPTER

  • Alright, so I showed you how to use buttons and LEDs with the Raspberry Pi now were going to move on to something a little more advanced. Ever wanted one of your scripts to start running as soon as your Pi boots up? Getting tired of having to type the shutdown command into the terminal whenever you want to safely power down your Pi or have your Pi powering a project so that you cant type into it? Want to know how long your Pis been running during a certain experiment or application?

    If you answered yes to any of those questions, this tutorial has got you covered!

    You will learn how to

    Start running a script as soon as the Pi boots

    Make any command you want execute when you press your button (particularly the shutdown command in this example)

    Use an LED as an indicator that your script is running in the background

    Aaaaaaaand

    Run Shutdown Button Script at Boot

  • Use Initial State to track how long you use your Raspberry Pi from boot to shutdown

    Get a behind-the-scenes look at how Initial State helped me discover something very interesting about how the Pi tracks time

    Overcome this time-tracking issue

    I used a Canakit so all of these pieces minus the monitor, keyboard, and mouse were included:

    Raspberry Pi B+ w/ Raspbian loaded SD card HDMI cable + HDMI Monitor + Bluetooth Keyboard/Mouse WiFi Adapter/Dongle (can use ethernet cord for hard connection instead) Breadboard 40-pin GPIO Ribbon Cable (can use 5 individual male-to-female jumper cables

    instead) 40-pin T-Shaped GPIO to Breadboard Interface Board (not necessary if using

    jumper cables) 3 Breadboard Tie Lines 1 Push Button Switch 1 LED (I used Green) 1 220 Ohm Resistors (to use with the LEDs; 180-2K Ohms is generally a safe

    range) 1 10K Ohm Resistors (to use with the buttons; 5K-100K Ohms is generally a

    safe range)

  • One row of the button to GPIO 23 (pin 16) and a 10K resistor; the other end of the resistor should be connected to ground

    The other row of the button to the voltage source (3.3 V)

    The short leg of the green LED to GPIO 4 (pin 7)

    The long leg of the green LED to a 220 resistor; the other end of the resistor should be connected to the voltage source

    Now were going to go over the script. I named mine offbutton.py.

    You want to connect

    The first thing youre going to want to do is import the Pis RPi.GPIO library, os to send commands to execute in the terminal, exit so that the script quits once the results of the button push are done executing, and sleep for waiting before the next action.

    import RPi.GPIO as GPIO ## library that lets you control the Pi's GPIO pins import os ## allows us to talk to the system like in the terminal from sys import exit ## allows us to use "exit" from time import sleep ## allows us to use "sleep"

    If you havent imported the GPIO module yet, youll need to enter sudo apt-get install python-rpi.gpio into the terminal and let it install. The only other import that requires installation is the Initial State streamer. If you havent installed it yet, its super easy and takes less than 2 minutes (instructions written in earlier tutorials).

  • ## allows us to use the Initial State streamer from ISStreamer.Streamer import Streamer ## designate bucket name and individual access_key## if the bucket name already exists in association with the access_key, ## then the data will append to that bucket ## if the bucket name does not already exist, then a new bucket will be created ## the access_key tells Initial State which account to send the data to streamer = Streamer(bucket_name=Shutdown", access_key="[Your Access Key Here]")

    GPIO.setwarnings(False) ## disables messages about GPIO pins already being in use GPIO.setmode(GPIO.BOARD) ## indicates which pin numbering configuration to use GPIO.setup(16, GPIO.IN) ## tells it that pin 16 (button) will be giving input GPIO.setup(7, GPIO.OUT) ## tells it that pin 7 (LED) will be outputting GPIO.output(7, GPIO.HIGH) ## sets pin 7 (LED) to "HIGH" or off

    Now we need to get the GPIO pins in order.

    Time to initialize some variables. i is going to keep track of how many times the LED blinks while our script is running.

    ## set i's initial value to 0 i=0 ## set prev_input's initial value to 0 prev_input=0

    This while loop will stream a message when it is running and wait for a button press. The first if statement will keep a status LED blinking as long as the button has not been pressed. The else statement will run sudo shutdown -h now as if it had been entered in the command line. You can change this to be a different command if you want.

  • ## this while loop constantly looks for button input (presses) while True: streamer.log("msg","Ready for button input") ## stream message ## if no button press if (GPIO.input(16) == False and prev_input!=1): i=i+1 ## iteration count increases by 1 streamer.log("iteration",(i)) ## stream current iteration GPIO.output(7,True) ## switch on pin 7 (LED) sleep(0.5) ## wait for 0.5 second GPIO.output(7,False) ## switch off pin 7 (LED) sleep(1) ## wait for 1 second ## when button is pressed else: GPIO.output(7,GPIO.HIGH) ## turn pin 7 (LED) off ## script to be called os.system("sudo shutdown -h now") ## shuts down Pi streamer.log("msg","Script has been called") ## keeps script from executing the "if" section while button is unpressed## after it has been pressed prev_input=1 streamer.close() ## send any messages left in the streamer

    Note: Because of the sleep, you may have to press and hold the button for half a second to make sure the press is picked up.

    Adding exit() at the end will stop the script. If you remove it along with prev_input=1, the LED will resume blinking and you can press the button to execute the same command again.

    Now, to call this script automatically! There are a couple of ways that you can run a script at a certain time or when something specific happens. A very easy way to do this is with Cron, a tool that comes ready to use on Unix systems (like the Pi!). Cron allows you to specify minute, hour, day of month, month of year and day of week. A more advanced method that also allows you greater freedom to designate when your script is run is by creating an init (initialization) file.

    exit() ## terminates this script

  • Because I only needed my script to start at boot, I chose to use Cron. While init files do allow you greater control, they are much more complicated to write. If youd like to use an init file, you can see how to here. Getting to the file you need to edit is as easy as typing

    sudo crontab -e

    In your terminal and hitting enter. You will see a file pop up with a lot of comments. At the bottom of this file youll want to add the line

    @reboot sudo python /home/pi/Streamer/offbutton.py

    @reboot tells Cron to execute the line following it once the system has booted up. My file is named offbutton.py and it is located in my Streamer folder. Youll want to replace those with the name and location of your file. If its just in the main folder on the Pi, its location is /home/pi/. Whenever you dont want the script to run just comment out the line with # and save the file.

    Note: You do need to reboot the Pi before this new Crontab will take effect. Since our script also starts at boot, we had to do this anyways!

    The first time I ran this script, it worked beautifully. I saw the LED start flashing a bit after the Pi had started, and when I pressed the button, my Pi safely shutdown. I then went over to Initial State to make sure that everything was streaming correctly.

    Check out my visualization

  • As may be able to tell, something funny is going on! It looks like the code is stuck on iteration 5 for about 90 seconds. But thats strange because I never noticed the LED blinking irregularly, and I dont even think that it takes the Pi that long to startup. I consulted Initial States resident expert (our backend developer, David Sulpy), and he thought that it might be a time stamping issue. I investigated further, and he was right!! Turns out that most (if not all) computers utilize a Network Time Protocol daemon (NTP) to synchronize their clocks over a network since theyre generally not very good at keeping time themselves. The Pi makes use of this to ensure that, after being shutdown for an unknown amount of time, it displays the correct time. However, this means that at boot the Pi thinks its the wrong time.

    So, what exactly are we seeing when the iteration counter sticks at 5? We are seeing that the Pi starts running our script before it has updated its time. That 90 second gap is not a physical 90 second period but a 90 second difference between the time the Pi thought it was and the time the NTPD told the Pi it actually is. Its good to know that something with our streamer isnt broken, but how do we get ride of that apparent time skip? Well, we can use a python library called psutil to look for the NTPD process before starting the main part of our script that way we know that the time has already been updated. If you dont have psutil installed already, install it by entering

    sudo pip install psutilinto the terminal. First, lets import psutil at the beginning with our other imports:

    import psutil ## allows us to look at processes on the Pi

    Next were going to want to initialize two new parameters: counter to regulate how long we look for the NTPD process and found_ntpd. Do this before the while loop, where we initialized i and prev_input.

    ## set counter's initial value to 0 counter = 0 ## set found_ntpd's initial value to False found_ntpd = False

  • Now we need to add a new while loop. This loop will look for ntpd in the list of processes that psutil.process_iter() returns. If it doesnt find NTPD before the counter reaches 60 (60 seconds based on our sleep time), then found_ntpd will be set to True so that the next while loop will run. You want to insert the following code before the previous while loop:

    ## this while loop looks to see if NTPD has been executed yet while found_ntpd == False: ## use psutil to iterate through a list of current processes for proc in psutil.process_iter(): ## only execute if "ntpd" is found if proc.name() == "ntpd": streamer.log("msg","Found NTPD") ## stream alert that ntpd was found streamer.log("psutil_msg",proc.status()) ## stream process status of ntpd; "stream name", value found_ntpd=True ## change variable to True to exit this loop ## assume that ntpd has already run if not found in 60 seconds elif counter>=60: streamer.log"msg","Search for NTPD timeout") ## stream alert that 60 seconds passed before ntpd was found found_ntpd=True ## change variable to True to exit this loop else: counter = counter + 1 ## add to the counter to track time passed streamer.log("counter",counter) ## stream current counter value sleep(1) ## wait for 1 second

    And change the second while loop to

    while found_ntpd == True:

    import RPi.GPIO as GPIO ## library that lets you control the Pi's GPIO pins import os ## allows us to talk to the system like in the terminal from sys import exit ## allows us to use "exit" from time import sleep ## allows us to use "sleep" import psutil ## allows us to look at processes on the Pi ## allows us to use the Initial State streamer from ISStreamer.Streamer import Streamer

    Below is the complete new code.

  • ## designate bucket name and individual access_key## if the bucket name already exists in association with the access_key, ## then the data will append to that bucket ## if the bucket name does not already exist, then a new bucket will be created ## the access_key tells Initial State which account to send the data to streamer = Streamer(bucket_name=Shutdown", access_key="[Your Access Key Here]") GPIO.setwarnings(False) ## disables messages about GPIO pins already being in use GPIO.setmode(GPIO.BOARD) ## indicates which pin numbering configuration to use GPIO.setup(16, GPIO.IN) ## tells it that pin 16 (button) will be giving input GPIO.setup(7, GPIO.OUT) ## tells it that pin 7 (LED) will be outputting GPIO.output(7, GPIO.HIGH) ## sets pin 7 (LED) to "HIGH" or off ## set counter's initial value to 0 counter = 0 ## set found_ntpd's initial value to False found_ntpd = False ## set i's initial value to 0 i=0 ## set prev_input's initial value to 0 prev_input=0 ## this while loop looks to see if NTPD has been executed yet while found_ntpd == False: ## use psutil to iterate through a list of current processes for proc in psutil.process_iter(): ## only execute if "ntpd" is found if proc.name() == "ntpd": streamer.log("msg","Found NTPD") ## stream alert that ntpd was found streamer.log("psutil_msg",proc.status()) ## stream process status of ntpd; "stream name", value found_ntpd=True ## change variable to True to exit this loop ## assume that ntpd has already run if not found in 60 seconds elif counter>=60: streamer.log"msg","Search for NTPD timeout") ## stream alert that 60 seconds passed before ntpd was found found_ntpd=True ## change variable to True to exit this loop else: counter = counter + 1 ## add to the counter to track time passed #streamer.log("counter",counter) ## stream current counter value sleep(1) ## wait for 1 second

  • ## this while loop constantly looks for button input (presses) once NTPD has run or 60 seconds have passed while found_ntpd == True: streamer.log("msg","Ready for button input") ## stream message ## if no button press if (GPIO.input(16) == False and prev_input!=1): i=i+1 ## iteration count increases by 1 streamer.log("iteration",(i)) ## stream current iteration GPIO.output(7,True) ## switch on pin 7 (LED) sleep(0.5) ## wait for 0.5 second GPIO.output(7,False) ## switch off pin 7 (LED) sleep(1) ## wait for 1 second ## when button is pressed else: GPIO.output(7,GPIO.HIGH) ## turn pin 7 (LED) off ## script to be called os.system("sudo shutdown -h now") ## shuts down Pi streamer.log("msg","Script has been called") ## keeps script from executing the "if" section while button is unpressed ## after it has been pressed prev_input=1 streamer.close() ## send any messages left in the streamer exit() ## terminates this script

    If you reboot your Pi so that the script starts running again, you should see something like what I have below:

  • This time its the counter that shows the time-keeping hiccup. You can see that the NTPD process is found after about 58 seconds, and then the main portion of our script begins running. If you comment out streamer.log(counter, counter), the hiccup becomes invisible and our script only runs once NTP has updated the Pis clock.

    A shutdown button is pretty handy, but you could run a number of other useful scripts at boot (though the Pi cant handle too much!). An interesting application would be running our monitoring script in the background while you use the Pi and seeing how much processing power your project takes!

  • 9Building a Mobile GPS Streamer

    CHAPTER

  • A little while ago I showed you how to start a script on your Raspberry Pi from boot and then use a button to execute a command in the terminal. One of the cool applications of being able to do this is that now you just have to turn on your Raspberry Pi for something to happen no keyboard, mouse, ssh-ing or monitor required!

    I decided to apply this awesomeness to Adafruits Ultimate GPS Breakout Board so that I could take the GPS and the Pi anywhere I wanted.

    You will learn how to

    Make your Pi truly mobile with a battery pack and mobile hotspot

    Collect location, speed, time, and other information from the GPS board

    Stream the GPS data to Initial State to see location and speed over time

    Start collecting GPS data with the press of a button and safely shutdown your Pi with another button

    In this tutorial you will learn how to

    Completely Mobile GPS Streamer

  • I used a Canakit so a lot of this was included:

    Raspberry Pi B+ w/ Raspbian loaded SD card HDMI cable + HDMI Monitor + Bluetooth Keyboard/Mouse (unless you already know your

    Pis IP address and can SSH in) WiFi Adapter/Dongle 2 Breadboards 40-pin GPIO Ribbon Cable (can use 5 individual male-to-female jumper cables instead) 40-pin T-Shaped GPIO to Breadboard Interface Board (not necessary if using jumper

    cables) 14 Breadboard Tie Lines 2 Push Button Switches 2 LEDs (I used Red and Blue) 2 220 Ohm Resistors (to use with the LEDs; 180-2K Ohms is generally a safe range) 2 10K Ohm Resistors (to use with the buttons; 5K-100K Ohms is generally a safe range) Adafruits Ultimate GPS Breakout Board 1 USB to TTL Serial Cable 1 Breakout Pin Header with at least 9 pins (mine came with the GPS) 1 Portable Power Bank w/microUSB connector (5V/0.7-2Amps)

    On the breadboard with the GPIO interface board, you want to connect:

    One row of the first button to GPIO 23 (pin 16) and a 10K resistor; the other end of the resistor should be connected to ground

    The other row of the button to the voltage source (3.3 V) One row of the second button to GPIO 24 (pin 18) and a 10K

    resistor; the other end of the resistor should be connected to ground

    The other row of the button to the voltage source (3.3 V) The short leg of the blue LED to GPIO 4 (pin 7) The long leg of the blue LED to a 220 resistor; the other end of the

    resistor should be connected to the voltage source The short leg of the red LED to GPIO 17 (pin 11) The long leg of the red LED to a 220 resistor; the other end of the

    resistor should be connected to the voltage source

  • On the second breadboard, you want to:

    Now just plug the USB cable into the Pi and youre ready to start in on the terminal action! The first thing we need to do is make sure that the Pi recognizes your GPS through the USB port. It is a ttyUSB device, so entering

    Attach the GPS breakout board using the breakout pins Connect TX to the USB cables white line Connect RX to the USB cables green line Connect GND to the USB cables black line Connect VIN to the USB cables red line

  • should return a list of all of these devices. Your USB cable is probably the only one, so you should see /dev/ttyUSB0 as the output.

    ls /dev/ttyUSB*

    sudo lsusb

    will show you a list of all USB devices. Your cable will appear as Prolific Technology, Inc. PL2303 if you purchased the one I listed.

    Next we need to install some GPS software that will interpret the data coming from our GPS. To install the GPS Daemon, enter this into the terminal (make sure your Pi has internet):

    sudo apt-get install gpsd gpsd-clients python-gps

    sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock

    cgps -s

    After gpsd has installed, you can check to make sure that your GPS is working/has a fix by running

    to point gpsd to the USB port and then running

    to see some GPS data in a nice format.

    The first time I tried to see my GPS data, cgps kept timing out because I couldnt get a fix. If youre not sure if your problem is finding a fix or not, run

    gpsmon

    to see raw GPS data. If $GPRMC has a V following it, then you dont have a fix and need to move your GPS somewhere less obstructed from the sky. If $GPRMC has an A following it, then you do have a fix, but a different problem.

    You may need to kill and reset gpsd once you get a fix for cgps to work. You can do this by running

  • Once cgps is displaying good gps data, youre ready to do something fancy with gpsd in a script! Now, since our end goal is to have this all run when the Pi boots up, itd be best if we didnt have to run sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock to point to the USB port every time. We can fix this by editing /etc/default/gpsd. Some of these may be filled in already, but you want it to look like this:

    sudo apt-get install python-rpi.gpio

    sudo killall gpsdsudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock

    # Default settings for gpsd. # Please do not edit this file directly - use `dpkg-reconfigure gpsd' to # change the options. START_DAEMON="true" GPSD_OPTIONS="/dev/ttyUSB0" DEVICES="" USBAUTO="true" GPSD_SOCKET="/var/run/gpsd.sock"

    Save it with CTRL-X, and gpsd will automatically look at the USB port for your GPS on boot.

    We do need to install a couple more modules before were ready to write our script. The GPIO module lets us interface with the Pis GPIO pins so that we can control the LEDs and sense button inputs. Install it with

    I also wanted to know the actual location that my latitude and longitude corresponded to, so I used a geocoding library called Geopy. Install it with

    pip install geopy

  • First we need to import everything.

    import os ## allows us to talk to the system like in the terminal from gps import * ## import the gps module from time import * ## import time for sleeping import threading ## import threading from sys import exit ## allows us to use "exit" import RPi.GPIO as GPIO ## library that lets you control the Pi's GPIO pins from ISStreamer.Streamer import Streamer ## import the Initial State streamer from geopy.geocoders import Nominatim ## import the Geopy geocoderfrom geopy.exc import GeocoderTimedOut ## import GeocoderTimedOut so we can handle Geopy timeouts import sys, traceback ## import sys and traceback for exception handling

    Lastly, you want to install the Initial State streamer so that you can visualize your GPS data without needing to look directly into the Pi. Its super easy and takes less than 2 minutes. Instructions are explained earlier in this eBook.

  • There is some initialization too handling the geocoder, gps, GPIO pins and the streamer (which I called logger).

    geolocator=Nominatim() ## call the geocoder "geolocator" gpsd = gps(mode=WATCH_ENABLE) ## set gpsd to start gps info prev_input=0 ## set prev_input's initial value to 0 btn_pressed=False ## set btn_pressed's initial value to False ## designate bucket name and individual access_key## a new bucket will be created with every script run ## the access_key tells Initial State which account to send the data to ## specify .ini file location if you are using one that affects the streamer logger=Streamer(bucket_name=Pi GPS",access_key="[Your Access Key Here]", ini_file_location="/home/pi/isstreamer.ini") GPIO.setwarnings(False) ## disables messages about GPIO pins already being in use GPIO.setmode(GPIO.BOARD) ## indicates which pin numbering configuration to use GPIO.setup(16, GPIO.IN) ## tells it that pin 16 (button) will be giving input GPIO.setup(7, GPIO.OUT) ## tells it that pin 7 (LED) will be outputting GPIO.output(7, GPIO.HIGH) ## sets pin 7 (LED) to "HIGH" or off

    This function is to handle unhandled exceptions by turning off the LED and exiting the script. This way you can know if your GPS script has given up on you!

    ## this function will handle any exceptions we don't account for below## the LED will turn off to tell us that the script has exiteddef handleTheUnhandled(type, value, traceback): logger.log("msg","The Unhandled was handled") ## stream that an unexpected exception occured GPIO.output(7,GPIO.HIGH) ## turn off the LED exit() ## exit the script ## when an exception happens that we don't account for, call our scriptsys.excepthook = handleTheUnhandled

  • Now we use a thread to collect the gpsd information.

    ## this thread will look for and collect gpsd infoclass GpsPoller(threading.Thread): def __init__(self): threading.Thread.__init__(self) global gpsd ## bring gpsd in scope self.current_value = None self.running = True ## setting the thread running to true def run(self): global gpsd while gpsd.running: gpsd.next() sleep(10)

    We want to know when we are ready to start collecting information (since you cant watch the Pi boot up), so once the button is ready to be pressed our blue LED will start blinking and we will stream a message. Once the button is pressed, another message is streamed and the LED stops blinking but stays on. The gpsd information is collected, and, if you are watching the terminal, will output in a readable format. It will also stream to Initial State where you can see how it changes over time. It will gather and stream this information every second, but you can change sleep if you want.

    ## this while loop constantly looks for button inputwhile True: ## if no button press if (GPIO.input(16) == False and prev_input!=1): logger.log("Button 1","Looking for Input") ## stream that button is ready to press GPIO.output(7,True) ## switch on pin 7 (LED) sleep(0.5) ## wait for 0.5 second GPIO.output(7,False) ## switch off pin 7 (LED) sleep(1) ## wait for 1 second ## when button is pressed else: if btn_pressed==False: logger.log("Button 1","Pressed") ## stream that button has been pressed btn_pressed=True ## change btn_pressed so "Pressed" only streams once GPIO.output(7,GPIO.LOW) ## turn pin 7 (LED) on prev_input=1 ## keep the if statement from executing again ## start thread if __name__ == '__main__':

  • try: while True: gpsd.next() os.system('clear') ## clear the terminal window to display GPS data ## this is handy to see when making sure the script works print print ' GPS reading' print '----------------------------------------' print 'latitude ' , gpsd.fix.latitude print 'longitude ' , gpsd.fix.longitude print 'time utc ' , gpsd.utc,' + ', gpsd.fix.time print 'altitude (m)' , gpsd.fix.altitude print 'eps ' , gpsd.fix.eps print 'epx ' , gpsd.fix.epx print 'epv ' , gpsd.fix.epv print 'ept ' , gpsd.fix.ept print 'speed (m/s) ' , gpsd.fix.speed print 'climb ' , gpsd.fix.climb print 'track ' , gpsd.fix.track print 'mode ' , gpsd.fix.mode print print 'sats ' , gpsd.satellites ## stream whatever you'd like to collect from the gps logger.log("Latitude",gpsd.fix.latitude) logger.log("Longitude",gpsd.fix.longitude) logger.log("Reported Time",gpsd.utc,) logger.log("Altitude (m)",gpsd.fix.altitude) logger.log("Climb (m/s)",gpsd.fix.climb) logger.log("Lat Error",gpsd.fix.epy) logger.log("Long Error",gpsd.fix.epx) logger.log("Timestamp Error",gpsd.fix.ept) logger.log("Speed (m/s)",gpsd.fix.speed) logger.log("Speed Error",gpsd.fix.eps) ## the geolocator requires a string so we turn lat and long into one coord=str(gpsd.fix.latitude) + ", " + str(gpsd.fix.longitude) location=geolocator.reverse(coord,timeout=10) ## reverse geocode coordinates logger.log("Location",location.address) ## if the geocoder times out, stream a message and keep looping except GeocoderTimedOut as e: logger.log("msg","Geocoder Timeout") pass

  • ## if you press CTRL-C or the systeme exits, print a message and close everything except (KeyboardInterrupt, SystemExit): #when you press ctrl+c print "\nKilling Thread..." GPIO.output(7,GPIO.HIGH) ## turn LED off logger.close() ## send any messages left in the streamer gpsd.running = False gpsd.join() ## wait for the thread to finish what it's doing print "Done.\nExiting." exit() ## exit the script

    The except statements will let us stop the script while testing it and keep it running if the geocoder times out.

    There is one more script we need if we want to be able to safely shutdown the Pi without being able to execute the command in the terminal. I discussed this in more detail in my previous blog post, but I have slightly edited my original script for this use case. The main difference is the sub.Popen(sudo python /home/pi/navigation.py, shell=True) line. This runs the navigation script from the offbutton.py script. This was my solution to wanting to run two scripts at boot, but there are a couple of other ways to accomplish roughly the same thing.

    import RPi.GPIO as GPIO ## library that lets you control the Pi's GPIO pinsimport os ## allows us to talk to the system like in the terminalfrom sys import exit ## allows us to use "exit"from time import sleep ## allows us to use "sleep"import subprocess as sub ## allows us to call another script ## allows us to use the Initial State streamerfrom ISStreamer.Streamer import Streamer ## designate bucket name and individual client_key## a new bucket will be created with every script run## the client_key tells Initial State which account to send the data to## specify .ini file location if you are using one that affects the streamerlogger = Streamer(bucket_name="Shutdown", client_key="[Your Client Key Here]", ini_file_location="/home/pi/isstreamer.ini") ## create files for logging stdout and stderr#output_file = open("/home/pi/navdebug.out", "w")#error_file = open("/home/pi/navdebug.err","w") ## add "stdout=output_file,stderr=error_file" to pipe to filessub.Popen('sudo python /home/pi/navdebug.py', shell=True)

  • GPIO.setwarnings(False) ## disables messages about GPIO pins already being in useGPIO.setmode(GPIO.BOARD) ## indicates which pin numbering configuration to use GPIO.setup(18, GPIO.IN) ## tells it that pin 18 (button) will be giving inputGPIO.setup(11, GPIO.OUT) ## tells it that pin 11 (LED) will be outputtingGPIO.output(11, GPIO.HIGH) ## sets pin 11 (LED) to "HIGH" or off ## set prev_input's initial value to 0prev_input=0 ## this while loop constantly looks for button input (presses)while True: ## if no button press if (GPIO.input(18) == False and prev_input!=1): logger.log("Button 2","Looking for input") ## stream message GPIO.output(11,True) ## switch on pin 11 (LED) sleep(0.5) ## wait for 0.5 second GPIO.output(11,False) ## switch off pin 11 (LED) sleep(1) ## wait for 1 second ## when button is pressed else: logger.log("Button 2","Pressed") GPIO.output(11,GPIO.HIGH) ## turn pin 11 (LED) off ## script to be called os.system("sudo shutdown -h now") ## shuts down Pi logger.log("msg","Script has been called") ## keeps script from executing the "if" section while button is unpressed ## after it has been pressed prev_input=1 logger.close() ## send any messages left in the streamer exit() ## terminates this script

    I left the statements I used for debugging commented out in the script in case you might need them. All that they do is specify files to write the standard output and standard error of the navigation.py script to.

    So you have the scripts, but how do we get them to run automatically when the Pi boots up? There are a couple of ways that you can run a script at a certain time or when something specific happens. A very easy way to do this is with Cron, a tool that comes ready to use on Unix systems (like the Pi!). Cron allows you to specify minute, hour, day of month, month of year and day of week. A more advanced method that also allows you greater freedom to designate when your script is run is by creating an init (initialization) file.

  • Because I only needed my script to start at boot, I chose to use Cron. While init files do allow you greater control, they are much more complicated to write. If youd like to use an init file, you can see how to here.

    Getting to the file you need to edit is as easy as typingsudo crontab -e

    @reboot sudo python /home/pi/Streamer/offbutton.py

    in your terminal and hitting enter. You will see a file pop up with a lot of comments. At the bottom of this file youll want to add the line

    @reboot tells Cron to execute the line following it once the system has booted up. My file is named offbutton.py and it is located in my Streamer folder. Youll want to replace those with the name and location of your file. If its just in the main folder on the Pi, its location is /home/pi/. Whenever you dont want the script to run just comment out the line with # and save the file.

    Note: You do need to reboot the Pi before this new Crontab will take effect. Since our script also starts at boot, we had to do this anyways!

    Now that your scripts will run automatically when you boot the Pi, you have LED status indicators, and a portable power bank, we are almost ready to hit the ground running. The only thing that we havent taken care of yet is how to maintain an internet connection.

    Its surprisingly easy to get your Pi to automatically connect to a specific WiFi. In my case, I wanted it to connect to my iPhones hotspot (the ssid will obviously differ). You need to edit /etc/wpa_supplicant/wpa_supplicant.conf and make this the first network:

    network={ ssid="iPhone" psk="password" key_mgmt=WPA-PSK }

  • Save the file and go to /etc/network/interfaces. If you dont see auto wlan0, add it.

    Youre good to go! Just make sure that your phones personal hotspot is turned on and power on your Pi. I drove around with my Pi running and could see this in Initial States Waves:

    Pretty sweet, huh? A cool addition to this project would be a neat way to bundle all of the equipment into a case of some sort.

  • 10Building a Hamster Fitness Tracker

    CHAPTER

  • Have you ever wondered just how much your hamster runs throughout the day/night? How far? How fast? My 9 year old daughter did, and we decided to find out. Turns out, it was pretty easy, and the results were unbelievable.

    Here are the supplies you will need:

    An internet connected Raspberry Pi or your single-board computer of choice. A laser break beam sensor (such as this sensor from Adafruit https://

    www.adafruit.com/product/2122). A breadboard for wiring up a simple circuit (such as the one found in the

    Adafruit Pi starter kit). An LED (optional, also found in the Adafruit Pi starter kit). Two pull-up resistors (one 220 ohm resistor and one 10K ohm resistor, also

    in the Adafruit Pi starter kit). A hamster cage with a running wheel that is outside the main living area (to

    avoid ever shining a laser into your hamsters eyes). Here is an example cage.

    A hamster.

    Turn Your Raspberry Pi Into a Hamster Fitness Tracker

  • The measurement system is very simple. The laser break beam sensor will be aimed at a small target on the wheel that will only reflect the beam once per full rotation of the wheel. The Pi will detect each time the wheel turns a full rotation and calculate the distance traveled and speed (the distance traveled is simply the circumference of the wheel). The resulting measurements will be captured and streamed to a data visualization that you can look at when you wake up each morning (because your hamster is probably getting his workout on while you sleep at night).

    The laser break beam sensor from Adafruit is a good choice for this project because of its simplicity to wire up and use. No extra weight will be added to the wheel to make it harder to spin for your 2 oz. dwarf hamster. Both the laser transmitter and receiver are built into the same small plastic housing. If the laser beam reflects off of a target within 1 meter or so, the receiver detects and outputs the break.

    This is much better than a traditional laser break sensor that requires a separate receiver that must be aligned to the laser (like your garage door sensor that can easily get off track if you touch it). The laser break beam sensor will have three wires to attach. Attach the red wire to 5V. Attach the black wire to ground. The blue wire will be the sensor output. Connect this wire to a 10K ohm pull-up resistor and to an input pin on your Pi as shown below. *Warning* Do not shine the laser into the living area of your hamster!!! You could cause damage to your hamsters eyes. If your wheel is inside the cage, consider using a magnetic contact switch instead of a laser break beam sensor.

  • The LED will be used to visually indicate that the laser break sensor has detected a break. This is extremely useful when lining up the laser with the target and making sure that nothing unwanted is causing a light reflection into the sensor. Initially, I taped the laser break sensor to the wall, but enough light was reflecting off of the white wall to cause the sensor to always detect a break.

  • Having the LED helped me find the best place to mount the sensor. You can hook the input of the LED directly to the output of the sensor (make sure you have a pull-up or pull-down resistor on your LED). I hooked my LED up to an output pin on my Pi in case I wanted to use the LED for something else in the project. Turns out, having the LED blink each time a laser break is detected is more useful than I anticipated. The entire hardware setup is shown above.

    Create a target on the outside of the wheel for the laser. I used a small piece of masking tape. Align the laser to the target and make sure no other part of the wheel breaks the laser when it spins. Keep the laser out of any area that your hamsters eyes can enter!!

    For the software setup, first install the Initial State streamer to give your hamster fitness measurements a destination to go to (go here for instructions on setting up the Initial State streamer; it is super easy and takes less than two minutes). Create a new file on your Raspberry Pi (e.g. hamster_fitness.py) and copy+paste the code below into it. You will need to copy+paste the access key associated with your Initial State account in between the quotes on line 6 where it says PUT YOUR ACCESS KEY HERE. You can find your access key under your account settings or on the landing page once you log into your account. The code below is all of the code that you will need.

    import RPi.GPIO as GPIO import time import datetimeimport math from ISStreamer.Streamer import Streamer streamer = Streamer(bucket_name=Hamster Fitness Tracker", access_key="PUT YOUR ACCESS KEY HERE") streamer.log("ZooZoo Says","") # Setup Pins pinNumLaserBreak = 18 pinNumLED = 4 GPIO.setmode(GPIO.BCM) # numbering scheme that corresponds to breakout board and pin layout GPIO.setup(pinNumLaserBreak,GPIO.IN) GPIO.setup(pinNumLED,GPIO.OUT)

  • # Setup Constants diameter = 13 # inches circumference = diameter * math.pi * 0.0000157828283 # miles distanceTotal = 0 timeNoActivity = 5 # seconds speed = 0 lastTime = datetime.datetime.now() while True: input = GPIO.input(pinNumLaserBreak) if not input: if speed == 0: streamer.log("ZooZoo Says", "It's time to get pumped") # Calculate stuff thisTime = datetime.datetime.now() timeDiff = (thisTime-lastTime).total_seconds() speed = circumference/(timeDiff/3600) # miles per hour # Log stuff streamer.log("Full Rotation", "1") if speed < 5: # Filter out glitches (rocking on the sensor) distanceTotal += circumference streamer.log("Speed(mph)", speed) streamer.log("Total Distance(miles)", distanceTotal) GPIO.output(pinNumLED,GPIO.HIGH) # Turn LED on for visual cue that everthing is working lastTime = thisTime # Wait for sensor break to clear input = GPIO.input(pinNumLaserBreak) while not input: input = GPIO.input(pinNumLaserBreak) time.sleep(.05) else: if speed > 0: thisTime = datetime.datetime.now() timeDiff = (thisTime-lastTime).total_seconds() # Reset the speed to 0 if no activity (for log visualization) if timeDiff > timeNoActivity: speed = 0 # Log stuff streamer.log("ZooZoo Says", "I need a rest") streamer.log("Speed(mph)", speed) streamer.flush() GPIO.output(pinNumLED,GPIO.LOW) # Turn LED off for visual cue that everthing is working

  • Line 6 sets up the destination bucket for our data stream. We will name the bucket Hamster Fitness Tracker. Every time you run this script, a new bucket named Hamster Fitness Tracker will be created under your Initial State account (identified by your access key), and all data generated from that script run will be contained there. Line 7 streams the first message to the newly constructed stream.

    Lines 10-20 setup the constants that we will use. Set the pin numbers according to how you wired up your sensor input and LED output. Measure the diameter of the wheel and enter the diameter on line 17. The script above assumes the diameter is measured in inches and the speed will be calculated in miles/hour. Convert to your desired units accordingly.

    Line 25 checks the sensor output. If the sensor outputs a logic 0 (which means there was a laser break detected), the distance and speed measurements will be calculated and streamed. A simple attempt to filter out glitches (e.g. when the wheel stops right on the target and rocks) happens on line 37. If a speed greater than 5 is detected, this is assumed to be a glitch and is filtered out of the speed and distance traveled calculation. Line 42 turns on the LED to indicate a laser break is detected. If the wheel stops right on the target, all calculations are paused until the break is cleared (lines 46-49).Lines 51-61 detect if there is no activity on the wheel for x number of seconds (x specified on Line 20). If there is no activity, the speed is cleared to 0 and message is output, I need a rest. After a rest has been detected, the first full rotation of the wheel will stream another message, Its time to get pumped, on line 28.

    We are ready to test our setup. Run the script at the command line of your Pi (type sudo python hamster_fitness.py). Spin your wheel and make sure the LED blinks only when the laser hits the target on the wheel. After a few spins, log into your Initial State account and a new log will pop up in your log shelf called Hamster Fitness Tracker. View this in Waves or Lines to see your hamsters activity. When you are ready to let this script run for a long time, you might want to use the nohup command (no hangup), especially if you are sshing into your Pi (e.g. nohup sudo python hamster_fitness.py > tmp.txt &).

  • We measured the activity of my daughters hamster, ZooZoo, for the last four days. You can see a screenshot of all her captured activity over this time in Waves above. At a quick glance, you can see the big gaps in speed (and flat line of total distance) that correlate to the daylight hours when she sleeps. Ar