dimanche 26 janvier 2014

Mesurer la capacité d'un condensateur avec un Arduino Uno...et rien d'autre

Jonathan Nethercott a publié sur son blog "PIC Tutorials" un sketch permettant de mesurer la capacité d'un condensateur en le branchant à un Arduino.

Utiliser un microcontrôleur pour mesurer une capacité n'a peut-être rien de révolutionnaire, mais une particularité de la présente méthode, c'est qu'aucun composant supplémentaire n'est requis: vous branchez le condensateur dans les entrées A0 et A2, et sa capacité s'affiche dans le moniteur série.

Dans sa version la plus récente (25 janvier 2014),. le sketch de Jonathan Nethercott utilise deux méthodes différentes pour mesurer la capacité, ce qui lui permet de couvrir une gamme allant de  1 pF à plus de 1000 uF!

La première méthode consiste à mesurer la tension du condensateur alors qu'il est branché en série avec la capacité parasite de l'Arduino, ce qui donne des résultats satisfaisants à la condition que la capacité ne soit pas trop grande.  Puisque la capacité interne n'est pas identique d'un Arduino à l'autre, vous devez faire des tests au moyen d'un condensateur de valeur connue afin calibrer le dispositif (il s'agit de modifier la valeur de la constante IN_STRAY_CAP_TO_GND).

Si le résultat est supérieur à 1 nF (auquel cas la capacité du condensateur à tester est trop grande par rapport à l'étalon), l'Arduino prend une deuxième mesure en chargeant le condensateur à travers la résistance de tirage (pull-up) interne du microcontrôleur, de façon à déterminer la constante de temps du circuit RC. Encore une fois, il est nécessaire d'effectuer une calibration à partir d'un condensateur dont la capacité est connue, puisque la valeur exacte de la résistance pull-up interne peut être différente d'un Arduino à l'autre (il faut modifier la valeur de la constante R_PULLUP).

Je l'ai essayé, et ça fonctionne remarquablement bien:  simple et efficace!

Yves Pelletier (Twitter:  @ElectroAmateur)

samedi 25 janvier 2014

Boutons sans rebond (bascules de Schmitt)

Supposons que vous désirez allumer et éteindre une LED au moyen d'un seul bouton poussoir:  la LED s'allumera si vous appuyez sur le bouton, et s'éteindra lorsque vous appuierez à nouveau sur le même bouton.

Toutefois, lors de la mise à l'essai de votre circuit, vous constatez que la LED réagit de façon aléatoire à vos commandes:  une fois sur deux, il ne se passe rien lorsque vous appuyez sur le bouton!

La raison:  votre bouton poussoir rebondit à la manière d'un ballon de basket.  Pendant une fraction de seconde, l'interrupteur se met successivement en état "fermé" et "ouvert" plusieurs fois de suite... Même si vous n'avez appuyé qu'une seule fois sur le bouton, le reste du circuit a reçu plusieurs signaux consécutifs en provenance de l'interrupteur.

Si votre bouton poussoir est relié à un microcontrôleur (Arduino, par exemple), la solution anti-rebond généralement préconisée est purement logicielle:  lorsque le microcontrôleur détecte que le bouton est pressé, on le fait attendre quelques dizaines de millisecondes, le temps que les rebonds soient terminés (voir le sketch fourni avec l'IDE Arduino:  Fichier - Exemples - 02.Digital - Debounce).

Mais je n'aime pas trop cette solution:  elle alourdit le code, et pour des raisons qui demeurent nébuleuses, je n'obtiens pas toujours des résultats impeccables lorsque je l'applique.  De plus, on n'a pas le choix de procéder autrement si le bouton actionne autre chose qu'un microcontrôleur (une bascule, par exemple).

Pour toutes ces raisons, j'ai assemblé un module comportant 6 boutons munis d'un circuit anti-rebond.  Chaque bouton est associé à un condensateur de 10 nanofarads et à une résistance de tirage ("pull up") de 10 kΩ.

Lorsque le bouton n'est pas enfoncé, aucun courant ne peut circuler dans la résistance et cette dernière n'est donc soumise à aucune différence de potentiel; le condensateur est chargé, puisqu'il est soumis à une différence de potentiel de 5 V (le signal de sortie est de 5 V).   Lorsqu'on appuie sur le bouton, le signal de sortie chute à 0, mais pas instantanément, car le condensateur doit d'abord se décharger.  Lors d'un rebond du bouton, le contact est trop bref pour que le condensateur ait le temps de se décharger et le signal de sortie n'a pas le temps de descendre à zéro.

Un problème demeure:  nous voulons quand même obtenir à la sortie un signal logique qui passe brusquement de 5 V à 0 V, et non un signal qui varie progressivement de 5 V à 0 V (la courbe de décharge est de forme exponentielle).  La solution:  une bascule de Schmitt.  Aussi longtemps que le signal de sortie du bouton est supérieur à un certain seuil, la sortie de la bascule de Schmitt sera à 0 V.  Et la sortie de la bascule de Schmitt passera soudainement à 5 V lorsque le signal de sortie du bouton descendra en-dessous du seuil.  De plus, la bascule de Schmitt est munie d'une hystérésis:  le seuil d'un signal décroissant est plus bas que celui d'un signal montant, pour éviter qu'un signal d'entrée très rapproché du seuil cause une instabilité à la sortie.

dimanche 19 janvier 2014

Modules RF 433 MHz, VirtualWire et Arduino

N.B.: Puisque la bibliothèque VirtualWire n'est plus mise à jour par son auteur, vous préférerez peut-être consulter cet article plus récent, dans lequel on utilise la bibliothèque RadioHead.

Aujourd'hui, je vous présente quelques expérimentations réalisées avec un émetteur et un récepteur radiofréquence à 433 MHz obtenus sur eBay pour un prix ridiculement bas (on parle d'environ 1 euro pour une paire émetteur/récepteur).

Contrairement aux modules NRF24L01 2,4 GHz (qui coûtent à peine plus cher mais sont plus sophistiqués), ces modules ne permettent qu'une communication unidirectionnelle:  l'émetteur peut envoyer un message au récepteur, mais ce dernier ne peut pas envoyer de réponse à l'émetteur, ne serait-ce que pour confirmer que le message a bel et bien été reçu (une communication bidirectionnelle est toutefois possible si vous disposez de deux paires émetteur-récepteur).

L'émetteur

Il est de forme carrée et porte les numéros XY-FST et FS1000A.  Il est muni de 3 pins: DATA transmettra les données à émettre et sera branché à la sortie 12 de votre Arduino.  Sans trop de surprise, vous branchez la pin "VCC" au 5 volts de l'Arduino et la pin "GND" à une des pins "GND" de l'Arduino.

Une connexion identifiée "ANT" vous permet de souder une antenne à votre émetteur.  Cette antenne n'est pas indispensable si votre émetteur est à proximité du récepteur.

Quelques tests m'ont permis de constater qu'en absence d'antenne, un nombre assez important de données émises n'atteignent pas le récepteur à partir d'une distance d'environ 2 m.

En ajoutant une antenne de 17 cm à l'émetteur et au récepteur, la portée atteint facilement une dizaine de mètres.

Le récepteur

Le récepteur est de forme rectangulaire et porte le numéro "XY-MK-5V".  Pour une raison qui m'échappe il est muni de 4 pins mais d'après ce que j'ai constaté les deux pins centrales identifiées "DATA" sont identiques et interchangeables.  Vous reliez donc une de ces deux pins "DATA" à l'entrée 11 d'un deuxième Arduino (ce deuxième Arduino peut très bien être branché au même ordinateur que l'Arduino qui contrôle l'émetteur).

Encore une fois, vous branchez la pin "VCC" du récepteur à la pin 5 V de l'Arduino, et vous reliez les masses (GND).

La bibliothèque VirtualWire

Assurez-vous d'installer la bibliothèque VirtualWire, qui va énormément nous simplifier la vie lors de la conception des sketches.

Les exemples qui accompagnent la bibliothèque VirtualWire montrent qu'il est très facile d'envoyer des chaînes de caractères de l'émetteur vers le récepteur (message du genre "Hello World").  Mais il est souvent beaucoup plus utile et pertinent d'émettre des valeurs numériques (des données provenant d'un capteur, par exemple) .  La lecture du blog Generic Nerd de Markus Ulfberg m'a rappelé l'importance des fonctions atoi et itoa pour transformer un nombre entier en chaîne de caractères et inversement.


Premier test:  envoi et réception de nombres croissants

Cette première paire de sketches est bien utile pour vérifier le bon fonctionnement de notre paire émetteur/récepteur:  plutôt qu'envoyer sans cesse le même message, l'Arduino émetteur envoi des nombres entiers en ordre croissants, et l'Arduino récepteur les affiche dans le moniteur série.   Vous pouvez donc vérifier si la totalité des  messages émis par l'émetteur sont bel et bien reçus par le récepteur.

/******************************************************
* Envoi de nombres croissants par l'entremise de VirtualWire
* Sketch de l'émetteur (branché à la pin 12, par défaut).
* http://electroniqueamateur.blogspot.com/2014/01/modules-rf-433-mhz-virtualwire-et.html
******************************************************/
#include <VirtualWire.h>
int Nombre = 0;
char Message[VW_MAX_MESSAGE_LEN];
void setup() {
vw_setup(2000); // Bits par seconde
}
void loop() {
Nombre++;
// Conversion du int en tableau de chars
itoa(Nombre,Message,10); // 10 car décimal
vw_send((uint8_t *)Message, strlen(Message));
vw_wait_tx(); // On attend la fin de la transmission
delay(200); // et on se repose un peu...
}

/**************************************************************
* Affiche sur le moniteur serie le nombre entier reçu.
* Sketch du récepteur (branché à la pin 11, par défaut).
* http://electroniqueamateur.blogspot.com/2014/01/modules-rf-433-mhz-virtualwire-et.html
***************************************************************/
#include <VirtualWire.h>
int Nombre;
char Message[VW_MAX_MESSAGE_LEN];
void setup() {
Serial.begin(9600);
vw_setup(2000); // Bits par seconde
vw_rx_start();
}
void loop(){
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen))
{
int i;
for (i = 0; i < buflen; i++)
{
Message[i] = char(buf[i]);
}
Message[buflen] = '\0';
// Conversion du tableau de chars en int:
Nombre = atoi(Message);
Serial.print("Message recu: ");
Serial.println(Nombre);
}
}

Deuxième test:  contrôle à distance de la luminosité d'une LED au moyen d'un potentiomètre

Cette fois, un potentiomètre est branché à l'entrée A0 de l'Arduino émetteur, et une LED (accompagnée de sa résistance de protection) est branchée à la sortie 5 de l'Arduino.  L'émetteur envoie l'état du potentiomètre (entier entre 0 et 1023) et le récepteur utilise cette valeur pour contrôler la luminosité de la LED par PWM (la valeur doit toutefois être divisée par 4, puisque analogWrite accepte un paramètre entre 0 et 255).