vendredi 12 janvier 2018

Télémètre ultrasonore HC-SR04 et MPLAB Xpress Evaluation Board

Aujourd'hui, je vous explique comment procéder pour mesurer la distance d'un obstacle au moyen d'un télémètre HC-SR04 branché à une carte de développement MPLAB Xpress Evaluation Board de la compagnie Microchip.  La distance mesurée sera transmise à un ordinateur par communication série (via USB).

Même si j'ai utilisé une carte MPLAB Xpress Evaluation Board de première génération (celle qui est munie d'un microcontrôleur PIC 16F18855), je suppose que cet article pourrait vous être utile même si vous utilisez un autre microcontrôleur PIC.

Le module HC-SR04 est un sonar: lorsque sa broche "Trig" est brièvement soumise à un signal logique haut, une brève impulsion ultrasonore est émise.  La broche "Echo" prend ensuite l'état logique haut pendant une durée égale à la durée du trajet aller-retour de l'ultrason.  Si on connaît la vitesse du son (environ 340 m/s), on peut  utiliser cette durée pour calculer la distance qui sépare le module HC-SR04 de l'obstacle qui a réfléchi l'impulsion ultrasonore.  (Dans d'autres articles de ce blog, je vous indique comment utiliser un HC-SR04 avec un Arduino, un Raspberry Pi, un STM32 Nucleo et un ATTiny: ce n'est pas le choix qui manque...).

Connexions

Le module HC-SR04 est branché à la carte de la façon suivante:

Broche Vcc du HC-SR04 : sortie 5V du MPLAB Xpress Evaluation Board
Broche Trig du HC-SR04: broche RC5 du MPLAB Xpress Evaluation Board
Broche Echo du HC-SR04: broche RC6 du MPLAB Xpress Evaluation Board
Broche Gnd du HC-SR04: broche GND du MPLAB Xpress Evaluation Board



À moins que j'aie interprété la fiche technique de travers, les entrées du 16F18855 tolèrent les tensions de 5 V; je n'ai donc pas jugé utile d'abaisser le signal de sortie du HC-SR04 (broche "Echo") avant de l'acheminer à la carte.

Configuration avec MCC

Nous allons maintenant créer un nouveau projet dans l'IDE en ligne MPLAB Xpress, puis effectuer quelques configurations au moyen du MPLAB Xpress Code Configurator (si vous n'êtes pas familiers avec ces deux outils, je vous réfère à cet article).

Tout d'abord, dans le "System Module" de MCC, les valeurs par défaut "HFINTOSC" avec une fréquence d'horloge de 4_MHz sont tout à fait appropriés, mais il faut régler l'option "Clock Divider" à la valeur 1.



Nous aurons besoin de communiquer par UART et de chronométrer la durée de l'impulsion produite par le HC-SR04.  Dans la liste "Device Resources", nous allons donc choisir "EUSART" et "TMR1", qui vont ensuite apparaître dans la zone "Project Resources".

Réglages des paramètres de l'EUSART:  il faut cocher les cases "Enable Transmit" et "Redirect STDIO to USART".  La valeur par défaut des autres paramètres devrait être correcte.


Les changements à effectuer dans les paramètres du timer sont assez nombreux: d'abord, régler "Clock Source" à FOSC. Ensuite, cocher les cases "Enable Gate" et "Enable Gate Single-Pulse Mode", puis régler "Gate Polarity" à high.

Il est bon de régler "Timer Period" à une valeur se situant entre le maximum et le minimum indiqués (en fait, cette valeur ne semble avoir aucun effet sur le fonctionnement de notre programme, mais MCC vous affichera un message d'erreur si vous laisser ce champ à une valeur qui ne se situe pas dans la plage admise).


Dans la grille où on retrouve plusieurs petits cadenas, il faut décocher le cadenas qui lie par défaut RC6 au TX de l'EUSART, puisque nous voulons utiliser cette entrée pour une autre fonction (l'icône devrait devenir un cadenas ouvert).  Nous cliquons RC0 pour le TX de l'EUSART, et RC1 pour le RX de l'EUSART (ces deux broches sont liées à l'USB de la carte MPLAB Xpress Evaluation Board).

Réglez RC5 comme GPIO output, et liez RC6 au timer (TMR1 - T1G input).


Finalement, dans "Pin Module", rebaptisez la broche RC5 "Trig_pin" et décochez la case "Analog" qui lui a été attribuée par défaut.


Maintenant que la configuration est terminée, il ne faut pas oublier de cliquer sur le bouton "Generate" afin que les fichiers soient crées dans notre projet MPLAB Xpress.

Script

Voici le code à placer dans le fichier "main.c" de votre projet.




Il s'agit de démarrer sur votre ordinateur un logiciel de communication série (j'ai utilisé le moniteur série de l'IDE Arduino), et de déplacer un obstacle devant le module HC-SR04 pour voir la distance en centimètres s'afficher à l'écran.



Yves Pelletier   (TwitterFacebook)


vendredi 5 janvier 2018

Distinguer un signal analogique d'un signal numérique

Voilà un concept qui peut être nébuleux pour les néophytes: quelle est la différence entre un signal analogique et un signal numérique?

Signal numérique

Un signal numérique (certains disent "digital", mais c'est en anglais) est une tension qui ne peut prendre que deux valeurs: une valeur haute et une valeur basse.

Le schéma ci-contre illustre un circuit numérique simple: selon l'état de l'interrupteur (ouvert ou fermé), la tension du point A peut prendre deux valeurs possibles:  0 V ou 6 V.  C'est tout.  La tension n'est jamais de 4 V ou de 2,657 V; il n'y a que deux états possibles: 0 V ou 6 V.


Les sorties d'une carte Arduino sont des sorties numériques: votre programme peut régler une sortie pour qu'elle soit à 0 V (niveau logique bas) ou à 5 V (niveau logique haut), mais il ne peut pas régler la sortie à 4 V, ou à 2,657 V.   Il n'existe que deux possibilités: 0 V ou 5 V.  C'est le même principe pour le Raspberry Pi: ses sorties peuvent être à 0 V ou à 3,3 V, et rien d'autre.

Ces deux états logiques peuvent être désignés de différentes façons:   haut / bas, vrai / faux, oui / non, 0 / 1...


Signal analogique

Contrairement au signal numérique, un signal analogique est une tension qui peut prendre une infinité de valeurs possibles.  Dans le schéma ci-contre, en tournant le bouton du potentiomètre, vous pouvez faire en sorte que la tension au point A prenne n'importe quelle valeur entre 0 V et 6 V: elle peut être de 1,579 V, ou encore 3,03947 V, etc.  De plus, lorsque vous tournez le bouton du potentiomètre, la tension varie de façon continue et non par bonds.  Pour aller de 0 V à 6 V, vous devrez nécessairement passer par toutes les valeurs situées entre 0 V et 6 V.  Un signal analogique varie de façon continue.



Combiner plusieurs signaux numériques

Un signal numérique ne peut donc prendre que deux valeurs (on parle de valeur binaire)...mais peut-on malgré tout exprimer un plus grand nombre de valeurs différentes de façon numérique?  Oui: en combinant plusieurs valeurs binaires.

Le schéma ci-contre illustre un circuit numérique à 2 bits.  Même si les points A et B ne peuvent prendre que deux états possibles (0 V ou 6 V), l'ensemble du circuit peut prendre 4 états possibles:
  • A à 0 V et B à 0 V
  • A à 0 V et B à 6 V
  • A à 6 V et B à 0 V
  • A à 6 V et B à 6 V
Mathématiquement, on peut exprimer ces 4 états par les nombres binaires 00, 01, 10, et 11.

En ajoutant un troisième interrupteur, on obtient un circuit numérique à 3 bits.  Il s'agit bien d'un circuit numérique: partout dans le circuit, la tension ne peut être que de 0 V ou 6 V.

Ce circuit à 3 bits peut prendre 8 états possibles:

  • A à 0 V, B à 0 V, C à 0 V  (nombre binaire 000)
  • A à 0 V, B à 0 V, C à 6 V (nombre binaire 001)
  • A à 0 V, B à 6 V, C à 0 V (nombre binaire 010)
  • A à 0 V, B à 6 V, C à 6 V (nombre binaire 011)
  • A à 6 V, B à 0 V, C à 0 V (nombre binaire 100)
  • A à 6 V, B à 0 V, C à 6 V (nombre binaire 101)
  • A à 6 V, B à 6 V, C à 0 V (nombre binaire 110)
  • A à 6 V, B à 6 V, C à 6 V (nombre binaire 111)
Le nombre d'états possibles peut être calculé de cette façon:
  • circuit à 1 bit: 21 = 2 états possibles
  • circuit à 2 bits: 22 = 4 états possibles
  • circuit à 3 bits: 23 = 8 états possibles
  • circuit à 4 bits: 24 = 16 états possibles
  • circuit à n bits: 2n états possibles


Transmission parallèle / transmission série


Le circuit numérique à 3 bits représenté plus haut comporte 3 sorties (une pour chaque bit) et nécessitera donc 3 conducteurs distincts pour transmettre l'information.  C'est un exemple de transmission parallèle.

Si vous avez déjà eu l'occasion d'interfacer un afficheur LCD de type Hitachi HD44780 à une carte Arduino, vous avez appliqué ce principe:  l'afficheur comporte 8 connecteurs permettant de transmettre des données à 8 bits de façon parallèle.  En général, on préfère toutefois le mode 4 bits, qui accapare moins de sorties sur notre Arduino.  Sur l'illustration ci-dessous, les sorties 2, 3, 4 et 5 de l'Arduino transmettent à l'afficheur un signal à 4 bit en mode parallèle.




Revenons à notre circuit à 3 bits constitué de 3 interrupteurs. Plutôt que contrôler 3 bits avec 3 interrupteurs contrôlant 3 sorties différentes, je peux choisir d'utiliser un seul interrupteur et lire la tension au point A à plusieurs moments différents.  Par exemple, si vous appuyez sur l'interrupteur pendant 10 secondes, puis vous le relâchez pendant 10 secondes, et vous l'appuyez à nouveau pendant 10 secondes, vous obtiendrez au point A, en mesurant le signal toutes les 10 secondes: 6 V, 0 V, 6 V, ce qui pourrait correspondre au nombre binaire à 3 bits "101".  (Nous pourrions alors dire que la fréquence d'horloge était de 1/10 de Hz.)

Cette façon de procéder, qui rappelle le bon vieux télégraphe de Samuel Morse, est une transmission série.  Lorsque vous utilisez les broches RX et TX de l'Arduino pour transmettre ou recevoir de l'information, c'est une transmission série.  De nombreux capteurs qu'on branche à l'Arduino transmettent l'information en utilisant les protocole I2C ou SPI: il s'agit également d'une transmission série.


Conversion d'un signal analogique en signal numérique

Le graphique ci-contre représente une tension qui varie de façon sinusoïdale.  Nous voyons qu'il s'agit d'un signal analogique, puisque le signal prend tour à tour toutes les valeurs situées entre 10 V et - 10 V.

Il est possible de numériser ce signal analogique, c'est à dire d'exprimer l'information qu'il contient sous une forme numérique, au moyen d'un convertisseur analogique/numérique.  La résolution de la conversion dépendra du nombre de bits.

Par exemple, si on ne dispose que d'un seul bit, on ne peut utiliser que deux valeurs possibles: on pourrait, par exemple, assigner la valeur 1 à toutes les tensions analogiques positives, et la valeur 0 à toutes les tensions analogiques négatives.  Il en résulterait une résolution de 10 V.  Avec cette faible résolution, la copie numérique ressemble bien peu peu à l'original analogique...


 Avec deux bits, nous disposons de 4 valeurs possibles.  Par exemple: "00" pour les valeurs situées entre - 10 V et - 5 V, "01" pour les valeurs situées entre -5 V et 0 V, "10" pour les valeurs situées entre 0 V et +5 V, et "11" pour les valeurs situées entre 5 V et 10 V.  Il s'agit d'une résolution de 5 V.  C'est déjà un peu plus ressemblant:

Avec trois bits, nous disposons maintenant d'une gamme de 8 valeurs possibles, avec une résolution de 2,5 V.

On constate que plus le nombre de bits est élevé, meilleure est la résolution, et il en résulte une copie numérisée plus fidèle au signal analogique d'origine.

Le convertisseur analogique/numérique de l'Arduino Uno est à 10 bits, ce qui permet de séparer le signal analogique reçu en 210 = 1024 valeurs possibles.  Sur un signal analogique qui peut varier entre 0 et 5 V, il s'agit d'une excellente résolution d'environ 0,005 V!

Mais disposer d'une bonne résolution n'est pas le seul critère à respecter: encore faut-il mesurer le signal analogique suffisamment souvent.  On appelle "fréquence d'échantillonnage" le rythme auquel on convertit les valeurs analogiques en valeur numérique.

Par exemple, pour le signal périodique illustré ci-dessous, vous perdrez beaucoup d'information si vous vous contentez de mesurer la tension au rythme indiqué par les "x" bleus:  à chaque lecture, vous obtiendrez une tension nulle, mais bien des choses se passent à votre insu entre deux lectures consécutives!


Bref, la numérisation d'un signal analogique implique nécessairement une certaine perte d'information, mais cette perte peut être sans conséquences si la résolution et la fréquence d'échantillonnage sont suffisantes.

Tolérance au bruit

Lorsque vous acheminez un signal électrique dans un câble conducteur (peu importe que ce signal soit numérique ou analogique), le câble agit comme une antenne: il capte les ondes électromagnétiques qui sont émises, par exemple, par des stations de radio, par les fils qui constituent l'installation électrique de votre résidence, etc.  Ces ondes électromagnétiques modifient de façon indésirable la tension du fil: c'est ce qu'on appelle du bruit, ou des parasites.  En général, les signaux analogiques sont plus affectés par le bruit que les signaux numériques.

Par exemple:  supposons que votre câble transporte un signal analogique pouvant varier entre 0 et 5 V et que le bruit ajoute ou soustrait une valeur aléatoire pouvant atteindre 0,5 V.  Lorsque la valeur d'entrée est de 2,5 V, vous pouvez donc recevoir à l'autre extrémité du câble de transmission n'importe quelle valeur située entre 2,0 V et 3,0 V!

Supposons maintenant que le même câble de transmission achemine un signal numérique qui se manifeste par une tension d'entrée qui est parfois de 0 V, et parfois de 5 V.  À cause du bruit, le signal qui aurait dû être de 0 V sera peut-être reçu à -0,5 V ou +0,5 V mais, dans les deux cas, il sera interprété comme un niveau logique bas correspondant à 0 V.  De la même façon, le signal de 5 V qui devient, à cause du bruit, 4,5 V ou 5,5 V, sera malgré tout interprété comme un niveau logique haut correspondant à une valeur de 5 V.

Capteurs numériques / capteurs analogiques

Pour que votre Arduino puisse réagir à son environnement, vous devez le munir de capteurs.  Ces capteurs peuvent être analogiques ou numériques.

Par exemple, pour permettre à l'Arduino de savoir s'il fait chaud ou froid, vous pourriez utiliser une thermistance: il s'agit d'un composant dont la résistance dépend fortement de la température ambiante.

La thermistance est un capteur analogique, car elle produit une tension qui varie de façon continue avec la température.  Pour cette raison, on la branche à une entrée analogique de l'Arduino, car le convertisseur analogique/numérique de l'Arduino devra transformer ce signal analogique en une information numérique.

Le capteur de température LM35 est un autre exemple de capteur analogique, car il produit une tension proportionnelle à la température.

Par contre, le capteur de température DS18B20 est un capteur numérique qui utilise le protocole "1-Wire" pour transmettre des signaux série de 9 à 12 bits.    Le MCP9808 est un autre capteur de température numérique, mais il utilise le protocole I2C.

Circuits intégrés analogiques ou numériques

Les circuits intégrés sont souvent classés selon le type analogique ou numérique.

Par exemple, les amplificateurs opérationnels sont des circuits intégrés analogiques car leur tension de sortie peut varier de façon continue en prenant une infinité de valeurs différentes.

Un CD4001, par contre, comporte 4 portes "NON-OU": il s'agit d'un circuit intégré numérique dont les sorties ne peuvent prendre que deux états possibles, en fonction de l'état logique des entrées.

Instruments de mesure analogiques ou numériques


Un multimètre analogique comporte une aiguille dont la position dépend du courant qui circule dans l'appareil.  Si la tension mesurée varie progressivement de 0 à 5 V, l'aiguille passera nécessairement de façon continue par toutes les positions situées entre 0 et 5 V.  La difficulté, toutefois, est dans l'interprétation de sa position par la personne qui prend la mesure.

Le multimètre numérique est beaucoup plus facile à lire, mais il affiche des valeurs discontinues qui dépendent de sa résolution.  On peut améliorer la résolution du multimètre en modifiant son échelle de lecture.  Sur l'échelle "200 V", le multimètre peut mesurer n'importe quelle tension située entre -200 V et +200 V, mais sa résolution sera beaucoup moins bonne que sur l'échelle "2 V", qui le restreint à une plage de valeurs située entre -2V et +2V.

Quiz

Pour terminer, un petit quiz pour vérifier si vous avez bien suivi...

1. On peut régler l'état de la sortie numéro 7 de l'Arduino au moyen de deux commandes:  "digitalWrite(7, HIGH);" qui règle la tension à 5 V, et "digitalWrite(7, LOW);" qui règle la tension à 0 V.  On peut en déduire qu'il s'agit d'une sortie...

 a) ...analogique
 b) ...numérique


2. Lorsque vous lisez la valeur d'une entrée analogique de l'Arduino avec la fonction analogRead, vous obtenez un nombre entier situé entre 0 et 1023 inclusivement.  On peut donc en conclure que le convertisseur analogique-numérique de l'Arduino est à...

 a) 8 bits
 b) 10 bits
 c) 12 bits
 d) 16 bits
 e) 32 bits


3.  Ce graphique de la tension en fonction du temps représente un signal...


 a) ...analogique
 b) ...numérique

4.  Ce graphique de la tension en fonction du temps représente un signal..;



 a) ...analogique
 b) ...numérique


5. Un capteur numérique produit une tension qui varie proportionnellement avec le paramètre qu'on désire mesurer.

 a) Vrai
 b) Faux


6. Lorsqu'on veut mesurer une tension analogique, on utilise un voltmètre analogique.  Si on veut mesurer un signal numérique, il faut alors utiliser un voltmètre numérique.

 a) Vrai
 b) Faux




(Cliquez sur le bouton "Valider" pour vérifier vos réponses)

Yves Pelletier   (TwitterFacebook)

dimanche 31 décembre 2017

Horloge temps réel (RTC) DS3231 et STM32 Nucleo


Le billet d'aujourd'hui pourrait vous être utile si vous travaillez sur un projet dans lequel il est important que votre carte STM32 Nucleo ait en tout temps accès à l'heure et/ou à la date.

Une horloge temps réel (RTC pour Real Time Clock) est un circuit intégré spécialement conçu à cette fin.  Un avantage de ce genre de dispositif, c'est que, grâce à une petite pile d'appoint, il peut continuer de maintenir l'heure correcte même pendant que le Nucleo n'est pas alimenté.

Le modèle DS3231 est tout à fait approprié, puisqu'il fonctionne très bien avec un niveau logique de 3,3 V.

La photographie ci-dessous montre le module DS3231 que je me suis procuré sur eBay (il en existe d'autres versions que vous devriez pouvoir utiliser sans problème même si elles ne sont pas rigoureusement identiques à celle-ci).

En plus du circuit intégré DS3231, le module comporte deux résistances pull-up de 4,3 kΩ pour la connexion I2C (nous n'aurons donc pas besoin d'en ajouter nous-mêmes) et un condensateur dont le rôle est de stabiliser l'alimentation.


L'autre côté comporte 5 connecteurs femelles pour la liaison avec la carte Nucleo, et un espace prévu pour la pile d'appoint.



Votre modèle comporte peut-être un support pour y insérer la pile, mais le miens n'en comportait pas, et j'ai dû en bricoler un en soudant deux fils sur les connecteurs prévus à cet effet, que j'ai reliés à la pile au moyen d'un peu de ruban gommé...  (attention de respecter la polarité:  le fil rouge va sur la borne positive de la pile).



Le circuit

On branche le module DS3231 à la carte Nucleo de la façon suivante:

  • "+" du DS3231:  "3V3" du Nucleo
  • "D" du DS3231: "SDA/D14" du Nucleo
  • "C" du DS3231: "SCL/D15" du Nucleo
  • "NC" du DS3231:  pas branchée
  • "-" du DS3231:  "GND" du Nucleo

(le connecteur "NC", inutile pour une carte Nucleo, est présent pour faciliter le branchement du module sur les GPIO du Rasbperry Pi)


Script et bibliothèque

Pour piloter le DS3231, j'ai utilisé une bibliothèque et un programme d'exemple proposés sur mbed par nul autre que Maxim Integrated, fabriquant du DS3231.  On peut aussi accéder à ce script dans la section "Import" du compilateur mbed, en faisant une recherche pour "DS3231demo".  


Vous pouvez tester ce script avec un logiciel de communication série comme Putty ou le moniteur série de l'IDE Arduino.  On vous demande d'abord la date et l'heure, afin de régler le DS3231 (vous pouvez évidemment effacer cette partie si votre DS3231 est déjà réglé à la bonne heure).  Ensuite, la date et l'heure sont affichés dans différents formats, chaque seconde.



Il sera facile de modifier ce script pour qu'il réponde à vos besoins.

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