Sommario:

Pan-Tilt Multi Servo Control: 11 passaggi (con immagini)
Pan-Tilt Multi Servo Control: 11 passaggi (con immagini)

Video: Pan-Tilt Multi Servo Control: 11 passaggi (con immagini)

Video: Pan-Tilt Multi Servo Control: 11 passaggi (con immagini)
Video: Pan Tilt Control using Servos for ESP32 Cam | WiFi Security Camera 2024, Luglio
Anonim
Controllo multi-servo pan-tilt
Controllo multi-servo pan-tilt

In questo tutorial, esploreremo come controllare più servi usando Python su un Raspberry Pi. Il nostro obiettivo sarà un meccanismo PAN/TILT per posizionare una telecamera (una PiCam).

Qui puoi vedere come funzionerà il nostro progetto finale:

Controllo del circuito di controllo del servo test:

Immagine
Immagine

Passaggio 1: Distinta base - Distinta base

Parti principali:

  1. Raspberry Pi V3 - US$ 32,00
  2. 5 Megapixel 1080p Sensore OV5647 Mini Modulo Video Fotocamera - 13,00 USD
  3. TowerPro SG90 9G Micro Servo a 180 gradi (2 X)- US$ 4.00
  4. Supporto per telecamera antivibrante con piattaforma per telecamera mini pan/tilt con 2 servi (*) - 8,00 USD
  5. Resistore 1K ohm (2X) - Opzionale
  6. Varie: parti metalliche, cinturini, ecc (nel caso in cui costruirai il tuo meccanismo Pan/Tilt)

(*) puoi acquistare una piattaforma Pan/Tilt completa con i servi o costruirne una tua.

Passaggio 2: come funziona PWM

Il Raspberry Pi non ha un'uscita analogica, ma possiamo simularla utilizzando un approccio PWM (Pulse Width Modulation). Quello che faremo è generare un segnale digitale con una frequenza fissa, dove cambieremo la larghezza del treno di impulsi, cosa verrà "tradotto" come un livello di tensione di uscita "medio" come mostrato di seguito:

Immagine
Immagine

Possiamo utilizzare questo livello di tensione "medio" per controllare la luminosità di un LED, ad esempio:

Immagine
Immagine

Si noti che ciò che conta qui non è la frequenza in sé, ma il "Duty Cycle", cioè la relazione tra il tempo in cui l'impulso è "alto" diviso per il periodo dell'onda. Ad esempio, supponiamo di generare una frequenza di impulsi di 50Hz su uno dei nostri GPIO Raspberry Pi. Il periodo (p) sarà l'inverso della frequenza o 20 ms (1/f). Se vogliamo che il nostro LED sia "mezzo" luminoso, dobbiamo avere un Duty Cycle del 50%, cioè un "impulso" che sarà "Alto" per 10ms.

Questo principio sarà molto importante per noi, per controllare la nostra posizione del servo, una volta che il "Duty Cycle" definirà la posizione del servo come mostrato di seguito:

Servo

Passaggio 3: installazione dell'Hw

Installazione dell'Hw
Installazione dell'Hw
Installazione dell'Hw
Installazione dell'Hw

I servi saranno collegati a un'alimentazione esterna a 5 V, con il loro pin dati (nel mio caso, il loro cablaggio giallo) collegato a Raspberry Pi GPIO come di seguito:

  • GPIO 17 ==> Servo inclinazione
  • GPIO 27 ==> Servo Pan

Non dimenticare di collegare i GND insieme ==> Raspberry Pi - Servi - Alimentazione esterna)

È possibile avere come opzione una resistenza da 1K ohm tra il GPIO Raspberry Pi e il pin di input dei dati del server. Ciò proteggerebbe il tuo RPi in caso di problemi con il servo.

Passaggio 4: calibrazione dei servi

Calibrazione dei servi
Calibrazione dei servi
Calibrazione dei servi
Calibrazione dei servi
Calibrazione dei servi
Calibrazione dei servi

La prima cosa da fare è confermare le caratteristiche principali dei tuoi servi. Nel mio caso, sto usando un Power Pro SG90.

Dalla sua scheda tecnica, possiamo considerare:

  • Gamma: 180o
  • Alimentazione: 4,8 V (esterno 5 V CC come alimentatore USB funziona bene)
  • Frequenza di lavoro: 50Hz (Periodo: 20 ms)
  • Larghezza dell'impulso: da 1ms a 2ms

In teoria, il servo sarà sul suo

  • Posizione iniziale (0 gradi) quando viene applicato un impulso di 1 ms al suo terminale dati
  • Posizione neutra (90 gradi) quando viene applicato un impulso di 1,5 ms al suo terminale dati
  • Posizione finale (180 gradi) quando viene applicato un impulso di 2 ms al suo terminale dati

Per programmare una posizione servo utilizzando Python sarà molto importante conoscere il corrispondente "Duty Cycle" per le posizioni di cui sopra, facciamo qualche calcolo:

  • Posizione iniziale ==> (0 gradi) Larghezza impulso ==> 1ms ==> Duty Cycle = 1ms/20ms ==> 2.0%
  • Posizione neutra (90 gradi) Larghezza di impulso di 1,5 ms ==> Ciclo di lavoro = 1,5 ms/20 ms ==> 7,5%
  • Posizione finale (180 gradi) Larghezza dell'impulso di 2 ms ==> Duty Cycle = 2 ms/20 ms ==> 10%

Quindi il Duty Cycle dovrebbe variare in un intervallo dal 2 al 10%.

Proviamo i servi individualmente. Per questo, apri il tuo terminale Raspberry e avvia il tuo editor di shell Python 3 come "sudo" (perché dovresti essere un "super utente" da gestire con i GPIO):

sudo python3

Su Python Shell

>>

Importa il modulo RPI. GPIO e chiamalo GPIO:

importa RPi. GPIO come GPIO

Definire quali schemi di numerazione dei pin si desidera utilizzare (BCM o BOARD). Ho fatto questo test con BOARD, quindi i pin che ho usato erano i pin fisici (GPIO 17 = Pin 11 e GPIO 27 Pin 13). È stato facile per me individuarli e non commettere errori durante il test (nel programma finale utilizzerò BCM). Scegli quello che preferisci:

GPIO.setmode(GPIO. BOARD)

Definisci il pin del servo che stai utilizzando:

tiltPin = 11

Se invece hai utilizzato lo schema BCM, gli ultimi 2 comandi dovrebbero essere sostituiti da:

GPIO.setmode(GPIO. BCM)

tiltPin = 17

Ora, dobbiamo specificare che questo pin sarà un "output"

GPIO.setup(tiltPin, GPIO. OUT)

E, quale sarà la frequenza generata su questo pin, quella per il nostro servo sarà di 50Hz:

tilt = GPIO. PWM(tiltPin, 50)

Ora, iniziamo a generare un segnale PWM sul pin con un duty cycle iniziale (lo terremo "0"):

inclinazione = inizio (0)

Ora puoi inserire diversi valori del ciclo di lavoro, osservando il movimento del tuo servo. Partiamo dal 2% e vediamo cosa succede (ci aspettiamo che il servo vada in "posizione zero"):

tilt. ChangeDutyCycle(2)

Nel mio caso il servo è andato in posizione zero ma quando ho cambiato il duty cycle al 3% ho notato che il servo è rimasto nella stessa posizione, iniziando a muoversi con duty cycle superiori al 3%. Quindi, il 3% è la mia posizione iniziale (o gradi). Lo stesso è successo con il 10%, il mio servo è andato al di sopra di questo valore, raggiungendo la fine del 13%. Quindi per questo particolare servo, il risultato è stato:

  • 0 gradi ==> duty cycle del 3%
  • 90 gradi ==> duty cycle dell'8%
  • 180 gradi ==> duty cycle del 13%

Dopo aver terminato i test, è necessario interrompere il PWM e ripulire i GPIO:

tilt= stop()

GPIO.cleanup()

La schermata di stampa del terminale sopra mostra il risultato per entrambi i miei servi (che ha risultati simili). La tua gamma può essere diversa.

Passaggio 5: creazione di uno script Python

Creazione di uno script Python
Creazione di uno script Python

I comandi PWM da inviare al nostro servo sono in "ciclo di lavoro" come abbiamo visto nell'ultimo passaggio. Ma di solito, dobbiamo usare "angolo" in gradi come parametro per controllare un servo. Quindi, dobbiamo convertire "angolo" che è una misura più naturale per noi nel ciclo di lavoro come comprensibile dal nostro Pi.

Come farlo? Molto semplice! Sappiamo che l'intervallo del ciclo di lavoro va dal 3% al 13% e che questo è equivalente ad angoli che vanno da 0 a 180 gradi. Inoltre, sappiamo che tali variazioni sono lineari, quindi possiamo costruire uno schema proporzionale come mostrato sopra. quindi, dato un angolo, possiamo avere un ciclo di lavoro corrispondente:

dutycycle = angolo/18 + 3

Conserva questa formula. Lo useremo nel prossimo codice.

Creiamo uno script Python per eseguire i test. Fondamentalmente, ripeteremo ciò che abbiamo fatto prima su Python Shell:

dal tempo importa il sonno

import RPi. GPIO as GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) def setServoAngle(servo, angle): pwm = GPIO. PWM(servo, 50) pwm.start(8) dutyCycle = angle / 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()

Il nucleo del codice sopra è la funzione setServoAngle(servo, angle). Questa funzione riceve come argomenti un numero di servo GPIO e un valore dell'angolo rispetto al punto in cui deve essere posizionato il servo. Una volta che l'input di questa funzione è "angolo", dobbiamo convertirlo in duty cycle in percentuale, utilizzando la formula sviluppata in precedenza.

Quando lo script viene eseguito, è necessario inserire come parametri, servo GPIO e angolo.

Per esempio:

sudo python3 angleServoCtrl.py 17 45

Il comando precedente posizionerà il servo collegato su GPIO 17 con 45 gradi in "elevazione". Un comando simile potrebbe essere utilizzato per il controllo Pan Servo (posizione a 45 gradi in "azimut"):

sudo python angleServoCtrl.py 27 45

Il file angleServoCtrl.py può essere scaricato dal mio GitHub

Passaggio 6: il meccanismo pan-tilt

Il meccanismo di pan-tilt
Il meccanismo di pan-tilt

Il servo "Pan" sposterà "orizzontalmente" la nostra telecamera ("angolo di azimut") e il nostro servo "Tilt" la sposterà "verticalmente" (angolo di elevazione).

L'immagine sotto mostra come funziona il meccanismo Pan/Tilt:

Immagine
Immagine

Durante il nostro sviluppo non andremo agli "estremi" e utilizzeremo il nostro meccanismo Pan/Tilt solo da 30 a 150 gradi. Questa gamma sarà sufficiente per essere utilizzata con una fotocamera.

Passaggio 7: il meccanismo di pan-tilt - costruzione meccanica

Il meccanismo pan-tilt - costruzione meccanica
Il meccanismo pan-tilt - costruzione meccanica
Il meccanismo pan-tilt - costruzione meccanica
Il meccanismo pan-tilt - costruzione meccanica
Il meccanismo pan-tilt - costruzione meccanica
Il meccanismo pan-tilt - costruzione meccanica

Ora montiamo i nostri 2 servi come un meccanismo Pan/Tilt. Puoi fare 2 cose qui. Acquista un meccanismo di piattaforma Pan-Tilt come quello mostrato nell'ultimo passaggio o costruisci il tuo secondo le tue necessità.

Un esempio può essere quello che ho costruito, legando solo i servi l'uno all'altro e usando piccoli pezzi di metallo di vecchi giocattoli come mostrato nelle foto sopra.

Passaggio 8: assemblaggio elettrico pan/tilt

Gruppo pan/tilt elettrico
Gruppo pan/tilt elettrico
Gruppo pan/tilt elettrico
Gruppo pan/tilt elettrico
Gruppo pan/tilt elettrico
Gruppo pan/tilt elettrico
Gruppo pan/tilt elettrico
Gruppo pan/tilt elettrico

Una volta assemblato il meccanismo Pan/Tilt, seguire le foto per il collegamento elettrico completo.

  1. Spegni il tuo Pi.
  2. Eseguire tutti i collegamenti elettrici.
  3. Ricontrollalo.
  4. Accendi prima il tuo Pi.
  5. Se tutto è a posto, alimenta i tuoi servi.

Non esploreremo in questo tutorial come impostare la fotocamera, questo verrà spiegato nel prossimo tutorial.

Passaggio 9: lo script Python

Creiamo uno script Python per controllare entrambi i servi contemporaneamente:

dal tempo importa il sonno

import RPi. GPIO come GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO. OUT) # white => TILT GPIO.setup(pan, GPIO. OUT) # gray ==> PAN def setServoAngle(servo, angle): asserire angolo >=30 e angolo 90 (punto centrale) ==> 150 setServoAngle(tilt, int(sys.argv[2])) # 30 ==> 90 (punto centrale) ==> 150 GPIO.cleanup()

Quando lo script viene eseguito, è necessario inserire come parametri, Pan angle e Tilt angle. Per esempio:

sudo python3 servoCtrl.py 45 120

Il comando precedente posizionerà il meccanismo Pan/Tilt con 45 gradi in "azimut" (angolo di panoramica) e 120 gradi di "elevazione" (angolo di inclinazione). Si noti che se non vengono immessi parametri, il valore predefinito sarà entrambi, gli angoli di panoramica e inclinazione impostati fino a 90 gradi.

Di seguito puoi vedere alcuni test:

Immagine
Immagine

Il file servoCtrl.py può essere scaricato dal mio GitHub.

Passaggio 10: test del ciclo dei server

Creiamo ora uno script Python per testare automaticamente l'intera gamma di servi:

dal tempo importa il sonno

import RPi. GPIO come GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO. OUT) # white => TILT GPIO.setup(pan, GPIO. OUT) # grigio ==> PAN def setServoAngle(servo, angolo): asserire angolo >=30 e angolo <= 150 pwm = GPIO. PWM(servo, 50) pwm.start(8) dutyCycle = angolo / 18. + 3. pwm. ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop() if _name_ == '_main_': for i nell'intervallo (30, 160, 15): setServoAngle(pan, i) setServoAngle(tilt, i) for i in range (150, 30, -15): setServoAngle(pan, i) setServoAngle(tilt, i) setServoAngle(pan, 100) setServoAngle(tilt, 90) GPIO.cleanup()

Il programma eseguirà automaticamente un ciclo da 30 a 150 gradi in entrambi gli angoli.

Sotto il risultato:

Ho collegato un oscilloscopio solo per illustrare la teoria del PWM come spiegato prima.

Immagine
Immagine

Il codice sopra, servoTest.py può essere scaricato dal mio GitHub.

Passaggio 11: conclusione

Conclusione
Conclusione

Come sempre, spero che questo progetto possa aiutare gli altri a trovare la loro strada nell'eccitante mondo dell'elettronica!

Per i dettagli e il codice finale, visita il mio deposito GitHub: RPi-Pan-Tilt-Servo-Control

Per altri progetti, visita il mio blog: MJRoBot.org

Di seguito un assaggio del mio prossimo tutorial:

Immagine
Immagine

Saludos dal sud del mondo!

Ci vediamo nel mio prossimo istruibile!

Grazie, Marcelo

Consigliato: