From 2473ab19aad73e276e62ab42f33465c629ca4c8a Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Sun, 23 Feb 2020 10:07:48 +0100 Subject: Reorganisation en chapiter --- chapters/alimentation.rst | 140 ++++++ chapters/c.rst | 170 +++++++ chapters/input.rst | 357 ++++++++++++++ chapters/output.rst | 702 ++++++++++++++++++++++++++ notes_arduino.rst | 1198 +-------------------------------------------- 5 files changed, 1380 insertions(+), 1187 deletions(-) create mode 100644 chapters/alimentation.rst create mode 100644 chapters/c.rst create mode 100644 chapters/input.rst create mode 100644 chapters/output.rst diff --git a/chapters/alimentation.rst b/chapters/alimentation.rst new file mode 100644 index 0000000..ec3ea5f --- /dev/null +++ b/chapters/alimentation.rst @@ -0,0 +1,140 @@ +.. -*- mode: rst -*- +.. -*- coding: utf-8 -*- + +.. default-role:: literal +.. role:: smallcaps +.. role:: index + +USB +=== + +L'|usb| fourni une tension de 5 |V| avec une intensité maximale de 100 |mA| sur +les bornes d'alimentation. Il est donc possible d'alimenter une carte Arduino +avec un câble |usb| (c'est d'ailleurs ainsi que l'on procède lorsque l'on +programme la carte). + +Source externe +============== + +.. sidebar:: Régulateur LM1117 + + .. image:: content/LM1117.jpg + :align: center + :width: 75% + +La carte Arduino possède un régulateur de tension intégré capable de produire +une tension de 5 |V|. Il est donc possible d'alimenter la carte avec une +tension supérieure pour alimenter le circuit. + +.. note:: + + La régulation de la tension est réalisée en convertissant la puissance + superflue en chaleur. Si la tension est trop importante, le composant va trop + chauffer et la carte va s'abîmer. + + De même, le régulateur consomme également du courant en fonctionnement, + donner une tension de 5 |V| sera trop juste pour alimenter le circuit. + + Aussi, la tension recommandée pour un bon fonctionnement est comprise entre 7 + à 12 |V|. + +.. sidebar:: Attention au sens ! + + En inversant le sens des fils entre la masse et l'alimentation, on applique + l'opposé de la tension attendue, ce qui ne plaira pas beaucoup au circuit ! + [#]_ + +.. [#] https://www.rugged-circuits.com/10-ways-to-destroy-an-arduino + +Il existe deux points de connexions sur la carte permettant d'utiliser le +régulateur de tension : la prise jack, ainsi que la borne `Vin`. + +Alimentation via prise jack +--------------------------- + +Il s'agit de la manière la plus simple pour alimenter le circuit, puisque la +carte Arduino possède une prise Jack. En respectant les limites des tensions +indiquées ci-dessus, il ne reste qu'à brancher la fiche sur la carte. + +Dans le cas d'un transformateur externe, il faut veiller à ce que symbole suivant + +.. image:: content/polarity.pdf + :width: 25% + :align: center + +soit présent sur la carte : c'est à dire que le fil `+` soit connecée au centre +de la borne d'alimentation. + +Alimentation directe sur la carte +--------------------------------- + +La borne `Vin` permet de connecter directement une alimentation à la carte : +elle est également reliée au régulateur de tension et supporte donc une tension +supérieure jusque 12 |V|. + +Là encore, il faut veiller à connecter les deux fils sur les bonnes bornes : la +carte Arduino n'offre aucune protection en cas d'erreur… + +Alimentation externe 5 |V| +========================== + +.. note:: + + Cette solution peut être utilisée si la tension d'entrée est supérieure à + 12 |V| : l'utilisation d'un régulateur de tension externe tel que le `LM7805` + permettra de prendre en entrée une tension jusqu'à 20 |V|. + +Si la tension externe est déjà stabilisée à 5 |V|, il n'est pas possible de se +connecter sur la broche `Vin` de la carte, puisqu'il faut au minimum du 7 |V| +pour avoir une tension de fonctionnement correcte. + +Alimentation par usb +-------------------- + +.. sidebar:: Cable + + .. image :: content/USB-2-0-B-MALE-TO-5.jpg + :width: 100% + +La solution la plus sûre dans ce cas est de brancher cette alimentation sur +l'entrée |usb| de la carte. On gagne ainsi en sécurité, au détriment d'un petit +peu de cablage supplémentaire. + +Alimentation par la broche 5V +----------------------------- + +Autre solution envisageable, brancher l'alimentation directement sur la broche +`5V` de la carte Arduino : cette borne est reliée au circuit 5 |V| de la carte, +et n'est pas uniquement une borne de sortie : elle relie l'ensemble des +composants qui ont besoin d'être alimentés avec cette tension. + +.. admonition:: Attention + :class: warning + + Alimenter la carte par la prise `5V` de la carte n'est pas recommandé : + + - Étant donné que l'on passe outre le régulateur de tension, il y a un risque + important de griller la carte si l'on applique une tension trop importante. + - Il interdit d'utiliser en même temps la prise |usb| + - Il interdit d'utiliser en même temps la prise `Vin` sous risque de griller + la carte + +En effet, cette prise est directement reliée au circuit 5 |V| et outrepasse +**toutes** les protections de la carte, qui n'est pas prévue pour être +alimentée ainsi. Il faut réserver cet usage a des cas particuliers (par exemple +alimenter deux cartes Arduino ensemble) + +Tableau récapitulatif +===================== + +Les différentes tensions admissibles : + +================ =============== =============== ============== +Entrée Tension min. Tension max. Intensité max. +================ =============== =============== ============== +Port USB 4,5 |V| 5,5 |V| +Broche `5V` 4,5 |V| 5,5 |V| +Prise jack 7 |V| 12 |V| +Broche `Vin` 6,6 |V| 12 |V| +================ =============== =============== ============== + diff --git a/chapters/c.rst b/chapters/c.rst new file mode 100644 index 0000000..2948db4 --- /dev/null +++ b/chapters/c.rst @@ -0,0 +1,170 @@ +.. -*- mode: rst -*- +.. -*- coding: utf-8 -*- + +.. role:: raw-latex(raw) + :format: latex + +La carte Arduino se programme en langage C. + +Les types +========= + +La carte Arduino (ou l'ordinateur), ne comprend que le binaire, mais nous +n'allons pas écrire nos programme en binaire. Nous avons besoin de manipuler +des nombres pour calculer des délais, mesurer des températures etc. Nous avons +besoin d'indiquer au programme comment ces données binaires doivent être +chargée en mémoire pour pouvoir travailler avec. + +Chaque type occupe une certaine quantité d'octets en mémoire, en fonction de la +donnée, et de ce que l'on peut faire avec. Plus la taille mémoire est grande, +meilleure sera la précision de la valeur (ou la liste des valeurs possibles etc). + +L'instruction :index:`sizeof` `sizeof` [#]_ permet de calculer la taille +d'une variable, elle est utile dans le cas où l'on souhaite faire des calculs +directement sur la mémoire de l'arduino. + +.. [#] https://www.arduino.cc/reference/en/language/variables/utilities/sizeof/ + +Les booléens +------------ + +.. sidebar:: Boole + + L'adjectif booléen vient du nom du mathématicien George Boole qui a travaillé + sur la logique et catégorisé ce type qui ne peut prendre que deux valeurs. + +Le type booléen représente une valeur binaire `1` ou `0`, ou encore *Oui* ou +*Non*. Nous l'avons vu quand nous avons utilisé les valeurs `HIGH` ou `LOW` sur +les sorties de la carte Arduino. + +.. code-block:: c + + /* Crée une variable qui servira à savoir s'il faut mettre à + jour les données. + */ + bool mettre_a_jour = true; + if (mettre_a_jour) { + /* fait la mise à jour, puis passe l'indicateur à false + pour éviter de le faire une deuxième fois. + */ + mettre_a_jour = false; + } + +Opérations sur les booléens +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Il existe trois opérations principales que l'on peut retrouver sur les booléens +et qui permettent de construire la logique du programme. + +:et: + + Le *et* (`&&` [#]_ :index:`&&`) permet d'associer deux booléens entre eux, et + donne un résultat qui est lui-même booléen, et vaut `true` si les deux sont à + `true`. + +.. [#] https://www.arduino.cc/reference/en/language/structure/boolean-operators/logicaland/ + +:ou: + + Le *ou* (`||` [#]_ :raw-latex:`\index{\textbar{} \textbar{}}\marginpar{\texttt{||}}`) permet d'associer deux booléens entre eux, et + donne un résultat qui est lui-même booléen, et vaut `true` si l'un ou l'autre + est à `true`. + +.. [#] https://www.arduino.cc/reference/en/language/structure/boolean-operators/logicalor/ + +:non: + + Le *non* (`!` [#]_ :raw-latex:`\index{"!}\marginpar{\texttt{!}}`) permet d'inverser la valeur d'un booléen + +.. [#] https://www.arduino.cc/reference/en/language/structure/boolean-operators/logicalnot/ + +.. note:: + + Ces opérateurs peuvent se combiner entre eux pour réaliser, on les retrouve + dans les tests de condition pour faire des tests évolués. Par exemple, pour + mettre à jour l'affichage si la température a changé, ou si la pression a + changé, ou s'il s'est écoulé plus d'une heure depuis la dernière mise à jour… + +Les nombres entiers +------------------- + +Les nombres entiers permettent de représenter des nombres entre deux bornes. +Ils peuvent être signés (prendre une valeur négative) ou non. + +En fonction de la taille occupée en mémoire, les types auront des plages de +valeurs possibles plus ou moins importantes : + +=============== =============== ================ =============== +Type Valeur Minimale Valeur Maximale Taille mémoire +=============== =============== ================ =============== +`byte` 0 256 1 +`int` -32 768 32 767 2 +`unsigned int` 0 65 536 2 +`long` -2 147 483 647 2 147 483 647 4 +`unsigned long` 0 4 294 967 295 4 +=============== =============== ================ =============== + +.. admonition:: Attention + :class: warning + + Si jamais la valeur dépasse la limite, aucune erreur ne sera remontée par + l'application, mais la valeur va repartir à 0 ! + +Les nombres flottants +--------------------- + +Les nombres flottants peuvent représenter des nombres décimaux, avec toutes les +valeurs possibles. Cela se fait au prix d'une plus grande consommation de la +mémoire, et d'une approximation de la valeur. + + +Comparer deux nombres flottants +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Il n'est pas possible de comparer directement deux nombres flottants +différents, car la probabilité d'avoir exactement deux fois la même valeur est +quasiment nulle. Il faut utiliser une méthode de ce type, qui permet de +comparer les deux nombres avec une marge d'erreur : + +.. code-block:: C + + bool Equality(float a, float b, float epsilon) + { + return fabs(a - b) < epsilon; + } + +Ce code utilise la valeur absolue de la différence des nombres `a` et `b` +:index:`fabs` pour comparer ce résultat avec le delta. + +Les tableaux +------------ + +Les tableaux permettent de représenter une *série* de donnée d'un même type. + +Le texte +-------- + +Le texte est représenté par le type `char` qui peut stocker un caratère. C'est +pourquoi on utilise souvent des tableaux de caratères qui permettent de stocker +des mots. + +Formatter du texte +~~~~~~~~~~~~~~~~~~ + +.. code-block:: C + + char str[80]; + sprintf(str, "Value of Pi = %f", M_PI); + + +Pour les nombres flottants, il faut d'abord convertir le nombre en texte : + +.. code-block:: C + + char str_temp[6]; + + /* 4 is mininum width, 2 is precision; float value is copied + onto str_temp*/ + dtostrf(temp, 4, 2, str_temp); + sprintf(temperature,"%s F", str_temp); + diff --git a/chapters/input.rst b/chapters/input.rst new file mode 100644 index 0000000..f298c7a --- /dev/null +++ b/chapters/input.rst @@ -0,0 +1,357 @@ +.. -*- mode: rst -*- +.. -*- coding: utf-8 -*- + +Maintenant que nous avons vu comment contrôler les sorties de la carte Arduino, +il est temps de se poser la question d'utiliser les entrées de la carte : c'est +par ce moyen que nous allons pouvoir donner un peu de réaction à notre robot, à +travers des capteurs qui nous fournirons des informations sur le monde +extérieur. + +Utiliser Arduino comme ohmmètre +=============================== + +Lecture de la tension +--------------------- + +Il existe six ports sur la carte Arduino permettant de lire des valeurs +analogiques (`A0` — `A5`). + +Par exemple, la tension peut être lue le port `A0` sur avec l'instruction +:index:`analogRead` `analogRead(A0)` [#]_. Celle-ci est lue sur dix bits (soit +une valeur comprise entre `0` et `1023`), en fonction de la tension +d'alimentation de la carte Arduino (normalement 5 |V|). + +.. [#] https://www.arduino.cc/en/Reference/AnalogRead + +.. raw:: latex + + \begin{center} + \begin{tikzpicture}[scale=2.5] + + \foreach \x in {0,0.5,...,5} { + \pgfmathtruncatemacro\result{\x * 1023 / 5} + \draw (\x,-4pt) -- (\x,4pt) + node [below,yshift=-20] {\pgfmathprintnumber{\result}} + node [above] {$\x$ V}; + } + + \draw (0,0) -- (5.0,0); + + \end{tikzpicture} + \end{center} + +.. note:: + + Lors de l'écriture sur un port analogique, la précision est réalisée sur huit + bits (soit une valeur comprise entre `0` et `255`). Attention donc en + redirigeant l'entrée d'un port vers une sortie ! + +On peut donc utiliser la carte comme un voltmètre simple, pour mesurer une +tension entre 0 |V| et la tension d'alimentation (5 |V|). La formule suivante +permet de calculer la tension en fonction de la valeur retournée par la +fonction `AnalogRead` : + +.. math:: + + V = \frac{5 \times \mathtt{AnalogRead()}}{1023} + +Utiliser l'Arduino comme ohmmètre +--------------------------------- + +Notre premier montage pour illustrer la lecture d'une valeur consiste à +utiliser l'Arduino pour connaître la valeur d'une résistance. Nous allons +utiliser un *pont diviseur* (voir le schéma) avec une résistance connue, et une +autre dont on souhaitera déterminer la valeur : en lisant la tension +:math:`V_A`, il sera possible de déterminer la valeur de la résistance +inconnue. + +.. figure:: content/pont_diviseur.pdf + :width: 50% + :align: center + + Le pont diviseur + + + La plus simple représentation du diviseur de tension consiste à placer deux + résistances électriques en série. Ce type d'association de résistances étant + omniprésent dans les montages électriques, le pont diviseur en devient une des + notions fondamentales en électronique. + + + Il est possible de calculer facilement la valeur de :math:`V_A` dans le + montage, à la condition de connaitre les valeurs des résistances et la valeur + de la tension Vcc. La première formule à utiliser est celle de la loi d'Ohm qui + permet de citer cette équation : + + .. math:: + + I = \frac{V_\text{cc}}{R_1+R_2} + + En utilisant la loi d'Ohm une seconde fois, il est possible de déterminer + l'équation suivante: + + .. math:: + + V_a = R_2 \times I + + Dans la formule ci-dessous, il suffit de remplacer le courant :math:`I` par + sa valeur équivalente (la première équation) pour déterminer facilement + l'équation de :math:`V_A`: + + .. math:: + + V_a = R_2 \times (\frac{V_\text{cc}}{R_1+R_2}) + + **Exemple** + + Prenons les valeurs suivantes : + + - :math:`V_\text{cc}`: 9V + - :math:`R_1`: 1k :math:`\Omega` + - :math:`R_2`: 3k :math:`\Omega` + + .. math:: + + V_a &= R_2 \times \frac{V_\text{cc}}{R_1 + R_2} \\ + &= 3000 \times \frac{9}{1000+3000} \\ + & = \frac{27000}{4000} \\ + &= 6.75V + + La différence de potentiel :math:`V_A` sera égal à 6.75 |V| en utilisant les valeurs + précédentes. + +Dans notre cas, nous connaissons la tension ainsi que la valeur de la +résistance :math:`R_2`. Donc en reprenant la formule du calcul de :math:`V_A` +nous obtenons : + +.. math:: + + %V_a &= R_2 \times \frac{V_\text{cc}}{R_1 + R_2} \\ + %(R_1 + R_2) \times V_a &= R_2 \times V_\text{cc} \\ + %R_1 \times V_a + R_2 \times V_a &= R_2 \times V_\text{cc} \\ + %R_1 \times V_a &= R_2 \times V_\text{cc} - R_2 \times V_a \\ + %R_1 &= \frac{R_2 \times V_\text{cc}}{V_a} - \frac{R_2 \times V_a}{V_a} \\ + %R_1 &= \frac{R_2 \times V_\text{cc}}{V_a} - R_2 \\ + %R_1 &= R_2 \times \left(\frac{V_\text{cc}}{V_a} - 1\right) \\ + R_1 &= R_2 \times \left(\frac{1023}{\mathtt{AnalogRead()}} - 1\right) + +.. .. note:: +.. +.. +.. La dernière ligne du calcul peut se retrouver ainsi : on sait que la tension +.. lue par fonction `analogRead()` est échelonée de `0` à `1023` par rapport à +.. la tension d'alimentation, ce que l'on peut représenter dans la ligne +.. suivante : +.. +.. .. math:: +.. +.. V_A &= \frac{V_\text{cc} \times \mathtt{AnalogRead()}}{1023} && \text{donc} \\ +.. \frac{V_\text{cc}}{V_A} &= \frac{V_\text{cc}}{\frac{V_\text{cc} \times \mathtt{AnalogRead()}}{1023}} \\ +.. \frac{V_\text{cc}}{V_A} &= V_\text{cc} \times {\frac{1023}{V_\text{cc} \times \mathtt{AnalogRead()}}} \\ +.. \frac{V_\text{cc}}{V_A} &= \frac{1023}{\mathtt{AnalogRead()}} + +Contrôle théorique +~~~~~~~~~~~~~~~~~~ + +Ce programme en python permet de prédire les différentes valeurs qui seront +lues par la carte Arduino. Il reproduit (dans une certaine mesure) les erreurs +d'arrondis qui seront susceptible d'arriver sur la carte lors du calcul des +valeurs : + +.. sidebar:: Programme + + Ce programme va calculer la tension :math:`V_A`, la valeur lue par la fonction + `analogRead`, la valeur de la résistance calculée, et l'intensité qui + traverse les composants. + +.. include:: ../content/ohm.py + :code: python + +.. raw:: latex + + \pagebreak + + +Il permet de construire le tableau de valeurs suivant (avec :math:`R_2` = 1000 +:math:`\Omega`, et :math:`V_\text{cc}` = 5 |V|) : + +.. sidebar:: Tension théorique + + Ce tableau est construit à partir de la différence de potentielle théorique + au niveau de la résistance :math:`R_2`. Les valeurs réelles seront toujours + légèrement différentes lors du montage. + +=================== ================= ============= =================== +Résistance Tension théorique Valeur lue Résistance calculée +=================== ================= ============= =================== +10 :math:`\Omega` 4,95 |V| 1012 10 +220 :math:`\Omega` 4,1 |V| 838 220 +1k :math:`\Omega` 2.5 |V| 511 1 001 +10k :math:`\Omega` 0,45 |V| 93 10 000 +220k :math:`\Omega` 0,02 |V| 4 254 750 +=================== ================= ============= =================== + +Au delà de 220k :math:`\Omega`, la tension qui traverse :math:`R_2` devient si +faible que la valeur lue par la fonction `analogRead` tombe à `0`, ce qui +empêche toute mesure. En prenant une valeur plus importante pour la résistance +:math:`R_2`, la plage d'erreur sera plus faible pour des valeurs plus +importante de :math:`R_1` + +Montage +------- + +Le montage reste simple à mettre en place, il ne nécessite que deux résistances +(dont celle dont on souhaite calculer la valeur). + +.. figure:: content/arduino_ohmetre.pdf + :width: 70% + + Arduino comme ohmmètre + + La résistance :math:`R_1` sera calculée en fonction de la valeur de + :math:`R_2`. + + La résistance :math:`R_2` peut être choisie avec une valeur de + 1000 :math:`\Omega` par défaut, et changée en fonction du besoin. + +Le programme reprend la formule que nous avons calculé ci-dessus, et affiche le +résultat sur la console. + +.. code-block:: arduino + + // La résistance r2 doit être connue et + // renseignée dans le programme + int r2 = ...; + + void setup() { + Serial.begin(9600); + } + + void loop() { + + int r1 = r2 * ((1023 / (float)analogRead(A0)) - 1); + + Serial.print("R1: "); + Serial.println(r1); + + delay(1000);// wait for a second + } + +.. [#] https://www.arduino.cc/en/Serial/Print + +.. note:: + + Nous découvrons à l'occasion de ce programme la librairie `Serial` [#]_ qui + permet d'envoyer des données à l'ordinateur via le port |usb|. Il s'agit d'un + moyen pratique pour transmettre une valeur lue sur la carte. + + Nous pourrions enrichir ce schéma avec une sortie sur un écran |lcd| plutôt + que d'envoyer l'information vers l'ordinateur : nous aurons ainsi un ohmmètre + autonome ! + + +Capteur de proximité infrarouge +=============================== + +Dans un projet de robot mobile, il est nécessaire de tester la présence +d'objets à proximité pour éviter que celui-ci ne percute les obstacles. + +.. sidebar:: Capteur infrarouge + + .. image:: content/Sharp_GP2Y0A21YK.jpg + :align: center + :width: 100% + +Nous retrouvons deux types de senseurs sur les robots : des senseurs +optiques, ou par ultrasons. Le senseur Sharp relève de la première catégorie. +Il permet de détecter la présence d'un objet entre 10 et 80 cm, à partir du +retour de lumière infrarouge. + +Montage général +--------------- + +Le schéma suivant indique comment placer les différents câbles du connecteur +:smallcaps:`JST`. + +.. sidebar:: Condensateur + + Le condensateur présent sur le schéma permet ici de lisser les variations de + la tension. On l'appelle *Condensateur de découplage* [#]_. + +.. [#] https://fr.wikipedia.org/wiki/Condensateur_de_d%C3%A9couplage + +.. figure:: content/capteur_infra.pdf + :width: 100% + + Arduino, `GP2Y0A21YK` + + :Cable Rouge: +5 |V| + :Cable Noir: GND/Masse + :Cable Jaune ou Blanc: Entrée Analogique `A0` + +Tension de sortie +~~~~~~~~~~~~~~~~~ + +.. sidebar:: Tension d'entrée + + Même si le composant supporte une tension allant jusque 7 |V|, il fonctionne de + manière optimale avec des valeurs allant de 4,5 à 5,5 |V|. + +La tension de sortie, sur le fil jaune, nous indique la distance de l'objet. +Celle-ci varie entre 0,5 |V| et 3 |V| selon la distance de l'obstacle [#]_. + +.. [#] http://www.sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y0a21yk_e.pdf + +.. image:: content/gp2y0a21yk_e.pdf + :width: 100% + +.. Mesure de la tension en fonction de la distance + +Exemple +~~~~~~~ + +Ce programme lit l'entrée sur la broche `A0` et allume une |led| si un objet +est détecté à proximité (±20 |cm|) : + +.. code-block:: arduino + + + int ledPin = 9; // LED connected to digital pin 9 + + void setup() {} + + void loop() { + int sensorValue = analogRead(A0); + if (sensorValue < 220) + sensorValue = 0; + + analogWrite(ledPin, sensorValue >> 2); + delay(200); // delay 200 milliseconds + } + +.. Déclencher le capteur sur demande +.. --------------------------------- +.. +.. Plutôt que d'activer le capteur en continu, nous allons modifier le programme +.. pour n'activer la détection d'objets seulement en cas de mouvements du robot +.. (il n'est pas nécessaire de chercher à tester les obstacles si le robot ne se +.. déplace pas). Cela permettra d'augmenter l'autonomie du robot (en contre-partie +.. d'un port digital utilisé). La consommation du composant étant de 30 |mA|, nous +.. pouvons connecter directement la broche à l'Arduino, il sera capable de fournir +.. le courant nécessaire. +.. +.. Le capteur nécessite un délai minimal avant de fournir une valeur fiable. +.. +.. Créer une tension seuil +.. ----------------------- +.. +.. Nous n'avons pas un besoin réel d'évaluer la distance de l'objet, simplement de +.. pouvoir arrêter le robot s'il s'approche trop près d'un objet. Si l'on connaît +.. la distance d'arrêt souhaitée (et donc la tension) avant de construire le +.. robot, nous pouvons paramétrer le seuil de déclenchement de l'alarme, et +.. utiliser une broche digitale au lieu d'une broche analogique. + + +.. -*- mode: rst -*- +.. -*- coding: utf-8 -*- + diff --git a/chapters/output.rst b/chapters/output.rst new file mode 100644 index 0000000..097cef2 --- /dev/null +++ b/chapters/output.rst @@ -0,0 +1,702 @@ +.. -*- mode: rst -*- +.. -*- coding: utf-8 -*- + +Premier programme +================= + +Faire clignoter une |led| est l'une des premières étapes avec Arduino. C'est +aussi une introduction pour comprendre le fonctionnement de la carte. + +Ce premier programme ne nécessite pas de branchement : une |led| est présente +sur la carte et devrait s'allumer automatiquement en lançant le programme. + +Décomposition du programme +-------------------------- + +L'initialisation +~~~~~~~~~~~~~~~~ + +L'initialisation s'exécute seulement au démarrage du programme sur la carte +(et sera de nouveau exécutée si l'on appuie sur le bouton `reset`). + +.. code-block:: arduino + :number-lines: 9 + + // the setup routine runs once when you press reset: + void setup() { + // initialize the digital pin as an output. + pinMode(13, OUTPUT); + } + +Une seule instruction est lancée dans cet extrait : :index:`pinMode` +`pinMode` [#]_. Celle-ci permet d'indiquer au microcontrolleur si la broche +doit être configurée pour envoyer du courant, ou en recevoir. Puisque nous +souhaitons ici allumer une |led|, nous lui passons le paramètre `OUTPUT` en +argument. + +.. [#] https://www.arduino.cc/en/Reference/pinMode + +L'exécution +~~~~~~~~~~~ + +Voici le cœur du programme, ces instructions seront exécutées en boucles, +indéfiniment, tant que la carte sera sous tension. + +.. code-block:: arduino + :number-lines: 15 + + // the loop routine runs over and over again forever: + void loop() { + // turn the LED on (HIGH is the voltage level) + digitalWrite(13, HIGH); + delay(1000); // wait for a second + digitalWrite(13, LOW); + // turn the LED off by making the voltage LOW + delay(1000); // wait for a second + } + +Ce bloc est composé de quatre instructions, qui appellent deux fonctions +différentes. :index:`digitalWrite` `digitalWrite` [#]_ permet d'envoyer ou de +couper le courant sur une broche donnée. Pour allumer la |led|, nous commençons +donc en donnant `HIGH` en paramètre. + +.. [#] https://www.arduino.cc/en/Reference/digitalWrite + +Vient ensuite une instruction permettant de faire une pause dans le programme : +:index:`delay` `delay` [#]_. Cette fonction prend en paramètre la durée de la +pause (en millisecondes, `1000` vaut donc une seconde). + +.. [#] https://www.arduino.cc/en/Reference/delay + +Afin de faire clignoter la |led|, il est nécessaire de l'éteindre ensuite. +C'est pourquoi nous retrouvons l'instruction `digitalWrite`, mais cette fois +avec la valeur `LOW`, suivi d'une nouvelle pause d'une seconde. + +.. sidebar:: digital + + digital signifie *numérique*. Le terme indique une valeur que l'on peut + exprimer en nombre entier (1, 2, 3…). + +Le programme complet +-------------------- + +.. sidebar:: Chargement + + Ce programme est disponible dans l'environnement Arduino dans les exemples : + Basic / Blink + +.. code-block:: arduino + + /* + Blink + Turns on an LED on for one second, then off for one + second, repeatedly. + + This example code is in the public domain. + */ + + // the setup routine runs once when you press reset: + void setup() { + // initialize the digital pin as an output. + pinMode(13, OUTPUT); + } + + // the loop routine runs over and over again forever: + void loop() { + // turn the LED on (HIGH is the voltage level) + digitalWrite(13, HIGH); + delay(1000); // wait for a second + digitalWrite(13, LOW); + // turn the LED off by making the voltage LOW + delay(1000); // wait for a second + } + +Utiliser une led externe +======================== + +.. sidebar:: Une led + + .. image:: content/5mm_Red_LED.jpg + :align: center + :width: 100% + +Suite à ce premier exemple, nous allons maintenant faire évoluer notre +programme pour l'adapter à une |led| que nous allons brancher à la carte. +Puisque nous intégrons un composant externe, nous allons devoir veiller à ce +que celui-ci soit compatible avec l'alimentation de la carte Arduino : certains +composants nécessitent une tension plus importante (par exemple un moteur), +d'autre des tensions plus faibles (au risque de faire griller le composant). + +Le tableau suivant indique la valeur minimale et maximale supportée par +différents types de |led|, ainsi que l'intensité du courant pour la tension +minimale et maximale. + +======= =========== ============== ================ +Taille Couleur Tension (`V`) Intensité (`mA`) +======= =========== ============== ================ +3mm rouge `1.8`-`2.5` `5`-`18` +3mm vert `2.1`-`2.6` `5`-`17.5` +3mm jaune `1.8`-`2.0` `5`-`17.5` +5mm rouge `1.9`-`2.3` `5`-`18` +5mm vert `1.9`-`2.5` `4`-`14` +5mm jaune `1.9`-`2.5` `5`-`15` +======= =========== ============== ================ + +.. sidebar:: Polarisation + + la |led| ne laisse passer le courant que dans un seul sens. C'est pourquoi + les deux broches ne sont pas de la même longueur. La patte la plus courte + doit être branchée sur le pôle `-`. + +.. admonition:: Attention + :class: warning + + La tension de sortie de la carte est de 5 |V|. Or, en lisant le tableau, on + voit bien que les |led|\ s ne supporteront pas cette tension à leur borne, il + est donc nécessaire de mettre en place un système pour réduire la tension + dans les limites de ce qui est acceptable par la |led|. + +Dans notre situation, la tension délivrée par la carte Arduino et le courant +qui traversera la |led| sont stables — la |led| ne modifie pas son comportement +pendant son fonctionnement. Nous pouvons utiliser le schéma le plus simple pour +réduire la tension : *la résistance chutrice*. + +.. figure:: content/cligo_led.pdf + :width: 100% + + Arduino, LED et une résistance + +Calcul de la résistance +----------------------- + +La résistance à placer se calcule de la manière suivante : + +.. math:: + + R = \frac{(U-Ul)}{I} + +.. sidebar:: Valeurs + + :R: Résistance + :U: Tension de l'alimentation + :Ul: Tension de la |led| + :I: Intensité de la |led| + +Dans notre exemple, en prenant l'intensité maximale supportée par la |LED| nous +obtenons le calcul suivant : + +.. math:: + + R &= \frac{(5-2.5)}{0.018} \\ + &= 139\ \Omega + +.. sidebar:: Déjà des calculs ? + + Ce petit calcul peut sembler théorique, toutefois nous en aurons besoin par + la suite, quand il sera nécessaire d'alimenter des composants avec des + tensions différentes que l'alimentation. (Nous aborderons cela plus loin avec + les notions de *Pont diviseur*, ainsi que les *régulateurs de tension*). + +La résistance choisie doit donc avoir une valeur supérieure. En consultant la +série E12 [#]_, on peut choisir la valeur la plus proche (par exemple 220 +:math:`\Omega`). + +.. [#] Série de douze valeurs utilisées dans les composants électroniques : + https://fr.wikipedia.org/wiki/CEI_60063 + +Vérification de l'intensité +--------------------------- + +On sait que : :math:`I = \frac{U}{R}` soit ici : + +.. math:: + + I &= \frac{U-Ul}{R} \\ + &= \frac{5-2.5}{220} \\ + &= 11.36\ mA + +Ce qui est suffisant pour alimenter notre composant. + + +Mise à jour du programme +------------------------ + +Nous pouvons maintenant mettre à jour notre programme. Il s'agit toujours du +même code que celui présenté plus haut avec toutefois une légère différence : +au lieu d'envoyer du courant sur la broche `13`, nous l'envoyons désormais sur +la broche `9`. Il est donc nécessaire de faire quelques modifications au lignes +`12`, `18` et `20`. + +Faire varier la luminosité +========================== + +Il existe 6 ports sur la carte Arduino permettant de faire varier la tension de +sortie : `3`, `5`, `6`, `9`, `10` et `11`. Les autres port permettent seulement +d'envoyer la tension `HIGH` ou `LOW`, c'est-à-dire 5 |V| ou 0 |V|. + +Il est possible d'utiliser la fonction :index:`analogWrite` `analogWrite` [#]_ +sur chacun de ses ports, en envoyant une valeur comprise entre `0` et `255`. + +.. [#] https://www.arduino.cc/en/Reference/AnalogWrite + +.. raw:: latex + + + \begin{center} + \begin{tikzpicture}[scale=2.6] + + \foreach \x in {0,0.5,...,5} { + \pgfmathtruncatemacro\result{\x * 255 / 5} + \draw (\x,-4pt) -- (\x,4pt) + node [below,yshift=-20] {\pgfmathprintnumber{\result}} + node [above] {$\x$V}; + } + + \draw (0,0) -- (5,0); + + \end{tikzpicture} + \end{center} + +.. sidebar:: `PWM` + + La variation de la tension est réalisée via la *modulation de largeur + d'impulsions* [#]_ qui permet de faire varier la tension en faisant varier de + manière très brève la durée pendnant laquelle le courant est émis. + +.. [#] https://fr.wikipedia.org/wiki/Modulation_de_largeur_d'impulsion + +.. note:: + + Les valeurs présentées ici sont des tensions *moyennes*. En envoyant la + valeur `127`, la tension sur la broche sera de 5 |V|, mais pendant une durée + très courte : + + .. raw:: latex + + \begin{tikzpicture} + \draw[help lines] (0,0) grid (7,1); + \draw[thick] (0,0) node[anchor=base east] {0V} -- ++(0,0) + \foreach \x in {1,...,7}{ + -- +(0,1) -- +(0.5,1) -- +(0.5,0) -- ++(1,0) + } -- +(0,.5); + \draw[thick,anchor=north east] (0,1) node {5V}; + \end{tikzpicture} + + Avec la valeur `192` la tension reste à 5 |V| pendant une durée plus longue : + + .. raw:: latex + + \begin{tikzpicture} + \draw[help lines] (0,0) grid (7,1); + \draw[thick] (0,0) node[anchor=south east] {0V} -- ++(0,0) + \foreach \x in {1,...,7}{ + -- +(0,1) -- +(0.75,1) -- +(0.75,0) -- ++(1,0) + } -- +(0,.5); + \draw[thick,anchor=north east] (0,1) node {5V}; + \end{tikzpicture} + + Dans tous les cas, la tension à la sortie de la borne sera de 5 |V|. Il est + toutefois possible de transformer ce signal en une vraie tension linéaire, à + l'aide d'un condensateur supplémentaire [#]_. + +.. [#] https://provideyourown.com/2011/analogwrite-convert-pwm-to-voltage/ + +.. admonition:: Mesure de la tension + :class: exercice + + Avec un multimètre, mesurer la tension en sortie de la borne en fonction de + diverses valeurs. + +Programme +--------- + +.. sidebar:: Ressource limitée ! + + Cette capacité à contrôler la tension de sortie est très intéressante (par + exemple pour demander à un moteur de tourner plus ou moins vite), mais est + limitée à 6 bornes seulement. Il vaut mieux les réserver quand nous avons + besoin d'une sortie analogique. + +.. code-block:: arduino + + // Fade + + // This example shows how to fade an LED on pin 9 + // using the analogWrite() function. + + // This example code is in the public domain. + + int led = 9; // the pin that the LED is attached to + int brightness = 0; // how bright the LED is + int fadeAmount = 5; // how many points to fade the LED by + + // the setup routine runs once when you press reset: + void setup() { + // declare pin 9 to be an output: + pinMode(led, OUTPUT); + } + + // the loop routine runs over and over again forever: + void loop() { + // set the brightness of pin 9: + analogWrite(led, brightness); + + // change the brightness for next time through the loop: + brightness = brightness + fadeAmount; + + // reverse the direction of the fading + // at the ends of the fade: + if (brightness == 0 || brightness == 255) { + fadeAmount = -fadeAmount ; + } + // wait for 30 milliseconds to see the dimming effect + delay(30); + } + + +Générer du son +============== + +.. sidebar:: Un piezzo buzzer + + .. image:: content/piezzo_buzzer.jpg + :align: center + :width: 100% + +Avec un piezzo buzzer il est possible d'ajouter une sortie sonore au programme. +Ceux que l'on trouve dans le commerce supportent une tension allant de 3 à +24 |V|, ce qui permet de brancher le buzzer directement en sortie de la carte. + +Le composant permet de produire du son en fonction de la fréquence du signal de +sortie. + +Il est possible d'utiliser la fonction `digitalWrite` sur une borne pour +produire un beep, mais il est plus intéressant de pouvoir contrôler la +fréquence de sortie. Nous utiliserons pour cela la fonction :index:`tone` +`tone` [#]_. (Cette instruction peut être utilisée sur une sortie numérique, il +n'est donc pas nécessaire de réserver une sortie analogique pour le buzzer.) + +.. [#] https://www.arduino.cc/en/Reference/Tone + +.. sidebar:: Qualité du son + + La fonction `tone` ne sait produire qu'un signal carré, ce qui signifie que + le son n'aura jamais les harmoniques d'un fichier :smallcaps:`mp3` ou + :smallcaps:`wav`. + +.. note:: + + La fonction `tone` n'est pas disponible sur toutes les cartes Arduino. Si + vous utilisez une carte *Gemma* ou *Due* (ou un autre microcontrolleur), la + fonction ne sera pas disponible. + + Dans ce cas, il est possible d'écrire soit même la fonction en utilisant + les instructions `delayMicroseconds` et `digitalWrite`. Dans ce cas la + fréquence des sons ne sera pas garantie, mais le but n'est pas de faire de la + carte Arduino un outil `hi-fi` : + + .. code-block:: arduino + + void tone(int targetPin, long frequency, long length) { + // calculate the delay value between transitions + // 1 second's worth of microseconds, divided by the + // frequency, then split in half since there are two + // phases to each cycle + long delayValue = 1000000/frequency/2; + // calculate the number of cycles for proper timing + // multiply frequency, which is really cycles per + // second, by the number of seconds to get the + // total number of cycles to produce + long numCycles = frequency * length/ 1000; + for (long i=0; i < numCycles; i++) { + // write the buzzer pin high to push out the diaphram + digitalWrite(targetPin,HIGH); + // wait for the calculated delay value + delayMicroseconds(delayValue); + // write the buzzer pin low to pull back the diaphram + digitalWrite(targetPin,LOW); + // wait again or the calculated delay value + delayMicroseconds(delayValue); + } + } + +Par exemple, en connectant le buzzer sur la broche `8`, l'instruction suivante +permettra de jouer un *la* pendant une seconde : + +.. code-block:: arduino + + tone(8, 440, 1000); + +En faisant varier la fréquence ainsi que la durée de chaque note, nous pourrons +ainsi jouer des mélodies (simples). Il est par contre nécessaire de connaître +la fréquence de la note que l'on souhaite jouer. (La table peut être obtenue +facilement sur internet [#]_). + +.. [#] https://fr.wikipedia.org/wiki/Note_de_musique + +.. sidebar:: Codification des notes + + En anglais, chaque note est codée par une lettre de A à G : C pour Do, D pour + Ré, F pour Mi, etc. + +Plutôt que d'écrire directement les fréquence dans le programme, il est plus +simple de coder les notes, et laisser l'application jouer les notes +correspondantes ; la notation anglaise est souvent utilisée. En associant +chaque fréquence à une valeur dans le programme, il devient plus facile +d'écrire la mélodie qui peut être codée en écrivant directement les notes de +musiques ! + +.. admonition:: Exercice + :class: exercice + + Écrire une petite mélodie ! + +Contrôler un moteur +=================== + +Avec ces instructions, il est temps de passer aux choses sérieuses. En +contrôlant les sorties à l'aide de l'instruction `digitalWrite`, nous allons +pouvoir donner du mouvement au robot en lui donant des roues. Mettre en route +un moteur n'est pas difficile, mais nécessite de prendre certaines précautions +avant de connecter notre moteur. + +.. admonition:: Attention + :class: warning + + Ne jamais brancher un moteur directement à la carte Arduino. D'une part parce + que la tension nécessaire pour activer le moteur risque d'être trop + importante pour la carte (dans le meilleur des cas, le moteur ne tournera + pas, dans le pire des cas la carte grillera), mais aussi parce qu'un moteur + fonctionne de la même manière qu'une dynamo : il produit du courant quand il + tourne. Ce courant risque de remonter dans la carte et générer un + court-circuit. + +Pour cette raison, nous utiliserons un contrôleur externe, destiné à nous +éviter de nombreuses complications : le L293D [#]_. Cette puce va nous permettre : + +.. [#] http://www.ti.com/lit/ds/symlink/l293d.pdf [#]_ + +.. [#] Prenez le temps de lire les spécification des composants. Elles sont en + anglais, mais donnent toutes les informations nécessaire pour utiliser + le composant au mieux : les caractéristiques générale, mais également + les cas d'utilisation, les valeurs maximales supportées, les conseils + de branchement etc. + +.. sidebar:: Une puce L293D + + .. image:: content/L293D_Motor_Driver.jpg + :align: center + :width: 100% + +- de protéger la carte Arduino en empêchant les surtensions : il intègre des + diodes de protections et des contrôleurs thermiques pour protéger le circuit. +- de limiter le cablage et les composants à utiliser : le composant supporte + des tensions de fonctionnement allant de 4,5 à 36 |V|, et permettra donc de + délivrer des tensions beaucoup plus puissantes que ce que peut fournir la + carte Arduino. + +.. note:: + + Il est parfaitement possible de contrôler un moteur directement à partir de + la carte Arduino sans utiler ce type de composant, mais nous compliquons + alors le schéma de cablage inutilement. La documentation technique du + composant nous montre comment réaliser le cablage équivalent avec des diodes + et des transitors (un double pont en H). + +En fait, la puce ne permet pas simplement de contrôler un moteur, mais quatre +! (ou alors deux moteurs pouvant tourner dans les deux sens). Cela correspond à +notre robot qui aura deux roues motrices : une seule puce et quelques fils +pourront permettre de faire rouler notre robot et lui faire réaliser quelques +manœuvres. + +.. figure:: content/l293d.pdf + :width: 50% + + L293D + + :EN: Puissance du moteur : permet de contrôler la vitesse de rotation du + moteur en fonction de la tension appliquée à la borne. Cette borne + peut être reliée à une borne analogique de la carte Arduino. + :A: Activation du moteur : permet d'activer le moteur connecté. Ces + bornes sont à relier aux sorties digitales de la carte. + :Y: Sortie à relier aux bornes des moteurs. + :VCC2: Alimentation des moteurs : cette borne est à relier à + l'alimentation générale (36 |V| max.) + :VCC1: Alimentation du composant (5 |V|) : cette borne est à relier à + l'alimentation stabilisée de la carte Arduino. + :ground: Ces bornes sont à relier à la masse + +Montage général +--------------- + +Il y a trois types de bornes sur le composant : celles destinées à être +connectées au moteur (`Y`), celles destinées à la carte Arduino (`EN` et `A`), +et celles qui qui servent à l'alimentation (`VCC`). Comme il est possible de +contrôler plusieurs moteurs, les bornes sont numérotées en fonction du moteur +contrôlé. + +Dans le cas d'un moteur devant tourner dans les deux sens, les bornes `Y` +doivent être connectées aux deux pattes du moteur : en envoyant du courant sur +l'une des deux bornes `A`, il devient possible de faire tourner le moteur dans +un sens ou un autre (le tableau présente l'exemple d'un moteur connecté aux +bornes `1` et `2`, un deuxième moteur pourra être contrôlé de la même manière +en le branchant sur les bornes `3` et `4`) : + +.. sidebar:: frein électromagnétique + + Le moteur génère de l'électricité en tournant (comme une dynamo). En + alimentant le moteur avec l'électricité qu'il produit lui-même, on peut ainsi + freiner le moteur avec sa propre énergie ! + +=========== =========== ============================================= +Tension 1A Tension 2A Résultat +=========== =========== ============================================= +`LOW` `LOW` Arrêt du moteur (frein électromagnétique) +`LOW` `HIGH` Faire tourner le moteur dans un sens +`HIGH` `LOW` Faire tourner le moteur en sens inverse +`HIGH` `HIGH` Arrêt du moteur (frein électromagnétique) +=========== =========== ============================================= + +Voir le schéma de branchement avec deux moteurs contrôlés depuis la carte +Arduino. + +.. figure:: content/arduino_l293d.pdf + :width: 100% + + L293D, Arduino et deux moteurs + + Les cables reliant le L293D à la masse, et l'alimentation des moteurs ne sont + pas représentés. + + :Cable bleu: Marche avant + :Cable vert: Marche arrière + :Cable orange: Puissance du moteur + +.. raw:: latex + + \pagebreak + +Programme +--------- + +.. sidebar:: Valeurs + + Les valeurs ne sont pas choisies par hasard : elles correspondent aux + paramètres des fonctions `digitalWrite` et `analogWrite` ! + +Ce programme n'est pas disponible dans l'environnement Arduino, cette fois nous +allons devoir l'écrire nous même. Afin de simplifier l'écriture, nous allons +définir une fonction `runMotor` qui prendra trois paramètres : + +:motor: Le numéro du moteur à activer, le 1er moteur déclaré aura la numéro `0` +:direction: La direction du moteur, elle peut prendre deux valeurs `HIGH` ou + `LOW` +:speed: La vitesse de rotation, cette valeur peut aller de `0` à `255` + +.. code-block:: arduino + + void runMotor(int motor, int direction, int speed) { + // … + } + + +.. admonition:: Contrôle du moteur + :class: exercice + + Avec la fonction `runMotor`, nous pouvons donner du mouvement au robot. En + donnant des paramètres de sens et de vitesse différents à la roue gauche et + droite le robot se déplacera différement. Donnez les paramètres de la + fonction `runMotor` pour réaliser les actions suivantes : + + - Marche avant + - Marche arrière + - Faire tourner le robot sur lui-même + - Faire un virage serré + - Faire un virage large + - Arrêt complet + +.. ========================= ========================= ========================== +.. Moteur 1 Moteur 2 Effet +.. ========================= ========================= ========================== +.. `runMotor(0, HIGH, 255)` `runMotor(1, HIGH, 255)` Marche avant +.. `runMotor(0, LOW, 255)` `runMotor(1, HIGH, 255)` Tourner sur lui-même +.. `runMotor(0, HIGH, 255)` `runMotor(1, LOW, 255)` Tourner sur lui-même (sens +.. inverse) +.. `runMotor(0, LOW, 255)` `runMotor(1, LOW, 255)` Marche arrière +.. `runMotor(0, LOW, 0)` `runMotor(1, HIGH, 255)` Virage serré +.. `runMotor(0, HIGH, 127)` `runMotor(1, HIGH, 255)` Virage large +.. `runMotor(0, LOW, 0)` `runMotor(1, LOW, 0)` Arrêt complet +.. ========================= ========================= ========================== + +Connecter un écran Nokia 5110 +============================= + +.. sidebar:: L'écran LCD + + .. image:: content/s-l500.jpg + :align: center + :width: 100% + +L'écran Nokia 5110 est un composant de base et peu honéreux (environ 2€) +permettant un affichage depuis la carte Arduino. Il permet un affichage sur une +grille de 84x48 pixels, soit 4 lignes de textes. + +.. admonition:: Tension de fonctionnement + :class: warning + + Le composant fonctionne sous 3,3 |V|, il n'est donc pas recommandé de le + brancher directement sur la carte Arduino (même si certains le font [#]_). + Dans le doute, commencez avec un correcteur de courant. + +.. [#] https://circuitdigest.com/microcontroller-projects/nokia5110-graphical-lcd-arduino-interfacing + +Level shifter 74HC4050N +----------------------- + +Ce composant est *unidirectionnel* et *High to Low* : en alimentant le +composant en 3.3 |V|, nous avons la possibilité de générer une sortie à 3.3 |V| +à partir de la carte Arduino : le composant possède 6 entrées et 6 sorties : à +chaque fois que la tension sur une borne d'entrée est supérieure à la tension +d'alimentation, la sortie correspondante sera activée. + +.. admonition:: Broches non connectées + :class: note + + Deux bornes ne sont pas connectées sur le composants : les bornes `13` et + `16`. Attention au moment du cablage ! + +.. sidebar:: Cablage + + Le cablage sur le composant `74HC4050N` importe peu, tant que chaque entrée + est bien associée à la sortie correspondantes. + +.. figure:: content/nokia_5110.pdf + :width: 100% + + Arduino, Nokia 5110, 74HC4050N + + :Cable Rouge: +3.3 |V| + :Cable Noir: Masse + :Cable Vert: Broche 7 - 3 (SCE) + :Cable Bleu: Broche 6 - 4 (RST) + :Cable Orange: Broche 5 - 5 (D/C) + :Cable Maron: Broches 11 - 6 (DN(MOSI)) + :Cable Cyan: Broche 13 - 7 (SeriaL CLock) + :Cable Mauve: Broche 9 - 8 (LED) + + +Le programme [#]_ + +.. image:: content/nokia_5110_montage.jpg + :width: 100% + + +.. [#] https://learn.sparkfun.com/tutorials/graphic-lcd-hookup-guide + + +.. default-role:: literal +.. role:: smallcaps +.. role:: index +.. |lcd| replace:: :smallcaps:`lcd` +.. |usb| replace:: :smallcaps:`usb` + diff --git a/notes_arduino.rst b/notes_arduino.rst index 2b4d648..68d1cf6 100644 --- a/notes_arduino.rst +++ b/notes_arduino.rst @@ -34,1205 +34,25 @@ La carte Arduino Les sorties de la carte Arduino =============================== -Premier programme -================= - -Faire clignoter une |led| est l'une des premières étapes avec Arduino. C'est -aussi une introduction pour comprendre le fonctionnement de la carte. - -Ce premier programme ne nécessite pas de branchement : une |led| est présente -sur la carte et devrait s'allumer automatiquement en lançant le programme. - -Décomposition du programme --------------------------- - -L'initialisation -~~~~~~~~~~~~~~~~ - -L'initialisation s'exécute seulement au démarrage du programme sur la carte -(et sera de nouveau exécutée si l'on appuie sur le bouton `reset`). - -.. code-block:: arduino - :number-lines: 9 - - // the setup routine runs once when you press reset: - void setup() { - // initialize the digital pin as an output. - pinMode(13, OUTPUT); - } - -Une seule instruction est lancée dans cet extrait : :index:`pinMode` -`pinMode` [#]_. Celle-ci permet d'indiquer au microcontrolleur si la broche -doit être configurée pour envoyer du courant, ou en recevoir. Puisque nous -souhaitons ici allumer une |led|, nous lui passons le paramètre `OUTPUT` en -argument. - -.. [#] https://www.arduino.cc/en/Reference/pinMode - -L'exécution -~~~~~~~~~~~ - -Voici le cœur du programme, ces instructions seront exécutées en boucles, -indéfiniment, tant que la carte sera sous tension. - -.. code-block:: arduino - :number-lines: 15 - - // the loop routine runs over and over again forever: - void loop() { - // turn the LED on (HIGH is the voltage level) - digitalWrite(13, HIGH); - delay(1000); // wait for a second - digitalWrite(13, LOW); - // turn the LED off by making the voltage LOW - delay(1000); // wait for a second - } - -Ce bloc est composé de quatre instructions, qui appellent deux fonctions -différentes. :index:`digitalWrite` `digitalWrite` [#]_ permet d'envoyer ou de -couper le courant sur une broche donnée. Pour allumer la |led|, nous commençons -donc en donnant `HIGH` en paramètre. - -.. [#] https://www.arduino.cc/en/Reference/digitalWrite - -Vient ensuite une instruction permettant de faire une pause dans le programme : -:index:`delay` `delay` [#]_. Cette fonction prend en paramètre la durée de la -pause (en millisecondes, `1000` vaut donc une seconde). - -.. [#] https://www.arduino.cc/en/Reference/delay - -Afin de faire clignoter la |led|, il est nécessaire de l'éteindre ensuite. -C'est pourquoi nous retrouvons l'instruction `digitalWrite`, mais cette fois -avec la valeur `LOW`, suivi d'une nouvelle pause d'une seconde. - -.. sidebar:: digital - - digital signifie *numérique*. Le terme indique une valeur que l'on peut - exprimer en nombre entier (1, 2, 3…). - -Le programme complet --------------------- - -.. sidebar:: Chargement - - Ce programme est disponible dans l'environnement Arduino dans les exemples : - Basic / Blink - -.. code-block:: arduino - - /* - Blink - Turns on an LED on for one second, then off for one - second, repeatedly. - - This example code is in the public domain. - */ - - // the setup routine runs once when you press reset: - void setup() { - // initialize the digital pin as an output. - pinMode(13, OUTPUT); - } - - // the loop routine runs over and over again forever: - void loop() { - // turn the LED on (HIGH is the voltage level) - digitalWrite(13, HIGH); - delay(1000); // wait for a second - digitalWrite(13, LOW); - // turn the LED off by making the voltage LOW - delay(1000); // wait for a second - } - -Utiliser une led externe -======================== - -.. sidebar:: Une led - - .. image:: content/5mm_Red_LED.jpg - :align: center - :width: 100% - -Suite à ce premier exemple, nous allons maintenant faire évoluer notre -programme pour l'adapter à une |led| que nous allons brancher à la carte. -Puisque nous intégrons un composant externe, nous allons devoir veiller à ce -que celui-ci soit compatible avec l'alimentation de la carte Arduino : certains -composants nécessitent une tension plus importante (par exemple un moteur), -d'autre des tensions plus faibles (au risque de faire griller le composant). - -Le tableau suivant indique la valeur minimale et maximale supportée par -différents types de |led|, ainsi que l'intensité du courant pour la tension -minimale et maximale. - -======= =========== ============== ================ -Taille Couleur Tension (`V`) Intensité (`mA`) -======= =========== ============== ================ -3mm rouge `1.8`-`2.5` `5`-`18` -3mm vert `2.1`-`2.6` `5`-`17.5` -3mm jaune `1.8`-`2.0` `5`-`17.5` -5mm rouge `1.9`-`2.3` `5`-`18` -5mm vert `1.9`-`2.5` `4`-`14` -5mm jaune `1.9`-`2.5` `5`-`15` -======= =========== ============== ================ - -.. sidebar:: Polarisation - - la |led| ne laisse passer le courant que dans un seul sens. C'est pourquoi - les deux broches ne sont pas de la même longueur. La patte la plus courte - doit être branchée sur le pôle `-`. - -.. admonition:: Attention - :class: warning - - La tension de sortie de la carte est de 5 |V|. Or, en lisant le tableau, on - voit bien que les |led|\ s ne supporteront pas cette tension à leur borne, il - est donc nécessaire de mettre en place un système pour réduire la tension - dans les limites de ce qui est acceptable par la |led|. - -Dans notre situation, la tension délivrée par la carte Arduino et le courant -qui traversera la |led| sont stables — la |led| ne modifie pas son comportement -pendant son fonctionnement. Nous pouvons utiliser le schéma le plus simple pour -réduire la tension : *la résistance chutrice*. - -.. figure:: content/cligo_led.pdf - :width: 100% - - Arduino, LED et une résistance - -Calcul de la résistance ------------------------ - -La résistance à placer se calcule de la manière suivante : - -.. math:: - - R = \frac{(U-Ul)}{I} - -.. sidebar:: Valeurs - - :R: Résistance - :U: Tension de l'alimentation - :Ul: Tension de la |led| - :I: Intensité de la |led| - -Dans notre exemple, en prenant l'intensité maximale supportée par la |LED| nous -obtenons le calcul suivant : - -.. math:: - - R &= \frac{(5-2.5)}{0.018} \\ - &= 139\ \Omega - -.. sidebar:: Déjà des calculs ? - - Ce petit calcul peut sembler théorique, toutefois nous en aurons besoin par - la suite, quand il sera nécessaire d'alimenter des composants avec des - tensions différentes que l'alimentation. (Nous aborderons cela plus loin avec - les notions de *Pont diviseur*, ainsi que les *régulateurs de tension*). - -La résistance choisie doit donc avoir une valeur supérieure. En consultant la -série E12 [#]_, on peut choisir la valeur la plus proche (par exemple 220 -:math:`\Omega`). - -.. [#] Série de douze valeurs utilisées dans les composants électroniques : - https://fr.wikipedia.org/wiki/CEI_60063 - -Vérification de l'intensité ---------------------------- - -On sait que : :math:`I = \frac{U}{R}` soit ici : - -.. math:: - - I &= \frac{U-Ul}{R} \\ - &= \frac{5-2.5}{220} \\ - &= 11.36\ mA - -Ce qui est suffisant pour alimenter notre composant. - - -Mise à jour du programme ------------------------- - -Nous pouvons maintenant mettre à jour notre programme. Il s'agit toujours du -même code que celui présenté plus haut avec toutefois une légère différence : -au lieu d'envoyer du courant sur la broche `13`, nous l'envoyons désormais sur -la broche `9`. Il est donc nécessaire de faire quelques modifications au lignes -`12`, `18` et `20`. - -Faire varier la luminosité -========================== - -Il existe 6 ports sur la carte Arduino permettant de faire varier la tension de -sortie : `3`, `5`, `6`, `9`, `10` et `11`. Les autres port permettent seulement -d'envoyer la tension `HIGH` ou `LOW`, c'est-à-dire 5 |V| ou 0 |V|. - -Il est possible d'utiliser la fonction :index:`analogWrite` `analogWrite` [#]_ -sur chacun de ses ports, en envoyant une valeur comprise entre `0` et `255`. - -.. [#] https://www.arduino.cc/en/Reference/AnalogWrite - -.. raw:: latex - - - \begin{center} - \begin{tikzpicture}[scale=2.6] - - \foreach \x in {0,0.5,...,5} { - \pgfmathtruncatemacro\result{\x * 255 / 5} - \draw (\x,-4pt) -- (\x,4pt) - node [below,yshift=-20] {\pgfmathprintnumber{\result}} - node [above] {$\x$V}; - } - - \draw (0,0) -- (5,0); - - \end{tikzpicture} - \end{center} - -.. sidebar:: `PWM` - - La variation de la tension est réalisée via la *modulation de largeur - d'impulsions* [#]_ qui permet de faire varier la tension en faisant varier de - manière très brève la durée pendnant laquelle le courant est émis. - -.. [#] https://fr.wikipedia.org/wiki/Modulation_de_largeur_d'impulsion - -.. note:: - - Les valeurs présentées ici sont des tensions *moyennes*. En envoyant la - valeur `127`, la tension sur la broche sera de 5 |V|, mais pendant une durée - très courte : - - .. raw:: latex - - \begin{tikzpicture} - \draw[help lines] (0,0) grid (7,1); - \draw[thick] (0,0) node[anchor=base east] {0V} -- ++(0,0) - \foreach \x in {1,...,7}{ - -- +(0,1) -- +(0.5,1) -- +(0.5,0) -- ++(1,0) - } -- +(0,.5); - \draw[thick,anchor=north east] (0,1) node {5V}; - \end{tikzpicture} - - Avec la valeur `192` la tension reste à 5 |V| pendant une durée plus longue : - - .. raw:: latex - - \begin{tikzpicture} - \draw[help lines] (0,0) grid (7,1); - \draw[thick] (0,0) node[anchor=south east] {0V} -- ++(0,0) - \foreach \x in {1,...,7}{ - -- +(0,1) -- +(0.75,1) -- +(0.75,0) -- ++(1,0) - } -- +(0,.5); - \draw[thick,anchor=north east] (0,1) node {5V}; - \end{tikzpicture} - - Dans tous les cas, la tension à la sortie de la borne sera de 5 |V|. Il est - toutefois possible de transformer ce signal en une vraie tension linéaire, à - l'aide d'un condensateur supplémentaire [#]_. - -.. [#] https://provideyourown.com/2011/analogwrite-convert-pwm-to-voltage/ - -.. admonition:: Mesure de la tension - :class: exercice - - Avec un multimètre, mesurer la tension en sortie de la borne en fonction de - diverses valeurs. - -Programme ---------- - -.. sidebar:: Ressource limitée ! - - Cette capacité à contrôler la tension de sortie est très intéressante (par - exemple pour demander à un moteur de tourner plus ou moins vite), mais est - limitée à 6 bornes seulement. Il vaut mieux les réserver quand nous avons - besoin d'une sortie analogique. - -.. code-block:: arduino - - // Fade - - // This example shows how to fade an LED on pin 9 - // using the analogWrite() function. - - // This example code is in the public domain. - - int led = 9; // the pin that the LED is attached to - int brightness = 0; // how bright the LED is - int fadeAmount = 5; // how many points to fade the LED by - - // the setup routine runs once when you press reset: - void setup() { - // declare pin 9 to be an output: - pinMode(led, OUTPUT); - } - - // the loop routine runs over and over again forever: - void loop() { - // set the brightness of pin 9: - analogWrite(led, brightness); - - // change the brightness for next time through the loop: - brightness = brightness + fadeAmount; - - // reverse the direction of the fading - // at the ends of the fade: - if (brightness == 0 || brightness == 255) { - fadeAmount = -fadeAmount ; - } - // wait for 30 milliseconds to see the dimming effect - delay(30); - } - - -Générer du son -============== - -.. sidebar:: Un piezzo buzzer - - .. image:: content/piezzo_buzzer.jpg - :align: center - :width: 100% - -Avec un piezzo buzzer il est possible d'ajouter une sortie sonore au programme. -Ceux que l'on trouve dans le commerce supportent une tension allant de 3 à -24 |V|, ce qui permet de brancher le buzzer directement en sortie de la carte. - -Le composant permet de produire du son en fonction de la fréquence du signal de -sortie. - -Il est possible d'utiliser la fonction `digitalWrite` sur une borne pour -produire un beep, mais il est plus intéressant de pouvoir contrôler la -fréquence de sortie. Nous utiliserons pour cela la fonction :index:`tone` -`tone` [#]_. (Cette instruction peut être utilisée sur une sortie numérique, il -n'est donc pas nécessaire de réserver une sortie analogique pour le buzzer.) - -.. [#] https://www.arduino.cc/en/Reference/Tone - -.. sidebar:: Qualité du son - - La fonction `tone` ne sait produire qu'un signal carré, ce qui signifie que - le son n'aura jamais les harmoniques d'un fichier :smallcaps:`mp3` ou - :smallcaps:`wav`. - -.. note:: - - La fonction `tone` n'est pas disponible sur toutes les cartes Arduino. Si - vous utilisez une carte *Gemma* ou *Due* (ou un autre microcontrolleur), la - fonction ne sera pas disponible. - - Dans ce cas, il est possible d'écrire soit même la fonction en utilisant - les instructions `delayMicroseconds` et `digitalWrite`. Dans ce cas la - fréquence des sons ne sera pas garantie, mais le but n'est pas de faire de la - carte Arduino un outil `hi-fi` : - - .. code-block:: arduino - - void tone(int targetPin, long frequency, long length) { - // calculate the delay value between transitions - // 1 second's worth of microseconds, divided by the - // frequency, then split in half since there are two - // phases to each cycle - long delayValue = 1000000/frequency/2; - // calculate the number of cycles for proper timing - // multiply frequency, which is really cycles per - // second, by the number of seconds to get the - // total number of cycles to produce - long numCycles = frequency * length/ 1000; - for (long i=0; i < numCycles; i++) { - // write the buzzer pin high to push out the diaphram - digitalWrite(targetPin,HIGH); - // wait for the calculated delay value - delayMicroseconds(delayValue); - // write the buzzer pin low to pull back the diaphram - digitalWrite(targetPin,LOW); - // wait again or the calculated delay value - delayMicroseconds(delayValue); - } - } - -Par exemple, en connectant le buzzer sur la broche `8`, l'instruction suivante -permettra de jouer un *la* pendant une seconde : - -.. code-block:: arduino - - tone(8, 440, 1000); - -En faisant varier la fréquence ainsi que la durée de chaque note, nous pourrons -ainsi jouer des mélodies (simples). Il est par contre nécessaire de connaître -la fréquence de la note que l'on souhaite jouer. (La table peut être obtenue -facilement sur internet [#]_). - -.. [#] https://fr.wikipedia.org/wiki/Note_de_musique - -.. sidebar:: Codification des notes - - En anglais, chaque note est codée par une lettre de A à G : C pour Do, D pour - Ré, F pour Mi, etc. - -Plutôt que d'écrire directement les fréquence dans le programme, il est plus -simple de coder les notes, et laisser l'application jouer les notes -correspondantes ; la notation anglaise est souvent utilisée. En associant -chaque fréquence à une valeur dans le programme, il devient plus facile -d'écrire la mélodie qui peut être codée en écrivant directement les notes de -musiques ! - -.. admonition:: Exercice - :class: exercice - - Écrire une petite mélodie ! - -Contrôler un moteur -=================== - -Avec ces instructions, il est temps de passer aux choses sérieuses. En -contrôlant les sorties à l'aide de l'instruction `digitalWrite`, nous allons -pouvoir donner du mouvement au robot en lui donant des roues. Mettre en route -un moteur n'est pas difficile, mais nécessite de prendre certaines précautions -avant de connecter notre moteur. - -.. admonition:: Attention - :class: warning - - Ne jamais brancher un moteur directement à la carte Arduino. D'une part parce - que la tension nécessaire pour activer le moteur risque d'être trop - importante pour la carte (dans le meilleur des cas, le moteur ne tournera - pas, dans le pire des cas la carte grillera), mais aussi parce qu'un moteur - fonctionne de la même manière qu'une dynamo : il produit du courant quand il - tourne. Ce courant risque de remonter dans la carte et générer un - court-circuit. - -Pour cette raison, nous utiliserons un contrôleur externe, destiné à nous -éviter de nombreuses complications : le L293D [#]_. Cette puce va nous permettre : - -.. [#] http://www.ti.com/lit/ds/symlink/l293d.pdf [#]_ - -.. [#] Prenez le temps de lire les spécification des composants. Elles sont en - anglais, mais donnent toutes les informations nécessaire pour utiliser - le composant au mieux : les caractéristiques générale, mais également - les cas d'utilisation, les valeurs maximales supportées, les conseils - de branchement etc. - -.. sidebar:: Une puce L293D - - .. image:: content/L293D_Motor_Driver.jpg - :align: center - :width: 100% - -- de protéger la carte Arduino en empêchant les surtensions : il intègre des - diodes de protections et des contrôleurs thermiques pour protéger le circuit. -- de limiter le cablage et les composants à utiliser : le composant supporte - des tensions de fonctionnement allant de 4,5 à 36 |V|, et permettra donc de - délivrer des tensions beaucoup plus puissantes que ce que peut fournir la - carte Arduino. - -.. note:: - - Il est parfaitement possible de contrôler un moteur directement à partir de - la carte Arduino sans utiler ce type de composant, mais nous compliquons - alors le schéma de cablage inutilement. La documentation technique du - composant nous montre comment réaliser le cablage équivalent avec des diodes - et des transitors (un double pont en H). - -En fait, la puce ne permet pas simplement de contrôler un moteur, mais quatre -! (ou alors deux moteurs pouvant tourner dans les deux sens). Cela correspond à -notre robot qui aura deux roues motrices : une seule puce et quelques fils -pourront permettre de faire rouler notre robot et lui faire réaliser quelques -manœuvres. - -.. figure:: content/l293d.pdf - :width: 50% - - L293D - - :EN: Puissance du moteur : permet de contrôler la vitesse de rotation du - moteur en fonction de la tension appliquée à la borne. Cette borne - peut être reliée à une borne analogique de la carte Arduino. - :A: Activation du moteur : permet d'activer le moteur connecté. Ces - bornes sont à relier aux sorties digitales de la carte. - :Y: Sortie à relier aux bornes des moteurs. - :VCC2: Alimentation des moteurs : cette borne est à relier à - l'alimentation générale (36 |V| max.) - :VCC1: Alimentation du composant (5 |V|) : cette borne est à relier à - l'alimentation stabilisée de la carte Arduino. - :ground: Ces bornes sont à relier à la masse - -Montage général ---------------- - -Il y a trois types de bornes sur le composant : celles destinées à être -connectées au moteur (`Y`), celles destinées à la carte Arduino (`EN` et `A`), -et celles qui qui servent à l'alimentation (`VCC`). Comme il est possible de -contrôler plusieurs moteurs, les bornes sont numérotées en fonction du moteur -contrôlé. - -Dans le cas d'un moteur devant tourner dans les deux sens, les bornes `Y` -doivent être connectées aux deux pattes du moteur : en envoyant du courant sur -l'une des deux bornes `A`, il devient possible de faire tourner le moteur dans -un sens ou un autre (le tableau présente l'exemple d'un moteur connecté aux -bornes `1` et `2`, un deuxième moteur pourra être contrôlé de la même manière -en le branchant sur les bornes `3` et `4`) : - -.. sidebar:: frein électromagnétique - - Le moteur génère de l'électricité en tournant (comme une dynamo). En - alimentant le moteur avec l'électricité qu'il produit lui-même, on peut ainsi - freiner le moteur avec sa propre énergie ! - -=========== =========== ============================================= -Tension 1A Tension 2A Résultat -=========== =========== ============================================= -`LOW` `LOW` Arrêt du moteur (frein électromagnétique) -`LOW` `HIGH` Faire tourner le moteur dans un sens -`HIGH` `LOW` Faire tourner le moteur en sens inverse -`HIGH` `HIGH` Arrêt du moteur (frein électromagnétique) -=========== =========== ============================================= - -Voir le schéma de branchement avec deux moteurs contrôlés depuis la carte -Arduino. - -.. figure:: content/arduino_l293d.pdf - :width: 100% - - L293D, Arduino et deux moteurs - - Les cables reliant le L293D à la masse, et l'alimentation des moteurs ne sont - pas représentés. - - :Cable bleu: Marche avant - :Cable vert: Marche arrière - :Cable orange: Puissance du moteur - -.. raw:: latex - - \pagebreak - -Programme ---------- - -.. sidebar:: Valeurs - - Les valeurs ne sont pas choisies par hasard : elles correspondent aux - paramètres des fonctions `digitalWrite` et `analogWrite` ! - -Ce programme n'est pas disponible dans l'environnement Arduino, cette fois nous -allons devoir l'écrire nous même. Afin de simplifier l'écriture, nous allons -définir une fonction `runMotor` qui prendra trois paramètres : - -:motor: Le numéro du moteur à activer, le 1er moteur déclaré aura la numéro `0` -:direction: La direction du moteur, elle peut prendre deux valeurs `HIGH` ou - `LOW` -:speed: La vitesse de rotation, cette valeur peut aller de `0` à `255` - -.. code-block:: arduino - - void runMotor(int motor, int direction, int speed) { - // … - } - - -.. admonition:: Contrôle du moteur - :class: exercice - - Avec la fonction `runMotor`, nous pouvons donner du mouvement au robot. En - donnant des paramètres de sens et de vitesse différents à la roue gauche et - droite le robot se déplacera différement. Donnez les paramètres de la - fonction `runMotor` pour réaliser les actions suivantes : - - - Marche avant - - Marche arrière - - Faire tourner le robot sur lui-même - - Faire un virage serré - - Faire un virage large - - Arrêt complet - -.. ========================= ========================= ========================== -.. Moteur 1 Moteur 2 Effet -.. ========================= ========================= ========================== -.. `runMotor(0, HIGH, 255)` `runMotor(1, HIGH, 255)` Marche avant -.. `runMotor(0, LOW, 255)` `runMotor(1, HIGH, 255)` Tourner sur lui-même -.. `runMotor(0, HIGH, 255)` `runMotor(1, LOW, 255)` Tourner sur lui-même (sens -.. inverse) -.. `runMotor(0, LOW, 255)` `runMotor(1, LOW, 255)` Marche arrière -.. `runMotor(0, LOW, 0)` `runMotor(1, HIGH, 255)` Virage serré -.. `runMotor(0, HIGH, 127)` `runMotor(1, HIGH, 255)` Virage large -.. `runMotor(0, LOW, 0)` `runMotor(1, LOW, 0)` Arrêt complet -.. ========================= ========================= ========================== - -Connecter un écran Nokia 5110 -============================= - -.. sidebar:: L'écran LCD - - .. image:: content/s-l500.jpg - :align: center - :width: 100% - -L'écran Nokia 5110 est un composant de base et peu honéreux (environ 2€) -permettant un affichage depuis la carte Arduino. Il permet un affichage sur une -grille de 84x48 pixels, soit 4 lignes de textes. - -.. admonition:: Tension de fonctionnement - :class: warning - - Le composant fonctionne sous 3,3 |V|, il n'est donc pas recommandé de le - brancher directement sur la carte Arduino (même si certains le font [#]_). - Dans le doute, commencez avec un correcteur de courant. - -.. [#] https://circuitdigest.com/microcontroller-projects/nokia5110-graphical-lcd-arduino-interfacing - -Level shifter 74HC4050N ------------------------ - -Ce composant est *unidirectionnel* et *High to Low* : en alimentant le -composant en 3.3 |V|, nous avons la possibilité de générer une sortie à 3.3 |V| -à partir de la carte Arduino : le composant possède 6 entrées et 6 sorties : à -chaque fois que la tension sur une borne d'entrée est supérieure à la tension -d'alimentation, la sortie correspondante sera activée. - -.. admonition:: Broches non connectées - :class: note - - Deux bornes ne sont pas connectées sur le composants : les bornes `13` et - `16`. Attention au moment du cablage ! - -.. sidebar:: Cablage - - Le cablage sur le composant `74HC4050N` importe peu, tant que chaque entrée - est bien associée à la sortie correspondantes. - -.. figure:: content/nokia_5110.pdf - :width: 100% - - Arduino, Nokia 5110, 74HC4050N - - :Cable Rouge: +3.3 |V| - :Cable Noir: Masse - :Cable Vert: Broche 7 - 3 (SCE) - :Cable Bleu: Broche 6 - 4 (RST) - :Cable Orange: Broche 5 - 5 (D/C) - :Cable Maron: Broches 11 - 6 (DN(MOSI)) - :Cable Cyan: Broche 13 - 7 (SeriaL CLock) - :Cable Mauve: Broche 9 - 8 (LED) - - -Le programme [#]_ - -.. image:: content/nokia_5110_montage.jpg - :width: 100% - - -.. [#] https://learn.sparkfun.com/tutorials/graphic-lcd-hookup-guide - - -.. default-role:: literal -.. role:: smallcaps -.. role:: index -.. |lcd| replace:: :smallcaps:`lcd` -.. |usb| replace:: :smallcaps:`usb` +.. include:: chapters/output.rst =============================== Les entrées de la carte Arduino =============================== -Maintenant que nous avons vu comment contrôler les sorties de la carte Arduino, -il est temps de se poser la question d'utiliser les entrées de la carte : c'est -par ce moyen que nous allons pouvoir donner un peu de réaction à notre robot, à -travers des capteurs qui nous fournirons des informations sur le monde -extérieur. - -Utiliser Arduino comme ohmmètre -=============================== - -Lecture de la tension ---------------------- - -Il existe six ports sur la carte Arduino permettant de lire des valeurs -analogiques (`A0` — `A5`). - -Par exemple, la tension peut être lue le port `A0` sur avec l'instruction -:index:`analogRead` `analogRead(A0)` [#]_. Celle-ci est lue sur dix bits (soit -une valeur comprise entre `0` et `1023`), en fonction de la tension -d'alimentation de la carte Arduino (normalement 5 |V|). - -.. [#] https://www.arduino.cc/en/Reference/AnalogRead - -.. raw:: latex - - \begin{center} - \begin{tikzpicture}[scale=2.5] - - \foreach \x in {0,0.5,...,5} { - \pgfmathtruncatemacro\result{\x * 1023 / 5} - \draw (\x,-4pt) -- (\x,4pt) - node [below,yshift=-20] {\pgfmathprintnumber{\result}} - node [above] {$\x$ V}; - } - - \draw (0,0) -- (5.0,0); - - \end{tikzpicture} - \end{center} - -.. note:: - - Lors de l'écriture sur un port analogique, la précision est réalisée sur huit - bits (soit une valeur comprise entre `0` et `255`). Attention donc en - redirigeant l'entrée d'un port vers une sortie ! - -On peut donc utiliser la carte comme un voltmètre simple, pour mesurer une -tension entre 0 |V| et la tension d'alimentation (5 |V|). La formule suivante -permet de calculer la tension en fonction de la valeur retournée par la -fonction `AnalogRead` : - -.. math:: - - V = \frac{5 \times \mathtt{AnalogRead()}}{1023} - -Utiliser l'Arduino comme ohmmètre ---------------------------------- - -Notre premier montage pour illustrer la lecture d'une valeur consiste à -utiliser l'Arduino pour connaître la valeur d'une résistance. Nous allons -utiliser un *pont diviseur* (voir le schéma) avec une résistance connue, et une -autre dont on souhaitera déterminer la valeur : en lisant la tension -:math:`V_A`, il sera possible de déterminer la valeur de la résistance -inconnue. - -.. figure:: content/pont_diviseur.pdf - :width: 50% - :align: center - - Le pont diviseur - - - La plus simple représentation du diviseur de tension consiste à placer deux - résistances électriques en série. Ce type d'association de résistances étant - omniprésent dans les montages électriques, le pont diviseur en devient une des - notions fondamentales en électronique. - - - Il est possible de calculer facilement la valeur de :math:`V_A` dans le - montage, à la condition de connaitre les valeurs des résistances et la valeur - de la tension Vcc. La première formule à utiliser est celle de la loi d'Ohm qui - permet de citer cette équation : - - .. math:: - - I = \frac{V_\text{cc}}{R_1+R_2} - - En utilisant la loi d'Ohm une seconde fois, il est possible de déterminer - l'équation suivante: - - .. math:: - - V_a = R_2 \times I - - Dans la formule ci-dessous, il suffit de remplacer le courant :math:`I` par - sa valeur équivalente (la première équation) pour déterminer facilement - l'équation de :math:`V_A`: - - .. math:: - - V_a = R_2 \times (\frac{V_\text{cc}}{R_1+R_2}) - - **Exemple** - - Prenons les valeurs suivantes : - - - :math:`V_\text{cc}`: 9V - - :math:`R_1`: 1k :math:`\Omega` - - :math:`R_2`: 3k :math:`\Omega` - - .. math:: - - V_a &= R_2 \times \frac{V_\text{cc}}{R_1 + R_2} \\ - &= 3000 \times \frac{9}{1000+3000} \\ - & = \frac{27000}{4000} \\ - &= 6.75V - - La différence de potentiel :math:`V_A` sera égal à 6.75 |V| en utilisant les valeurs - précédentes. - -Dans notre cas, nous connaissons la tension ainsi que la valeur de la -résistance :math:`R_2`. Donc en reprenant la formule du calcul de :math:`V_A` -nous obtenons : - -.. math:: - - %V_a &= R_2 \times \frac{V_\text{cc}}{R_1 + R_2} \\ - %(R_1 + R_2) \times V_a &= R_2 \times V_\text{cc} \\ - %R_1 \times V_a + R_2 \times V_a &= R_2 \times V_\text{cc} \\ - %R_1 \times V_a &= R_2 \times V_\text{cc} - R_2 \times V_a \\ - %R_1 &= \frac{R_2 \times V_\text{cc}}{V_a} - \frac{R_2 \times V_a}{V_a} \\ - %R_1 &= \frac{R_2 \times V_\text{cc}}{V_a} - R_2 \\ - %R_1 &= R_2 \times \left(\frac{V_\text{cc}}{V_a} - 1\right) \\ - R_1 &= R_2 \times \left(\frac{1023}{\mathtt{AnalogRead()}} - 1\right) - -.. .. note:: -.. -.. -.. La dernière ligne du calcul peut se retrouver ainsi : on sait que la tension -.. lue par fonction `analogRead()` est échelonée de `0` à `1023` par rapport à -.. la tension d'alimentation, ce que l'on peut représenter dans la ligne -.. suivante : -.. -.. .. math:: -.. -.. V_A &= \frac{V_\text{cc} \times \mathtt{AnalogRead()}}{1023} && \text{donc} \\ -.. \frac{V_\text{cc}}{V_A} &= \frac{V_\text{cc}}{\frac{V_\text{cc} \times \mathtt{AnalogRead()}}{1023}} \\ -.. \frac{V_\text{cc}}{V_A} &= V_\text{cc} \times {\frac{1023}{V_\text{cc} \times \mathtt{AnalogRead()}}} \\ -.. \frac{V_\text{cc}}{V_A} &= \frac{1023}{\mathtt{AnalogRead()}} - -Contrôle théorique -~~~~~~~~~~~~~~~~~~ - -Ce programme en python permet de prédire les différentes valeurs qui seront -lues par la carte Arduino. Il reproduit (dans une certaine mesure) les erreurs -d'arrondis qui seront susceptible d'arriver sur la carte lors du calcul des -valeurs : - -.. sidebar:: Programme - - Ce programme va calculer la tension :math:`V_A`, la valeur lue par la fonction - `analogRead`, la valeur de la résistance calculée, et l'intensité qui - traverse les composants. - -.. include:: content/ohm.py - :code: python - -.. raw:: latex - - \pagebreak - - -Il permet de construire le tableau de valeurs suivant (avec :math:`R_2` = 1000 -:math:`\Omega`, et :math:`V_\text{cc}` = 5 |V|) : - -.. sidebar:: Tension théorique - - Ce tableau est construit à partir de la différence de potentielle théorique - au niveau de la résistance :math:`R_2`. Les valeurs réelles seront toujours - légèrement différentes lors du montage. - -=================== ================= ============= =================== -Résistance Tension théorique Valeur lue Résistance calculée -=================== ================= ============= =================== -10 :math:`\Omega` 4,95 |V| 1012 10 -220 :math:`\Omega` 4,1 |V| 838 220 -1k :math:`\Omega` 2.5 |V| 511 1 001 -10k :math:`\Omega` 0,45 |V| 93 10 000 -220k :math:`\Omega` 0,02 |V| 4 254 750 -=================== ================= ============= =================== - -Au delà de 220k :math:`\Omega`, la tension qui traverse :math:`R_2` devient si -faible que la valeur lue par la fonction `analogRead` tombe à `0`, ce qui -empêche toute mesure. En prenant une valeur plus importante pour la résistance -:math:`R_2`, la plage d'erreur sera plus faible pour des valeurs plus -importante de :math:`R_1` - -Montage -------- - -Le montage reste simple à mettre en place, il ne nécessite que deux résistances -(dont celle dont on souhaite calculer la valeur). - -.. figure:: content/arduino_ohmetre.pdf - :width: 70% - - Arduino comme ohmmètre - - La résistance :math:`R_1` sera calculée en fonction de la valeur de - :math:`R_2`. - - La résistance :math:`R_2` peut être choisie avec une valeur de - 1000 :math:`\Omega` par défaut, et changée en fonction du besoin. - -Le programme reprend la formule que nous avons calculé ci-dessus, et affiche le -résultat sur la console. - -.. code-block:: arduino - - // La résistance r2 doit être connue et - // renseignée dans le programme - int r2 = ...; - - void setup() { - Serial.begin(9600); - } - - void loop() { - - int r1 = r2 * ((1023 / (float)analogRead(A0)) - 1); - - Serial.print("R1: "); - Serial.println(r1); - - delay(1000);// wait for a second - } - -.. [#] https://www.arduino.cc/en/Serial/Print - -.. note:: - - Nous découvrons à l'occasion de ce programme la librairie `Serial` [#]_ qui - permet d'envoyer des données à l'ordinateur via le port |usb|. Il s'agit d'un - moyen pratique pour transmettre une valeur lue sur la carte. - - Nous pourrions enrichir ce schéma avec une sortie sur un écran |lcd| plutôt - que d'envoyer l'information vers l'ordinateur : nous aurons ainsi un ohmmètre - autonome ! - - -Capteur de proximité infrarouge -=============================== - -Dans un projet de robot mobile, il est nécessaire de tester la présence -d'objets à proximité pour éviter que celui-ci ne percute les obstacles. - -.. sidebar:: Capteur infrarouge - - .. image:: content/Sharp_GP2Y0A21YK.jpg - :align: center - :width: 100% - -Nous retrouvons deux types de senseurs sur les robots : des senseurs -optiques, ou par ultrasons. Le senseur Sharp relève de la première catégorie. -Il permet de détecter la présence d'un objet entre 10 et 80 cm, à partir du -retour de lumière infrarouge. - -Montage général ---------------- - -Le schéma suivant indique comment placer les différents câbles du connecteur -:smallcaps:`JST`. - -.. sidebar:: Condensateur - - Le condensateur présent sur le schéma permet ici de lisser les variations de - la tension. On l'appelle *Condensateur de découplage* [#]_. - -.. [#] https://fr.wikipedia.org/wiki/Condensateur_de_d%C3%A9couplage - -.. figure:: content/capteur_infra.pdf - :width: 100% - - Arduino, `GP2Y0A21YK` - - :Cable Rouge: +5 |V| - :Cable Noir: GND/Masse - :Cable Jaune ou Blanc: Entrée Analogique `A0` - -Tension de sortie -~~~~~~~~~~~~~~~~~ - -.. sidebar:: Tension d'entrée - - Même si le composant supporte une tension allant jusque 7 |V|, il fonctionne de - manière optimale avec des valeurs allant de 4,5 à 5,5 |V|. - -La tension de sortie, sur le fil jaune, nous indique la distance de l'objet. -Celle-ci varie entre 0,5 |V| et 3 |V| selon la distance de l'obstacle [#]_. - -.. [#] http://www.sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y0a21yk_e.pdf - -.. image:: content/gp2y0a21yk_e.pdf - :width: 100% - -.. Mesure de la tension en fonction de la distance - -Exemple -~~~~~~~ - -Ce programme lit l'entrée sur la broche `A0` et allume une |led| si un objet -est détecté à proximité (±20 |cm|) : - -.. code-block:: arduino - - - int ledPin = 9; // LED connected to digital pin 9 - - void setup() {} - - void loop() { - int sensorValue = analogRead(A0); - if (sensorValue < 220) - sensorValue = 0; - - analogWrite(ledPin, sensorValue >> 2); - delay(200); // delay 200 milliseconds - } - -.. Déclencher le capteur sur demande -.. --------------------------------- -.. -.. Plutôt que d'activer le capteur en continu, nous allons modifier le programme -.. pour n'activer la détection d'objets seulement en cas de mouvements du robot -.. (il n'est pas nécessaire de chercher à tester les obstacles si le robot ne se -.. déplace pas). Cela permettra d'augmenter l'autonomie du robot (en contre-partie -.. d'un port digital utilisé). La consommation du composant étant de 30 |mA|, nous -.. pouvons connecter directement la broche à l'Arduino, il sera capable de fournir -.. le courant nécessaire. -.. -.. Le capteur nécessite un délai minimal avant de fournir une valeur fiable. -.. -.. Créer une tension seuil -.. ----------------------- -.. -.. Nous n'avons pas un besoin réel d'évaluer la distance de l'objet, simplement de -.. pouvoir arrêter le robot s'il s'approche trop près d'un objet. Si l'on connaît -.. la distance d'arrêt souhaitée (et donc la tension) avant de construire le -.. robot, nous pouvons paramétrer le seuil de déclenchement de l'alarme, et -.. utiliser une broche digitale au lieu d'une broche analogique. - - -.. -*- mode: rst -*- -.. -*- coding: utf-8 -*- - -.. default-role:: literal -.. role:: smallcaps -.. role:: index - +.. include:: chapters/input.rst ========================= L'alimentation du système ========================= -USB -=== - -L'|usb| fourni une tension de 5 |V| avec une intensité maximale de 100 |mA| sur -les bornes d'alimentation. Il est donc possible d'alimenter une carte Arduino -avec un câble |usb| (c'est d'ailleurs ainsi que l'on procède lorsque l'on -programme la carte). - -Source externe -============== - -.. sidebar:: Régulateur LM1117 - - .. image:: content/LM1117.jpg - :align: center - :width: 75% - -La carte Arduino possède un régulateur de tension intégré capable de produire -une tension de 5 |V|. Il est donc possible d'alimenter la carte avec une -tension supérieure pour alimenter le circuit. - -.. note:: - - La régulation de la tension est réalisée en convertissant la puissance - superflue en chaleur. Si la tension est trop importante, le composant va trop - chauffer et la carte va s'abîmer. - - De même, le régulateur consomme également du courant en fonctionnement, - donner une tension de 5 |V| sera trop juste pour alimenter le circuit. - - Aussi, la tension recommandée pour un bon fonctionnement est comprise entre 7 - à 12 |V|. - -.. sidebar:: Attention au sens ! - - En inversant le sens des fils entre la masse et l'alimentation, on applique - l'opposé de la tension attendue, ce qui ne plaira pas beaucoup au circuit ! - [#]_ - -.. [#] https://www.rugged-circuits.com/10-ways-to-destroy-an-arduino - -Il existe deux points de connexions sur la carte permettant d'utiliser le -régulateur de tension : la prise jack, ainsi que la borne `Vin`. - -Alimentation via prise jack ---------------------------- - -Il s'agit de la manière la plus simple pour alimenter le circuit, puisque la -carte Arduino possède une prise Jack. En respectant les limites des tensions -indiquées ci-dessus, il ne reste qu'à brancher la fiche sur la carte. - -Dans le cas d'un transformateur externe, il faut veiller à ce que symbole suivant - -.. image:: content/polarity.pdf - :width: 25% - :align: center - -soit présent sur la carte : c'est à dire que le fil `+` soit connecée au centre -de la borne d'alimentation. +.. include:: chapters/alimentation.rst -Alimentation directe sur la carte ---------------------------------- - -La borne `Vin` permet de connecter directement une alimentation à la carte : -elle est également reliée au régulateur de tension et supporte donc une tension -supérieure jusque 12 |V|. - -Là encore, il faut veiller à connecter les deux fils sur les bonnes bornes : la -carte Arduino n'offre aucune protection en cas d'erreur… - -Alimentation externe 5 |V| -========================== - -.. note:: - - Cette solution peut être utilisée si la tension d'entrée est supérieure à - 12 |V| : l'utilisation d'un régulateur de tension externe tel que le `LM7805` - permettra de prendre en entrée une tension jusqu'à 20 |V|. - -Si la tension externe est déjà stabilisée à 5 |V|, il n'est pas possible de se -connecter sur la broche `Vin` de la carte, puisqu'il faut au minimum du 7 |V| -pour avoir une tension de fonctionnement correcte. - -Alimentation par usb --------------------- - -.. sidebar:: Cable - - .. image :: content/USB-2-0-B-MALE-TO-5.jpg - :width: 100% - -La solution la plus sûre dans ce cas est de brancher cette alimentation sur -l'entrée |usb| de la carte. On gagne ainsi en sécurité, au détriment d'un petit -peu de cablage supplémentaire. - -Alimentation par la broche 5V ------------------------------ - -Autre solution envisageable, brancher l'alimentation directement sur la broche -`5V` de la carte Arduino : cette borne est reliée au circuit 5 |V| de la carte, -et n'est pas uniquement une borne de sortie : elle relie l'ensemble des -composants qui ont besoin d'être alimentés avec cette tension. - -.. admonition:: Attention - :class: warning - - Alimenter la carte par la prise `5V` de la carte n'est pas recommandé : - - - Étant donné que l'on passe outre le régulateur de tension, il y a un risque - important de griller la carte si l'on applique une tension trop importante. - - Il interdit d'utiliser en même temps la prise |usb| - - Il interdit d'utiliser en même temps la prise `Vin` sous risque de griller - la carte - -En effet, cette prise est directement reliée au circuit 5 |V| et outrepasse -**toutes** les protections de la carte, qui n'est pas prévue pour être -alimentée ainsi. Il faut réserver cet usage a des cas particuliers (par exemple -alimenter deux cartes Arduino ensemble) - -Tableau récapitulatif -===================== - -Les différentes tensions admissibles : - -================ =============== =============== ============== -Entrée Tension min. Tension max. Intensité max. -================ =============== =============== ============== -Port USB 4,5 |V| 5,5 |V| -Broche `5V` 4,5 |V| 5,5 |V| -Prise jack 7 |V| 12 |V| -Broche `Vin` 6,6 |V| 12 |V| -================ =============== =============== ============== +============ +Le langage C +============ +.. include:: chapters/c.rst ============================== Créer sa propre plaque arduino @@ -1258,3 +78,7 @@ Avec un AtTiny85 Cablage du programmateur + +.. raw:: latex + + \printindex -- cgit v1.2.3