Lampe Pantone (Arduino + Capteur de couleurs + RGB Leds)

Croyez-vous à la lampe dévoreuse de couleurs Pantone? Et bien elle existe et elle est présentée en détail dans cet article.

Il y a un an j’ai acheté une boite de cartes postales Pantone sans trop savoir pourquoi. Surement parce que les jolies couleurs me fascinent, surtout quand elles sont estampillées de noms comme Grass Green, Caribbean Sea ou encore Striking Purple. Et puis un jour, une idée me traversa l’esprit: pourquoi ne pas faire une lampe capable de reconnaître les couleurs et des les retransmettre lumineusement ? La lampe Pantone est née ! Découvrez la en vidéo:

Comment la fabriquer ?

Pour réaliser ce style de lampe, vous avez besoin de:

  • Un Arduino
  • Un capteur de couleurs TCS230D (10€ sur eBay)
  • 4 Leds RGB avec 12 résistances
  • Fils électrique
  • 2 Shift Register (74HC595)
  • Cartes postales Pantone (15$ sur Amazon)
  • Une boite en bois pour le support (5€ chez Loisirs & Création)
  • Tubes à essai avec support (6€ chez Loisirs & Création)

Le budget total pour réaliser la lampe est d’environ 60€ (en comptant l’Arduino)

Je suppose ici que vous avez de bonnes bases en Arduino, c’est pourquoi je ne vais pas détailler l’ensemble du montage. Mais si vous avez des question n’hésitez pas à les poser via les commentaires :)

Le montage des Leds RGB

Pour cette lampe j’ai choisis de mettre 4 Leds RGB (avec cathode commune). Le problème avec les leds RGB c’est qu’elles disposent de 4 pattes: 1 pour la masse (cathode), 1 pour le rouge, 1 pour le vert et 1 pour le bleu. Chaque led RGB doit donc être connectée à 3 pins analogique (PWM) de l’Arduino soit au total 12 pins analogiques (en sortie) pour 4 leds. Malheureusement l’Arduino Uno n’en dispose que de 6, c’est pourquoi j’ai utilisé les registres à décalage permettant de multiplexer les pins (passage de 3 pins à 8 pins et plus si montage des registres en série). Globalement, un registre à décalage permet de transformer des bits en série vers du parallèle grâce à une horloge. Pour pouvoir faire de l’analogique avec les registres à décalage, il existe une très bonne librairie nommée ShiftPWM. Le schéma du montage des led est présenté sur cette page. A noté que je n’ai pas utilisé d’accumulateur, car pour 4 leds ce n’est pas nécessaire.

Le montage du capteur TCS230D

Je ne vais pas détailler le montage du capteur de couleurs car ce site internet explique très bien comment interfacer le capteur à l’Arduino et comprendre son fonctionnement.

Le programme de l’Arduino

Le programme est assez compliqué, vous avez besoin de 3 librairies:

Attention à ne rien connecter sur les pins 9 et 10 de l’Arduino, en effet la librairie TimeOne les utilise pour gérer les timers. J’utilise la conversion RGB vers HSV afin de redonner de la saturation aux couleurs, en effet les couleurs capturées sont un peu ternes. Le fait de les coder en HSV permet d’augmenter facilement la saturation afin d’avoir les bonnes couleurs.

#include 
#include 
#define _useTimer1
#include 

/* Color Sensor Pins */
#define S0     6
#define S1     4
#define S2     7
#define S3     5
#define OUT    2

/* LED Pins  */
#define LEDROUGE   5
#define LEDVERT    6
#define LEDBLEU    3

int   g_count = 0;    // Count the frequecy
int   g_array[3];     // Store the RGB value
int   g_flag = 0;     // Filter of RGB queue
float g_SF[3];        // Save the RGB Scale factor

/* ShiftPWM Config */
const int ShiftPWM_latchPin=8;
const bool ShiftPWM_invertOutputs = false; 
const bool ShiftPWM_balanceLoad = false;
unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int numRegisters = 2;
int numRGBleds = numRegisters*8/3;

// Init TSC230 and setting Frequency.
void TSC_Init()
{
  // Set output pin
  pinMode (LEDVERT,OUTPUT); 
  pinMode (LEDROUGE,OUTPUT);
  pinMode (LEDBLEU,OUTPUT); 
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(OUT, INPUT);

  // Output frequency scaling 2%
  digitalWrite(S0, LOW);  
  digitalWrite(S1, HIGH); 
}

// Select the filter color 
void TSC_FilterColor(int Level01, int Level02)
{
  if(Level01 != 0)
    Level01 = HIGH;

  if(Level02 != 0)
    Level02 = HIGH;

  digitalWrite(S2, Level01); 
  digitalWrite(S3, Level02); 
}

void TSC_Count()
{
  g_count ++ ;
}

void TSC_Callback()
{
  switch(g_flag)
  {
    case 0: 
         Serial.println("->WB Start");
         TSC_WB(LOW, LOW); //Filter without Red
         break;
    case 1:
         Serial.print("->Frequency R=");
         Serial.println(g_count);
         g_array[0] = g_count;
         TSC_WB(HIGH, HIGH); //Filter without Green
         break;
    case 2:
         Serial.print("->Frequency G=");
         Serial.println(g_count);
         g_array[1] = g_count;
         TSC_WB(LOW, HIGH); //Filter without Blue
         break;

    case 3:
         Serial.print("->Frequency B=");
         Serial.println(g_count);
         Serial.println("->WB End");
         g_array[2] = g_count;
         TSC_WB(HIGH, LOW); //Clear(no filter)   
         break;
   default:
         g_count = 0;
         break;
  }
}

void TSC_WB(int Level0, int Level1)      //White Balance
{
  g_count = 0;
  g_flag ++;
  TSC_FilterColor(Level0, Level1);
  Timer1.setPeriod(1000000);             // Set 1s period
}

void setup()
{
  TSC_Init();
  Serial.begin(9600);
  Timer1.initialize(1000);
  Timer1.attachInterrupt(TSC_Callback);  
  attachInterrupt(0, TSC_Count, RISING);
  delay(5000);
  g_SF[0] = 255.0/ g_array[0];     //R Scale factor
  g_SF[1] = 255.0/ g_array[1];    //G Scale factor
  g_SF[2] = 255.0/ g_array[2];    //B Scale factor

  ShiftPWM.SetAmountOfRegisters(numRegisters);
  ShiftPWM.SetPinGrouping(1);
  ShiftPWM.Start(pwmFrequency,maxBrightness);
}

void loop()
{
   ShiftPWM.SetAll(0);
   g_flag = 0;
   int valR = int(g_array[0] * g_SF[0]);
   int valG = int(g_array[1] * g_SF[1]);
   int valB = int(g_array[2] * g_SF[2]);
   ledRVBpwm(valR,valG,valB);
   delay(5000);
}

void ledRVBpwm(int pwmRed, int pwmGreen, int pwmBlue) {
 if(pwmRed > 255)
   pwmRed = 255;
 if(pwmGreen > 255)
   pwmGreen = 255;
 if(pwmBlue > 255)
   pwmBlue = 255;

   // RGB to HSV conversion
   byte r = pwmRed;
   byte g = pwmGreen;
   byte b = pwmBlue;
   double hsv[3];
   byte rgb[3];
   RGBConverter color;
   color.rgbToHsv(r,g,b,hsv);

   // Saturate the color thanks to HSV
   color.hsvToRgb(hsv[0],1,1,rgb);
   ShiftPWM.SetAllRGB(rgb[0],rgb[1],rgb[2]);
}

N’hésitez pas à laisser un commentaire pour toutes questions ou avis.

Discussion6 Comments

  1. Damien dit :

    Il y a probablement moyen d’utiliser ce même principe pour piloter une vraie lampe d’ambiance (http://www.livingambiance.philips.com/), chouette idée !

  2. jinman dit :

    Salut! Bravo c’est vraiment super !!!!

  3. ITBAG (by Sacdunjour) propose la vente de sacs à main prestigieux (Chanel, Louis Vuitton, Gucci, Dior et bien d’autres). Profitez de nos offres en neuf, occasion
    paul smith sacs http://www.chranene-dilny.eu/?post=37444

Ajouter son grain de sel