Table des matières:

Pan-Tilt Multi Servo Control : 11 étapes (avec photos)
Pan-Tilt Multi Servo Control : 11 étapes (avec photos)

Vidéo: Pan-Tilt Multi Servo Control : 11 étapes (avec photos)

Vidéo: Pan-Tilt Multi Servo Control : 11 étapes (avec photos)
Vidéo: Pan Tilt Control using Servos for ESP32 Cam | WiFi Security Camera 2024, Juillet
Anonim
Commande multi-servo Pan-Tilt
Commande multi-servo Pan-Tilt

Dans ce tutoriel, nous allons explorer comment contrôler plusieurs servos à l'aide de Python sur un Raspberry Pi. Notre objectif sera un mécanisme PAN/TILT pour positionner une caméra (une PiCam).

Ici vous pouvez voir comment notre projet final fonctionnera:

Test de boucle de contrôle servocommande:

Image
Image

Étape 1: BoM - Nomenclature

Parties principales:

  1. Framboise Pi V3 - 32,00 $ US
  2. 5 Mégapixels 1080p Capteur OV5647 Mini Module Vidéo Caméra - 13,00 $ US
  3. Micro servomoteur TowerPro SG90 9G 180 degrés (2 X) - 4,00 $ US
  4. Mini plate-forme de caméra panoramique/inclinable Support de caméra anti-vibration avec 2 servos (*) - 8,00 $ US
  5. Résistance 1K ohm (2X) - En option
  6. Divers: pièces métalliques, bandes, etc (au cas où vous construirez votre mécanisme Pan/Tilt)

(*) vous pouvez acheter une plate-forme Pan/Tilt complète avec les servos ou construire la vôtre.

Étape 2: Comment PWM fonctionne

Le Raspberry Pi n'a pas de sortie analogique, mais nous pouvons simuler cela, en utilisant une approche PWM (Pulse Width Modulation). Ce que nous allons faire est de générer un signal numérique avec une fréquence fixe, où nous allons changer la largeur du train d'impulsions, ce qui sera "traduit" par un niveau de tension de sortie "moyen" comme indiqué ci-dessous:

Image
Image

On peut utiliser ce niveau de tension « moyen » pour contrôler une luminosité de LED par exemple:

Image
Image

Notez que ce qui compte ici n'est pas la fréquence elle-même, mais le "Duty Cycle", c'est-à-dire la relation entre le temps pendant lequel l'impulsion est "haute" divisée par la période d'onde. Par exemple, supposons que nous générons une fréquence d'impulsion de 50 Hz sur l'un de nos GPIO Raspberry Pi. La période (p) sera l'inverse de la fréquence ou 20ms (1/f). Si nous voulons que notre LED ait un "demi" lumineux, nous devons avoir un Duty Cycle de 50%, c'est-à-dire une "impulsion" qui sera "High" pendant 10ms.

Ce principe sera très important pour nous, pour contrôler notre position servo, une fois que le "Duty Cycle" définira la position servo comme indiqué ci-dessous:

Servomoteur

Étape 3: Installation du matériel

Installation du matériel
Installation du matériel
Installation du matériel
Installation du matériel

Les servos seront connectés à une alimentation externe 5V, leur broche de données (dans mon cas, leur câblage jaune) se connectant au Raspberry Pi GPIO comme ci-dessous:

  • GPIO 17 ==> Servo d'inclinaison
  • GPIO 27 ==> Pan Servo

N'oubliez pas de connecter les GND ensemble ==> Raspberry Pi - Servos - Alimentation externe)

Vous pouvez avoir en option, une résistance de 1K ohm entre Raspberry Pi GPIO et la broche d'entrée de données du serveur. Cela protégerait votre RPi en cas de problème de servo.

Étape 4: Étalonnage des servos

Étalonnage des servos
Étalonnage des servos
Étalonnage des servos
Étalonnage des servos
Étalonnage des servos
Étalonnage des servos

La première chose à faire est de valider les principales caractéristiques de vos servos. Dans mon cas, j'utilise un Power Pro SG90.

A partir de sa fiche technique, on peut considérer:

  • Portée: 180o
  • Alimentation: 4,8 V (le 5 VCC externe en tant qu'alimentation USB fonctionne bien)
  • Fréquence de travail: 50 Hz (Période: 20 ms)
  • Largeur d'impulsion: de 1ms à 2ms

En théorie, le servo sera sur son

  • Position initiale (0 degré) lorsqu'une impulsion de 1 ms est appliquée à son terminal de données
  • Position neutre (90 degrés) lorsqu'une impulsion de 1,5 ms est appliquée à sa borne de données
  • Position finale (180 degrés) lorsqu'une impulsion de 2 ms est appliquée à son terminal de données

Pour programmer une position d'asservissement à l'aide de Python, il sera très important de connaître le "Duty Cycle" correspondant pour les positions ci-dessus, faisons quelques calculs:

  • Position initiale ==> (0 degré) Largeur d'impulsion ==> 1ms ==> Duty Cycle = 1ms/20ms ==> 2,0%
  • Position neutre (90 degrés) Largeur d'impulsion de 1,5 ms ==> Duty Cycle = 1,5ms/20ms ==> 7,5%
  • Position finale (180 degrés) Largeur d'impulsion de 2 ms ==> Duty Cycle = 2ms/20ms ==> 10%

Ainsi, le Duty Cycle devrait varier sur une plage de 2 à 10 %.

Testons les servos individuellement. Pour cela, ouvrez votre terminal Raspberry et lancez votre éditeur de shell Python 3 en tant que "sudo" (car vous devriez être un "super utilisateur" pour gérer les GPIO):

sudo python3

Sur Python Shell

>>

Importez le module RPI. GPIO et appelez-le GPIO:

importer RPi. GPIO en tant que GPIO

Définissez les schémas de numérotation des broches que vous souhaitez utiliser (BCM ou BOARD). J'ai fait ce test avec BOARD, donc les broches que j'ai utilisées étaient les broches physiques (GPIO 17 = Pin 11 et GPIO 27 Pin 13). C'était facile pour moi de les identifier et de ne pas faire d'erreurs pendant le test (Dans le programme final, j'utiliserai BCM). Choisissez celui de votre préférence:

GPIO.setmode(GPIO. BOARD)

Définissez la broche de servo que vous utilisez:

tiltPin = 11

Si à la place, vous avez utilisé le schéma BCM, les 2 dernières commandes doivent être remplacées par:

GPIO.setmode(GPIO. BCM)

tiltPin = 17

Maintenant, il faut préciser que cette broche sera une "sortie"

GPIO.setup(tiltPin, GPIO. OUT)

Et, quelle sera la fréquence générée sur cette broche, celle pour notre servo sera de 50Hz:

inclinaison = GPIO. PWM (tiltPin, 50)

Maintenant, commençons à générer un signal PWM sur la broche avec un rapport cyclique initial (nous le garderons à "0"):

inclinaison = départ(0)

Maintenant, vous pouvez entrer différentes valeurs de cycle de service, en observant le mouvement de votre servo. Commençons par 2% et voyons ce qui se passe (on s'aperçoit que le servo passe en "position zéro"):

inclinaison. ChangeDutyCycle(2)

Dans mon cas, le servo est passé à la position zéro, mais lorsque j'ai changé le rapport cyclique à 3%, j'ai observé que le servo restait dans la même position, commençant à se déplacer avec des rapports cycliques supérieurs à 3%. Donc, 3% est ma position initiale (o degrés). La même chose s'est produite avec 10%, mon servo est passé au-dessus de cette valeur, dépassant sa fin à 13%. Donc pour ce servo particulier, le résultat était:

  • 0 degré ==> cycle de service de 3%
  • 90 degrés ==> cycle de service de 8%
  • 180 degrés ==> cycle de service de 13%

Une fois vos tests terminés, vous devez arrêter le PWM et nettoyer les GPIO:

inclinaison= arrêt()

GPIO.cleanup()

L'écran d'impression du terminal ci-dessus montre le résultat pour mes deux servos (qui a des résultats similaires). Votre gamme peut être différente.

Étape 5: Création d'un script Python

Création d'un script Python
Création d'un script Python

Les commandes PWM à envoyer à notre servo sont en "cycles de service" comme nous l'avons vu à la dernière étape. Mais généralement, nous devons utiliser "angle" en degrés comme paramètre pour contrôler un servo. Donc, nous devons convertir "l'angle" qui est une mesure plus naturelle pour nous en cycle de service comme compréhensible par notre Pi.

Comment faire? Très simple! Nous savons que la plage de cycle de service va de 3% à 13% et que cela équivaut à des angles qui vont de 0 à 180 degrés. De plus, nous savons que ces variations sont linéaires, nous pouvons donc construire un schéma proportionnel comme indiqué ci-dessus. donc, étant donné un angle, nous pouvons avoir un rapport cyclique correspondant:

rapport cyclique = angle/18 + 3

Gardez cette formule. Nous l'utiliserons dans le prochain code.

Créons un script Python pour exécuter les tests. En gros, nous allons répéter ce que nous avons fait auparavant sur Python Shell:

du temps importer le sommeil

importer RPi. GPIO en tant que 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()

Le noyau du code ci-dessus est la fonction setServoAngle(servo, angle). Cette fonction reçoit comme arguments, un numéro GPIO d'asservissement et une valeur d'angle par rapport à l'endroit où le servo doit être positionné. Une fois que l'entrée de cette fonction est "angle", il faut la convertir en rapport cyclique en pourcentage, en utilisant la formule développée précédemment.

Lorsque le script est exécuté, vous devez entrer comme paramètres, servo GPIO et angle.

Par exemple:

sudo python3 angleServoCtrl.py 17 45

La commande ci-dessus positionnera le servo connecté sur GPIO 17 à 45 degrés en "élévation". Une commande similaire pourrait être utilisée pour le contrôle Pan Servo (position à 45 degrés en "azimut"):

sudo python angleServoCtrl.py 27 45

Le fichier angleServoCtrl.py peut être téléchargé depuis mon GitHub

Étape 6: Le mécanisme Pan-Tilt

Le mécanisme Pan-Tilt
Le mécanisme Pan-Tilt

Le servo "Pan" déplacera "horizontalement" notre caméra ("angle d'azimut") et notre servo "Tilt" la déplacera "verticalement" (angle d'élévation).

L'image ci-dessous montre comment fonctionne le mécanisme Pan/Tilt:

Image
Image

Lors de notre développement nous n'irons pas dans les "extrêmes" et nous utiliserons notre mécanisme Pan/Tilt de 30 à 150 degrés uniquement. Cette gamme sera suffisante pour être utilisée avec un appareil photo.

Étape 7: Le mécanisme Pan-Tilt - Construction mécanique

Le mécanisme Pan-Tilt - Construction mécanique
Le mécanisme Pan-Tilt - Construction mécanique
Le mécanisme Pan-Tilt - Construction mécanique
Le mécanisme Pan-Tilt - Construction mécanique
Le mécanisme Pan-Tilt - Construction mécanique
Le mécanisme Pan-Tilt - Construction mécanique

Assemblons maintenant nos 2 servos en mécanisme Pan/Tilt. Vous pouvez faire 2 choses ici. Achetez un mécanisme de plate-forme Pan-Tilt comme celui illustré à la dernière étape ou construisez le vôtre selon vos besoins.

Un exemple peut être celui que j'ai construit, en attachant uniquement les servos les uns aux autres et en utilisant de petits morceaux de métal provenant de vieux jouets, comme le montrent les photos ci-dessus.

Étape 8: Assemblage électrique panoramique/inclinaison

Assemblage électrique panoramique/inclinaison
Assemblage électrique panoramique/inclinaison
Assemblage électrique panoramique/inclinaison
Assemblage électrique panoramique/inclinaison
Assemblage électrique panoramique/inclinaison
Assemblage électrique panoramique/inclinaison
Assemblage électrique panoramique/inclinaison
Assemblage électrique panoramique/inclinaison

Une fois que vous avez assemblé votre mécanisme Pan/Tilt, suivez les photos pour une connexion électrique complète.

  1. Éteignez votre Pi.
  2. Faire tous les branchements électriques.
  3. Vérifiez-le.
  4. Allumez d'abord votre Pi.
  5. Si tout va bien, alimentez vos servos.

Nous n'explorerons pas sur ce tutoriel comment paramétrer la caméra, cela sera expliqué dans le prochain tutoriel.

Étape 9: le script Python

Créons un script Python pour contrôler les deux servos simultanément:

du temps importer le sommeil

importer RPi. GPIO en tant que GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO. OUT) # blanc => TILT GPIO.setup(pan, GPIO. OUT)) # gray ==> PAN def setServoAngle(servo, angle): assert angle >=30 et angle 90 (milieu) ==> 150 setServoAngle(tilt, int(sys.argv[2])) # 30 ==> 90 (point médian) ==> 150 GPIO.cleanup()

Lorsque le script est exécuté, vous devez entrer comme paramètres, l'angle Pan et l'angle d'inclinaison. Par exemple:

sudo python3 servoCtrl.py 45 120

La commande ci-dessus positionnera le mécanisme Pan/Tilt à 45 degrés en "azimut" (angle Pan) et 120 degrés en "élévation" (angle d'inclinaison). Notez que si aucun paramètre n'est entré, la valeur par défaut sera à la fois les angles de panoramique et d'inclinaison réglés jusqu'à 90 degrés.

Ci-dessous vous pouvez voir quelques tests:

Image
Image

Le fichier servoCtrl.py peut être téléchargé depuis mon GitHub.

Étape 10: Test en boucle des serveurs

Créons maintenant un script Python pour tester automatiquement la gamme complète de servos:

du temps importer le sommeil

importer RPi. GPIO en tant que GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO. OUT) # blanc => TILT GPIO.setup(pan, GPIO. OUT)) # gray ==> PAN def setServoAngle(servo, angle): assert angle >=30 et angle <= 150 pwm = GPIO. PWM(servo, 50) pwm.start(8) dutyCycle = angle / 18. + 3. pwm. ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop() if _name_ == '_main_': for i in range (30, 160, 15): setServoAngle(pan, i) setServoAngle(tilt, i) for i in plage (150, 30, -15): setServoAngle(pan, i) setServoAngle(tilt, i) setServoAngle(pan, 100) setServoAngle(tilt, 90) GPIO.cleanup()

Le programme exécutera automatiquement une boucle de 30 à 150 degrés dans les deux angles.

Ci-dessous le résultat:

J'ai connecté un oscilloscope uniquement pour illustrer la théorie PWM comme expliqué précédemment.

Image
Image

Le code ci-dessus, servoTest.py peut être téléchargé depuis mon GitHub.

Étape 11: Conclusion

Conclusion
Conclusion

Comme toujours, j'espère que ce projet pourra aider d'autres personnes à trouver leur chemin dans le monde passionnant de l'électronique !

Pour plus de détails et le code final, veuillez visiter mon dépôt GitHub: RPi-Pan-Tilt-Servo-Control

Pour plus de projets, veuillez visiter mon blog: MJRoBot.org

Ci-dessous un aperçu de mon prochain tutoriel:

Image
Image

Salutations du sud du monde !

Rendez-vous dans mon prochain instructable !

Merci, Marcelo

Conseillé: