Kitchen Mood Light LED Lightning

 

History

    This project began when I was surfing the web looking for any cool electronic projects. I found the mood lamp made by Toon Beerten "http://tobe.nimio.info/led_mood_lamp.php". I was really impressed by the 3 watt RGB LED. I bought some of those on ebay and made some tests with an AVR with PWM to control each color intensity. At this point I found those LEDs very interesting and powerful, so then I needed a project. One week later a crazy idea came to my mind. I would light my entire kitchen with LEDs so I will be able to light it with up to 16 million colors. With software I would also be able automatically make the light change colors randomly but with smooth fading effects. As you know with programming you can make any pattern, with only your imagination as the limit. I made a controller with a LCD, keypad, and 4 slide pots, 3 for manual led color intensity, and the other to control the speed of the color patterns changing. This master module communicates in RS485 to all slave devices, each of which drives 2 LEDs. Each of the slaves has their own address so the master control can address the LEDs individually.

I also made group of LEDs. If you want you can specify different patterns to each group. The communication protocol I used is the standard for the lighting control industry, DMX512. It's a very old and simple protocol. Each slave module is given an 8-bit address (the protocol actually supports up to 512 devices), and each 8-bit byte in the 512-byte data packet is the lighting data for the corresponding module. The start bit is done by a framing error.

Finally I had another idea. With 3 colors I can make a music color organ!!! I worked hard on this because I wanted a color organ that would be independent of the sound level and the sound quality. It must work with Elvis to Pink Floyd or to any others. I built an AGC that outputs the same level from 1mV to 10V. Next, 3 filters give you the low, middle and high frequency bands. The last stage is a rectifier that gives a DC voltage level equal to the level of the frequency. This DC is connected to the A/D of the MCU and all of the comparator triggering is done by the software, that like I said, makes any type of song work perfectly. One very important thing is the powering of all the slaves with their 3W LEDs. Each color sinks 350ma, so you must calculate 1 amp per LED. I have 16 of those so it uses 16 amps!!! At 5V, I had to use a PC power supply that can handle up to 25 amps. At this point the rest is not too difficult, but you must think about the resistance of your conductor. At 16 amps it's very easy to lose 1 volt. I used #8 wire, which is the minimum you can use.

   

Features

puce 1024 3W RGB LEDs can be controlled
puce Over 16 million colors can be generated
puce Very powerful, can be used as your primary lighting
puce Many patterns are pre-programmed
puce Can be connected to any audio RCA jack and the system will became a Music color organ!!! (It's crazy)
puce Firmware upgradeable via RS232

Thanks to John E Evans who help me with my english!
 

Pictures

Click to enlarge

Kitchen with normal lightning

In red

In green

 

In blue

In orange

In purple

 

Multi-Color

Multi-Color

 

PCB of the master unit

PCB of the color organ

PCB of the slave unit

 

Final look of the master unit

 

 

Sources codes & Schematics

-Schematic of the Master Module  in PDF format

-Schematic of the Slave Module  in PDF format

-Schematic of the Color Organ in PDF format

 

MoodLightContDMX.c

//*****************************************************************************
// MoodLight Controller
// Version 1.0 June 2007
//
// 1.0 -> New code
//
// Sylvain Bissonnette
//*****************************************************************************
//
//            R E T U R N   S T A C K   6 4
//                   X T A L  16 MHZ
//               BootLoader of 512 word
//
//*****************************************************************************
//
//                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
//
// PA0 -> POT BLUE
// PA1 -> POT GREEN
// PA2 -> POT RED
// PA3 -> POT SPEED
// PA4 -> COLOR ORGAN MIDDLE
// PA5 -> COLOR ORGAN BASE
// PA6 -> COLOR ORGAN AGC
// PA7 -> COLOR ORGAN TREBLE
//
// PB0 -> KEYBOARD Y1
// PB1 -> KEYBOARD Y2
// PB2 -> KEYBOARD Y3
// PB3 -> KEYBOARD Y4
// PB4 -> KEYBOARD X1
// PB5 -> KEYBOARD X2   / ISP
// PB6 -> KEYBOARD X3 / ISP
// PB7 ->                  / ISP
//
// PC0 -> LCD DB7
// PC1 -> LCD DB6
// PC2 -> LCD DB5
// PC3 -> LCD DB4
// PC4 -> LCD E
// PC5 -> LCD R/W
// PC6 -> LCD RS
// PC7 -> N/C
//
// PD0 ->  SERIAL RX
// PD1 ->  SERIAL TX
// PD2 -> 
// PD3 ->
// PD4 -> PIEZO
// PD5 -> LED BLUE
// PD6 -> LED GREEN
// PD7 -> LED RED
//
//*****************************************************************************
//                T I M E R   U S A G E
//
// Timer 0 is use by TaskManager
// Timer 1 is not use
// Timer 2 is use by LedEngine
//
//*****************************************************************************
//-----------------------------------------------------------------------------
//
//*****************************************************************************
//                      I N C L U D E
//*****************************************************************************
#include <iom32v.h>
#include <macros.h>
#include <stdlib.h>
#include <eeprom.h>
#include <shortnametype.h>
#include <string.h>
#include <stdio.h>
#include "TaskManager.h"

//*****************************************************************************
//                      D E F I N E
//*****************************************************************************
#define VERSION                  10
#define DEVICE                   8535
#define TRUE                     1
#define FALSE                    0
#define XTAL                     16000000
#undef  RAND_MAX
#define RAND_MAX                256
#define NO_PARAMETER                -1

// Keypad                       
#define ROW1                        0x01
#define ROW2                              0x02
#define ROW3                              0x04
#define ROW4                              0x08
#define COL1                              0x10
#define COL2                              0x20
#define COL3                              0x40
#define COL4                              0x80

#define KEYPIN                         PINB
#define KEYDDR                         DDRB
#define KEYPORT                           PORTB

// LCD
#define LCD_D7                  0x01
#define LCD_D6                  0x02
#define LCD_D5                  0x04
#define LCD_D4                  0x08
#define LCD_E                   0x10
#define LCD_RW                  0x20
#define LCD_RS                  0x40
#define LCD_SOUND                0x80

#define LCD_PIN                 PINC
#define LCD_DDR                 DDRC
#define LCD_PORT                PORTC

#define LCD_DATA                0x01
#define LCD_CTRL                0x00

#define LCD_C_BLINK_ON          0x09
#define LCD_C_BLINK_OFF         0xfe
#define LCD_C_ON                0x0a
#define LCD_C_OFF               0xfd
#define LCD_DISPLAY_ON          0x0c
#define LCD_DISPLAY_OFF         0xfb
#define LCD_BRIGHT_25           0x23
#define LCD_BRIGHT_50           0x22
#define LCD_BRIGHT_75           0x21
#define LCD_BRIGHT_100          0x20
#define LCD_SOUND_ON             0x24
#define LCD_SOUND_OFF            0x25

// DMX
#define DMX_SPEED                      250000

// Code
#define MAX_LED                           32
#define MAX_GROUP                      10

#define NONE                              255
#define MANUAL_MODE                       0
#define RANDOM_ALL_SMOOTH           30
#define RANDOM_ALL                  31
#define RANDOM_SMOOTH                  32
#define RANDOM                         33
#define  COLOR_ORGAN                   34
#define REMOVE_ALL_GROUP            60
#define GROUP_SETUP                    90

#define STOP_COMM                      98
#define RESET                             99

#define LEDRED                         0x80
#define LEDGREEN                       0x20
#define LEDBLUE                           0x40
#define LEDPORT                           PORTD
#define LEDDDR                         DDRD

// DMX
#define MAX_DMX                           100

//*****************************************************************************
//                      C O N S T A N T
//*****************************************************************************
const unsigned char Table[16] =  {0x31,0x32,0x33,0x00,
                                             0x34,0x35,0x36,0x00,
                                                   0x37,0x38,0x39,0x00,
                                                   0x2a,0x30,0x23,0x00};

//*****************************************************************************
//                  P R O T O T Y P E
//*****************************************************************************
void main(void);
void _StackOverflowed(char c);
void Info(void);
void Delay(ushort Del);
void LEDInit(void);
void LEDEngine(void);
void UpdateDisplay(void);
void Reset(void);
void StopComm(void);
void Group_Setup(void);
void DisplayRGB(void);

void RemoveAllGroup(void);
void ManualModeSingle(int Parameter);
void ManualMode(int Parameter);
void RandomAllSmooth(int);
void RandomAll(int);
void RandomSmooth(int);
void Random(int);
void ColorOrgan(int);
void ColorOrgan2(int);

ushort GetRand(ushort Mask);
void DoKey(void);

// SERIAL
void DMXInit(void);
void SerialSendBuffer(void);

// KEY
void KeyInit(void);
void KeyScan(int Parameter);
unsigned char KeyLook(void);
void SwitchScan(void);
void Sound(ushort i);

// AD
void ADInit(void);
void AD_Int(void);

// LCD
void LCDInit(ushort x,ushort y);
void LCDOff(void);
void LCDClrSCR(void);
void LCDGotoXY(ushort,ushort);
ushort LCDWhereX(void);
ushort LCDWhereY(void);
void LCDWriteString(char *);
void LCDWriteConstString(const char *);
void LCDWriteChar(char);
void LCDWriteData(ushort,ushort);
ushort LCDReadData(ushort rs);
void LCDCreateCHR(ushort chnumber, char *ptr);
void LCDWait(void);
void LCDDelay50us(int Delay);
void LCDTextAttr(ushort attribute);
void LCDContrast(ushort Cont);

// DMX
void DMXInit(void);
void DMXSendFrame(void);
void DMXSendByte(void);
void DMXDelay100us(void);
void DMXDelay10us(void);

//*****************************************************************************
//            G L O B A L   V A R I A B L E
//*****************************************************************************
// LCD
ushort MaxX, MaxY, LCDStat;
char Text[20];

// Key & Pot & Switch
ushort PotRed, PotGreen, PotBlue;
ushort Speed;
ushort Bass, Middle, Treble;
ushort AGC;
int CapBass, CapMiddle, CapTreble;
ushort Red, Green, Blue;

ushort Buzz = FALSE;

ushort Key = 48;
ushort KeyFirst = 48;
ushort KeySecond = 48;
ushort KeyThird   = 48;
ushort Value;

ushort Switch;

// LED
typedef struct
{
   ushort Red;
   ushort Green;
   ushort Blue;
}LedStruct;

LedStruct *Led;

long Group_Led[MAX_GROUP];

ushort Group;
ushort Manual;

// DMX
ushort DMXBuffer[MAX_DMX];
ushort DMXStartFrame;
ushort DMXFirstByte;
ushort DMSCommStop;

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

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

  Led = (LedStruct*)&DMXBuffer[0];

  for (i=0;i<MAX_GROUP;i++) EEPROMReadBytes(i * sizeof(long), &Group_Led[i], sizeof(long));

  LCDInit(20,2);
  TaskInit();
  KeyInit();

   TaskRegister(&KeyScan,NO_PARAMETER,T100MS,TRUE);
   SEI();

  if (MCUCSR & (1<<WDRF))
  {
   LCDClrSCR();
      LCDGotoXY(1,1);
      LCDWriteConstString("  Watch Dog Reset   \0");
      LCDGotoXY(1,2);
      LCDWriteConstString("*->Reload     #->Run\0");
      Key = -1;
      while(TRUE)
      {
         if (Key == '*')
         {
            CLI();
            while(TRUE);
         }

         if (Key == '#')
         {
            break;
         }
      }

      Key = 48;
      KeyFirst = 48;
      KeySecond = 48;
      MCUCSR = 0x00;
  }

  ADInit();
  LEDInit();
  DMXInit();

  Info();
  Delay(20);
  LCDClrSCR();
   LCDGotoXY(1,1);
   LCDWriteConstString("  R:    G:    B:    \0");
   RemoveAllGroup();
  while(1)
  {
    _StackCheck();
    WDR();
    DoKey();
    if (DMXStartFrame) DMXSendFrame();
  }
}

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

Name:         void _StackOverflowed(char c)

Description:  This function is automaticaly called if
the stack trash,


Input:        none

Output:       none

Misc:
******************************************************************************/
void _StackOverflowed(char c)
{
   CLI();
   LCDClrSCR();
   LCDGotoXY(1,1);
   LCDWriteConstString("   STACK CRASH!&?\0");
   while(1) WDR();
}

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

Name:         void Info(void)

Description:  Display power on message

Input:        void

Output:       void

Misc:        

******************************************************************************/
void Info(void)
{
  LCDClrSCR();
  LCDGotoXY(1,1);
  LCDWriteConstString("-Mood Light- Ver:1.0\0");
  LCDGotoXY(1,2);
  LCDWriteConstString("Sylvain  Bissonnette\0");
}

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

Name:         void Delay(ushort Del)

Description:  This function make a delay

Input:        none

Output:       none

Misc:
******************************************************************************/
void Delay(ushort Del)
{
  int i,j;
  for (i=0;i<Del;i++) for (j=0;j<32000;j++) WDR();
}

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

Name:         void LEDInit(void)

Description:  This function initialize MCU for LEDEngine function


Input:        none

Output:       none

Misc:
******************************************************************************/
void LEDInit(void)
{
   LEDDDR |= LEDRED + LEDGREEN + LEDBLUE;
   TCCR2 = (1<<CS20);
   TIMSK |= (1<<TOIE2);
}

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

Name:         void LEDEngine(void)

Description:  This function drive all the LED with PWM


Input:        none

Output:       none

Misc:
******************************************************************************/
#pragma interrupt_handler LEDEngine:6
void LEDEngine(void)
{
   static ushort Ticker;

   Ticker++;
   if (Ticker == 255) Ticker = 0;

   //--------------------------

   if ((Red>>3) > Ticker)   LEDPORT |= LEDRED;
   else LEDPORT &= ~LEDRED;

   if ((Green>>3) > Ticker) LEDPORT |= LEDGREEN;
   else LEDPORT &= ~LEDGREEN;

   if ((Blue>>3) > Ticker)  LEDPORT |= LEDBLUE;
   else LEDPORT &= ~LEDBLUE;
}

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

Name:       void DoKey(void)

Description:  

Input:         none

Output:        none

Misc:      

**********************************************************/
void DoKey(void)
{
   ushort i;

   DisplayRGB();

   if ((Key != -1) && (Key != '*') && (Key != '#'))
   {
      KeySecond = KeyFirst;
      KeyFirst = Key;
      LCDGotoXY(1,2);
      LCDWriteData(LCD_DATA  ,KeySecond);
      LCDWriteData(LCD_DATA  ,KeyFirst);
      Value = ((KeySecond - 48) * 10) + (KeyFirst - 48);

      UpdateDisplay();
      Key = -1;
   }

   // -------

   if ((Key == '*') || (Key == '#')) if (TaskCheckRegister(&ManualModeSingle)) TaskUnRegister(&ManualModeSingle);

   if (Key == '*')
   {
      TaskUnRegisterWParameter(Group);
      Red = 0;
      Green = 0;
      Blue = 0;
      for (i=0;i<MAX_LED-1;i++)
      {
         if (Group_Led[Group] & (1<<i))
         {
            Led[i].Red = 0;
            Led[i].Green = 0;
            Led[i].Blue = 0;
         }
      }
   }

   if ((Key == '#') && (Value == MANUAL_MODE))
   {
      TaskUnRegisterWParameter(Group);
      if (!TaskCheckRegister(&ManualMode)) TaskRegister(&ManualMode,Group,T10MS,TRUE);
      Key = -1;
   }

   else  if ((Key == '#') && (Value >= 1) && (Value <= 20))
   {
      Manual = Value;
      if (!TaskCheckRegister(&ManualModeSingle)) TaskRegister(&ManualModeSingle,Group,T10MS,TRUE);
      Key = -1;
   }

   else  if ((Key == '#') && (Value >= 50) && (Value <= 59))
   {
      Group = Value - 50;
      Key = -1;
   }

   else if ((Key == '#') && (Value ==  RANDOM_ALL_SMOOTH))
   {
      TaskUnRegisterWParameter(Group);
      if (!TaskCheckRegister(&RandomAllSmooth)) TaskRegister(&RandomAllSmooth,Group,T500MS,TRUE);
      Key = -1;
   }

   else if ((Key == '#') && (Value ==  RANDOM_ALL))
   {
      TaskUnRegisterWParameter(Group);
      if (!TaskCheckRegister(&RandomAll)) TaskRegister(&RandomAll,Group,T500MS,TRUE);
      Key = -1;
   }

   else if ((Key == '#') && (Value ==  RANDOM_SMOOTH))
   {
      TaskUnRegisterWParameter(Group);
      if (!TaskCheckRegister(&RandomSmooth)) TaskRegister(&RandomSmooth,Group,T500MS,TRUE);
      Key = -1;
   }

   else if ((Key == '#') && (Value ==  RANDOM))
   {
      TaskUnRegisterWParameter(Group);
      if (!TaskCheckRegister(&Random)) TaskRegister(&Random,Group,T500MS,TRUE);
      Key = -1;
   }

   else if ((Key == '#') && (Value ==  COLOR_ORGAN))
   {
      TaskUnRegisterWParameter(Group);
      if (!TaskCheckRegister(&ColorOrgan)) TaskRegister(&ColorOrgan,Group,T20MS,TRUE);
      Key = -1;
   }

   else  if ((Key == '#') && (Value == REMOVE_ALL_GROUP))
   {
      RemoveAllGroup();
      Key = -1;
   }

   else  if ((Key == '#') && (Value == GROUP_SETUP))
   {
      Group_Setup();
      Key = -1;
   }

   else if ((Key == '#') && (Value ==  STOP_COMM))
   {
      StopComm();
      Key = -1;
   }

   else if ((Key == '#') && (Value ==  RESET))
   {
      Reset();
      Key = -1;
   }

   else
   {
      Key = -1;
   }
}

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

Name:       void UpdateDisplay(void)

Description:  

Input:         none

Output:        none

Misc:      

**********************************************************/
void UpdateDisplay(void)
{
      LCDGotoXY(3,2);

      if (Value == 0)
      {
         LCDWriteConstString("->Manual Mode       \0");
      }

      else if ((Value >= 1) && (Value <= 20))
      {
         csprintf(&Text[0],"->Set Light : %d \0",Value);
         LCDWriteString(&Text[0]);
      }

      else if ((Value >= 50) && (Value <= 59))
      {
         csprintf(&Text[0],"->Set Group For ->\0",Value);
         LCDWriteString(&Text[0]);
      }

      else if (Value == RANDOM_ALL_SMOOTH)
      {
         LCDWriteConstString("->Rnd All Smooth  \0");
      }

      else if (Value == RANDOM_ALL)
      {
         LCDWriteConstString("->Random All      \0");
      }

      else if (Value == RANDOM_SMOOTH)
      {
         LCDWriteConstString("->Random Smooth   \0");
      }

      else if (Value == RANDOM)
      {
         LCDWriteConstString("->Random          \0");
      }

      else if (Value == COLOR_ORGAN)
      {
         LCDWriteConstString("->Color Organ     \0");
      }

      else if (Value == REMOVE_ALL_GROUP)
      {
         LCDWriteConstString("->Remove All Group \0");
      }

      else if (Value == GROUP_SETUP)
      {
         LCDWriteConstString("->Group Setup      \0");
      }

      else if (Value == STOP_COMM)
      {
         LCDWriteConstString("->Stop Comm        \0");
      }

      else if (Value == RESET)
      {
         LCDWriteConstString("->Reset MCU        \0");
      }

      else
    {
        LCDWriteConstString("->                 \0");
     }
}

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

Name:         void Reset(void)

Description: 

Input:        none

Output:       none

Misc:
******************************************************************************/
void Reset(void)
{
      CLI();
      LCDClrSCR();
      LCDGotoXY(1,1);
      LCDWriteConstString("   Resetting MCU    \0");
      while(TRUE);
}

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

Name:         void StopComm(void)

Description: 

Input:        none

Output:       none

Misc:
******************************************************************************/
void StopComm(void)
{
      DMSCommStop = TRUE;
      LCDClrSCR();
      LCDGotoXY(1,1);
      LCDWriteConstString("    Comm Stoped     \0");
      Delay(20);
      LCDClrSCR();
      LCDWriteConstString("  R:    G:    B:    \0");
      Key = 48;
      KeyFirst = 48;
      KeySecond = 48;
      UpdateDisplay();
      LCDGotoXY(1,2);
      LCDWriteConstString("98\0");
}

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

Name:         void Group_Setup(void)

Description: 

Input:        none

Output:       none

Misc:
******************************************************************************/
void Group_Setup()
{
   char Text[20];

   ushort i;
   char KeyFirst = 48;
   char KeySecond = 48;
   ushort Group;
   ushort LastKey;

   LCDClrSCR();

   for (i=0;i<MAX_GROUP;i++) Group_Led[i] = 0;
   Group = 0;
   while(TRUE)
   {
      LCDGotoXY(1,1);
      csprintf(&Text[0],"Enter Group #%d:\0", Group + 50);
      LCDWriteString(&Text[0]);
      LCDGotoXY(1,2);
      LCDWriteConstString("  Press * to quit   \0");

      while(TRUE)
      {
         WDR();
         if (DMXStartFrame) DMXSendFrame();

         if ((Key != -1) && (Key != '*') && (Key != '#'))
         {
            KeySecond = KeyFirst;
            KeyFirst = Key;
            LCDGotoXY(18,1);
            LCDWriteData(LCD_DATA  ,KeySecond);
            LCDWriteData(LCD_DATA  ,KeyFirst);
            Value = (((KeySecond - 48) * 10) + (KeyFirst - 48));
            LastKey = Key;
            Key = -1;
         }

         if (Key == '#')
         {
            if (Value < MAX_LED)
            {
               Value -= 1;
               Group_Led[Group] |= (1<<Value);
            }
            LastKey = Key;
            Key = -1;

         }

         if (Key == '*')
         {
            if (Key == LastKey)
            {
               for (i=0;i<MAX_GROUP;i++) EEPROMWriteBytes(i * sizeof(long), &Group_Led[i], sizeof(long));

               LCDClrSCR();
               LCDGotoXY(1,1);
               LCDWriteConstString("  R:    G:    B:    \0");
               Key = -1;
               UpdateDisplay();
               LCDGotoXY(1,2);
               return;
            }

            Group++;
            LastKey = Key;
            Key = -1;
            break;
         }
      }
   }
}

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

Name:         void DisplayRGB(void)

Description: 

Input:        none

Output:       none

Misc:
******************************************************************************/
void DisplayRGB(void)
{
   ushort Tmp,i;

   for (i=0;i<3;i++)
   {
      if (i == 0)
      {
         LCDGotoXY(5,1);
         Tmp = Red;
      }

      if (i == 1)
      {
         LCDGotoXY(11,1);
         Tmp = Green;
      }

      if (i == 2)
      {
         LCDGotoXY(17,1);
         Tmp = Blue;
      }

      itoa(&Text[0],Tmp,10);
      Tmp = strlen(&Text[0]);
      LCDWriteString(Text);
      if (Tmp < 2) LCDWriteData(LCD_DATA  ,' ');
      if (Tmp < 3) LCDWriteData(LCD_DATA  ,' ');
   }
}

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

Name:         void RemoveAllGroup(void)

Description:

Input:        none

Output:       none

Misc:             #30
******************************************************************************/
void RemoveAllGroup(void)
{
   ushort i;

   for (i=0;i<MAX_GROUP-1;i++) TaskUnRegisterWParameter(i);

   for (i=0;i<MAX_LED-1;i++)
   {
         Led[i].Red = 0;
         Led[i].Green = 0;
         Led[i].Blue = 0;
   }

   Red = 0;
   Green = 0;
   Blue = 0;
}


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

Name:         void ManualModeSingle

Description:

Input:        none

Output:       none

Misc:             #30
******************************************************************************/
void ManualModeSingle(int Parameter)
{
   Parameter = Parameter;
   Group = 60;

   Led[Manual - 1].Red = PotRed;
   Led[Manual - 1].Green = PotGreen;
   Led[Manual - 1].Blue = PotBlue;

   Red = PotRed;
   Green = PotGreen;
   Blue = PotBlue;
}

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

Name:         void ManualMode

Description:

Input:        none

Output:       none

Misc:             #30
******************************************************************************/
void ManualMode(int Parameter)
{
   ushort i;

   for (i=0;i<MAX_LED-1;i++)
   {
      if (Group_Led[Parameter] & (1<<i))
      {
         Led[i].Red = PotRed;
         Led[i].Green = PotGreen;
         Led[i].Blue = PotBlue;
      }
   }

   if (Parameter == Group)
   {
      Red = PotRed;
      Green = PotGreen;
      Blue = PotBlue;
   }
}

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

Name:         void RandomAllSmooth(void)

Description:

Input:        none

Output:       none

Misc:             #30
******************************************************************************/
void RandomAllSmooth(int Parameter)
{
   short i;
   static ushort RndRed, RndGreen, RndBlue;
   static ushort RealRed, RealGreen, RealBlue;

   srand(TCNT2);

   if (RealRed > RndRed) RealRed--;
   if (RealRed < RndRed) RealRed++;
   if (RealRed == RndRed