Today I successfully connected the DS18B20 temperature sensor to the RPi. I ordered the waterproof version that comes with ~ 2 ft leads.
I used the following Adafruit lesson to the letter and it worked great:
http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/overview
Wednesday, January 8, 2014
Monday, December 30, 2013
RPi - Controlling a Servo Motor
Today I set up the Raspberry Pi to control a servo motor.
For the hardware setup, I referred to chapter 10 from the Raspberry Pi Cookbook. Aside from the Pi, I only used the Pi Cobbler, a 1k resistor, and a 4AA battery pack. I didn't use any other special components. In the future, I'll consider getting a specialized breakout board for controlling servos.
For the software, I started with the code from this blog post: http://www.doctormonk.com/2012/07/raspberry-pi-gpio-driving-servo.html
Note that in Simon Monk's post, he uses a transistor in his circuit that I didn't use based on the circuit in the book.
My first attempt didn't work well. The servo would turn very slowly, arriving at the 180 degree position, and stay there. I could feel the motor working but there was little to no movement.
After further research, I made some modifications to the starting code including changing the order of the True and False statements and playing with the timing. Things started to work. I was reading that servos needed between a .001 and .002 second pulse to move between 0 and 180 degrees respectively. I was finding those to be too long. For my servo, the range was between .00055 and .002. I don't know if that is a servo thing or if that helps to compensate for a delay from the RPi itself.
Finally, I added some code to accept an angle 0-180 as input and convert that angle into the appropriate timing of the pulses. I also had that input affect the number of loops because for shorter angle changes, a greater number of loop iterations would result in the motor jumping around slightly after reaching the desired angle. Now I can probably convert this to a function and use with other programs.
I had been reading about others experiencing a jittery movement when only using GPIO to control the servo but once I figured out the appropriate timing and loops, I found that it moved very smoothly. I don't know if there are other factors that I'm not experiencing that could affect the performance.
The Code:
import RPi.GPIO as GPIO
import time
import math
pin = 18
refresh_period = 0.02
prev_angle = 90 #initiate previous angle
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, False)
while True:
angle = int(input('Angle: '))
# convert degrees (0-180) to the servo pulse (.00055 to .002ms)
pulse = (angle * .00000805555) + .00055
# determine the number of loops based on degrees needed to travel, a shorter distance (degrees) to travel = fewer loops
loops = math.ceil(math.fabs(prev_angle - angle) * .135) + 2
prev_angle = angle
# move the servo arm
for i in range(1, loops):
time.sleep(refresh_period)
GPIO.output(pin, True)
time.sleep(pulse)
GPIO.output(pin, False)
For the hardware setup, I referred to chapter 10 from the Raspberry Pi Cookbook. Aside from the Pi, I only used the Pi Cobbler, a 1k resistor, and a 4AA battery pack. I didn't use any other special components. In the future, I'll consider getting a specialized breakout board for controlling servos.
For the software, I started with the code from this blog post: http://www.doctormonk.com/2012/07/raspberry-pi-gpio-driving-servo.html
Note that in Simon Monk's post, he uses a transistor in his circuit that I didn't use based on the circuit in the book.
My first attempt didn't work well. The servo would turn very slowly, arriving at the 180 degree position, and stay there. I could feel the motor working but there was little to no movement.
After further research, I made some modifications to the starting code including changing the order of the True and False statements and playing with the timing. Things started to work. I was reading that servos needed between a .001 and .002 second pulse to move between 0 and 180 degrees respectively. I was finding those to be too long. For my servo, the range was between .00055 and .002. I don't know if that is a servo thing or if that helps to compensate for a delay from the RPi itself.
Finally, I added some code to accept an angle 0-180 as input and convert that angle into the appropriate timing of the pulses. I also had that input affect the number of loops because for shorter angle changes, a greater number of loop iterations would result in the motor jumping around slightly after reaching the desired angle. Now I can probably convert this to a function and use with other programs.
I had been reading about others experiencing a jittery movement when only using GPIO to control the servo but once I figured out the appropriate timing and loops, I found that it moved very smoothly. I don't know if there are other factors that I'm not experiencing that could affect the performance.
The Code:
import RPi.GPIO as GPIO
import time
import math
pin = 18
refresh_period = 0.02
prev_angle = 90 #initiate previous angle
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, False)
while True:
angle = int(input('Angle: '))
# convert degrees (0-180) to the servo pulse (.00055 to .002ms)
pulse = (angle * .00000805555) + .00055
# determine the number of loops based on degrees needed to travel, a shorter distance (degrees) to travel = fewer loops
loops = math.ceil(math.fabs(prev_angle - angle) * .135) + 2
prev_angle = angle
# move the servo arm
for i in range(1, loops):
time.sleep(refresh_period)
GPIO.output(pin, True)
time.sleep(pulse)
GPIO.output(pin, False)
The circuit:
The servo I used:
The servo specs:
Years ago, I created a very simple robotic arm that waves and was able to revive it once again with the RPi!
Labels:
circuit,
cobbler,
GPIO,
python,
raspberry pi,
servo motor
Saturday, December 28, 2013
FitBit Data to Google Spreasheet
I received a FitBit for Christmas and while the website provides access to a lot of data a graphs, I wanted a way to access the data in a format to process with R (statistics).
I found the following blog post which points to the use of a Google script that accesses the data via the developer API and populates a Google spreadsheet.
http://citizen-statistician.org/2012/09/30/getting-data-from-fitbit/
It was pretty straight forward since I've worked a bit with Google scripts before.
It provides daily summary data across a dozen or so categories. What would be nice is more granular data.
I found the following blog post which points to the use of a Google script that accesses the data via the developer API and populates a Google spreadsheet.
http://citizen-statistician.org/2012/09/30/getting-data-from-fitbit/
It was pretty straight forward since I've worked a bit with Google scripts before.
It provides daily summary data across a dozen or so categories. What would be nice is more granular data.
Freezing Temp Alert
I created an alert on my phone to tell me when the temperature outside drops below freezing. Since I don't have my own network accessible thermometer, I am using the wunderground api to query the closest weather station, a couple of miles away. It should be close enough.
I used this blog post as a guide for accessing the wunderground api: http://www.pocketables.com/2012/07/tasker-task-that-speaks-the-weather-forecast-download.html
I set up a wunderground developer account here: http://www.wunderground.com/weather/api/
In Tasker:
The profile runs every hour.
The task is as follows:
A1: HTTP Get [ Server:Port:api.wunderground.com Path:/api/[mykey]/conditions/q/[my state abbrev]/[the town or neigborhood with the station I wanted to query].xml Attributes: Cookies: Timeout:10 Mime Type:text/plain Output File: ]
A2: Variable Set [ Name:%wunderresults To:%HTTPD Do Maths:Off Append:Off ]
A3: Variable Search Replace [ Variable:%wunderresults Search:\<temp\_f\>\d\d.\d\<\/temp\_f\> Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%matchedtemp Replace Matches:Off Replace With:a ]
A4: Variable Search Replace [ Variable:%matchedtemp1 Search:\d\d.\d Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%matchedtemptwo Replace Matches:Off Replace With: ]
A5: Variable Set [ Name:%oakbrookTemp To:%matchedtemptwo1 Do Maths:Off Append:Off ]
A6: Flash [ Text:%myTemp Long:Off ]
A7: If [ %myTemp < 33 ]
A8: Notify [ Title:Temperature Warning Text:%myTemp Icon:hd_alerts_and_states_warning Number:0 Permanent:Off Priority:3 ]
I had to do some parsing gymnastics to get the temperature out of the xml returned from wunderground (actions 3 and 4).
I also have the temp display on a MimialistText widget so I can see the temp anytime, not just when it's freezing.
I used this blog post as a guide for accessing the wunderground api: http://www.pocketables.com/2012/07/tasker-task-that-speaks-the-weather-forecast-download.html
I set up a wunderground developer account here: http://www.wunderground.com/weather/api/
In Tasker:
The profile runs every hour.
The task is as follows:
A1: HTTP Get [ Server:Port:api.wunderground.com Path:/api/[mykey]/conditions/q/[my state abbrev]/[the town or neigborhood with the station I wanted to query].xml Attributes: Cookies: Timeout:10 Mime Type:text/plain Output File: ]
A2: Variable Set [ Name:%wunderresults To:%HTTPD Do Maths:Off Append:Off ]
A3: Variable Search Replace [ Variable:%wunderresults Search:\<temp\_f\>\d\d.\d\<\/temp\_f\> Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%matchedtemp Replace Matches:Off Replace With:a ]
A4: Variable Search Replace [ Variable:%matchedtemp1 Search:\d\d.\d Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%matchedtemptwo Replace Matches:Off Replace With: ]
A5: Variable Set [ Name:%oakbrookTemp To:%matchedtemptwo1 Do Maths:Off Append:Off ]
A6: Flash [ Text:%myTemp Long:Off ]
A7: If [ %myTemp < 33 ]
A8: Notify [ Title:Temperature Warning Text:%myTemp Icon:hd_alerts_and_states_warning Number:0 Permanent:Off Priority:3 ]
I had to do some parsing gymnastics to get the temperature out of the xml returned from wunderground (actions 3 and 4).
I also have the temp display on a MimialistText widget so I can see the temp anytime, not just when it's freezing.
RPi - Python and Blinking LED
I successfully created a python script to blink an LED attached to the RPi/Pi Cobbler.
The circuit attaches to the 3.3V output, routes through the LED, a 470R, and back to GPIO pin 18.
I wrote it using IDLE on the RPi GUI.
I used this blog post as my guide: http://www.thirdeyevis.com/pi-page-2.php
I also referred to this one and even started to set up the WebIDE: http://www.akeric.com/blog/?tag=pi-cobbler
The code:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
def Blink(numTimes,speed):
for i in range(0,numTimes):
print "Iteration " + str(i+1)
GPIO.output(18,True)
time.sleep(speed)
GPIO.output(18,False)
time.sleep(speed)
print "Done"
GPIO.cleanup()
iterations = raw_input("Enter total number of times to blink: ")
speed = raw_input("Enter length of each blink(seconds): ")
Blink(int(iterations),float(speed))
The circuit attaches to the 3.3V output, routes through the LED, a 470R, and back to GPIO pin 18.
I wrote it using IDLE on the RPi GUI.
I used this blog post as my guide: http://www.thirdeyevis.com/pi-page-2.php
I also referred to this one and even started to set up the WebIDE: http://www.akeric.com/blog/?tag=pi-cobbler
The code:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
def Blink(numTimes,speed):
for i in range(0,numTimes):
print "Iteration " + str(i+1)
GPIO.output(18,True)
time.sleep(speed)
GPIO.output(18,False)
time.sleep(speed)
print "Done"
GPIO.cleanup()
iterations = raw_input("Enter total number of times to blink: ")
speed = raw_input("Enter length of each blink(seconds): ")
Blink(int(iterations),float(speed))
Tuesday, December 24, 2013
Simple LED Circuit
My Pi Cobbler arrived the other day and finally got around to playing. Created a simple LED circuit using the 3.3 V and ground pins on the cobbler. No Pi functionality was used other than as a source of power.
I used this blog post as a guide.
https://projects.drogon.net/raspberry-pi/gpio-examples/tux-crossing/gpio-examples-1-a-single-led/
Next, I'll control the LED via gpio on the pi.
Circuit:
I used this blog post as a guide.
https://projects.drogon.net/raspberry-pi/gpio-examples/tux-crossing/gpio-examples-1-a-single-led/
Next, I'll control the LED via gpio on the pi.
Circuit:
Google Location Data
Using this blog post as my guide, I downloaded the location data that Google stores about me and plotted it via R: http://seasci.wordpress.com/2013/12/20/it-knows-where-i-live/
The json file downloaded from Google Takeout was 123 MBs, over 780k location records. It takes several minutes for the script to parse all those records.
The blog author is from UK so I needed to adjust map parameters to my relevant locations.
This script uses get_map() a lot. Here's the documentation for get_map(): http://www.inside-r.org/packages/cran/ggmap/docs/get_map
I also tried to convert the json file to a csv prior to importing into R using this py script: https://github.com/Scarygami/location-history-json-converter/blob/master/location_history_json_converter.py
I modified the csv output format a bit to include accuracy data and to add a comma between lat and lon. I think because there were some records without accuracy, I was getting errors so applied a Catch KeyError function to the accuracy line. This helped me: http://stackoverflow.com/questions/16154032/catch-keyerror-in-python
Next I need to modify my R script to read in csv instead of json.
I also tried to convert the json file to a csv prior to importing into R using this py script: https://github.com/Scarygami/location-history-json-converter/blob/master/location_history_json_converter.py
I modified the csv output format a bit to include accuracy data and to add a comma between lat and lon. I think because there were some records without accuracy, I was getting errors so applied a Catch KeyError function to the accuracy line. This helped me: http://stackoverflow.com/questions/16154032/catch-keyerror-in-python
Next I need to modify my R script to read in csv instead of json.
Subscribe to:
Posts (Atom)