lundi 23 mars 2020

Arduino caméléon


Je me permets aujourd'hui de revisiter un mini-projet amorcé en 2014: l'utilisation d'une sonde RGB pour analyser, par réflexion, la couleur d'une surface. À l'époque, j'avais tenté (avec plus ou moins de succès) de nommer la couleur analysée. Dans cette nouvelle version, je tente (avec plus ou moins de succès) de reproduire la couleur analysée sur un écran couleur (ST7735) branché à l'Arduino.  L'écran affiche du rouge lorsque la sonde est placée sur une surface rouge, alors qu'il affiche du bleu lorsque la sonde est placée sur une surface bleue, etc.

La vidéo ci-dessous montre l'utilisation du dispositif: au démarrage du programme, on doit placer la sonde sur une surface blanche, puis sur une surface noire, afin de calibrer l'appareil. L'écran prend ensuite une couleur qui, sans être identique,  s'approche de celle de la surface sur laquelle on a placé la sonde.




La sonde RGB: principe de fonctionnement

La sonde RGB (red-green-blue) est constituée d'une LED RGB et d'une photorésistance (la LED RGB peut être remplacée par 3 LEDs: une rouge, une verte et une bleue).

Le dispositif fonctionne par réflexion: la LED émet d'abord une lumière rouge sur la surface à analyser. La lumière réfléchie est captée par la photorésistance.

La LED émet ensuite une lumière verte, et la photorésistance mesure la réflexion.  Finalement, la LED émet une lumière bleue, et la photorésistance mesure à nouveau la réflexion.

Une surface de couleur rouge va fortement réfléchir le rouge, alors que le vert et le bleu seront plutôt absorbés (donc faiblement réfléchis). Le vert réfléchit surtout la lumière verte, le bleu réfléchit surtout la lumière bleue, le blanc réfléchit toutes les couleurs alors que le noir les absorbe toutes, etc.

D'une certaine façon, on peut considérer notre sonde RGB comme une caméra numérique rudimentaire...à un seul pixel.

Fabrication de la sonde RGB

Parlons d'abord de la source de lumière: la LED RGB. Il s'agit en fait de 3 LEDs (une rouge, une verte et une bleue) réunies dans un même dispositif. J'ai utilisé un modèle à cathode commune (une broche "-" commune aux 3 LEDs pour la sortie du courant). La broche commune est celle qui est la plus longue.

Puisque notre analyse repose sur la lumière réfléchie par la surface colorée, il est important que notre LED émette une lumière assez intense. La tension de la LED rouge (environ 2 V) étant plus faible que la tension des deux autres LEDs (environ 3 V) j'ai associé la LED rouge à une résistance de 150 Ω, et les deux autres à une résistance de 100 Ω (il en résulte un courant d'environ 20 mA pour une tension de 5 V). La LED RGB a été branché aux sorties 2 (rouge), 3 (vert) et 4 (bleu) de l'Arduino.



Votre photorésistance sera associée à une résistance dont la valeur maximisera autant que possible l'écart entre les différentes valeurs mesurées. Pour trouver cette valeur, vous pouvez mesurer avec un multimètre la résistance de la photorésistance lorsque la LED éclaire une surface blanche (Rmin), et sa résistance lorsque la LED éclaire une surface noire (Rmax). La valeur optimale de la résistance à relier en série avec la photorésistance se calcule de cette façon:

      Rfixe = (Rmin * Rmax)1/2

Ceci étant dit, la valeur exacte de cette résistance n'est pas tellement importante, pourvu qu'elle soit du même ordre de grandeur que la résistance moyenne de votre photorésistance. La valeur de la photorésistance sera mesurée à l'entrée A0 de l'Arduino.

L'ensemble du circuit constitué de la LED et de la photorésistance est enfermé dans un petit récipient opaque, ouvert à une extrémité,  dont la surface intérieure est peinte en noir. Un obstacle opaque doit empêcher la lumière émise par la LED d'atteindre directement la photorésistance (on veut que la photorésistance capte uniquement la lumière réfléchie par la surface colorée).



Connexions de l'écran et installation de la bibliothèque

Je vous réfère à ce précédent article "Écran couleur KMR-1.8 SPI (ST7735) et Arduino" pour les instructions sur les connexions de l'écran à l'Arduino, le téléchargement de la bibliothèque de Bodmer et la configuration de cette bibliothèque.

Un autre modèle d'écran couleur peut évidemment être utilisé, ce qui pourrait vous obliger à le brancher différemment et à apporter certaines modifications au sketch ci-dessous.

Sélection de la couleur à l'écran: le système RGB 565

Ces écrans utilisent un système de couleur à 16 bits appelé "RGB 565": les 5 premiers bits (de poids fort) sont utilisés pour le dosage de rouge, les 6 bits suivants décrivent le vert, et les 5 derniers bits (de poids faible) décrivent le bleu.

Ainsi, le nombre binaire 1111100000000000 représente du rouge pur, sans vert ni bleu.
Le nombre binaire 0000011111100000 représente du vert pur, sans rouge ni bleu.
Le nombre binaire 0000000000011111 représente du bleu pur, sans rouge ni vert.

Les 5 bits qui qualifient le rouge et le bleu permettent donc 32 niveaux d'intensité différents (0 à 31), alors que les 6 bits qui qualifient le vert permettent 64 niveaux différents (0 à 63).

Le sketch

Au démarrage du programme (setup), on lit la valeur de la photorésistance lorsqu'on éclaire une surface blanche (toutes les couleurs réfléchies au maximum), puis une surface noire (toutes les couleurs réfléchies au minimum).

Pendant le reste du programme (loop), la valeur de la photorésistance est lue périodiquement, et convertie (fonction "map") de façon à être étalée entre 0 et 31 (pour le rouge et le bleu) et entre 0 et 63 (pour le vert).

Les valeurs représentant le rouge, le vert et le bleu sont ensuite combinées en une seule variable de 16 bits (la variable "couleur").

-

-

Résultats

Je dois malheureusement admettre que les résultats sont mitigés. L'écran prend effectivement une teinte rougeâtre si la sonde se trouve sur une surface rouge, une teinte verdâtre lorsque la sonde se trouve sur une surface verte, et une teinte bleuâtre lorsque la sonde se trouve sur une surface bleue...à la condition que la surface soit mate et de couleur très vive.

Mais pour le reste, les choses se compliquent: une surface de couleur orangée ne donnera probablement pas un écran orange. Avec un peu de chance, le jaune peut sortir en jaune-vert, mais il peut aussi donner du vert, ou encore du blanc...

Notre sonde RGB semble trop rudimentaire; la relation entre l'intensité lumineuse et la tension mesurée à l'entrée A0 n'est probablement pas linéaire.

Je serais curieux de répéter l'expérience avec un capteur de couleur plus sophistiqué, comme le TCS3200 (j'en ai commandé un ... à suivre).

Yves Pelletier (TwitterFacebook)


2 commentaires:

  1. Merci, je cherche, pour ma part, un détecteur de couleur pour les tubes néon et pour connaitre la température K de celui-ci.
    Par la suite recréer cette même couleur avec des LED.

    RépondreSupprimer
  2. Bonjour et merci pour cet article.
    Serait-il possible d'inclure un calibrage de l'écran avec la sonde, afin de faire un ajustement automatique entre le blanc et noir papier et l'écran ?
    Bonne continuation.

    RépondreSupprimer