mardi 19 septembre 2017

Déboguer l'ATTiny85 avec le moniteur série

Si vous êtes un tant soit peu familier avec la programmation d'une carte Arduino, vous savez à quel point le moniteur série peut s'avérer utile pour débusquer les erreurs dans votre sketch:  on affiche le contenu des variables à l'écran, ce qui permet souvent de trouver ce qui ne fonctionne pas correctement.

Lorsqu'on programme un ATTiny85 en utilisant une carte Arduino comme programmateur (Arduino as ISP), cette option n'est pas directement disponible puisque l'ATTiny85 ne dispose pas de ports UART hardware. Il est toutefois possible d'utiliser la bibliothèque "software serial" qui est distribuée par défaut avec l'IDE Arduino.

Je vais supposer que vous savez déjà comment utiliser une carte Arduino Uno comme programmateur de carte ATTiny (si ne n'est pas le cas, vous pouvez vous référez à cet article que j'ai récemment mis à jour).

Notez que j'utilise le core développé par David A. Mellis, avec une fréquence d'horloge de 1 MHz.

Pour transmettre les données de l'ATTiny vers l'ordinateur, j'utilise un convertisseur USB-TTL dont la broche "RX" est reliée au GPIO de l'ATTiny que j'ai choisi pour la communication série.



Je rappelle le pinout de l'ATTiny85, c'est toujours utile:



Première option:  affichage dans le moniteur série pendant que l'ATTiny demeure branché au programmateur Arduino

Cette option est pratique car vous pouvez téléverser votre sketch dans l'ATTiny et observer le résultat dans le moniteur série sans avoir à débrancher quoi que ce soit.  Elle n'est pas toujours réalisable, toutefois, car les GPIO 0, 1 et 2 de l'ATTiny sont déjà utilisées pour la programmation; vous devez donc dédier le GPIO 3 ou 4 à la transmission série, et un seul GPIO demeure disponible pour y brancher un capteur ou autre.

Sur le schéma ci-dessous, le GPIO 4 (qui est en fait la broche numéro 3 de l'ATTiny) est utilisé pour la transmission des données vers le moniteur série.  Les autres connexions sont celles qui sont requises pour programmer l'ATTiny au moyen de l'Arduino Uno.

La masse (GND) du convertisseur USB-TTL est reliée à la masse de l'ATTiny et à celle de la carte Arduino.



Puisque la carte Arduino et le convertisseur USB-TTL sont tous les deux branchés à l'ordinateur, je dois m'assurer de sélectionner le bon port dans le menu "Outil":  le port correspondant à l'Arduino lorsque je désire téléverser le sketch dans l'ATTiny, et le port correspondant au convertisseur Série-TTL lorsque je désire afficher le moniteur série.




Deuxième option:  affichage dans le moniteur série pendant que l'ATTiny n'est plus branché au programmateur Arduino

Puisque l'ATTiny85 comporte un nombre restraint de pins GPIO, il est souvent nécessaire de le débrancher de l'Arduino pour faire nos tests.  Vous pouvez alors utiliser n'importe lequel des GPIO pour la transmission des données, et utiliser les autres pour y brancher des capteurs, LEDs, etc.  Si désiré, le convertisseur USB-TTL peut servir à l'alimentation de votre circuit.



Un exemple de sketch

Aucune installation de bibliothèque n'est nécessaire, puisque "SoftwareSerial" est inclus avec l'IDE Arduino.  Les données sont transmise par le GPIO 4, ce qui correspond aux circuits illustrés plus haut.  Dans ce cas, puisque j'envoie des données vers l'ordinateur mais je ne désire pas en recevoir, j'ai assigné un numéro de GPIO bidon pour la pin RX.





Yves Pelletier   (TwitterFacebook)

jeudi 14 septembre 2017

Appli Android pour contrôler un moteur pas à pas par bluetooth (Arduino)

Vous désirez contrôler un moteur pas à pas par bluetooth au moyen de votre téléphone android? Ça tombe bien, c'est justement le sujet du billet d'aujourd'hui!

Côté récepteur, notre montage est constitué d'un moteur pas à pas bipolaire, d'une carte Arduino Uno, d'un module bluetooth HC-06, et d'un double pont en H L293D (un L298N aurait fait l'affaire aussi).

Côté émetteur, un appareil android qui exécutera une application que nous aurons nous-même conçue sur MIT App Inventor.

Cette activité suppose certaines connaissances préalables.  Si ce n'est pas déjà fait, je crois qu'il serait préférable de lire mon introduction au module bluetooth HC-06 avec Arduino, mes explications détaillées sur la façon de piloter un moteur pas à pas avec un L293D, mon introduction à la programmation d'une appli android avec MIT App Inventor 2 et, finalement, la programmation d'une appli androit pour communiquer en bluetooth avec MIT App Inventor 2!

Voici une vidéo du dispositif en action:



Connexions du L293D

Le circuit intégré L293D est branché de la même façon que dans ce précédent billet consacré au pilotage d'un moteur pas à pas.

  • Les broches 1, 9 et 16 du L293D sont branchées à la sortie 5 V de la carte Arduino.
  • Les broches 4, 5, 12 et 13 constituent la masse du L293D.  On doit y brancher la masse (GND) de l'Arduino, et la borne négative de la source d'alimentation du moteur pas à pas.
  • La borne positive de l'alimentation du moteur pas à pas est branché à la broche 8 du L293D.
  • Le moteur pas à pas est branché aux borches 3, 6, 11 et 14 du L293D
  • Les broches 2, 7, 10 et 15 du L293D sont branchées respectivement aux sorties 8, 9, 10 et 11 de l'Arduino.
Connexions du module bluetooth HC-06 et du CI 4050

Le module bluetooth HC-06 est conçu pour fonctionner à un niveau logique de 3,3 V.  Pour cette raison, l'utilisation d'un circuit intégré 4050 est conseillée pour abaisser le signal de 5 V émis par l'Arduino.

Voici les connexions du 4050; pour plus d'explications, référez-vous au billet sur l'utilisation d'un 4050 pour abaisser un niveau logique.

  • Broche 1 du 4050:  sortie 3,3 V de l'Arduino
  • Broche 2 du 4050:  entrée RXD du module HC-06
  • Broche 3 du 4050:  sortie Tx de l'Arduino (pin 1)
  • Broche 8 du 4050:  masse (GND de l'Arduino)


Le module HC-06, quant à lui, est branché de la façon suivante:


  • Vcc du HC-06 --- sortie 5 V de l'Arduino
  • GND du HC-06 --- GND de l'Arduino
  • TXD du HC-06 --- Rx de l'Arduino (pin 0)
  • RXD du HC-06 --- broche 2 du 4050

Vous pouvez bien sûr vous référer au billet Bluetooth et Arduino: le module HC-06 pour plus de détails.




Circuit complet

Voici donc le schéma complet, incluant la carte Arduino, le L293D, le 4050, le module HC-06 et le moteur pas à pas!



Sketch de l'Arduino

L'Arduino recevra par bluetooth un nombre entier situé entre 0 et 100.  Par défaut, on considère que la position angulaire initiale du moteur est 50.  À partir de cette position initiale, le moteur doit faire un demi-tour dans un sens pour atteindre la position 0, et un demi tour dans l'autre sens pour atteindre la position 100.




Réalisation de l'appli android avec MIT App Inventor 2

L'appli android comporte les boutons nécessaires pour établir une communication bluetooth, ainsi qu'un "ascenseur" que l'utilisateur déplace afin de faire tourner le moteur pas à pas à la position désirée.

L'interface comporte 8 éléments:



1)  Un rectangle "Arrangement horizontal", pris dans la catégorie "Disposition", qui permet de faire en sorte que les éléments 2, 3 et 4 seront disposés dans la fenêtre sur une même ligne horizontale.

2)  Un "Label" (disponible dans la catégorie "Interface Utilisateur").  Par défaut, ce label portait le nom "Label1", mais je l'ai renommé "StatutConnexion".  La mention "connecté" ou "déconnecté" s'affichera à cet endroit.

3)  Un "Sélectionneur de liste" (disponible dans la catégorie "Interface Utilisateur").  Lorsque l'utilisateur cliquera sur cet élément, la liste des appareils bluetooth disponibles s'affichera à l'écran. J'ai renommé cet élément "BoutonConnecter", et j'ai remplacé son texte par "Connecter".

4)  Un "Bouton" (disponible dans la catégorie "Interface Utilisateur") qui servira à interrompre la connexion avec l'Arduino.  J'ai renommé cet élément "BoutonDéconnecter", et j'ai remplacé son texte par "Déconnecter".

5)  Un deuxième "Label" (disponible dans la catégorie "Interface Utilisateur").  J'y ai inscrit le texte "Position".

6)  Un "Ascenseur" (disponible dans la catégorie "Interface Utilisateur").  Largeur:  80% de la fenêtre, valeur maximale:  100, valeur minimale:  0.

7) Un "Client Blutooth" (disponible dans la catégorie "Connectivité"), indispensable pour toute application qui communique avec bluetooth.

8)  Un "Notificateur" (disponible dans la catégorie "Interface Utilisateur"), qui permet d'afficher un message d'alerte si bluetooth n'a pas été activé sur l'appareil android.


Construction du programme

Passons maintenant en mode "Blocs".  Tout ce qui concerne le contenu le contenu de l'élément "Arrangement horizontal" est identique à ce que j'avais décrit dans le billet intitulé "Programmer une appli android pour communiquer en bluetooth":


Il ne reste plus qu'à gérer le comportement de notre ascenseur:  lorsqu'on le déplace, il envoie sa nouvelle position (un nombre situé entre 0 et 100) par l'entremise du client bluetooth:


Fichier .aia

Vous pouvez télécharger ici le programme complet:  Moteur_PAP.aia

Yves Pelletier   (TwitterFacebook)

jeudi 7 septembre 2017

Mesurer une température avec une carte STM32 Nucleo (mbed)

On a parfois besoin de mesurer une température au moyen d'un microcontrôleur (contrôle d'un système de chauffage ou de climatisation, station météorologique, expérience scientifique, etc.).

Je vous présente aujourd'hui quelques façons différentes de mesurer une température avec une carte STM32 Nucleo:  nous utiliserons successivement le capteur de température interne du STM32, un capteur numérique DS18B20, un capteur numérique BMP180, et un capteur analogique LM35.

(Si vous préférez mesurer une température au moyen d'une carte Arduino, consultez plutôt cet article).

Méthode 1:  Le capteur de température interne du STM32 (méthode déconseillée!)

Le microcontrôleur STM32 comporte un capteur de température intégré pouvant mesurer des températures situées entre -40°C et +125°C avec une résolution de 1,5°C.  L'avantage principal de cette méthode (et peut-être même le seul avantage), c'est que vous n'avez aucun composant externe à brancher au Nucleo.

Cette option n'est pas applicable à tous les projets, pour différentes raisons:  vous mesurez la température à l'intérieur du microcontrôleur, qui peut être sensiblement plus élevée que la température environnante, il n'est pas toujours possible de placer la totalité de votre carte Nucleo là où vous désirez connaître la température (dans un liquide, par exemple...), la résolution de 1,5°C peut être insuffisante pour ce que vous désirez faire...

Mais l'inconvénient majeur, c'est que pour fournir la température en degrés Celsius, chaque STM32 doit être individuellement calibré.  En d'autres mots, un script qui permet à votre carte Nucleo de lire la température avec une précision raisonnable pourra donner des résultats catastrophique sur une autre carte Nucleo!

Puisque le capteur de température est une caractéristique de l'ADC (convertisseur analogique/numérique) du STM32, vous lisez sa valeur exactement comme vous liriez une entrée analogique conventionnelle.   La seule différence, c'est que vous utilisez la constante "ADC_TEMP" plutôt que le numéro d'une entrée analogique.

Là où les choses se compliquent, c'est que cette lecture sera un nombre proportionnel à la température, situé entre 0 et 1,0 (0 à 100% de 3,3 V), et non une température en degrés Celsius.  Il faut donc faire une conversion.  (Notez que plus la température est élevée, plus la tension mesurée est faible, ce qui est quelque peu contre-intuitif.)

Le tableau ci-dessous provient de la fiche technique du STM32F030R8 (j'ai utilisé la carte NUCLEO-F030R8).


On y constate que la tension mesurée par mon Nucleo lorsque la température est de 30°C  peut prendre n'importe quelle valeur entre 1,34 V et 1,52 V (ça varie d'un exemplaire à l'autre).  De plus, pour chaque variation de température de 1 °C, la tension mesurée varie typiquement de 4,0 mV à 4,6 mV.

Si je connais ceux deux valeurs avec une précision raisonnable, c'est relativement facile de convertir la tension mesurée en degrés Celsius:


Supposons que j'ai mesuré 0,445, ce qui correspond à 1,47 V (44,5% de 3,3 V).  Si les caractéristique de mon Nucleo correspondent à la colonne "typique", la tension à 30°C est de 1,43 V, et la pente moyenne est de 4,3 mV/°C, ce qui donne une température de 20,7°C.


...mais si vous mesurez la même valeur de 1,47 V avec un Nucleo dont la tension à 30°C est de 1,34 V et la pente moyenne de 4,0 mV/°C, ça représente une température de -2,5°C:


...et si vous mesurez toujours 1,47 V, mais avec un Nucleo dont la tension à 30°C est de 1,52 V et la pente moyenne de 4,6 mV/°C, la température est plutôt de 40,9°C:


Conclusion:  pas question d'utiliser une simple approximation tirée de la fiche technique!  Vous devez connaître les paramètres précis de votre carte Nucleo!

Notez que, lors de la fabrication du microcontrôleur, la tension mesurée à 30°C (TS_CAL1) est enregistrée en mémoire.  Certains modèles de STM32 (mais pas mon F030R8) comportent aussi la température à 110°C (TS_CAL2).  L'utilisation de ces valeurs permettrait une mesure beaucoup plus fiable.   Cette méthode est inapplicable dans le cas de mon Nucleo F030R8:  connaître uniquement la valeur précise de la tension à 30°C est insuffisante pour me permettre de faire la conversion.

Je me suis donc résigné à produire une courbe d'étalonnage.  Pour ce faire, j'ai enfermé mon Nucleo et un thermomètre dans un même récipient de plastique fermé hermétiquement, que j'ai placé quelques minutes au congélateur. J'ai ensuite compilé la mesure brute du Nucléo et la température du thermomètre pendant que le contenu du récipient reprenait progressivement la température normale de la pièce.

À partir du graphique, on peut trouver une valeur raisonnablement précise pour la pente moyenne et la tension à 30°C (ou procéder autrement afin de convertir les données brutes en Celsius).

Ceci étant dit, tout ça me semble inutilement compliqué lorsqu'on considère qu'on peut se procurer un capteur de température déjà calibré en °C, facile à utiliser et pas cher du tout.

Voici quand même un script mbed qui affiche la valeur brute mesurée, pour ensuite la convertir en volts, puis en degrés Celsius (en supposant que connaissez la valeur exacte de la tension à 30°C et de la pente moyenne (Avg_slope):




Tout est beaucoup plus simple avec les 3 méthodes suivantes...

Méthode 2: le capteur de température DS18B20

Difficile de trouver des inconvénients au capteur DS18B20 de Maxim, qui peut mesurer des températures entre -55°C et +125°C, avec une résolution de l'ordre d'un demi degré.  Les connexions sont simples:

Vcc du DS18B20:  sortie 3V3 de la carte Nucleo
Data du DS18B20:  entrée A0 de la carte Nucleo*
GND du DS18B20:  GND de la carte Nucleo

Mais attention:  une résistance de 4,7 k doit obligatoirement être branchée entre la pin Vcc et la pin Data du DS18B20.

*:  Le DS18B20 étant un capteur numérique, l'entrée A0 est ici utilisée comme entrée numérique plutôt que comme entrée analogique.  Vous pouvez utiliser n'importe quelle autre entrée du Nucleo en modifiant légèrement le script proposé ci-dessous.

Si votre DS18B20 se trouve à l'intérieur d'une sonde hermétiquement fermée, Vcc est le fil rouge, GND est le fil noir, et Data est l'autre fil.


Ensuite, dans le compilateur mbed, vous pouvez importer le programme d'exemple réalisés par Erik Olieman.  Pour ce faire, vous pouvez cliquer sur le bouton "import", sélectionner l'onglet "Programs" et faire une recherche pour "ds18b20".  Vous pouvez alors sélectionner "DS1820_HelloWorld" par Erik Olieman (c'était le premier choix de la liste quand je l'ai fait).


Le Nucleo transmet à l'ordinateur, par communication série,  la température mesurée:


(c'était une chaude journée d'été, sans climatisation...)

Méthode 3: le capteur de pression BMP180

Même si le capteur BMP180 sert surtout à mesurer la pression atmosphérique, il mesure également la température.  Tout est déjà expliqué dans cet article sur l'utilisation du BMP180 avec la carte Nucleo.

Méthode 4:  le capteur de température LM35

Le capteur LM35 est analogique:  sa tension de sortie est proportionnelle à la température en degrés Celsius (10 mV par degré Celsius).  (Dans cette configuration simple, toutefois, il ne peut pas mesurer de températures plus basses que 2°C).  Tout comme le DS18B20, le LM35 comporte 3 fils:

Vcc du LM35:  sortie 3V3 de la carte Nucleo
Vout du LM35:  entrée A0 de la carte Nucleo
GND du LM35:  GND de la carte Nucleo

Si le signal en provenance du LM35 est acheminé par un câble de quelques dizaines de centimètres ou plus, le bruit pourrait être un problème (forte oscillation du signal mesuré).  Un condensateur placé entre Vout et GND devrait pouvoir atténuer ces fluctuations.





Yves Pelletier   (TwitterFacebook)
Related Posts Plugin for WordPress, Blogger...