My aim is to be able to control a servo motor with my keyboard in a real time fashion using the python module of pigpio. That is, when I press say the 'w' key it rotates clockwise and when I press the 's' key anticlockwise. I'm using an RPi 2, a tower Pro Micro servo SG90 and have connected it to the PWM enabled pin 13 (BCM denotation). My servo has not been modified for continuous rotation. My requests are:

  • A python code using pigpio to achieve this (or guidelines to do the same)
  • Is it possible for me to change the speed with which the servo rotates? As far as I understand it can be done using a for loop. If possible please allow that in the code

To use the keyboard I've tried reading this but am not able to decipher it. I've also tried going through the pigpio documentation and have managed to move the servo to a specific orientation.

1 Answer 1


I'm not sure if anyone will write the code for you. It's too broad a question.

You need to acquire a basic understanding of Python programming first, otherwise you'll be forever asking questions.

Personally I'd use the Python curses module (import curses) to handle keyboard entry. There are example of using curses within pigpio at http://abyz.me.uk/rpi/pigpio/code/gpio_status_py.zip and http://abyz.me.uk/rpi/pigpio/code/PCF8591.zip.

On the servo speed. Generally the speed of continuous rotation servos is controlled by the pulse width. 1500µs is the dead band and means stop (perhaps controlled by a trimming screw in the servo housing). As you increase the pulse width to 2000µs the servo goes faster and faster in one direction. As you decrease the pulse width to 1000µs the servo goes faster and faster in the other direction.

1000µs     1250µs     1500µs     1750µs     2000µs
fastest    fast       stop       fast       fastest
anti-      anti-                 clockwise  clockwise
clockwise  clockwise

Edited to add example code

#!/usr/bin/env python

# servo_key.py
# 2015-04-10
# Public Domain

import time
import curses
import atexit

import pigpio 


MIN_PW = 1000
MID_PW = 1500
MAX_PW = 2000

NONE        = 0
UP_ARROW    = 3
HOME        = 5
QUIT        = 6

def getch():
   global in_escape, in_cursor
   c = stdscr.getch()

   key = NONE

   if c == 27:
      in_escape = True
      in_cursor = False
   elif c == 91 and in_escape:
      in_cursor = True
   elif c == 68 and in_cursor:
      key = LEFT_ARROW
      in_escape = False
   elif c == 67 and in_cursor:
      key = RIGHT_ARROW
      in_escape = False
   elif c == 65 and in_cursor:
      key = UP_ARROW
      in_escape = False
   elif c == 66 and in_cursor:
      key = DOWN_ARROW
      in_escape = False
   elif c == 72 and in_cursor:
      key = HOME
      in_escape = False
   elif c == 113 or c == 81:
      key = QUIT
      in_escape = False
      in_cursor = False

   return key

def cleanup():

pi = pigpio.pi()

stdscr = curses.initscr()

atexit.register(cleanup) # Ensure original screen state is restored.

in_escape = False
in_cursor = False

pulsewidth = MID_PW

pi.set_servo_pulsewidth(SERVO, pulsewidth)

while True:


   c = getch()

   if c == QUIT:

   pw = pulsewidth

   if c == HOME:
      pw = MID_PW # Stop.
   elif c == UP_ARROW:
      pw = MAX_PW # Fastest clockwise.
   elif c == DOWN_ARROW:
      pw = MIN_PW # Fastest anti-clockwise
   elif c == LEFT_ARROW:
      pw = pw - 5 # Shorten pulse.
      if pw < MIN_PW:
         pw = MIN_PW
   elif c == RIGHT_ARROW:
      pw = pw + 5 # Lengthen pulse.
      if pw > MAX_PW:
         pw = MAX_PW

   if pw != pulsewidth:
      pulsewidth = pw
      pi.set_servo_pulsewidth(SERVO, pulsewidth)
  • Isn't the curses module more for enabling screen manipulation? Is there a simpler module which I can use to achieve the same? Apr 10, 2015 at 13:04
  • @VishaalDevanaboyina As you say it's probably used more for screen displays. Let me have a look at some alternatives and I'll get back to you.
    – joan
    Apr 10, 2015 at 13:16
  • Ok, please do tell if anything crops up. By the way, excellent work on pigpio! Apr 10, 2015 at 13:54
  • 1
    I still think curses is the better choice. I misread your original question and thought you did have a continuous rotation servo. I have edited my post to add code assuming a continuous rotation servo. Have a look and see if you can adapt it to your needs.
    – joan
    Apr 10, 2015 at 14:32
  • Curses is a terminal library, which includes output (the screen) and input. This is a pretty standard use for it.
    – goldilocks
    Apr 10, 2015 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.