Il y a quelques jours, on annonçait sur le blog officiel de Raspberry Pi le lancement d'une nouvelle version de l'environnement de programmation Processing. L'intérêt de cette nouvelle version, c'est qu'elle supporte officiellement le Raspberry Pi et est accompagnée d'une bibliothèque permettant l'accès aux pins GPIOs.
Pour installer ce nouveau logiciel, il s'agit de coller la ligne suivante dans le terminal:
curl https://processing.org/download/install-arm.sh | sudo sh
(L'installation a pris 4 minutes dans mon cas).
Suite à l'installation, on peut accéder au logiciel dans la catégorie "Programmation".
L'interface épurée rapelle un peu l'IDE Arduino.
Processing est très utile, entre autres choses, pour produire des effets graphiques à l'écran. Nous aurons certainement l'occasion d'exploiter ce genre de caractéristiques un de ces jours mais, la priorité de ce blog étant l'électronique, cette première exploration de Processing consistera à faire clignoter une LED.
Le circuit:
Le circuit est constitué d'une LED branchée en série à une résistance de protection (220 Ω, par exemple).
Le tout est branché à la pin BCM 14 et à une des pins GND, tel qu'illustré ci-dessous. (GND est la 3e pin en haut à partir de la gauche, alors que 14 est la 4e pin en haut à partir de la gauche.)
Attention, la LED n'est pas réversible: c'est sa broche la plus longue qui doit être du côté de la pin 14.
Le sketch:
Ça ressemble beaucoup à un sketch Arduino! La principale différence est que, puisque processing est généralement utilisé sur des ordinateurs conventionnels, une bibliothèque est nécessaire pour le contrôle des pins GPIO. Et plutôt que s'appeler "loop", la boucle principale qui s'exécute à répétition pendant toute la durée du programme s'appelle "draw".
Pour exécuter ce sketch, vous cliquez sur le bouton en haut à gauche de la fenêtre de Processing (ou vous choisissez "Exécuter" dans le menu "Sketch"). Au bout de quelques secondes, une petite fenêtre carrée grise apparaît. Il s'agit de cliquer dans cette fenêtre pour démarrer ou interrompre le clignotement de la LED.
Si vous préférez, vous pouvez également faire clignoter une LED branchée au Raspberry Pi en utilisant Python ou Scratch.
Yves Pelletier (Twitter, Facebook)
Pages d'index
▼
Pages d'index
▼
samedi 14 novembre 2015
lundi 9 novembre 2015
Une sortie analogique pour l'Arduino: réseau R2R
Il y a quelques mois, nous avions exploré une première méthode pour produire un signal analogique au moyen d'une carte Arduino: en faisant passer le signal modulé en largeur d'impulsion (pwm) par un filtre passe-bas (constitué d'une résistance et d'un condensateur), nous pouvions obtenir n'importe quelle tension continue située entre 0 et 5 V. Il s'agit d'une méthode simple et efficace si nous désirons obtenir un signal continu, ou de basse fréquence. La présence du filtre passe-bas, toutefois, rend cette méthode peu satisfaisante si nous avons besoin d'un signal analogique qui varie rapidement.
Qu'à cela ne tienne, nous explorons aujourd'hui une autre façon d'ajouter une sortie analogique à notre carte Arduino: nous allons construire un convertisseur numérique-analogique de type "réseau R-2R".
Combien de bits?
Plus notre système comporte un grand nombre de bits, meilleure sera la résolution du signal de sortie. Une meilleure résolution signifie que notre signal de sortie, tout en étant restreint à une valeur située entre 0 et 5 V, pourra prendre un plus grand nombre de valeurs possibles.
Par exemple, chaque sortie numérique de l'Arduino corespond à 1 bit: elles peuvent prendre deux valeurs possibles: 0 ou 1 (0 ou 5 V).
Un système à 2 bits peut prendre 4 valeurs possibles: les valeurs binaires 00, 01, 10 et 11 (qui pourraient correspondre, par exemple, à 0 V, 1,7 V, 3,3 V et 5 V).
Un système à 3 bits peut prendre 8 valeurs possibles: les valeurs binaires 000, 001, 010, 011, 100, 101, 110 et 111 (si on sépare 5 volts en 8 parts égales, on obtient 0 V, 0,7 V, 1,4 V, 2,1 V, 2,9 V, 3,6 V, 4,3 V et 5 V).
Par contre, chaque bit étant contrôlé par une sortie de l'Arduino, plus notre système comporte un grand nombre de bits, plus il accaparera un grand nombre de sorties sur l'Arduino.
Je vous propose ici un réseau R-2R à 8 bits, ce que correspond à 256 valeurs possibles: la tension de sortie pourra donc prendre n'importe quelle valeur située entre 0 et 5 volts, par bonds de 0,02 volts.
Le circuit
Le circuit s'appelle "réseau R-2R" parce qu'il est constitué d'une alternance de résistances identiques (R) et de leur double (2R). J'ai utilisé des résistances R de 10 kΩ et des résistances 2R de 20 kΩ.
Attention à la précision des résistances: si elles ne sont qu'approximativement égales, votre signal analogique risque de varier avec des bonds irréguliers. J'ai mesuré chaque résistance utilisée, en ne retenant que celles qui se situaient à l'intérieur d'une tolérance de 0,5%.
Dans ce circuit, la sortie 2 de l'Arduino représente le bit de poids faible, alors que la sortie 9 représente le bit de poids fort. Ainsi, si toutes les sorties sont à 0 sauf la numéro 2, ça correspond au nombre binaire 00000001, alors que si toutes les sorties sont à 0 sauf la numéro 9, ça correspond au nombre binaire 10000000. La tension de sortie est nulle quand toutes les sorties sont à 0 (nombre binaire 00000000) et elle est à son maximum (presque 5 V) quand toutes les sorties sont à 5 V (nombre binaire 11111111).
Sketch
Voici d'abord un sketch qui permet à l'utilisateur d'entrer la valeur numérique de la tension de sortie qu'il désire au moyen du moniteur série. Vous pouvez tester ce sketch en branchant un voltmètre à la sortie.
Dans ce deuxième sketch, les sorties de l'Arduino prennent successivement toutes les valeurs binaires situées entre 00000000 et 11111111: il en résulte un signal en dent de scie. Ce signal pourrait être capté avec un oscilloscope, mais ici je l'ai mesuré au moyen de l'entrée A0 de l'Arduino. On peut visualiser les valeurs numériques dans le moniteur série ou, mieux encore, visualiser le signal dans le nouveau traceur série de l'environnement de programmation Arduino.
Yves Pelletier (Twitter, Facebook)
Qu'à cela ne tienne, nous explorons aujourd'hui une autre façon d'ajouter une sortie analogique à notre carte Arduino: nous allons construire un convertisseur numérique-analogique de type "réseau R-2R".
Combien de bits?
Plus notre système comporte un grand nombre de bits, meilleure sera la résolution du signal de sortie. Une meilleure résolution signifie que notre signal de sortie, tout en étant restreint à une valeur située entre 0 et 5 V, pourra prendre un plus grand nombre de valeurs possibles.
Par exemple, chaque sortie numérique de l'Arduino corespond à 1 bit: elles peuvent prendre deux valeurs possibles: 0 ou 1 (0 ou 5 V).
Un système à 2 bits peut prendre 4 valeurs possibles: les valeurs binaires 00, 01, 10 et 11 (qui pourraient correspondre, par exemple, à 0 V, 1,7 V, 3,3 V et 5 V).
Un système à 3 bits peut prendre 8 valeurs possibles: les valeurs binaires 000, 001, 010, 011, 100, 101, 110 et 111 (si on sépare 5 volts en 8 parts égales, on obtient 0 V, 0,7 V, 1,4 V, 2,1 V, 2,9 V, 3,6 V, 4,3 V et 5 V).
Par contre, chaque bit étant contrôlé par une sortie de l'Arduino, plus notre système comporte un grand nombre de bits, plus il accaparera un grand nombre de sorties sur l'Arduino.
Je vous propose ici un réseau R-2R à 8 bits, ce que correspond à 256 valeurs possibles: la tension de sortie pourra donc prendre n'importe quelle valeur située entre 0 et 5 volts, par bonds de 0,02 volts.
Le circuit
Le circuit s'appelle "réseau R-2R" parce qu'il est constitué d'une alternance de résistances identiques (R) et de leur double (2R). J'ai utilisé des résistances R de 10 kΩ et des résistances 2R de 20 kΩ.
(Vous pouvez cliquer sur le schéma pour le voir en plus gros).
Dans ce circuit, la sortie 2 de l'Arduino représente le bit de poids faible, alors que la sortie 9 représente le bit de poids fort. Ainsi, si toutes les sorties sont à 0 sauf la numéro 2, ça correspond au nombre binaire 00000001, alors que si toutes les sorties sont à 0 sauf la numéro 9, ça correspond au nombre binaire 10000000. La tension de sortie est nulle quand toutes les sorties sont à 0 (nombre binaire 00000000) et elle est à son maximum (presque 5 V) quand toutes les sorties sont à 5 V (nombre binaire 11111111).
Sketch
Voici d'abord un sketch qui permet à l'utilisateur d'entrer la valeur numérique de la tension de sortie qu'il désire au moyen du moniteur série. Vous pouvez tester ce sketch en branchant un voltmètre à la sortie.
Dans ce deuxième sketch, les sorties de l'Arduino prennent successivement toutes les valeurs binaires situées entre 00000000 et 11111111: il en résulte un signal en dent de scie. Ce signal pourrait être capté avec un oscilloscope, mais ici je l'ai mesuré au moyen de l'entrée A0 de l'Arduino. On peut visualiser les valeurs numériques dans le moniteur série ou, mieux encore, visualiser le signal dans le nouveau traceur série de l'environnement de programmation Arduino.
Yves Pelletier (Twitter, Facebook)
mardi 3 novembre 2015
Le traceur série (Arduino IDE version 1.6.6)
La version 1.6.6 de l'environnement de programmation Arduino a été lancée aujourd'hui et, parmi les nouveautés, mon attention a été attirée par le traceur série ("serial plotter"). Ce nouvel outil vous permet de représenter sous forme de graphique les données numériques acheminées vers le moniteur série.
Par exemple: je vais faire varier le signal à l'entrée A0 au moyen d'un potentiomètre.
Pour le sketch, rien de bien compliqué: je fais exactement comme si je désirais accumuler les données dans le moniteur série.
Mais plutôt qu'ouvrir le moniteur série, j'ouvre le traceur série, disponible dans le menu "Outils".
Et voilà ce que j'obtiens en tournant le bouton du potentiomètre:
D'après ce que j'ai pu constater, le traceur série affiche un nombre fixe de données. Plus vous insérez un long délai dans la boucle (entre deux mesures successives), plus vous pourrez afficher dans la même fenêtre des données échelonnées sur une longue période de temps.
Yves Pelletier (Twitter, Facebook)
Par exemple: je vais faire varier le signal à l'entrée A0 au moyen d'un potentiomètre.
Pour le sketch, rien de bien compliqué: je fais exactement comme si je désirais accumuler les données dans le moniteur série.
Mais plutôt qu'ouvrir le moniteur série, j'ouvre le traceur série, disponible dans le menu "Outils".
Et voilà ce que j'obtiens en tournant le bouton du potentiomètre:
D'après ce que j'ai pu constater, le traceur série affiche un nombre fixe de données. Plus vous insérez un long délai dans la boucle (entre deux mesures successives), plus vous pourrez afficher dans la même fenêtre des données échelonnées sur une longue période de temps.
Yves Pelletier (Twitter, Facebook)
dimanche 1 novembre 2015
Contrôler un servomoteur en python avec un Raspberry Pi
Cet article a été mis à jour le 21 décembre 2020 (compatibilité Python 3)
Dans le passé, nous avons vu comment faire en sorte que notre Raspberry Pi contrôle un moteur dc et un moteur pas à pas au moyen d'un script en python. Aujourd'hui, c'est le tour d'un servomoteur.
Comment ça fonctionne
Un peu comme le moteur pas à pas, le servomoteur peut être contrôlé de façon à lui faire prendre une position angulaire très précise. Une différence importante, c'est qu'avec le moteur pas à pas, on contrôle le déplacement (comme dans "tourne de 5° vers la gauche") alors qu'avec le servomoteur, on contrôle la position (comme dans "va à la position 17°").
Cette position se contrôle au moyen d'un signal en modulation de largeur d'impulsion (PWM: voir cet article pour plus de détails): il s'agit d'une succession de signaux logiques hauts (3,3 V) et bas (0 V).
En général, le signal est envoyé toutes les 20 ms (donc la fréquence est de 50 Hz). Si le signal demeure haut pendant 1 ms (ce qui correspond à un rapport cyclique de 5 %), le servomoteur se place à sa position minimale, s'il demeure haut pendant 1,5 ms (rapport cyclique de 7,5%), il se place à sa position médiane, et s'il demeure haut pendant 2 ms (rapport cyclique de 10 %), il se place à sa position maximale.
Les valeurs exactes varient d'un servomoteur à l'autre, toutefois, et le mieux est d'effectuer quelques tests avec celui que vous utiliserez, afin de connaître les rapports cycliques nécessaires pour lui faire occuper ses positions extrêmes (le premier exemple de script, présenté un peu plus loin dans cet article, nous permettra d'atteindre cet objectif).
Le circuit
Le servomoteur est muni de trois connecteurs: le fil noir (ou marron) est la masse (GND), le fil rouge est l'alimentation (5 V) et le fil jaune (ou autre couleur) transmet le signal PWM.
Il est risqué d'alimenter directement votre servomoteur avec une sortie 5 V du Raspberry Pi, car il pourrait consommer un courant trop intense. Autant que possible, utilisez une alimentation externe pour votre servomoteur.
Il est important que toutes les masses soient connectées ensemble (celle du Raspberry Pi, celle du servomoteur, et celle (borne négative) de l'alimentation utilisée pour le servomoteur).
Le fil qui achemine le signal PWM est branché la broche 12 (numérotation board), aussi appelée GPIO 18 (numérotation BCM).
Des exemples de script
Le premier script nous permettra de trouver par essai/erreur les valeurs de rapport cyclique correspondant aux positions extrêmes de votre servomoteur. Au départ, le rapport cyclique est réglé automatiquement à 7 (ce qui devrait avoir pour effet de placer votre servomoteur environ à sa position médiane). On demande ensuite à l'utilisateur d'entrer au clavier le rapport cyclique désiré. Avec mon servo, la position minimale était atteinte avec un rapport cyclique de 3 (si j'entrais 2, le servo demeurait à la même position qu'à 3), et la position maximale était atteinte avec un rapport cyclique de 11 (là encore, si j'entrais 12, le servo demeurait à la même position qu'à 11). Notez que vous n'êtes pas limité aux nombres entiers: vous pouvez écrire "9.35", par exemple.
Vous remarquerez peut-être que plutôt que demeurer sagement immobile à la position que vous avez demandée (comme il le ferait si vous le contrôliez avec un Arduino), votre servomoteur tremblote un peu. Si j'ai bien compris, c'est l'aspect "multitâche" du système d'exploitation du Raspberry Pi qui est la cause de ces vibrations. Le Raspberry Pi ne consacre pas 100% de son temps à votre programme en python, ce qui cause certaines irrégularités dans le signal PWM transmis au servomoteur.
Si ce tremblement constitue un irritant majeur, vous pouvez déléguer le contrôle du servomoteur à un dispositif en temps réel comme l'Arduino (vous pouvez vous référer à de précédents articles de blog pour établir une communication entre le Raspberry Pi et l'Arduino par USB, ou par RF 433 MHz); vous pouvez également utiliser un circuit intégré spécialement conçu pour cette tâche.
Voici un deuxième script grâce auquel le servomoteur est toujours en mouvement: il tourne lentement dans une direction, puis revient rapidement à son point de départ afin de recommencer son cycle. Avant d'exécuter ce script, il est préférable d'avoir d'abord trouvé les valeurs limites du rapport cyclique au moyen du script précédent, et d'utiliser ces valeurs à la place de celles que j'ai placées (qui correspondent au caractéristiques de mon servo).
À lire également
On peut aussi contrôler un servomoteur avec une carte Arduino, un module ESP8266 ou ESP32, une carte STM32 Nucleo, un microcontrôleur PIC, etc.
D'autre part, vous trouverez sur cette page la liste des billets concernant le Raspberry Pi.
Yves Pelletier (Twitter, Facebook)
Comment ça fonctionne
Un peu comme le moteur pas à pas, le servomoteur peut être contrôlé de façon à lui faire prendre une position angulaire très précise. Une différence importante, c'est qu'avec le moteur pas à pas, on contrôle le déplacement (comme dans "tourne de 5° vers la gauche") alors qu'avec le servomoteur, on contrôle la position (comme dans "va à la position 17°").
Cette position se contrôle au moyen d'un signal en modulation de largeur d'impulsion (PWM: voir cet article pour plus de détails): il s'agit d'une succession de signaux logiques hauts (3,3 V) et bas (0 V).
En général, le signal est envoyé toutes les 20 ms (donc la fréquence est de 50 Hz). Si le signal demeure haut pendant 1 ms (ce qui correspond à un rapport cyclique de 5 %), le servomoteur se place à sa position minimale, s'il demeure haut pendant 1,5 ms (rapport cyclique de 7,5%), il se place à sa position médiane, et s'il demeure haut pendant 2 ms (rapport cyclique de 10 %), il se place à sa position maximale.
Les valeurs exactes varient d'un servomoteur à l'autre, toutefois, et le mieux est d'effectuer quelques tests avec celui que vous utiliserez, afin de connaître les rapports cycliques nécessaires pour lui faire occuper ses positions extrêmes (le premier exemple de script, présenté un peu plus loin dans cet article, nous permettra d'atteindre cet objectif).
Le circuit
Le servomoteur est muni de trois connecteurs: le fil noir (ou marron) est la masse (GND), le fil rouge est l'alimentation (5 V) et le fil jaune (ou autre couleur) transmet le signal PWM.
Il est risqué d'alimenter directement votre servomoteur avec une sortie 5 V du Raspberry Pi, car il pourrait consommer un courant trop intense. Autant que possible, utilisez une alimentation externe pour votre servomoteur.
Il est important que toutes les masses soient connectées ensemble (celle du Raspberry Pi, celle du servomoteur, et celle (borne négative) de l'alimentation utilisée pour le servomoteur).
Le fil qui achemine le signal PWM est branché la broche 12 (numérotation board), aussi appelée GPIO 18 (numérotation BCM).
Des exemples de script
Le premier script nous permettra de trouver par essai/erreur les valeurs de rapport cyclique correspondant aux positions extrêmes de votre servomoteur. Au départ, le rapport cyclique est réglé automatiquement à 7 (ce qui devrait avoir pour effet de placer votre servomoteur environ à sa position médiane). On demande ensuite à l'utilisateur d'entrer au clavier le rapport cyclique désiré. Avec mon servo, la position minimale était atteinte avec un rapport cyclique de 3 (si j'entrais 2, le servo demeurait à la même position qu'à 3), et la position maximale était atteinte avec un rapport cyclique de 11 (là encore, si j'entrais 12, le servo demeurait à la même position qu'à 11). Notez que vous n'êtes pas limité aux nombres entiers: vous pouvez écrire "9.35", par exemple.
Vous remarquerez peut-être que plutôt que demeurer sagement immobile à la position que vous avez demandée (comme il le ferait si vous le contrôliez avec un Arduino), votre servomoteur tremblote un peu. Si j'ai bien compris, c'est l'aspect "multitâche" du système d'exploitation du Raspberry Pi qui est la cause de ces vibrations. Le Raspberry Pi ne consacre pas 100% de son temps à votre programme en python, ce qui cause certaines irrégularités dans le signal PWM transmis au servomoteur.
Si ce tremblement constitue un irritant majeur, vous pouvez déléguer le contrôle du servomoteur à un dispositif en temps réel comme l'Arduino (vous pouvez vous référer à de précédents articles de blog pour établir une communication entre le Raspberry Pi et l'Arduino par USB, ou par RF 433 MHz); vous pouvez également utiliser un circuit intégré spécialement conçu pour cette tâche.
Voici un deuxième script grâce auquel le servomoteur est toujours en mouvement: il tourne lentement dans une direction, puis revient rapidement à son point de départ afin de recommencer son cycle. Avant d'exécuter ce script, il est préférable d'avoir d'abord trouvé les valeurs limites du rapport cyclique au moyen du script précédent, et d'utiliser ces valeurs à la place de celles que j'ai placées (qui correspondent au caractéristiques de mon servo).
À lire également
On peut aussi contrôler un servomoteur avec une carte Arduino, un module ESP8266 ou ESP32, une carte STM32 Nucleo, un microcontrôleur PIC, etc.
D'autre part, vous trouverez sur cette page la liste des billets concernant le Raspberry Pi.
Yves Pelletier (Twitter, Facebook)