samedi 2 juillet 2016

Un clignotant d'Audi !

Juste pour le plaisir et après m'être fait doubler en voiture par un exemplaire du dernier modèle d'Audi TT, voici un clignotant d'Audi dernière génération ! Pour ceux qui l'ignorent, ces clignotants "dynamiques" sont composés de DEL dont la lumière paraît défiler dans la direction indiquée par le clignotant...


  • Mise en œuvre :

N'ayant toujours pas de résistances appropriées pour le moment, j'ai utilisé les 560 Ω habituelles. Comme le nombre de DEL était plus élevé que d'habitude, je les ai branchées en parallèle sur une sortie 5 V de l'Arduino, pour ensuite les relier à des broches digitales en entrée, ce qui inverse alors le fonctionnement du digitalWrite(pin, state) : l'état LOW allume la DEL, l'état HIGH l'éteint.


Schéma du montage :




  • Code Arduino :

#define pin1 6  // Constantes préprocesseur.
#define pin2 7
#define pin3 8
#define pin4 9
#define pin5 10
#define pin6 11
#define pin7 12

void setup()
{

  pinMode(pin1, OUTPUT); // Broches fixées en sorties.
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
  pinMode(pin5, OUTPUT);
  pinMode(pin6, OUTPUT);
  pinMode(pin7, OUTPUT);

  resetLED();            // Appel à l'extinction des DEL.

}

void loop()
{

  delay(500);              // Pause.

  digitalWrite(pin1, LOW); // Allumage DEL 1.
  delay(75);

  digitalWrite(pin2, LOW); // Allumage DEL 2.
  delay(75);

  digitalWrite(pin3, LOW); // Allumage DEL 3.
  delay(75);

  digitalWrite(pin4, LOW); // Allumage DEL 4.
  delay(75);

  digitalWrite(pin5, LOW); // Allumage DEL 5.
  delay(75);

  digitalWrite(pin6, LOW); // Allumage DEL 6.
  delay(75);

  digitalWrite(pin7, LOW); // Allumage DEL 7.
  delay(500);

  resetLED();              // Appel à l'extinction des DEL.

}

void resetLED() // Fonction d'extinction des DEL.
{

  digitalWrite(pin1, HIGH);
  digitalWrite(pin2, HIGH);
  digitalWrite(pin3, HIGH);
  digitalWrite(pin4, HIGH);
  digitalWrite(pin5, HIGH);
  digitalWrite(pin6, HIGH);
  digitalWrite(pin7, HIGH);

}


Rien d'extraordinaire ici, mis à part l'inversement de la manière de fonctionner du digitalWrite(pin, state) comme précisé plus haut.


Rendu final approximatif :



mardi 21 juin 2016

Télémètre à ultrasons

Après avoir récupéré un module télémètre à ultrasons HC-SR04 sans réel besoin, je me suis dit que ça pouvait être sympa d'apprendre à m'en servir histoire de bricoler un peu ! Ce petit module a un fonctionnement tout bête : émission d'ultrasons par le capteur de sortie, rebond des ultrasons émis sur un objet, réception des ultrasons réfléchis par le capteur d'entrée, calcul de la distance à partir de la vitesse du son et du temps entre l'émission et la réception.

Le module HC-SR04 :



  • Caractéristiques du module :
La fiche de référence de ce module nous indique qu'il fonctionne avec une tension d'entrée de 5 V, nécessite 15 mA, possède une portée minimale de 2 cm et maximale de 4 m, et que le calcul de distance se fait comme suit :

distance (cm) = temps de réponse (µs) / 58

ou pour les anglo-saxons :

distance (po) = temps de réponse (µs) / 148

Le module possède quatre broches : Vcc (alimentation 5 V), Trig (émetteur), Echo (récepteur), GND (terre).


  • Mise en œuvre  :
Le module nécessitant 5 V et 15 mA pour fonctionner, elle peut très bien être utilisée telle quelle sur la plupart des cartes Arduino, ici une Nano, grâce aux broches pouvant délivrer jusqu'à 40 mA et sa broche 5 V.


Schéma du montage :


Photo du montage en action :



  • Code Arduino :
#define pinTrig 2 // Broche pour l'émission.
#define pinEcho 3 // Broche pour la réception.

unsigned short t; // Temps de réponse (µs).
unsigned short d; // Distance à mesurer (cm).

void setup()
{

  pinMode(pinTrig, OUTPUT);   // Broche pinTrig fixée en sortie.
  pinMode(pinEcho, INPUT);    // Broche pinEcho fixée en entrée.

  digitalWrite(pinTrig, LOW); // On n'envoie rien pour l'instant.

  Serial.begin(9600);         // Débit en bauds pour le terminal.

}

void loop()
{

  digitalWrite(pinTrig, HIGH); // Envoi d'un signal...

  delayMicroseconds(10);       // Pendant 10 µs.

  digitalWrite(pinTrig, LOW);  // Arrêt du signal.

  t = pulseIn(pinEcho, HIGH);  // Mesure du temps écoulé.

  d = t / 58;                  // Calcul de la distance.

  Serial.print("Distance : "); // Affichage dans la console.
  Serial.print(d);
  Serial.println(" cm.");

  delay(1000);                 // Pause d'une seconde.

}

Ce type de télémètre est très facile à utiliser et peut servir pour construire un robot autonome, un détecteur d'ouverture/fermeture, etc. Ce petit module ne paye pas de mine, mais permet tout de même de mesurer des distances comprises entre 2 et 400 cm, avec pour ma part un décalage de -3 cm par rapport à la réalité, petit écart simple à corriger avec une soustraction.

mardi 10 mai 2016

Contrôler des servomoteurs avec un joystick grâce à Arduino

Pour les besoins d'un petit projet qui me trotte dans la tête depuis un moment, j'ai décidé de voir comment fonctionnent les servomoteurs avec Arduino. Je me suis donc procuré deux petits servomoteurs d'aéromodélisme afin de commencer à bricoler avec.


Un servomoteur :



Ces deux servomoteurs sont des SG90, nécessitant une tension d'alimentation de 5 V et un signal d'entrée PWM pour fonctionner. Trois broches y sont connectées : alimentation (fil orange), terre (fil marron), et signal (fil jaune). Ils peuvent faire pivoter leur axe de +/- 90° par rapport à leur position initiale.


Les positions du servomoteur :
 


De plus, je me suis également procuré un joystick analogique deux axes afin de pouvoir contrôler les servomoteurs.

Le joystick : 



Ce joystick fonctionne également avec une tension d'alimentation de 5 V, et transmet des valeurs analogiques variant entre 0 et 1 023 inclus. Il est également équipé d'un bouton-poussoir, actionné lorsque l'on appuie sur le stick. Cinq broches y sont connectées : alimentation, axe X, axe Y, bouton-poussoir, terre.

L'idée de ce petit montage est simple : bouger le joystick en axe X fait réagir le servomoteur 1, bouger le joystick en axe Y fait réagir le servomoteur 2, et ces deux actions sont bien sûr combinables.

Schéma du montage : 



Photo du montage : 



Il ne reste plus qu'à s'occuper du plus intéressant : le code du programme ! Afin de me faciliter le travail et de ne pas réinventer la roue, j'ai utilisé la bibliothèque logicielle Servo.h, fournie par défaut avec l'environnement de développement Arduino, qui permet d'utiliser l'objet Servo, représentant un servomoteur. Une fois cet objet créé, deux méthodes seront utilisées : S.attach(P), qui permet d'utiliser le servomoteur S sur la broche P, et S.write(N), qui permet d'indiquer la valeur N de l'angle que doit prendre le servomoteur S.

Malheureusement, un problème s'est rapidement présenté : comment faire correspondre les valeurs analogiques reçues par le joystick en valeurs PWM utilisables par les servomoteurs ? Ou plus simplement : comment faire correspondre la plage de valeurs [0 ; 1 023] à la plage de valeurs [0 ; 180] ? 

Il a donc fallu fixer quelques constantes : la position initiale d'un axe du joystick (environ 512) correspondra à la position initiale du servomoteur (90°) ; la position 0 d'un axe du joystick correspondra à un angle de 180° ; la position 1 023 d'un axe du joystick correspondra à un angle de 0°. Chaque valeur d'angle sera obtenue à partir d'une valeur du joystick grâce à une fonction affine de la forme y = a x + b ; on obtient alors le système d'équations suivant, à résoudre :

{ 180 = 0 x + b
{ 0 = 1 023 a + b


{ b = 180
{ 1 023 a + 180 = 0


{ b = 180
{ a = -180 / 1 023


{ a ≈ -0,175953
{ b = 180

On obtient alors la fonction à utiliser pour transformer les valeurs du joystick en valeurs pour les servomoteurs : f(x) = -0,175953 x + 180, ce qui permet de finaliser le code.

  • Code Arduino : 
#include <Servo.h> // Utilisation de la bibliothèque Servo.h.

#define pinJx A0 // Broche pour l'axe X du joystick.
#define pinJy A1 // Broche pour l'axe Y du joystick.
#define pinSx 9  // Broche pour le signal du servomoteur X.
#define pinSy 10 // Broche pour le signal du servomoteur Y.

unsigned short X, Y; // Variables pour les valeurs du joystick.
Servo Sx, Sy;        // Déclaration de deux objets Servo.

void setup()
{
  
  pinMode(pinSx, OUTPUT); // Broches fixées en sortie.
  pinMode(pinSy, OUTPUT);
  
  Sx.attach(pinSx); // Correspondance broche/servomoteur.
  Sy.attach(pinSy);
  
  Sx.write(90); // Mouvement du servomoteur en position initiale.
  Sy.write(90);
  
}

void loop()
{

  X = analogRead(pinJx); // Lecture des valeurs du joystick.
  Y = analogRead(pinJy);
  
  Sx.write(joyToServo(X)); // Envoi des signaux de rotation.
  Sy.write(joyToServo(Y));

}

byte joyToServo(unsigned short n) // Fonction de correspondance.
{
  
  return (byte)(-0.175953 * n + 180); // f(x) calculée précédemment.
  
}

Une fois encore, ce code ne contient aucune difficulté particulière. J'ai pris soin d'utiliser des types de variables correspondant le plus possible aux valeurs qu'elles sont supposées prendre : les valeurs du joystick variant entre 0 et 1 023 inclus, j'ai utilisé pour les stocker un unsigned short, dont les valeurs utilisables varient entre 0 et 65 535 (entre - 32 768 et 32 767 pour un short signé). Même chose pour les valeurs d'angle : celles-ci variant entre 0 et 180, j'ai utilisé un byte, dont les valeurs utilisables varient entre 0 et 255 (le byte est d'office non-signé).

jeudi 31 mars 2016

Faire clignoter une DEL avec Arduino

Ce qui est sympa avec les cartes Arduino, c'est qu'il ne s'écoule que très peu de temps entre le déballage de la carte et les premiers montages, mais ça peut également être problématique si l'on ne prend pas le temps de faire les choses correctement !

Pour ma part, je suis en 4ème année d'école d'informatique et je n'ai pas étudié d'électronique depuis ma première année de classe préparatoire PCSI en 2010, donc autant dire que mes souvenirs sont plutôt flous... Heureusement que j'ai un ami ingénieur en génie électrique patient et prêt à m'aider. :)

Du coup reprise des bases avec loi d'Ohm, loi des mailles, etc. pour me remettre au point et éviter de détruire une nouvelle carte, et je propose ici une petite mise en application calculée et détaillée pour faire clignoter une DEL avec une Arduino Nano.

  • Caractéristiques de la carte :
Le site officiel Arduino nous indique que les broches digitales de la Nano délivrent une tension de 5 V et peuvent fournir du courant jusqu'à 40 mA.

  • Caractéristiques de la DEL :
Une DEL verte de 5 mm de diamètre récupérée dans mon bazar dont je ne connais pas les propriétés... Toutefois, si je me renseigne un peu sur ce type de DEL, on devine une tension de seuil entre 2,2 et 2,5 V, et une intensité minimale nécessaire de 10 mA

  • Calcul de la résistance à utiliser :
En choisissant une tension de seuil pour la DEL à 2,3 V et sachant que les broches de la Nano délivrent 5 V, on applique une petite méthode des mailles :

UNano = UDEL + Urésistance ⇔ Urésistance = UNano - UDEL = 5 - 2,3 = 2,7 V

On applique maintenant la loi d'Ohm :

Urésistance = R * I ⇔ R = Urésistance / I = 2,7 / 0,010 = 270 Ω

On sait donc que pour que la DEL soit traversée par un courant de 5 V et 10 mA, il faut placer une résistance de 270 Ω avec elle en série.

  • Mise en œuvre :
N'ayant à disposition que des résistances de 560 Ω pour l'instant, je vais en utiliser une à la place de celle de 270 Ω. L'intensité du courant sera alors réduite et la DEL clignotera plus faiblement.

Ceci peut également être vérifié par le calcul avec la loi d'Ohm :

Urésistance = R * I ⇔ I = Urésistance / R = 2,7 / 560 = 0,005 A = 5 mA

En utilisant une résistance de 560 Ω, l'intensité du courant vaudra 5 mA, une valeur bien inférieure aux 40 mA que peuvent fournir les broches, et donc sans danger pour la Nano.

Schéma du montage :


Photo du montage en action :


  • Code Arduino :
#define pinLed 2 // Constante préprocesseur.

void setup()

{
  
  pinMode(pinLed, OUTPUT); // Broche pinLed fixée en sortie.

}


void loop()

{
  
  digitalWrite(pinLed, HIGH); // La DEL s'allume...
  
  delay(500);                 // Pendant 500 ms...
  
  digitalWrite(pinLed, LOW);  // Puis s'éteint...
  
  delay(500);                 // Pendant 500 ms..

}

Rien d'exceptionnel pour ce code : déclaration d'une constante préprocesseur pinLed valant 2 correspondant à la broche digitale 2, déclaration de cette broche en sortie, puis clignotement avec délai.

Enfin voilà, si tout va bien la DEL clignote maintenant !

Cet exemple a été fait et refait un bon paquet de fois sur Internet, mais là c'était mon tour, et je tenais à faire ça calculs à l'appui et non pas en prenant des valeurs au hasard.


  • Mise à jour du 13/07/2016 :
C'est avec le temps qu'on apprend, et comme du temps s'est écoulé depuis la publication de cet article, je peux y apporter une légère modification : les deux digitalWrite(pin, state) de la fonction loop() peuvent être remplacés par une même ligne comme dans le morceau de code suivant.

void loop()
{

  digitalWrite(pinLed, !digitalRead(pinLed));

  delay(500);

}

Pour apporter quelques explications : on garde la fonction digitalWrite(pin, state) ainsi que notre pinLed, mais le state est remplacé par ce !digitalRead(pinLed). Ce dernier terme permet de prendre l'inverse (!) de l'état actuel (digitalRead(pin)) de la broche indiquée (pinLed), ce qui en langage humain devient "change l'état actuel de la broche pour son opposé", ce qui effectue le travail demandé pour moitié moins d'expressions !

Problème de driver...

Apparemment j'ai parlé trop vite à propos de mes cartes qui n'ont pas besoin de driver pour fonctionner... 

Après les mises à jour de Windows 10 d'hier, les drivers de mes cartes ont été supprimés et ne se sont pas réinstallés automatiquement, il a donc fallu que je creuse un peu pour les retrouver.

D'après le gestionnaire de périphériques, le driver "USB-SERIAL CH340" n'était pas installé, je l'ai donc retrouvé après quelques recherches, et il est téléchargeable ici.

Pour l'installer, il suffit de lancer SETUP.EXE, puis de sélectionner "CH341SER.INF" dans la liste déroulante, et enfin de cliquer sur le bouton INSTALL.



L'installation est presque immédiate, et ne nécessite pas de redémarrage pour que les cartes fonctionnent de nouveau, même s'il faut éventuellement les rebrancher.

Tout est bien qui finit bien. :)

mercredi 30 mars 2016

Mes cartes Arduino-like

Après avoir détruit mon Raspberry Pi B+, j'étais un peu réticent à retenter quelque chose en électronique, surtout avec des cartes de développement à une quinzaine d'euros...


C'est pourquoi j'ai préféré me rabattre sur des copies d'Arduino, dont la conception matérielle et logicielle est en licence libre, ce qui a amené d'autres constructeurs à créer leurs propres cartes de développement, plus ou moins fidèles aux originales (parfois médiocres, parfois meilleures !), mais toujours bien moins chères, dans les 5 euros pièce.



Du coup j'ai commandé en février dernier deux copies d'Arduino sur Deal eXtreme : une copie d'Arduino Nano et une copie d'Arduino Uno, que je nommerai juste "Nano" et "Uno" par commodité.



La Nano : 


La Uno : 


Comme sur les cartes Arduino officielles correspondantes, ces cartes sont équipées d'un processeur ATmega 328P, et sont 100 % compatibles avec l'environnement de développement Arduino.



Le ATmega 328P sur la Nano : 


Le ATmega 328P sur la Uno : 


Après un mois d'attente, je reçois mon colis de Chine et commence à tout brancher et à tester. Contrairement à ce que je craignais, aucun driver particulier n'a été nécessaire pour faire fonctionner mes cartes sur mon Windows 10 Familial.


Maintenant que j'ai de quoi faire, je n'ai plus qu'à poster ici quelques schémas et morceaux de codes... :)

mardi 29 mars 2016

De retour avec Arduino !

Me revoilà après un peu plus d'un an d'absence !


Je n'ai toujours pas pris le temps de me reprendre un Raspberry Pi, d'autant plus que de nouvelles versions sortent régulièrement, et que je n'en ai plus trop l'intérêt en ce moment.



En revanche, désirant plus tard travailler sur des systèmes embarqués, je me suis mis à l'électronique avec les cartes Arduino, et je m'amuse bien !



Du coup j'essaierai de poster quelques trucs sur ce blog : photos, montages, tutoriels, etc., histoire de m'encourager à bricoler un peu !