lundi 5 mars 2018

digitalRead(): où se situe la frontière entre LOW et HIGH?

Une des premières choses qu'on apprend lorsqu'on s'initie à l'Arduino, c'est que la fonction digitalRead() retourne 0 lorsque l'entrée numérique qui lui est associée est soumise à une tension nulle, et 1 lorsque l'entrée numérique est soumise à une tension de 5 V.  Mais qu'arrive-t-il si la tension de cette entrée numérique se situe quelque part entre 0 et 5 V?  Quelle valeur de tension constitue la frontière entre 0 et 1?

On peut trouver la réponse dans la fiche technique du mircontrôleur Atmega 328, qui est à la base de l'Arduino Uno.  Si vous avez en tête une fiche technique de moins de 10 pages comme celles qui accompagnent les transistors ou les amplificateurs opérationnels, détrompez-vous: les fiches techniques des microcontrôleurs sont beaucoup plus volumineuses (442 pages dans le cas de notre Atmega 328).

À la page 365, dans la section 32.2 intitulée "Common DC Characteristics", on peut voir les informations reproduites ci-dessous:


VIL (pour "voltage input low") représente la plus grande tension d'entrée qui sera, de façon certaine, interprétée comme un signal logique bas.  Pour une tension d'alimentation de 5 V, le tableau indique une valeur correspondant à 0,3*Vcc, c'est à dire 1,5 V.

VIH (pour "voltage input high") représente la plus petite tension d'entrée qui sera, de façon certaine, interprétée comme un signal logique haut. Pour une tension d'alimentation de 5 V, le tableau indique 0,6*Vcc, donc 3 V.

Le fabricant s'engage donc à ce que tous les microcontrôleurs qui sortent de son usine interprètent comme "bas" un signal d'entrée de 1,5 V ou moins, et interprètent comme "haut" un signal d'entrée de 3 V ou plus.

Il s'agit d'une bonne chose si vous devez brancher à l'Arduino un capteur qui utilise un niveau logique de 3,3 V: cette tension de 3,3 V sera correctement interprétée par l'Arduino comme un signal logique haut, même s'il est significativement inférieur à 5 V.

Mais qu'arrive-t-il si le signal d'entrée se situe entre 1,5 V et 3 V?  Vous vous retrouvez alors à l'extérieur de la zone garantie par le fabricant.   Les résultats pourraient donc être différent pour deux cartes Arduino Uno en apparence identiques entre elles.

Par curiosité, j'ai mesuré la tension de seuil pour quelques-unes de mes cartes Arduino.  J'ai utilisé le montage illustré ci-dessous:  une tension pouvant varier de 0 à 5 V grâce à un potentiomètre est acheminée à la fois à l'entrée numérique dont je désire mesurer la tension de seuil, et à une entrée analogique qui nous sert de voltmètre.


Le sketch ci-dessous permet d'afficher dans le moniteur série la tension correspondant à chaque changement d'état de l'entrée numérique (il faut, bien sûr, faire varier la tension en tournant lentement le potentiomètre).




Voici les résultats pour la broche 5 d'une de mes cartes.


On peut remarquer une petite hystérésis: lorsque le niveau initialement bas, il devient haut lorsque la tension atteint 2,55 V.  Par contre, si le niveau est initialement haut, il doit descendre à 2,23 V pour devenir un niveau bas.  En d'autres mots, le niveau logique ne change pas d'état lorsque la tension se situe entre 2,24 V et 2,54 V.

Sans surprise,  ces résultats respectent très facilement les valeurs minimales garanties dans la fiche technique.

J'ai effectué des mesures sur 5 cartes différentes, des clones chinois achetés de vendeurs différents à des moments différents, et je n'ai observé que de très faibles variations d'un carte à l'autre.


On peut voir que pour l'ensemble des 5 cartes testées, la tension nécessaire pour passer de l'état "bas" à l'état "haut" n'est pas très éloignée de 2,55 V, alors que la tension qui permet de passer de l'état "haut" à l'état "bas" se situe quelque part entre 2,20 et 2,25 V.

Je m'attendais à une assez forte dépendance à la température mais, après avoir laissé une carte au congélateur pendant plusieurs minutes (de façon à ce qu'elle devienne très froide), les résultats sont demeurés très similaires.

Yves Pelletier   (TwitterFacebook)

2 commentaires:

  1. Bonjour, merci pour les infos. Je débute avec Arduino et je trouve ça intéressant de voir qu'on peut obtenir des informations intrinsèques sur l'objet en utilisant le code d'une façon adaptée.
    J'ai répliqué le code que vous proposez avec la même carte et un pot de 10 kilo, je trouve des valeurs du même ordre de grandeur : 2.16 à 2.17 V en montant (LOW à HIGH) et 2;48 à 2.5 en descendant. J'ai juste modifié la configuration de la broche en INPUT_PULLUP parce que les valeurs n'étaient pas stables autrement. J'espère que ça ne modifie pas l'expérience d'utiliser la résistance de tirage interne ? (Il me semble que non en principe mais bon... je débute)
    Merci de présenter ce petit programme je trouve que c'est intéressant.

    RépondreSupprimer