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 hamster’s eyes). Here is an example cage.
- A hamster.
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 hamster’s 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 hamster’s 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 datetime import 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 everything 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, “It’s 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 hamster’s 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 ssh’ing into your Pi (e.g. “nohup sudo python hamster_fitness.py > tmp.txt &”).
We measured the activity of my daughter’s 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. Around 10 pm every night, she gets busy. After four days, she ran 12 miles!! If we zoom into one of her many runs, it looks like the following:
This is a 10 minute view of her activity. It is interesting to see the little mini-breaks that she takes but overall maintains a speed of about 1.15 mph, spiking up to 3.25 mph. We were surprised to see that such a little creature would willingly run so far, so fast every night. We had to do a little Google research to sanity check our results. Turns out, hamsters do indeed run 1-5 miles per night, averaging 0.8 to 1.5 mph with spikes up to 5 mph in speed. In the wild, hamsters are always moving around and burrowing to find food. In a cage with plenty of food, they have to maintain a significant amount of movement to remain healthy. A hamster that is sedentary will become paralyzed, making that hamster wheel a pretty important part of your hamster’s environment.
Another interesting observation was the fact that she ran 5 miles the night after we cleaned her cage and gave her a different type of food. The night before, she ran 1.5 miles. More surprising than any specific observation from this project is the fact that we were so fascinated by the capture of a hamster’s fitness schedule. Capture your hamster’s activity and tell us what you find. We want to compare notes :-).