Inhoudsopgave:

Pan-Tilt Multi Servo Control - Ajarnpa
Pan-Tilt Multi Servo Control - Ajarnpa

Video: Pan-Tilt Multi Servo Control - Ajarnpa

Video: Pan-Tilt Multi Servo Control - Ajarnpa
Video: Raspberry Pi Pan-Tilt Servo Control test 2024, November
Anonim
Pan-tilt multi-servobesturing
Pan-tilt multi-servobesturing

In deze tutorial zullen we onderzoeken hoe je meerdere servo's kunt besturen met Python op een Raspberry Pi. Ons doel zal een PAN/TILT-mechanisme zijn om een camera (een PiCam) te positioneren.

Hier kunt u zien hoe ons eindproject zal werken:

Control Servo Regelkringtest:

Afbeelding
Afbeelding

Stap 1: Stuklijst - Stuklijst

Hoofd onderdelen:

  1. Raspberry Pi V3 - US$ 32,00
  2. 5 Megapixels 1080p Sensor OV5647 Mini Camera Videomodule - US$ 13,00
  3. TowerPro SG90 9G 180 graden Micro Servo (2 X) - US $ 4.00
  4. Mini Pan/Tilt Camera Platform Anti-vibratie Camera Mount met 2 Servo's (*) - US$ 8.00
  5. Weerstand 1K ohm (2X) - Optioneel
  6. Diversen: metalen onderdelen, banden, enz (voor het geval u uw Pan/Tilt-mechanisme gaat bouwen)

(*) je kunt een compleet Pan/Tilt-platform kopen met de servo's of je eigen platform bouwen.

Stap 2: Hoe PWM werkt

De Raspberry Pi heeft geen analoge uitgang, maar we kunnen dit simuleren met behulp van een PWM-benadering (Pulse Width Modulation). Wat we zullen doen, is een digitaal signaal genereren met een vaste frequentie, waarbij we de pulstreinbreedte zullen veranderen, wat zal worden "vertaald" als een "gemiddeld" uitgangsspanningsniveau zoals hieronder weergegeven:

Afbeelding
Afbeelding

We kunnen dit "gemiddelde" spanningsniveau gebruiken om bijvoorbeeld een LED-helderheid te regelen:

Afbeelding
Afbeelding

Merk op dat het hier niet om de frequentie zelf gaat, maar om de "Duty Cycle", dat is de relatie tussen de tijd dat de puls "hoog" is, gedeeld door de golfperiode. Stel bijvoorbeeld dat we een pulsfrequentie van 50 Hz genereren op een van onze Raspberry Pi GPIO. De periode (p) is het omgekeerde van de frequentie of 20 ms (1/f). Als we willen dat onze LED een "half" felle kleur heeft, moeten we een Duty Cycle van 50% hebben, dat betekent een "puls" die 10ms "Hoog" zal zijn.

Dit principe zal erg belangrijk voor ons zijn, om onze servopositie te controleren, zodra de "Duty Cycle" de servopositie definieert zoals hieronder getoond:

Servo

Stap 3: De Hw. installeren

De Hw. installeren
De Hw. installeren
De Hw. installeren
De Hw. installeren

De servo's worden aangesloten op een externe 5V-voeding, waarbij hun datapin (in mijn geval hun gele bedrading) wordt aangesloten op Raspberry Pi GPIO zoals hieronder:

  • GPIO 17 ==> Kantelservo
  • GPIO 27 ==> Pan-servo

Vergeet niet de GND's met elkaar te verbinden ==> Raspberry Pi - Servo's - Externe voeding)

U kunt als optie een weerstand van 1K ohm hebben tussen Raspberry Pi GPIO en Server-gegevensinvoerpin. Dit zou uw RPi beschermen in geval van een servoprobleem.

Stap 4: Servokalibratie

Servokalibratie
Servokalibratie
Servokalibratie
Servokalibratie
Servokalibratie
Servokalibratie

Het eerste dat u moet doen, is de belangrijkste kenmerken van uw servo's bevestigen. In mijn geval gebruik ik een Power Pro SG90.

Uit de datasheet kunnen we overwegen:

  • Bereik: 180o
  • Voeding: 4.8V (externe 5VDC als USB-voeding werkt prima)
  • Werkfrequentie: 50Hz (Periode: 20 ms)
  • Pulsbreedte: van 1ms tot 2ms

In theorie staat de servo op zijn

  • Beginpositie (0 graden) wanneer een puls van 1 ms wordt toegepast op de dataterminal
  • Neutrale positie (90 graden) wanneer een puls van 1,5 ms wordt toegepast op de dataterminal
  • Eindpositie (180 graden) wanneer een puls van 2 ms wordt toegepast op de dataterminal

Om een servopositie te programmeren met behulp van Python is het erg belangrijk om de corresponderende "Duty Cycle" voor de bovenstaande posities te kennen, laten we een berekening maken:

  • Initiële positie ==> (0 graden) Pulsbreedte ==> 1ms ==> Duty Cycle = 1ms/20ms ==> 2,0%
  • Neutrale positie (90 graden) Pulsbreedte van 1,5 ms ==> Duty Cycle = 1,5ms/20ms ==> 7,5%
  • Eindpositie (180 graden) Pulsbreedte van 2 ms ==> Duty Cycle = 2ms/20ms ==> 10%

Dus de Duty Cycle moet variëren van 2 tot 10%.

Laten we de servo's afzonderlijk testen. Open daarvoor je Raspberry-terminal en start je Python 3-shell-editor als "sudo" (omdat je een "supergebruiker" zou moeten zijn om met GPIO's om te gaan):

sudo python3

Op Python Shell

>>

Importeer de RPI. GPIO-module en noem deze GPIO:

importeer RPi. GPIO als GPIO

Bepaal welke pin-nummeringsschema's u wilt gebruiken (BCM of BOARD). Ik deed deze test met BOARD, dus de pinnen die ik gebruikte waren de fysieke pinnen (GPIO 17 = Pin 11 en GPIO 27 Pin 13). Was gemakkelijk voor mij om ze te identificeren en geen fouten te maken tijdens de test (in het definitieve programma zal ik BCM gebruiken). Kies degene van uw voorkeur:

GPIO.setmode(GPIO. BOARD)

Definieer de servopin die u gebruikt:

kantelpen = 11

Als u in plaats daarvan het BCM-schema hebt gebruikt, moeten de laatste 2 opdrachten worden vervangen door:

GPIO.setmode(GPIO. BCM)

kantelpen = 17

Nu moeten we specificeren dat deze pin een "output" zal zijn

GPIO.setup (tiltPin, GPIO. OUT)

En wat zal de frequentie zijn die op deze pin wordt gegenereerd, die voor onze servo 50Hz zal zijn:

kantelen = GPIO. PWM(tiltPin, 50)

Laten we nu beginnen met het genereren van een PWM-signaal op de pin met een initiële duty cycle (we houden deze "0"):

kantelen = begin(0)

Nu kunt u verschillende duty cycle-waarden invoeren en de beweging van uw servo observeren. Laten we beginnen met 2% en kijken wat er gebeurt (we vermoeden dat de servo naar "nulpositie" gaat):

tilt. ChangeDutyCycle(2)

In mijn geval ging de servo naar de nulpositie, maar toen ik de werkcyclus in 3% veranderde, merkte ik dat de servo in dezelfde positie bleef en begon te bewegen met een werkcyclus van meer dan 3%. Dus 3% is mijn beginpositie (o graden). Hetzelfde gebeurde met 10%, mijn servo ging boven deze waarde en bereikte zijn einde op 13%. Dus voor deze specifieke servo was het resultaat:

  • 0 graden ==> inschakelduur van 3%
  • 90 graden ==> inschakelduur van 8%
  • 180 graden ==> inschakelduur van 13%

Nadat u klaar bent met uw tests, moet u de PWM stoppen en de GPIO's opschonen:

kantelen = stoppen()

GPIO.opschonen()

Het bovenstaande Terminal-afdrukscherm toont het resultaat voor mijn beide servo's (die vergelijkbare resultaten hebben). Je bereik kan anders zijn.

Stap 5: Een Python-script maken

Een Python-script maken
Een Python-script maken

De PWM-commando's die naar onze servo moeten worden verzonden, bevinden zich in "duty cycles" zoals we bij de laatste stap zagen. Maar meestal moeten we "hoek" in graden gebruiken als een parameter om een servo te besturen. We moeten dus "hoek" omzetten die voor ons een meer natuurlijke meting is in de duty cycle, zoals begrijpelijk voor onze Pi.

Hoe je dat doet? Erg makkelijk! We weten dat het duty cycle-bereik van 3% tot 13% gaat en dat dit overeenkomt met hoeken die variëren van 0 tot 180 graden. We weten ook dat die variaties lineair zijn, dus we kunnen een proportioneel schema construeren zoals hierboven weergegeven. dus, gegeven een hoek, kunnen we een corresponderende werkcyclus hebben:

inschakelduur = hoek/18 + 3

Bewaar deze formule. We zullen het gebruiken in de volgende code.

Laten we een Python-script maken om de tests uit te voeren. Kortom, we herhalen wat we eerder deden op Python Shell:

van tijd import slaap

importeer RPi. GPIO als GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) def setServoAngle(servo, angle): pwm = GPIO. PWM(servo, 50) pwm.start(8) dutyCycle = hoek / 18. + 3. pwm. ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop() if _name_ == '_main_': import sys servo = int(sys.argv[1]) GPIO.setup(servo, GPIO. OUT) setServoAngle (servo, int(sys.argv[2])) GPIO.cleanup()

De kern van bovenstaande code is de functie setServoAngle(servo, angle). Deze functie ontvangt als argument een servo GPIO-nummer en een hoekwaarde tot waar de servo moet worden geplaatst. Zodra de invoer van deze functie "hoek" is, moeten we deze in procenten omzetten in duty cycle, met behulp van de eerder ontwikkelde formule.

Wanneer het script wordt uitgevoerd, moet u als parameters, servo GPIO en hoek invoeren.

Bijvoorbeeld:

sudo python3 hoekServoCtrl.py 17 45

Het bovenstaande commando plaatst de servo aangesloten op GPIO 17 met 45 graden in "elevatie". Een soortgelijk commando kan worden gebruikt voor Pan Servo-besturing (positie tot 45 graden in "azimuth"):

sudo python hoekServoCtrl.py 27 45

Het bestand angleServoCtrl.py kan worden gedownload van mijn GitHub

Stap 6: Het pan-tilt-mechanisme

Het pan-tilt-mechanisme
Het pan-tilt-mechanisme

De "Pan" -servo zal onze camera "horizontaal" bewegen ("azimuthoek") en onze "Tilt" -servo zal deze "verticaal" bewegen (elevatiehoek).

De onderstaande afbeelding laat zien hoe het Pan/Tilt-mechanisme werkt:

Afbeelding
Afbeelding

Tijdens onze ontwikkeling zullen we niet naar "extremen" gaan en zullen we ons Pan/Tilt-mechanisme alleen van 30 tot 150 graden gebruiken. Dit bereik is voldoende om met een camera te worden gebruikt.

Stap 7: Het pan-tilt-mechanisme - mechanische constructie

Het pan-tilt-mechanisme - mechanische constructie
Het pan-tilt-mechanisme - mechanische constructie
Het pan-tilt-mechanisme - mechanische constructie
Het pan-tilt-mechanisme - mechanische constructie
Het pan-tilt-mechanisme - mechanische constructie
Het pan-tilt-mechanisme - mechanische constructie

Laten we nu onze 2 servo's assembleren als een Pan/Tilt-mechanisme. Je kunt hier 2 dingen doen. Koop een Pan-Tilt-platformmechanisme zoals getoond op de laatste stap of bouw er zelf een volgens uw behoeften.

Een voorbeeld kan degene zijn die ik heb gebouwd, waarbij ik de servo's alleen aan elkaar heb vastgemaakt en kleine metalen stukjes van oud speelgoed gebruik, zoals op de bovenstaande foto's.

Stap 8: Elektrische pan/tilt montage

Elektrische pan/tilt-montage
Elektrische pan/tilt-montage
Elektrische pan/tilt-montage
Elektrische pan/tilt-montage
Elektrische pan/tilt-montage
Elektrische pan/tilt-montage
Elektrische pan/tilt-montage
Elektrische pan/tilt-montage

Zodra u uw Pan/Tilt-mechanisme hebt gemonteerd, volgt u de foto's voor de volledige elektrische aansluiting.

  1. Zet je Pi uit.
  2. Doe alle elektrische aansluitingen.
  3. Dubbelcheck het.
  4. Zet eerst je Pi aan.
  5. Als alles in orde is, zet je je servo's aan.

We zullen in deze tutorial niet onderzoeken hoe de camera moet worden ingesteld, dit wordt uitgelegd in de volgende tutorial.

Stap 9: Het Python-script

Laten we een Python-script maken om beide servo's tegelijkertijd te besturen:

van tijd import slaap

importeer RPi. GPIO als GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO. OUT) # white => TILT GPIO.setup(pan, GPIO. OUT)) # grijs ==> PAN def setServoAngle(servo, hoek): bevestig hoek >=30 en hoek 90 (middelpunt) ==> 150 setServoAngle(tilt, int(sys.argv[2])) # 30 ==> 90 (middelste punt) ==> 150 GPIO.cleanup()

Wanneer het script wordt uitgevoerd, moet u als parameters Pan-hoek en Tilt-hoek invoeren. Bijvoorbeeld:

sudo python3 servoCtrl.py 45 120

De bovenstaande opdracht plaatst het Pan/Tilt-mechanisme met 45 graden in "azimut" (Pan-hoek) en 120 graden "elevatie" (Tilt-hoek). Merk op dat als er geen parameters worden ingevoerd, de standaard zowel pan- als tilthoeken zijn ingesteld op 90 graden.

Hieronder zie je enkele testen:

Afbeelding
Afbeelding

Het servoCtrl.py-bestand kan worden gedownload van mijn GitHub.

Stap 10: Lustest van servers

Laten we nu een Python-script maken om automatisch het volledige scala aan servo's te testen:

van tijd import slaap

importeer RPi. GPIO als GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO. OUT) # white => TILT GPIO.setup(pan, GPIO. OUT)) # grijs ==> PAN def setServoAngle(servo, angle): bevestig hoek >=30 en hoek <= 150 pwm = GPIO. PWM(servo, 50) pwm.start(8) dutyCycle = hoek / 18. + 3. pwm. ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop() if _name_ == '_main_': voor i binnen bereik (30, 160, 15): setServoAngle(pan, i) setServoAngle(tilt, i) for i in bereik (150, 30, -15): setServoAngle(pan, i) setServoAngle(tilt, i) setServoAngle(pan, 100) setServoAngle(tilt, 90) GPIO.cleanup()

Het programma voert automatisch een lus uit van 30 tot 150 graden in beide hoeken.

Hieronder het resultaat:

Ik heb alleen een oscilloscoop aangesloten om de PWM-theorie te illustreren zoals eerder uitgelegd.

Afbeelding
Afbeelding

De bovenstaande code, servoTest.py kan worden gedownload van mijn GitHub.

Stap 11: Conclusie

Conclusie
Conclusie

Zoals altijd hoop ik dat dit project anderen kan helpen hun weg te vinden in de opwindende wereld van elektronica!

Ga voor meer informatie en de definitieve code naar mijn GitHub-depot: RPi-Pan-Tilt-Servo-Control

Ga voor meer projecten naar mijn blog: MJRoBot.org

Hieronder een glimp van mijn volgende tutorial:

Afbeelding
Afbeelding

Saludos uit het zuiden van de wereld!

Tot ziens in mijn volgende instructable!

Bedankt, Marcelo

Aanbevolen: