Skyduino:~#
Articles
arduino, programmation, projet

[Arduino] Light-painting et capteur de température ? Humm …

Bonjour tout le monde !

Dans mon précédent article je vous ai présenté un capteur de température sans contact. Si vous ne l’avez pas lu c’est le moment pour aller y jeter un œil 😉

Température … light-painting … leds de couleurs … hummm, je sait pas vous mais moi ça me donne des idées tout ça !

Et si je faisait du light-painting avec des leds de couleurs contrôlaient par la température mesurée par le capteur sans contact ?
Le tout depuis un robot géant tirant des rayons laser dans l’espace ! Bon ok, laissons tomber le robot géant 🙂

Comment faire correspondre une couleur et une température ?

Bonne question ! En réalité c’est super simple 😉

Vous avez surement déjà entendu parler du modèle de couleurs TSV (Teinte Saturation Valeur) (HSV (Hue Saturation Value) en anglais) si vous avez fait de la photo.

Le modèle TSV définit une couleur au moyen de trois valeurs :
– la teinte qui définie la couleur en elle même (de 0 à 360),
– la saturation qui définie … la saturation (de 0 à 1),
– et la valeur qui définie l’intensité de la couleur (de 0 à 1).

Plus la saturation d’une couleur est faible, plus l’image sera sombre, une saturation de 0 équivaut à faire du niveau de gris.
Même chose pour la valeur.

Et la teinte ?
Et bien la teinte est codée par un angle en degré sur le cercle des couleurs :
– 0° ou 360° : rouge,
– 60° : jaune,
– 120° : vert,
– 180° : cyan,
– 240° : bleu,
– 300° : magenta.

En résumé le modèle TSV c’est ça :

Triangulo_HSV

(merci Wikipedia pour l’image ;))

Ok le modèle TSV c’est génial mais à quoi il sert dans ce projet ?

Pour faire simple : à tout.

En fixant la saturation et la valeur à 1 (valeur max) et en faisant varier la teinte on obtient les différentes couleurs du cercle ci dessus.
Il suffit ensuite de convertir le modèle TSV en trois composantes de base : Rouge Vert et Bleu.
Pour se faire il suffit de demander à google, voici le code que j’ai utilisé par exemple : http://www.cs.rit.edu/~ncs/color/t_convert.html

Reste un petit truc à définir : comment faire varier la teinte en fonction de la température mesurée, parce que bon au final c’est le but !

En laissant de côté le magenta qui n’as pas franchement de sens visuellement parlant on obtient ceci :
froid — (240° bleu) — (180° cyan) — (120° vert) — (60° jaune) — (0° rouge) –> chaud

Il suffit donc d’y faire correspondre une échelle de température, par exemple :
froid — (240° bleu) — (180° cyan) — (120° vert) — (60° jaune) — (0° rouge) –> chaud
froid — (-25°C) — (0°C) — (25°C) — (50°C) — (75°C) –> chaud

Au niveau code cela se résume à faire un map() sur des nombres flottants.

Le montage

S0042004

C’est le même que celui de mon précédent article, avec une led RGB en plus.
Les leds sont connectées aux sorties PWM 3, 5, et 6.

S0122012

Bon par contre j’ai du polir le boitier de la led.
De base le boitier « cristal » ne diffuse absolument rien et les trois couleurs RGB ne sont pas du tout mélangées ensembles.

Le code

C’est le même que celui de mon précédent article, la partie « couleurs » en plus.

/* Librairie Wire pour les communications I2C */
#include <Wire.h>

/* Adresse par défaut du capteur IR */
#define I2C_ADDR 0x5A

/** Map function (float version) */
float fmap(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

/** Fonction setup() */
void setup() {

  /* Initialisation du port série (pour debug) */
  Serial.begin(115200);
  Serial.println(F("BOOT"));

  /* Initialisation du bus I2C */
  Wire.begin();

  /* Mise en sortie de broches PWM */
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

/** Fonction loop() */
void loop() {

  /* Données brute de température */
  uint16_t data;

  /* Commande de lecture de la RAM à l'adresse 0x07 */
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(0x07);
  Wire.endTransmission(false);

  /* Lecture des données : 1 mot sur 16 bits + octet de contrôle (PEC) */
  Wire.requestFrom(I2C_ADDR, 3, false);
  while(Wire.available() < 3);
  data = Wire.read();
  data |= (Wire.read() & 0x7F) << 8;  // Le MSB est ignoré (bit de contrôle d'erreur)
  Wire.read(); // PEC
  Wire.endTransmission();

  /* Calcul de la température */
  const float tempFactor = 0.02; // 0.02°C par LSB -> résolution du MLX90614
  float tempData = (tempFactor * data) - 0.01;
  float celsius = tempData - 273.15; // Conversion des degrés Kelvin en degrés Celcius

  /* Affichage de la température (pour debug) */
  //Serial.print(F("Celcius: "));
  //Serial.println(celsius);

  /* Map la plage -25° ~ +75° vers la plage 240 (bleu sombre) ~ 0 (rouge vif) du modèle de couleur TSV */
  const float lowTempBlue = 10.0;
  const float highTempRed = 40.0;
  celsius = constrain(celsius, lowTempBlue, highTempRed);
  float hue = fmap(celsius, lowTempBlue, highTempRed, 240.0, 0);

  /* Affiche la teinte (pour debug) */
  //Serial.print(F("Hue: "));
  //Serial.println(hue);

  /* Affiche les couleurs */
  float r, g, b;
  HSVtoRGB(&r, &g, &b, hue, 1, 1);
  setLeds(r * 255, g * 255, b * 255);

  /* Affiche les composantes RGB (pour debug) */
  //Serial.print(F("R: "));
  //Serial.println(r);
  //Serial.print(F("G: "));
  //Serial.println(g);
  //Serial.print(F("B: "));
  //Serial.println(b);
  //Serial.println(F("---------------"));

  /* Temps d'attente */
  //delay(250);
}

/** From http://www.cs.rit.edu/~ncs/color/t_convert.html */
void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v ) {
  int i;
  float f, p, q, t;
  if( s == 0 ) {
    // achromatic (grey)
    *r = *g = *b = v;
    return;
  }
  h /= 60;			// sector 0 to 5
  i = floor( h );
  f = h - i;			// factorial part of h
  p = v * ( 1 - s );
  q = v * ( 1 - s * f );
  t = v * ( 1 - s * ( 1 - f ) );
  switch( i ) {
  case 0:
    *r = v;
    *g = t;
    *b = p;
    break;
  case 1:
    *r = q;
    *g = v;
    *b = p;
    break;
  case 2:
    *r = p;
    *g = v;
    *b = t;
    break;
  case 3:
    *r = p;
    *g = q;
    *b = v;
    break;
  case 4:
    *r = t;
    *g = p;
    *b = v;
    break;
  default:		// case 5:
    *r = v;
    *g = p;
    *b = q;
    break;
  }
}

void setLeds(byte r, byte g, byte b) {
  // Leds à anode commune
  analogWrite(6, 255 - r);
  analogWrite(5, 255 - g);
  analogWrite(3, 255 - b);

  // Leds à cathode commune
  //analogWrite(6, r);
  //analogWrite(5, g);
  //analogWrite(3, b);
}

Le résultat

Les premiers essais ont été un peu foireux, mais la dernière photo est à mes yeux un vrai succès !
Je vous laisse juger par vous même 😉

P1060981

P1060982

P1060983

P1060984

P1060985

P1060986

P1060987

Bon WE à tous !

Discussion

17 réflexions sur “[Arduino] Light-painting et capteur de température ? Humm …

  1. Quel artiste!

    Publié par barbudor | 2 novembre 2013, 17 h 15 min
    • J’ai nommé cette œuvre : « Soif de couleur » en référence à ## insérer ici le nom d’un mec ayant vaguement peint un tasse ##.
      Cette œuvre d’art moderne met en abysse l’importance du contenu par rapport au contenant, et son impact sur l’environnement immédiat du contenant.

      Bon ok je déconne j’avais que ces deux tasses sous la main et j’ai foutu de l’eau et des glaçons partout 🙂
      Notes pour ceux qui voudraient refaire la même photo :
      – l’eau ça mouille
      – les glaçons c’est froid
      – se casser la gueule quand on transporte une tasse d’eau froide rempli de glaçons n’est pas une bonne idée.

      Publié par skywodd | 2 novembre 2013, 17 h 34 min
  2. c’est bô! Bravo!

    Publié par f4grx | 2 novembre 2013, 23 h 03 min
  3. C’est beau !
    T’es génial ! Tu peux changer l’échelle de température ?
    Tu tires à quel distance ? La distance entre le boitier led et la tasse ?
    Tu peux augmenter la précision ?

    Publié par Barrois | 3 novembre 2013, 10 h 35 min
    • >> Tu peux changer l’échelle de température ?

      Oui, j’ai mis deux variables : lowTempBlue et highTempRed pour fixer la valeur basse et haute de l’échelle facilement.

      >> Tu tires à quel distance ? La distance entre le boitier led et la tasse ?

      Objet / led je doit être à 5 cm, mais mon montage sur breadboard n’est pas des plus pratique.
      Pour une utilisation « en vrai » il faudrait monter la led et le capteur dans une lampe stylo de médecin par exemple pour avoir un truc facile à bouger rapidement.

      >> Tu peux augmenter la précision ?

      0.02°C pas plus, c’est la limite du capteur. Mais bon c’est déjà largement suffisant.

      Publié par skywodd | 3 novembre 2013, 12 h 17 min
      • Merci de tes réponses trés prometteuses !
        Mon Pb : visualiser les flux d’air en face avant d’un rack de serveurs
        Penses-tu qu’en mettant une feuille grande feuille perpendiculairement à la face et en la balayant avec ton light-painter, on puisse éclairer la feuille avec sa température et donc celle du courant d’air ?
        Comment pourrait-on augmenter la distance entre light-painter et sa cible ?
        Pourrait-on en associer plusieurs ?

        Publié par Barrois | 3 novembre 2013, 12 h 42 min
      • Ce qu’il te faut c’est une vrai caméra thermique, ou un « thermomètre visuel » (même chose mais avec un nom différent pour éviter les brevet) 😉

        Pour 200€ j’en avait trouvé une chez casto (marque Titan), je sait plus si elle se fait encore mais voila à quoi ça ressemble au final :

        Après si tu veut de la haute résolution pour pas cher le plus simple c’est de faire un stylo dans ce genre :
        LED rgb —- petit contrôleur avec le code —- capteur

        Et tu déplaces le stylo devant ton rack, tu auras directement un trait comme sur mes 1er photos vu que la led est directement face à l’objectif.

        Publié par skywodd | 3 novembre 2013, 13 h 00 min
      • J’ai déjà essayé à la caméra thermique, l’angle de prise de vue est trop étroit pour l’espace que nous avons et la chaleur des racks perturbe la photo.
        Il y a un type qui a fait ça : http://www.instructables.com/id/Build-a-Thermal-Flashlight-Light-Painting-with-T/step5/Programming-and-Final-Assembly/
        C’est pas mal ! Ton idée en plus grand !

        Publié par Barrois | 3 novembre 2013, 13 h 27 min
      • C’est pas con de mettre le capteur au milieu d’un cercle de leds.

        Bon par contre son truc c’est bien pour faire du light painting à l’échelle d’une pièce, voir d’une maison, mais pas d’une tasse ^^ »

        Publié par skywodd | 3 novembre 2013, 13 h 33 min
  4. Désolé, je dois refaire un message pour réobtenir l’envoi des mails relatifs à cet article, que j’ai « écrasé »

    Publié par Barrois | 3 novembre 2013, 10 h 42 min
  5. Salut skywodd, C’est skizoh du forum arduino ^^ je faisait un petit tour de tes dernières bricoles et je suis tombé la dessus, alors autant j’ai adoré le rendu sur les photos etc, même sur les premières ou on voit les tracés en zigzag, j’ai bien compris que tu modifiai la lumière de la led en fonction de la température, mais ce que je n’ai pas compris ( en rapport avec ta photo ) comment tu fait avec une seul led et surtout une seul photo pour avoir de la couleur ( lumière de ta led ) à plusieurs endroit en même temps Oo …

    Tu prend la photo avec un appareil photo qui retient tout les tracé de lumière? sauf que ta lumière n’est pas la lampe vendu avec mais ton montage?

    Merci de m’apporter tes lumières ^^’

    Skizo !

    Publié par SKIZO | 6 novembre 2013, 16 h 48 min
  6. Je reste sur le cul, encore plus avec les image de l’autre lien Oo …. Je crois que tu te rend pas compte que ce que tu à fait est bien plus que commercialisable ! OMG ! Si un jour tu est en manque d’argent je te rachète ça immédiatement xD ( pris discrètement pour que skywodd tombe dans la misère et la pauvreté même si c’est pas gentil :$ xD )

    Publié par SKIZO | 8 novembre 2013, 17 h 27 min
  7. Salut,

    J’ai pas trop compris le principe au final. Tu récupères la température avec ton capteur sans contact, mais comment le dessin se fait il ?

    Merci

    Publié par Minipada | 17 novembre 2013, 22 h 41 min
    • Regarde « light painting » sur google (ou sinon la vidéo dans les commentaires de l’article deux com’s plus haut) 😉
      Pour faire court c’est juste de la photographie avec un temps d’exposition de plusieurs secondes.

      Publié par skywodd | 18 novembre 2013, 20 h 12 min

Rétroliens/Pings

  1. Pingback: Hardware | Pearltrees - 22 mars 2014

  2. Pingback: Techniques | Pearltrees - 16 septembre 2017

Skyduino devient Carnet du Maker

Le site Carnet du Maker remplace désormais le blog Skyduino pour tout ce qui touche à l'Arduino, l'informatique et au DIY.