Outils pour utilisateurs

Outils du site


issue114:python

This month, we are going to interface a servo motor to our RPi. This requires only a servo motor, the Raspberry Pi, the breadboard, some jumpers, and the battery pack we used last month. A servo motor is simply a motor that has a control circuit and a potentiometer to give the control circuit the position of the output shaft. MOST servos will rotate the shaft between 0° and 180°. There are some that go 360° and more, but they cost a lot. Gears do all the connections between the motor, the potentiometer, and the output shaft. We provide the power through batteries or another external power source, and the RPi will send out the control signals. Most servos have only three wires, Positive voltage, Negative voltage (ground) and Control Signal. Colors of the wires vary from manufacture to manufacture, but the voltage wires should be close in colour to red and black, and the control wire is the only one left. When in doubt, check for a data sheet from the manufacture. The control signals are expected in a very specific “format”, and we will use PWM (Pulse Width Modulation) for that. First, the pulses must come every 20 milliseconds. The width of the pulse determines where the output shaft turns to. If the pulse is 1 ms in width, the motor will move toward 0°. If the pulse is 1.5 ms, then the shaft moves toward 90°. If the pulse is 2 ms, the shaft moves toward 180°

Ce mois-ci, nous allons interfacer un servo-moteur à notre RPi. Il ne faut qu'un servo-moteur, le Raspberry Pi, la plaque d'essai, quelques cavaliers et le bloc de piles utilisées le mois dernier.

Un servo-moteur est simplement un moteur qui a un circuit de commande et un potentiomètre pour donner au circuit de commande la position de l'axe de sortie. La PLUPART des servos feront tourner leur axe entre 0 ° et 180 °. Quelques-uns vont jusqu'à 360 °, voire plus, mais ils coûtent cher. Des engrenages font toutes les liaisons entre le moteur, le potentiomètre et l'axe de sortie. Nous fournissons l'alimentation par des batteries ou une autre source extérieure d'alimentation et le RPi enverra les signaux de commande. La plupart des servos ont seulement 3 fils, tension positive, tension négative (masse) et signal de commande. La couleur des fils varie d'un fabricant à l'autre, mais les fils d'alimentation devraient être de couleurs proches du rouge et du noir et le fil de commande est celui qui reste. En cas de doute, vérifiez la feuille de données du fabricant.

Les signaux de commande sont attendus sous une « forme » très spécifique et nous utiliserons PWM ( Pulse Width Modulation - Modulation de largeur d'impulsion) pour cela. D'abord, les impulsions doivent arriver toutes les 20 millisecondes. La largeur de l'impulsion détermine dans quel sens tourne l'axe de sortie. Si l'impulsion est large de 1 ms, le moteur tournera jusqu'à 0 °. Si l'impulsion est de 1,5 ms, alors l'axe tourne jusqu'à 90 °. Si l'impulsion est de 2 ms, l'axe tourne jusqu'à 180 °.

The Wiring The connections are very simple this month. The battery pack powers the motor, so +voltage on the servo goes to the + voltage rail, and the negative servo wire goes to the negative rail. We connect the negative voltage from the battery pack (negative rail) to pin 6 of the RPi. GPIO pin 23 (pin 16) goes to the control wire of the servo. Now for some math. As we discussed earlier, the servo expects a signal every 20 ms in order to work, and we need to keep sending those pulses to keep the output shaft in the position that we want it in. The GPIO command to set the Pulse Width Modulation is Pwm = GPIO.pwm({RPi Pin},{Frequency}) We know the pin number (23), but we need to convert the 20 ms to Hertz in order to set the pwm setup command. How do we do that? It’s simple. Frequency = 1/time Frequency = 1/.02 (20ms) Frequency = 50 Hertz So now, when we set up our code, we can set the GPIO.pwm command to the control pin and use 50 for our frequency.

Le câblage

Les connexions sont très simples ce mois-ci. Le bloc de piles alimente le moteur, de sorte que la tension + sur le servo aille sur la ligne + et que le fil négatif du servo aille sur le ligne -. Nous connectons la tension négative du bloc de piles (ligne négative) sur le picot 6 du RPi. Le picot 23 de GPIO (picot 16) est relié au fil de commande du servo.

Maintenant, un peu de maths. Comme nous avons dit précédemment, le servo attend un signal toutes les 20 ms pour fonctionner, et nous devons envoyer en permanence ces impulsions pour garder l'axe de sortie dans la position que nous voulons. La commande GPIO pour paramétrer la modulation de largeur d'impulsion (PWM) est :

Pwm = GPIO.pwm({RPi Pin},{Frequency})

Nous connaissons le numéro du picot (23), mais nous devons convertir les 20 ms en Hertz pour paramétrer la commande de réglage de pwm. Comment le faire ? C'est simple.

Fréquence = 1/temps Fréquence = 1/0,02 (20 ms) Fréquence = 50 Hertz

Ainsi, maintenant, quand nous préparons notre code, nous pouvons régler la commande GPIO.pwm pour le picot de commande et utiliser 50 pour notre fréquence.

Our first program will start somewhere close to 0° and then move to close to 90° then move to close to 180°. I keep saying close, because every servo is a bit different. We don’t want to set the DutyCycle to 0 and have it slam to the limit and potentially damage the servo, so we will start off with a low number close to 0 and end with a number close to 12 in order to start to “dial in” a set of values that work. For my servo, the numbers 3 for 0° and 12 for 180° worked well. Servo1.py import RPi.GPIO as GPIO from time import sleep GPIO.setmode(GPIO.BCM) GPIO.setup(23,GPIO.OUT) pwm = GPIO.PWM(23,50) pwm.start(2) pwm.ChangeDutyCycle(3) sleep(5) 3 should give you the first angle. You might need to try changing it to 2,1,0 or 4 to get it there. Write down this number. pwm.ChangeDutyCycle(6) sleep(5) This should put the rotor into the centre position (90°). If you have changed the first number or the next number, this will have to change as well.

Notre premier programme commencera au voisinage de 0 ° et se déplacera à proximité de 90 ° puis ira jusqu'à 180 ° environ. Je dis seulement proche, parce que chaque servo est un peu différent. Nous ne voulons pas régler le rapport cyclique à 0 et l'entendre claquer en butée avec une détérioration éventuelle du servo ; aussi, nous commencerons avec un petit nombre, proche de 0, et terminerons avec un nombre proche de 12 de façon à commencer à « composer » un ensemble de valeurs qui fonctionnent. Pour mon servo, les nombres 3 pour 0 ° et 12 pour 180 ° marchent bien.

Servo1.py

import RPi.GPIO as GPIO from time import sleep

GPIO.setmode(GPIO.BCM) GPIO.setup(23,GPIO.OUT)

pwm = GPIO.PWM(23,50) pwm.start(2) pwm.ChangeDutyCycle(3) sleep(5)

3 vous donnera le premier angle, mais vous pourriez avoir à essayer avec 2, 1, 0 ou 4 pour y parvenir. Notez bien ce numéro.

pwm.ChangeDutyCycle(6)

sleep(5)

Ceci devrait placer le rotor en position centrale (90 °). Si vous avez modifié le premier chiffre ou le suivant, celui-ci devra aussi être changé.

pwm.ChangeDutyCycle(12) sleep(5) The final number should take you to the 180° position. Again, try a few numbers one side or the other to tweak this, and once you have it, write down the number. GPIO.cleanup() Finally we call GPIO.cleanup() to set everything to normal. Now comes the heavy duty math part. We will use the values 3 and 12 as y1 and y2 respectively for the formula. Substitute your numbers.

pwm.ChangeDutyCycle(12)

sleep(5)

Le dernier chiffre devrait vous amener à la position 180 °. Là encore, essayez quelques chiffres d'un côté ou de l'autre pour l'ajuster, et une fois fait, notez la valeur.

GPIO.cleanup()

Enfin, nous appelons GPIO.cleanup() pour un retour à la normale.

Maintenant arrive le gros morceau de maths. Nous utiliserons les valeurs 3 et 12 pour y1 et y2 respectivement dans la formule. Remplacez-les par vos propres numéros.

Offset = (y2-y1)/(x2-x1) Offset = (12-3)/(180-0) Offset = 9/180 Offset = .05 Now when we set the DutyCycle based on an angle between 0° and 180° we use the following formula DutyCycle = (Offset * angle) + 2.0 DutyCycle = (.05 * angle) + 2.0 When I did this, it worked, but I found the value of .061 worked a little bit better. Well, that’s about it for this month. Next time, we will be working with a stepper motor, somewhat a cross of both a servo and a regular motor. Until then, enjoy!

Offset = (y2-y1)/(x2-x1) Offset = (12-3)/(180-0) Offset = 9/180 Offset = .05

Maintenant, si nous réglons le rapport cyclique pour un angle entre 0 ° et 180 °, nous utilisons la formule suivante :

DutyCycle = (Offset * angle) + 2.0

DutyCycle = (.05 * angle) + 2.0

Quand je l'ai fait, ça fonctionnait, mais j'ai trouvé que la valeur de 0,061 marchait un petit peu mieux.

Voilà, c'est tout pour ce mois-ci. La prochaine fois, nous travaillerons avec un moteur pas-à-pas, une sorte de croisement entre un servo et un moteur ordinaire.

Jusque-là, amusez-vous bien !

issue114/python.txt · Dernière modification : 2016/11/18 12:27 de auntiee