Skip to content

Instantly share code, notes, and snippets.

@kobaltz
Created January 6, 2015 04:09
Show Gist options
  • Save kobaltz/442a2413f6db08a17cbe to your computer and use it in GitHub Desktop.
Save kobaltz/442a2413f6db08a17cbe to your computer and use it in GitHub Desktop.
Raspberry Pi Model B+ - GPIO18 Servo Control with PWM
#! /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