Created
January 6, 2015 04:09
-
-
Save kobaltz/442a2413f6db08a17cbe to your computer and use it in GitHub Desktop.
Raspberry Pi Model B+ - GPIO18 Servo Control with PWM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/ruby | |
# Servo Rotation | |
# Wiring: | |
# From +5V (PIN2) to Positive on Servo (Red) | |
# From Ground (PIN6) to Ground on Servo (Brown) | |
# From GPIO18 to 1kOhm Resistor to Signal on Servo (Orange) | |
# Requires Ruby (`sudo apt-get install ruby ruby1.9.1-dev`) | |
# Requires WiringPi (You may need to `sudo gem install wiringpi` first) | |
require 'wiringpi' | |
# Set variable io to interact with GPIO using the GPIO Pin Layout | |
# The Raspberry Pi B+ model has only one hardware implementation of | |
# PWM which means that you will need to use GPIO18 (Pin 1). | |
io = WiringPi::GPIO.new(WPI_MODE_GPIO) | |
pin = 18 | |
io.mode pin, PWM_OUTPUT | |
# We will use an instance variable to keep track of the last position. | |
# This will be helpful so that when making small iterations from the | |
# previous servo position, we will not bump the ends. | |
@last_position = 0 | |
# Pulser method will take the frequency and duration (20ms) | |
# This method will put HIGH load for freq miliseconds and pause for | |
# freq minus duration (20ms) for a total of 20ms execution time. | |
# For my crappy servo, I have the following rates which yours may differ: | |
# 0 Degrees - 0.5ms HIGH / 19.5ms LOW | |
# 90 Degrees - 1.5ms HIGH / 18.5ms LOW | |
# 180 Degrees - 2.5ms HIGH / 17.5ms LOW | |
def pulser(io,pin,freq,dur) | |
io.pwmWrite pin, 900 | |
sleep (freq/1000) | |
io.pwmWrite pin, 0 | |
sleep ((dur-freq)/1000) | |
end | |
# Main method to call for rotating the servo. Using the io and pin | |
# that was declared at the beginning of this script. | |
# iter - Calculates the difference in the last position to determine | |
# how many times to pulse the servo. A full range of motion | |
# from 0 to 180 degrees does a good job in about 25 loops | |
# degrees - Converts the degrees into miliseconds for pulsing | |
def servo_rotate(io,pin,deg,override = false) | |
iter = (((deg - @last_position).abs.to_f / 180) * 24).to_i + 1 | |
iter = 25 if override | |
iter.times do | |
degrees = 0.5 + ((deg.to_f/180)*2) | |
pulser(io,pin,degrees,20.0) | |
end | |
@last_position = deg | |
end | |
# Set the servo back to 0 degrees. Notice the override is being passed | |
# as true which will override the iter variable in the server_rotate | |
# method. | |
puts "Resetting servo to 0 degrees..." | |
servo_rotate(io,pin,0,true) | |
# Continuous loop to prompt for degrees input | |
loop do | |
puts "Enter Degrees (0..180)" | |
degrees = gets.chomp.downcase | |
case degrees.to_i | |
when (0..180) | |
servo_rotate(io,pin,degrees.to_i) | |
else | |
puts "Please enter a value between 0 and 180" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment