Lampe d'éclairage évoluée

Pour répondre à une problématique d'éclairage dans une pièce à vivre, et devant l'impossibilité de trouver un produit adapté, j'ai décidé de créer ma propre lampe.

Mon cahier des charges comprend :

  • être alimenté par un source unique (l'installation électrique n'est pas aisément modifiable)
  • dans un but écologique, être peu consommatrice d'énergie dans la mesure du possible
  • fournir un éclairage classique pour les activités nécessitant un environnement clair
  • fournir un éclairage indirect et un choix de couleur pour des activités plus 'cosy'
  • être pilotable sans ajout de fil
  • être économique

Cela fait plusieurs années que je suis tenté par l'idée d'un éclairage indirect, mais mon logement actuel ne permet pas d'en disposer facilement.

D'autre part, dans le logement que j'occupe, l’éclairage en place est peu performant et absolument pas ajustable, car composé d'une suspension avec une simple ampoule (c'est fluo-compacte quand même) qui ne connaît que deux états : allumée ou éteinte.

Comme je ne suis pas spécialement créatif, j'ai parcouru quelques sites de 'design astucieux', et j'ai trouvé l'idée de base sur le site http://www.ikeahackers.net/

Luminaire trouvé sur le site IkeaHackers et servant d'inspiration

Mon luminaire est donc donc composé des éléments suivant :

  • un plateau carré de 55x55 cm positionné à quelques centimètres du plafond (Table Läck Ikéa : 5,99€ )
  • 4 suspensions en verre incluant des leds blanches haute luminosité (Lampes à poser Gröno Ikéa, retournées : 4,50€x4)
  • un bandeau de leds Rouge/Vert/Bleu sur la face supérieur du plateau et éclairant le plafond
  • un micro-controlleur (arduino) pilotant les différentes séries de leds
  • quelques composants électroniques variés (transistor, récepteur infrarouge, régulateur, condensateur..)
  • un alimentation 220V => 12V

La gestion électronique Le cœur du montage est un Atmega328. Le prototypage initial à été réalisé sur une plateforme Arduino, puis très vite, je suis passé a l'arduino 'standalone', c'est à dire un Atmega328 sur platine sans soudure.

Après quelques déboire liés aux contraintes de la librairie 'IR' empêchant d'utiliser certaines sorties, je suis arrivé à un montage parfaitement fonctionnel.

Voici en exemple le code actuellement utilisé. Il sera ajusté ultérieurement, car j'utilise une télécommande de récupération pour l'instant, et je devrais donc modifier les codes infrarouge pour déclencher telle ou telle opération.

Quelques modes de fonctionnements sont également envisagés par la suite, mais pour l'heure, la partie électronique est largement assez aboutie pour trouver sa place dans mon luminaire.

/*
RGB control
This sketch is designed to control an RGB led stripe
and a white light with an IR remote

Final usage described on :
http://hackerspace.ouvrages-web.fr/projects/4

It use Ken Shirriff's IR Librarie
http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html
*/

/*
Remote Code for Nikenny DVP2198 - Decimal (Hex)


Repeat = 4294967295 (FFFFFF) // the code from the remote if you keep a button depressed

Power = 16744575 : function = Set all outputs to 0, and send an IR code to shutdown TV
Open/Close = 16756815

1 = 16741005 (FF728D) : function = Red +
2 = 16732845 (FF52AD) : function = Green +
3 = 16736925 (FF629D) : function = Blue +
4 = 16757325 (FFB24D) : function = Red -
5 = 16749165 (FF926D) : function = Green -
6 = 16753245 (FFA25D) : function = Blue -
7 = 16724685 (FF32CD) : function = White +
8 = 16716525 (FF12ED) : function = Not used
9 = 16720605 (FF22DD) : function = Restore saved memory (setting with 'program' button)
0 = 16724175 (FF30CF) : function = White -
+10 - = 16716015 (FF10EF) : function = Not used

Up = 16769055 : function = Increase all lights
Down = 16764975 : function = Decrease all lights
Left = 16740495
Right = 16732335


Program = 16720095 : function = save the W+RGB values to a memory (eeprom)
Setup = 16773135
Menu = 16736415
Stop = 16775175
Select = 16762935

*/

// IR receveir is a TSOP48xx module.
// For 38KHz remote, the part number used is TSOP4838

#include <IRremote.h>
#include <EEPROM.h> // EEPROM used to store datas


int RECV_PIN = 4;          // Used pin to receive IR signal
IRrecv irrecv(RECV_PIN);
decode_results results;

IRsend irsend;  // Init the Digital pin 3 to IR OUT

int WledPin = 9;  // White leds ramp
int WledValue = 0 ;
int RledPin = 6;   // Red Leds
int RledValue = 0 ;
int GledPin = 10;  // Green Leds
int GledValue = 0 ;
int BledPin = 5;  // Blue Leds
int BledValue = 0 ;


int PowerSensePin = 0 ;  // Pin is used to sense if power is applied or if there is only a battery
int Power = 0 ;
// int PowerOffCycles = 0 ;

unsigned long PreviousValue = 0 ;

// Limits :
int MaxLedValue = 255 ;   // set max value
int MinLedValue = 0 ;    // set min value
int Step = 2 ;           // step between 2 change in value
int StepTime = 0 ;      // Time between two step of ledValue change
// int WaitTime = 500 ;    // Time between two colors cycles




void setup()  { 
// set white and R,G,B Led Pin to ouput, with values to 0 during init
    pinMode(WledPin, OUTPUT);
    analogWrite(WledPin, 0);
    pinMode(RledPin, OUTPUT);
    analogWrite(RledPin, 0);
    pinMode(GledPin, OUTPUT);
    analogWrite(GledPin, 0);
    pinMode(BledPin, OUTPUT);
    analogWrite(BledPin, 0);

// set defined pin to sensing if power is present
    pinMode(PowerSensePin, INPUT);

// Start serial output for debugging
    Serial.begin(9600);
    Serial.println("RGB control by Rault Alexandre");


    irrecv.enableIRIn(); // Start the IR receiver

/*
Load stored value saved in EEPROM in last power down
Adress used are the same as for pin (more simple) :
*/

WledValue = EEPROM.read(WledPin) ;
RledValue = EEPROM.read(RledPin) ;
GledValue = EEPROM.read(GledPin) ;
BledValue = EEPROM.read(BledPin) ;

}                           // End of Setup

// Function to store W,R,G and B values to eeprom during power down
void EepromStoreOff (){
    EEPROM.write(WledPin, WledValue) ;
    EEPROM.write(RledPin, RledValue) ;
    EEPROM.write(GledPin, GledValue) ;
    EEPROM.write(BledPin, RledValue) ;
/*  Serial.println(WledValue);
    Serial.println(RledValue);
    Serial.println(GledValue);
    Serial.println(BledValue);
    Serial.println( "Values recorded to EEPROM" );
*/
}

// Function to store W,R,G and B values to eeprom in prog
void EepromStoreProg (){
    EEPROM.write(WledPin + 10 , WledValue) ;
    EEPROM.write(RledPin + 10 , RledValue) ;
    EEPROM.write(GledPin + 10 , GledValue) ;
    EEPROM.write(BledPin + 10, RledValue) ;
/*  Serial.println(WledValue);
    Serial.println(RledValue);
    Serial.println(GledValue);
    Serial.println(BledValue);
    Serial.println( "Values recorded to EEPROM" );
*/
}



// Function to writes values to PWM outputs
void WriteValues (){
    // Check Limits
    if (WledValue > MaxLedValue) {
      WledValue = MaxLedValue ;
    }

    if (WledValue < MinLedValue) {
      WledValue = MinLedValue ;
    }

    if (RledValue > MaxLedValue) {
      RledValue = MaxLedValue ;
    }

    if (RledValue < MinLedValue) {
      RledValue = MinLedValue ;
    }

    if (GledValue > MaxLedValue) {
      GledValue = MaxLedValue ;
    }

    if (GledValue < MinLedValue) {
      GledValue = MinLedValue ;
      }

    if (BledValue > MaxLedValue) {
      BledValue = MaxLedValue ;
    }

    if (BledValue < MinLedValue) {
      BledValue = MinLedValue ;
    }


// Write values to output
analogWrite(WledPin, WledValue);
analogWrite(RledPin, RledValue);
analogWrite(GledPin, GledValue);
analogWrite(BledPin, BledValue);
delay(StepTime);

}  // End of fonction to writes values to PWM outputs



void loop()  {

//  Serial.println("Loop begin");

    if (irrecv.decode(&results))
    {
      Serial.println(results.value, DEC);
      irrecv.resume(); // Receive the next value
    }


        if ( results.value != 0 )  // If an IR code is received
    {
        if ( results.value != 4294967295 ) // If this code is not 'repeat'
        {
        //Serial.println("");
        //Serial.println("Trame reçue");
        //Serial.print("results.value is ");
        //Serial.println(results.value);
        PreviousValue = results.value;
        //Serial.print("PreviousValue = ");
        //Serial.println(PreviousValue);
        }
       }


    // Repeat detection
        if ( results.value == 4294967295 )
        {
        // Serial.println("");
        // Serial.println("Repeat code received");
        // Serial.print("PreviousValue = ");
        // Serial.println(PreviousValue);
        results.value = PreviousValue ;
        // Serial.print("results.value set to ");
        // Serial.println(results.value);
            }


  switch(results.value){  // Select action according to IR code received

  case 16741005: // more red = 1
  RledValue = RledValue + Step ;
  delay (StepTime);
  break;

  case 16732845: // more green = 2
  GledValue = GledValue + Step ;
  delay (StepTime);
  break;

  case 16736925: // more Blue = 3
  BledValue = BledValue + Step ;
  delay (StepTime);
  break;


  case 16757325: // less red = 4
  RledValue = RledValue - Step ;
  delay (StepTime);
  break;

  case 16749165: // less green = 5
  GledValue = GledValue - Step ;
  delay (StepTime);
  break;

  case 16753245: // less Blue = 6
  BledValue = BledValue - Step ;
  delay (StepTime);
  break;

  case 16724685: // more white = 7
  WledValue = WledValue + Step ;
  delay (StepTime);
  break;

  case 16720605: // Restore setting = 9
   /*
    Load stored value saved in EEPROM in last power down
    Adress used are the same as for pin (more simple) :
    */
    WledValue = EEPROM.read(WledPin +10 ) ;
    RledValue = EEPROM.read(RledPin +10 ) ;
    GledValue = EEPROM.read(GledPin +10 ) ;
    BledValue = EEPROM.read(BledPin +10 ) ;
  break;

  case 16720095: // Set memory = Program
    EepromStoreProg ();
  break;

  case 16724175: // less red = 0
  WledValue = WledValue - Step ;
  delay (StepTime);
  break;

  case 16769055: // more All = Up
  WledValue = WledValue + Step ;
  RledValue = RledValue + ( Step / 2 ) ;
  GledValue = GledValue + Step ;
  BledValue = BledValue + Step ;
  delay (StepTime);
  break;

  case 16764975: // less All = Down
  WledValue = WledValue - Step ;
  RledValue = RledValue - ( Step / 2 ) ;
  GledValue = GledValue - Step ;
  BledValue = BledValue - Step ;
  delay (StepTime);
  break;


  case 16744575: // Power
    WledValue = 0 ;
    RledValue = 0 ;
    GledValue = 0 ;
    BledValue = 0 ;
    irsend.sendRC5(0xa90, 12) ; // Sony TV power code
    irrecv.enableIRIn(); // Start the receiver
  break;


  }

    results.value = 0 ; // re-init IR librarie

    WriteValues (); // Call the function to write values on the ports



/*
Power detection.
When you switch off the room with the wall switch, the
main power is removed, but a big capacitor will provide some
current to get 1 second or more of MCU running.

Then, the actual values are stored in eeprom.

During the next power up, the values will be read, and it will
restore the light at the same level.

If you do the following with the wall switch :
ON-OFF-ON, during the 'capacitor extra time',
a new power up is detected and the memory values
are used. You don't need the remote to light the room !

*/

Power = analogRead(PowerSensePin) ;

    if ( Power == 0)
    {
    Serial.println( " => No main power" );
    EepromStoreOff (); // Call the function to store values
    Serial.println( "Values stored to EEPROM" );

        while ( Power == 0)
        {
        Serial.println( " ... Waiting for Power" );
        Power = analogRead(PowerSensePin);
        Serial.println( Power );

            if ( Power > 5)
            {
                    WledValue = EEPROM.read(WledPin +10 ) ;
                    RledValue = EEPROM.read(RledPin +10 ) ;
                    GledValue = EEPROM.read(GledPin +10 ) ;
                    BledValue = EEPROM.read(BledPin +10 ) ;
            break;  
                    }


        }

    }

}
Auteur
.AleX.
Dernière mise à jour
samedi 02 mars 2013 à 14h16
Historique