Mood Lamp LED

 

History

    After I made my Kitchen Mood Light,  I had another idea for 3W RGB LED's.  My idea was to make a simple lamp with 3W RGB LED's, controlled by a MCU, and have an IR remote control to change the color, effects and patterns.  I found a nice lamp and spent a lot of time doing modifications to fit the LED's into it. I finally made something very nice - you can see them in the pictures below.  The code and electronics were very simple; the hardest thing was to make something that looked good.  You will see in the pictures that I have made 2 different lamps.
 

   

Features

puce 3W RGB LEDs
puce Over 16 million colors can be generated
puce Very powerful.
puce Many patterns are pre-programmed


 

Pictures

Click to enlarge

Lamp 1 at 2 different color

Lamp 1 at 2 different color

Lamp 1 Off

Inside the lamp 1 box

Lamp 2

View of the LED in the Lamp 2

Control of the Lamp 2

Inside the control of the Lamp 2

All in green

 

 

All in blue

Multi-Color

Multi-Color

 

 

Sources codes & Schematics

-Schematic in PDF format

 

//*****************************************************************************
// Mood Lamp
// Version 1.0 April 2008
//
//
// Sylvain Bissonnette
//*****************************************************************************
// Editor : UltraEdit32
//*****************************************************************************
//
//                         R E T U R N   S T A C K   3 2
//                                  X T A L  16 MHZ
//
//*****************************************************************************
//
//                F U S E   B I T
//
//( )7      ( )6     (X)BL12 (X)BL11  ( )BL02   ( )BL01    ( )Lock2   ( )Lock1
//( )RSTDIS ( )WDON  (X)SPIEN(X)CKOPT (X)EESAVE (X)BOOTSZ1 ( )BOOTSZ0 (X)BOOTRST
//(X)BODLEV (X)BODEN ( )SUT1 ( )SUT0  ( )CKSEL3 ( )CKSEL2  ( )CKSEL1  ( )CKSEL0
//
//*****************************************************************************
//                P I N   U S A G E
//
// PB0 -> IR input
// PB1 -> n/c
// PB2 -> n/c
// PB3 -> n/c
// PB4 -> n/c
// PB5 -> n/c
// PB6 -> Xtal
// PB7 -> Xtal
//
// PC0 -> n/c 
// PC1 -> n/c
// PC2 -> n/c
// PC3 -> n/c
// PC4 -> n/c
// PC5 -> n/c
// PC6 -> RESET
//
// PD0 -> LED 1 Red
// PD1 -> LED 1 Green
// PD2 -> LED 1 Blue
// PD3 -> LED 2 Red
// PD4 -> LED 2 Green
// PD5 -> LED 2 Blue
// PD6 -> n/c
// PD7 -> n/c
//
// ADC6-> n/c
// ADC7-> n/c
//
//*****************************************************************************
//                T I M E R   U S A G E
//
// Timer 0 is not used
// Timer 1 is use by IR remote controle
// Timer 2 is use by Led PWM
//
//*****************************************************************************

//*****************************************************************************
//                      I N C L U D E
//*****************************************************************************
#include <iom32v.h>
#include <macros.h>
#include <stdlib.h>
#include <eeprom.h>
#include <string.h>
#include <stdio.h>
#include <shortnametype.h>
#include "TaskManager.h"

//*****************************************************************************
//                      D E F I N E
//*****************************************************************************
#define VERSION               100
#define TRUE                  1
#define FALSE                 0
#define XTAL                  16000000
#define TASKLED                        1

#define LED1_RED                 0x01 //(1<<PD0)
#define LED1_GREEN            (1<<PD1)
#define LED1_BLUE                (1<<PD2)
#define LED1_DDR                 DDRD
#define LED1_PORT                PORTD
#define LED1_PIN                 PIND

#define LED2_RED                 (1<<PD3)
#define LED2_GREEN            (1<<PD4)
#define LED2_BLUE                (1<<PD5)
#define LED2_DDR                 DDRD
#define LED2_PORT                PORTD
#define LED2_PIN                 PIND

#define IR_DDR                DDRD
#define IR_PIN                PIND
#define IR_PORT               PORTD
#define IR_INPUT              0x40

#define REMOTE_UP             20
#define REMOTE_DOWN           21
#define REMOTE_RIGHT          22
#define REMOTE_LEFT           23
#define REMOTE_MENU           24
#define REMOTE_STOP           30
#define REMOTE_PLAY           31
#define REMOTE_MUTE           32
#define REMOTE_REW            33
#define REMOTE_FFWD           34
#define REMOTE_PAUSE          35
#define REMOTE_POWER          40

#define TIMEOUT                        100


#define DEBUG_XTAL                  16000000
#define DEBUG_DDR             DDRD
#define DEBUG_PORT               PORTD
#define DEBUG_BIT                0x80


//*****************************************************************************
//                  P R O T O T Y P E
//*****************************************************************************
void main(void);
void _StackOverflowed(char c);

ushort GetRand(ushort Mask);

ushort Delay(ulong DelayStep, ulong DelayMin);
ushort Automatic(void);
ushort ManualMode(ulong Delay, ulong DelayStep, ulong DelayMin);
void ClearAll(void);
ushort RandomAll(ulong Delay, ulong DelayStep, ulong DelayMin);
ushort RandomEqualAll(ulong Delay, ulong DelayStep, ulong DelayMin);
ushort RandomSmoothAll(ulong Delay, ulong DelayStep, ulong DelayMin);
ushort RGBAll(ulong Delay, ulong DelayStep, ulong DelayMin);
ushort ColorMixAll(ulong Delay, ulong DelayStep, ulong DelayMin);
ushort ColorMix(ulong Delay, ulong DelayStep, ulong DelayMin);
ushort Sablier(ulong Delay, ulong DelayStep, ulong DelayMin);

void LedInit(void);
void LedStartShow(void);
void LedEngine(void);

void IRInit(void);
void IRLightChange(void);
void IRDecode(void);

void DebugXYHex(ushort x, ushort y, char *Ptr, ushort Len);
void DebugXY(ushort x, ushort y, char *Ptr);
void Debug(char *Ptr);
void DebugInit(void);


//*****************************************************************************
//                    G L O B A L   V A R I A B L E
//*****************************************************************************
uint LatchedIrData = 0;
uint RemoteKey = 1;

ushort Led1Red;
ushort Led1Green;
ushort Led1Blue;

ushort Led2Red;
ushort Led2Green;
ushort Led2Blue;

ulong VariableDelay;

uint MegaTimer;
ushort Auto = FALSE;

char Buffer[20];

//*****************************************************************************
//                            M A I N
//*****************************************************************************
void main()
{
   ulong i;

  WDR();
  WDTCR = 0x0f;     // Enable WatchDog at 2.2 sec

  IRInit();
  LedInit();
  ADInit();
  //DebugInit();
   SEI();

  while(TRUE)
  {
   WDR();
      if      (RemoteKey == 1) RandomAll(30000,1000,10000);
      else if (RemoteKey == 2) RandomEqualAll(1000,50,100);
      else if (RemoteKey == 3) RandomSmoothAll(1000,100,100);
      else if (RemoteKey == 4) RGBAll(1000,100,100);
      else if (RemoteKey == 5) ColorMixAll(1000,100,100);
      else if (RemoteKey == 6) ColorMix(1000,100,100);
      else if (RemoteKey == 7) Sablier(1000,10,100);
      else if (RemoteKey == 8) ManualMode(1000,100,1000);
      else if (RemoteKey == 9) Automatic();
  }
}

/******************************************************************************

Name:         void _StackOverflowed(char c)

Description:  This function is automaticaly called if
              the stack crash.

Input:        none

Output:       PB2

Misc:
******************************************************************************/
void _StackOverflowed(char c)
{
   c++;

  CLI();

  while(1);
}

/******************************************************************************

Name:         void Automatic(void)

Description:

Input:        none

Output:       none

Misc:             #9
******************************************************************************/
ushort Automatic(void)
{
   static Counter = 0;

   Auto = TRUE;
   while(TRUE)
   {
      Counter++;
      if      (Counter == 1) if (RandomAll(30000,1000,10000) == 0)
                                        {
                                             RemoteKey = -1;
                                             Auto = FALSE;
                                             return TRUE;
                                        }
                                        else RemoteKey = -1;

      else if (Counter == 2) if (RandomEqualAll(1000,50,100) == 0)
                                        {
                                             RemoteKey = -1;
                                             Auto = FALSE;
                                             return TRUE;
                                        }
                                        else RemoteKey = -1;

      else if (Counter == 3) if (RandomSmoothAll(1000,100,100) == 0)
                                        {
                                             RemoteKey = -1;
                                             Auto = FALSE;
                                             return TRUE;
                                        }
                                        else RemoteKey = -1;

      else if (Counter == 4) if (RGBAll(1000,100,100) == 0)
                                        {
                                             RemoteKey = -1;
                                             Auto = FALSE;
                                             return TRUE;
                                        }
                                        else RemoteKey = -1;

      else if (Counter == 5) if (ColorMixAll(1000,100,100) == 0)
                                        {
                                             RemoteKey = -1;
                                             Auto = FALSE;
                                             return TRUE;
                                        }
                                        else RemoteKey = -1;

      else if (Counter == 6) if (ColorMix(1000,100,100) == 0)
                                        {
                                             RemoteKey = -1;
                                             Auto = FALSE;
                                             return TRUE;
                                        }
                                        else RemoteKey = -1;

      else if (Counter == 7) if (Sablier(1000,50,100) == 0)
                                        {
                                             RemoteKey = -1;
                                             Auto = FALSE;
                                             return TRUE;
                                        }
                                        else RemoteKey = -1;
      else Counter = 0;
   }
   return -1;
}

/******************************************************************************

Name:         void ClearAll(void)

Description:

Input:        none

Output:       none

Misc:            
******************************************************************************/
void ClearAll(void)
{
   Led1Red =   0;
   Led1Green = 0;
   Led1Blue =  0;

   Led2Red =   0;
   Led2Green = 0;
   Led2Blue =  0;
}

/******************************************************************************

name:         void randomall(void)

description:

input:        none

output:       none

misc:             #1
******************************************************************************/
ushort RandomAll(ulong DelayTick, ulong DelayStep, ulong DelayMin)
{
   ushort Key;

   RemoteKey = -1;
  VariableDelay = DelayTick;

   MegaTimer = 0;
   while(TRUE)
   {
      if ((MegaTimer++ > TIMEOUT) && (Auto == TRUE)) return -1;

      WDR();

      Led1Red =   GetRand(0xff);
      Led1Green = GetRand(0xff);
      Led1Blue =  GetRand(0xff);

      Led2Red =   Led1Red;
      Led2Green = Led1Green;
      Led2Blue =  Led1Blue;


      Key = Delay(DelayStep, DelayMin);
      if (Key == 0) return Key;
   }
   return -1;
}

/******************************************************************************

Name:         void RandomEqualAll(void)

Description:

Input:        none

Output:       none

Misc:             #2
******************************************************************************/
ushort RandomEqualAll(ulong DelayTick, ulong DelayStep, ulong DelayMin)
{
   ushort Key;
   ushort i;
   ushort First = TRUE;

   RemoteKey = -1;
   MegaTimer = 0;
   VariableDelay = DelayTick;


   while(TRUE)
   {
      if ((MegaTimer++ > TIMEOUT * 30) && (Auto == TRUE)) return -1;

      WDR();

      if (First)
      {
         First = FALSE;
         for (i=0;i<254;i++)
         {
            Key = Delay(DelayStep, DelayMin);         // Red ++
            if (Key == 0) return Key;
            Led1Red++;
            Led2Red++;
         }
      }

      for (i=0;i<254;i++)
      {
         Key = Delay(DelayStep, DelayMin);         // Green ++
         if (Key == 0) return Key;
         Led1Green++;
         Led2Green++;
      }

      for (i=0;i<254;i++)
      {
         Key = Delay(DelayStep, DelayMin);         // Red --
         if (Key == 0) return Key;
         Led1Red--;
         Led2Red--;
      }

      for (i=0;i<254;i++)
      {
         Key = Delay(DelayStep, DelayMin);         // Blue ++
         if (Key == 0) return Key;
         Led1Blue++;
         Led2Blue++;
      }

      for (i=0;i<254;i++)
      {
         Key = Delay(DelayStep, DelayMin);         // Green --
         if (Key == 0) return Key;
         Led1Green--;
         Led2Green--;
      }

      for (i=0;i<254;i++)
      {
         Key = Delay(DelayStep, DelayMin);         // Red ++
         if (Key == 0) return Key;
         Led1Red++;
         Led2Red++;
      }

      for (i=0;i<254;i++)
      {
         Key = Delay(DelayStep, DelayMin);         // Blue --
         if (Key == 0) return Key;
         Led1Blue--;
         Led2Blue--;
      }
   }
   return -1;
}

/******************************************************************************

Name:         void RandomSmoothAll(void)

Description: 

Input:        none

Output:       none

Misc:             #3
******************************************************************************/
ushort RandomSmoothAll(ulong DelayTick, ulong DelayStep, ulong DelayMin)
{
   ushort Key;

   ushort RndRed = 0x7f;
   ushort RndGreen = 0x30;
   ushort RndBlue = 0x90;

   RemoteKey = -1;
   VariableDelay = DelayTick;

   MegaTimer = 0;
   while(TRUE)
   {
      if ((MegaTimer++ > TIMEOUT * 30) && (Auto == TRUE)) return -1;

      WDR();

      if (Led1Red >= RndRed) Led1Red--;
      if (Led1Red < RndRed) Led1Red++;
      if (Led1Red == RndRed) RndRed = GetRand(0xff);

      if (Led1Green >= RndGreen) Led1Green--;
      if (Led1Green < RndGreen) Led1Green++;
      if (Led1Green == RndGreen) RndGreen = GetRand(0xff);

      if (Led1Blue >= RndBlue) Led1Blue--;
      if (Led1Blue < RndBlue) Led1Blue++;
      if (Led1Blue == RndBlue) RndBlue = GetRand(0xff);

      Led2Red =   Led1Red;
      Led2Green = Led1Green;
      Led2Blue =  Led1Blue;

      Key = Delay(DelayStep, DelayMin);
      if (Key == 0) return Key;
   }
   return -1;
}

/******************************************************************************

Name:         void RGBAll(void)

Description:

Input:        none

Output:       none

Misc:             #4
******************************************************************************/
ushort RGBAll(ulong DelayTick, ulong DelayStep, ulong DelayMin)
{
   ushort Key;

   short RedAdd = 1;
   short GreenAdd = 1;
   short BlueAdd = 1;

   RemoteKey = -1;
   VariableDelay = DelayTick;

   MegaTimer = 0;
   while(TRUE)
   {
      if ((MegaTimer++ > TIMEOUT * 30) && (Auto == TRUE)) return -1;

      WDR();
      Led1Red += RedAdd;
      if (Led1Red == 0xff) RedAdd = -1;
      if (Led1Red == 0x00) RedAdd = 0;

      if (RedAdd == 0)
      {
         Led1Green += GreenAdd;
         if (Led1Green == 0xff) GreenAdd = -1;
         if (Led1Green == 0x00) GreenAdd = 0;
      }

      if (GreenAdd == 0)
      {
         Led1Blue += BlueAdd;
         if (Led1Blue == 0xff) BlueAdd = -1;
         if (Led1Blue == 0x00) BlueAdd = 0;
      }

      if ((RedAdd == 0) && (GreenAdd == 0) && (BlueAdd == 0))
      {
         RedAdd = 1;
         GreenAdd = 1;
         BlueAdd = 1;
      }

      Led2Red =   Led1Red;
      Led2Green = Led1Green;
      Led2Blue =  Led1Blue;

      Key = Delay(DelayStep, DelayMin);
      if (Key == 0) return Key;
   }
   return -1;
}

/******************************************************************************

Name:         void ColorMixAll(void)

Description:

Input:        none

Output:       none

Misc:             #5
******************************************************************************/
ushort ColorMixAll(ulong DelayTick, ulong DelayStep, ulong DelayMin)
{
   ushort Key;

   short RedAdd = 0;
   short GreenAdd = 0;
   short BlueAdd = 0;
   ushort i = 0;

   RemoteKey = -1;
   VariableDelay = DelayTick;

   MegaTimer = 0;
   while(TRUE)
   {
      if ((MegaTimer++ > TIMEOUT * 30) && (Auto == TRUE)) return -1;

      WDR();

      i = GetRand(0x07);

      if ((i & 0x01) == 0x01)
      {
         Led1Red += RedAdd;
         if (Led1Red == 0xff) RedAdd = -1;
         if (Led1Red == 0x00) RedAdd = 1;
      }

      if ((i & 0x02) == 0x02)
      {
         Led1Green += GreenAdd;
         if (Led1Green == 0xff) GreenAdd = -1;
         if (Led1Green == 0x00) GreenAdd = 1;
      }

      if ((i & 0x04) == 0x04)
      {
         Led1Blue += BlueAdd;
         if (Led1Blue == 0xff) BlueAdd = -1;
         if (Led1Blue == 0x00) BlueAdd = 1;
      }

      if (i == 0x07) i = 1;

      Led2Red =   Led1Red;
      Led2Green = Led1Green;
      Led2Blue =  Led1Blue;

      Key = Delay(DelayStep, DelayMin);
      if (Key == 0) return Key;
   }
   return -1;
}

/******************************************************************************

Name:         void ColorMix(void)

Description:

Input:        none

Output:       none

Misc:             #6
******************************************************************************/
ushort ColorMix(ulong DelayTick, ulong DelayStep, ulong DelayMin)
{
   ushort Key;

   ushort RndRed1 = 0x7f;
   ushort RndGreen1 = 0x30;
   ushort RndBlue1 = 0x90;

   ushort RndRed2 = 0x10;
   ushort RndGreen2 = 0x30;
   ushort RndBlue2 = 0xe0;

   RemoteKey = -1;
   VariableDelay = DelayTick;

   MegaTimer = 0;
   while(TRUE)
   {
      if ((MegaTimer++ > TIMEOUT * 30) && (Auto == TRUE)) return -1;

      WDR();

      if (Led1Red >= RndRed1) Led1Red--;
      if (Led1Red < RndRed1) Led1Red++;
      if (Led1Red == RndRed1) RndRed1 = GetRand(0xff);

      if (Led1Green >= RndGreen1) Led1Green--;
      if (Led1Green < RndGreen1) Led1Green++;
      if (Led1Green == RndGreen1) RndGreen1 = GetRand(0xff);

      if (Led1Blue >= RndBlue1) Led1Blue--;
      if (Led1Blue < RndBlue1) Led1Blue++;
      if (Led1Blue == RndBlue1) RndBlue1 = GetRand(0xff);

      //---

      if (Led2Red >= RndRed2) Led2Red--;
      if (Led2Red < RndRed2) Led2Red++;
      if (Led2Red == RndRed2) RndRed2 = GetRand(0xff);

      if (Led2Green >= RndGreen2) Led2Green--;
      if (Led2Green < RndGreen2) Led2Green++;
      if (Led2Green == RndGreen2) RndGreen2 = GetRand(0xff);

      if (Led2Blue >= RndBlue2) Led2Blue--;
      if (Led2Blue < RndBlue2) Led2Blue++;
      if (Led2Blue == RndBlue2) RndBlue2 = GetRand(0xff);




      Key = Delay(DelayStep, DelayMin);
      if (Key == 0) return Key;
   }
   return -1;
}

/******************************************************************************

Name:         void Sablier(ulong Delay, ulong DelayStep, ulong DelayMin)

Description:

Input:        none

Output:       none

Misc:             #7
******************************************************************************/
ushort Sablier(ulong DelayTick, ulong DelayStep, ulong DelayMin)
{
   ushort Key;

   ushort i;
   ushort First = TRUE;

   RemoteKey = -1;
   VariableDelay = DelayTick;

   ClearAll();

   MegaTimer = 0;
   while(TRUE)
   {
      if ((MegaTimer++ > TIMEOUT / 20) && (Auto == TRUE)) return -1;

      if (First)
      {
         for (i=0;i<255;i++)
         {
            Key = Delay(DelayStep, DelayMin);
            if (Key == 0) return Key;
            Led1Red++;
         }
         First = FALSE;
      }

      for (i=0;i<255;i++)
      {
         Key = Delay(DelayStep, DelayMin);
         if (Key == 0) return Key;
         Led1Red--;
         Led2Red++;
      }

      for (i=0;i<255;i++)
      {
         Key = Delay(DelayStep, DelayMin);
         if (Key == 0) return Key;
         Led1Green++;
         Led2Red--;
      }

      for (i=0;i<255;i++)
      {
         Key = Delay(DelayStep, DelayMin);
         if (Key == 0) return Key;
         Led1Green--;
         Led2Green++;
      }


      for (i=0;i<255;i++)
      {
         Key = Delay(DelayStep, DelayMin);
         if (Key == 0) return Key;
         Led1Blue++;
         Led2Green--;
      }

      for (i=0;i<255;i++)
      {
         Key = Delay(DelayStep, DelayMin);
         if (Key == 0) return Key;
         Led1Blue--;
         Led2Blue++;
      }

      for (i=0;i<255;i++)
      {
         Key = Delay(DelayStep, DelayMin);
         if (Key == 0) return Key;
         Led1Red++;
         Led2Blue--;
      }
   }
   return -1;
}

/******************************************************************************

Name:         void ManualMode(void)

Description:

Input:        none

Output:       none

Misc:             #8
******************************************************************************/
ushort ManualMode(ulong DelayTick, ulong DelayStep, ulong DelayMin)
{
   ushort ManColor = 0;
   uint i;

   RemoteKey = -1;
   VariableDelay = DelayTick;

   while(TRUE)
   {
      WDR();

      if (RemoteKey != -1)
      {
         if       ((RemoteKey == REMOTE_UP)   && (ManColor == 0) && (Led2Red != 255))   Led2Red++;
         else  if ((RemoteKey == REMOTE_DOWN) && (ManColor == 0) && (Led2Red != 0))     Led2Red--;

         if       ((RemoteKey == REMOTE_UP)   && (ManColor == 1) && (Led2Green != 255)) Led2Green++;
         else  if ((RemoteKey == REMOTE_DOWN) && (ManColor == 1) && (Led2Green != 0))   Led2Green--;

         if       ((RemoteKey == REMOTE_UP)   && (ManColor == 2) && (Led2Blue != 255))  Led2Blue++;
         else  if ((RemoteKey == REMOTE_DOWN) && (ManColor == 2) && (Led2Blue != 0))    Led2Blue--;

         if (RemoteKey == REMOTE_RIGHT)
         {
            for (i=0;i<65000;i++) WDR();
            ManColor++;
            RemoteKey = -1;
         }
         if (ManColor > 2) ManColor = 0;

         if (RemoteKey == 0)
         {
            ClearAll();
            return RemoteKey;
         }

         Led1Red =   Led2Red;
         Led1Green = Led2Green;
         Led1Blue =  Led2Blue;

         RemoteKey = -1;
      }
   }
   return -1;
}

/******************************************************************************

name:         void delay(void)

description:

input:        none

output:       none

misc:            
**********************************************************************>********/
ushort Delay(ulong DelayStep, ulong DelayMin)