Raspberry Pi – Servo’s aansturen (SGXX) via GPIO
Hardware
Deze mini servo’s kunnen 180 graden draaien (als je de beveiliging eruit haalt 360 graden), de servo wordt veelal gebruikt in vliegtuig modelbouw, andere toepassingen zijn uiteraard ook mogeli
Specificaties:
- Modulatie: Analoog
- Krachtkoppel: 1.80 kg-cm (op 4.8 volt)
- Snelheid: 0.10 sec/60° (op 4.8 volt)
- Motor Type: 3-polig
- Tandwiel Type: Plastic
- Maximale draairichting: 180°
- Pulse breedte: 500-2400 µs
Pinout
Draadkleur: | Functie: |
---|---|
Rood | +5v |
Bruin | GND |
Oranje | Data (stuur signaal) |
Hoe werkt het?
Deze mini servo werkt met PWM (Pulse Width Modulation), volgens de documentatie:
– ca. 2.5 ms puls voor positie naar rechts.
– 1.5 ms puls voor het midden.
– ca. 0.5 ms puls voor positie naar links.
Als je PWM gebruikt, kun je deze op 50 Hz zetten, dan heb je pulsjes van 1 sec / 50 Hz = 20 ms
Veelal is de duty-cycle in te stellen van 0% t/m 100%, dat geeft voor:
– rechts (2.5 ms) > duty-cycle = 100 / (20ms / 2.5 ms) = 12.5%
– midden (1.5 ms) > duty-cycle = 100 / (20ms / 1.5 ms) = 7.5%
– links (0.5 ms) > duty-cycle = 100 / (20ms / 0.5 ms) = 2.5%
Let op: De waarden hierboven zijn theoretisch, voor mij werken deze waarden:
– rechts = duty-cycle van 11%
– midden = duty-cycle van 6%
– links = duty-cycle van 2.5%
Wat heb je nodig?
1) Python RPi.GPIO bibliotheek (standaard geinstalleerd op de wheezy image)
Aansluiten op de Raspberry Pi
Sluit de SG-90 servo aan zoals aangegeven op onderstaand schema:
Raspberry Pi pin: | Draadkleur SG-90: |
---|---|
Pin 1 (+ 3.3V) | Rood |
Pin 6 (GND) | Bruin |
Pin 7 | Oranje |
Script
Onderstaand script laat de servo tussen de 3 standen draaien 0, 90, 0, -90, etc.
Maak een bestand aan, bijvoorbeeld /usr/src/servo.py (evt onder root, en vergeet niet chmod te gebruiken om het bestand uit te kunnen voeren), voeg deze inhoud daar in toe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#!/bin/python # importeer de GPIO bibliotheek. import RPi.GPIO as GPIO # Importeer de time biblotheek voor tijdfuncties. from time import sleep # Zet de pinmode op Broadcom SOC. GPIO.setmode(GPIO.BCM) # Zet waarschuwingen uit. GPIO.setwarnings(False) # Zet de GPIO pin als uitgang. GPIO.setup(4, GPIO.OUT) # Configureer de pin voor PWM met een frequentie van 50Hz. p = GPIO.PWM(4, 50) # Start PWM op de GPIO pin met een duty-cycle van 6% p.start(6) try: while True: # 0 graden (neutraal) p.ChangeDutyCycle(6) sleep(1) # -90 graden (rechts) p.ChangeDutyCycle(2.5) sleep(1) # 0 graden (neutraal) p.ChangeDutyCycle(6) sleep(1) # 90 graden (links) p.ChangeDutyCycle(11) sleep(1) except KeyboardInterrupt: # Stop PWM op GPIO. p.stop() # GPIO netjes afsluiten GPIO.cleanup() |
Start het script met: sudo python /usr/src/servo.py , druk op CTRL+C om het script te stoppen!
Bron: pickupapi.com
Commandolijn gebruiken
Het volgende stuk laat zien hoe je een hoek van 0-180 graden kan instellen via een commandolijn parameter: sudo python draai.py [hoek]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#!/usr/bin/env python from __future__ import division # importeer de GPIO bibliotheek. import RPi.GPIO as GPIO # Importeer de time biblotheek voor tijdfuncties. import time import sys # Zet de pinmode op Broadcom SOC. GPIO.setmode(GPIO.BCM) # Zet waarschuwingen uit. GPIO.setwarnings(False) GPIO.setup(4, GPIO.OUT) # Zet de GPIO pin als uitgang. servopin = GPIO.PWM(4, 50) # Configureer de pin voor PWM met een frequentie van 50Hz. servopin.start(6) # Start PWM op de GPIO pin met een duty-cycle van 6% if len(sys.argv) > 1: waarde = int(sys.argv[1]) # Een MAP functie om eenvoudig verhoudingen tussen getallen te creeren. def arduino_map(x, in_min, in_max, out_min, out_max): return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min # Gebruik de MAP functie om eenvoudig verhoudingen tussen getallen te creeren. # De waarden met 10 vermenigvuldigen voor betere precisie. pwmwaarde = arduino_map(waarde, 0, 180, (2.5 * 10), (11.5 * 10)) # Print de gegevens naar de console. print "Hoek:", waarde, "| PWM:", pwmwaarde / 10 servopin.ChangeDutyCycle(pwmwaarde / 10) time.sleep(.5) |
Het kleine nadeel van dit script is dat wanneer het script eindigdt de servo “los” gelaten word, en je deze dus weer kan draaien met bijvoorbeeld de hand.
Commandolijn met achtergrond script (daemon)
Het volgende script is een “control” script, deze stuurt een ander python script aan die op de achtergrond actief blijft om de PWM op de pin te blijven aansturen!
Commando: sudo python paintc.py [hoek]
Je hebt dus 2 bestanden in de home folder:
– scriptc.py (control script)
– scriptd.py (daemon script)
1 2 3 4 5 6 7 8 9 10 11 12 |
#!/usr/bin/env python import sys import os if len(sys.argv) > 0: servoxhoek = sys.argv[1] # Eindig een python script met: pkill -f xxx.py # Eindig de achtergrond proces eerst. os.system("sudo pkill -f scriptd.py") # Start een nieuwe achtergrond process om de PWM op de pin te blijven houden. os.system("sudo python /home/pi/scriptd.py " + servoxhoek + " &") |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#!/usr/bin/env python from __future__ import division # importeer de GPIO bibliotheek. import RPi.GPIO as GPIO # Importeer de time biblotheek voor tijdfuncties. import time import sys # Zet de pinmode op Broadcom SOC. GPIO.setmode(GPIO.BCM) # Zet waarschuwingen uit. GPIO.setwarnings(False) GPIO.setup(4, GPIO.OUT) # Zet de GPIO pin als uitgang. servoxpin = GPIO.PWM(4, 50) # Configureer de pin voor PWM met een frequentie van 50Hz. servoxpin.start(6) # Start PWM op de GPIO pin met een duty-cycle van 6% if len(sys.argv) > 0: servoxhoek = int(sys.argv[1]) # Een MAP functie om eenvoudig verhoudingen tussen getallen te creeren. def arduino_map(x, in_min, in_max, out_min, out_max): return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min # Gebruik de MAP functie om eenvoudig verhoudingen tussen getallen te creeren. # De waarden met 10 vermenigvuldigen voor betere precisie. servoxpwm = arduino_map(servoxhoek, 0, 180, (2.5 * 10), (11.5 * 10)) # DEBUG - Print de gegevens naar de console. # print "X-Hoek:", servoxhoek, "| PWM:", servoxpwm / 10 while True: servoxpin.ChangeDutyCycle(servoxpwm / 10) time.sleep(.5) |
Meer info over: GPIO PWM