Code:
#define XMAS_PIN 8
#define xmas_color_t uint16_t
#define XMAS_LIGHT_COUNT (36)
#define XMAS_GROUP_COUNT (6)
#define XMAS_GROUP_LIGHT_COUNT (6)
#define XMAS_CHANNEL_MAX (0xF)
#define XMAS_DEFAULT_INTENSITY (0xCC)
#define XMAS_COLOR(r,g,b) ((r)+((g)<<4)+((b)<<8))
#define XMAS_COLOR_WHITE XMAS_COLOR(XMAS_CHANNEL_MAX,XMAS_CHANNEL_MAX,XMAS_CHANNEL_MAX)
#define XMAS_COLOR_BLACK XMAS_COLOR(0,0,0)
#define XMAS_COLOR_BLUE XMAS_COLOR(0,0,XMAS_CHANNEL_MAX)
bool sync;
void xmas_begin(uint8_t pin);
void xmas_one(uint8_t pin);
void xmas_zero(uint8_t pin);
void xmas_end(uint8_t pin);
void xmas_begin(uint8_t pin)
{
digitalWrite(pin,1);
delayMicroseconds(7);
digitalWrite(pin,0);
}
void xmas_one(uint8_t pin)
{
digitalWrite(pin,0);
delayMicroseconds(11); //This results in a 20 uS long low
digitalWrite(pin,1);
delayMicroseconds(7);
digitalWrite(pin,0);
}
void xmas_zero(uint8_t pin)
{
digitalWrite(pin,0);
delayMicroseconds(2);
digitalWrite(pin,1);
delayMicroseconds(20-3);
digitalWrite(pin,0);
}
void xmas_end(uint8_t pin)
{
digitalWrite(pin,0);
delayMicroseconds(40); // Can be made shorter
}
void xmas_set_color(uint8_t led,uint8_t intensity,xmas_color_t color, uint8_t pin)
{
uint8_t i;
cli(); //Disable interrupts while we write to GECEs
xmas_begin(pin);
//6-Bit bulb address (MSB first)
for(i=6;i;i--,(led<<=1))
{
if(led&(1<<5))
xmas_one(pin);
else
xmas_zero(pin);
}
//8-Bit brightness (MSB first)
for(i=8;i;i--,(intensity<<=1))
{
if(intensity&(1<<7))
xmas_one(pin);
else
xmas_zero(pin);
}
//12 bit Color (Blue, Green, Red) (MSB first)
for(i=12;i;i--,(color<<=1))
{
if(color&(1<<11))
xmas_one(pin);
else
xmas_zero(pin);
}
xmas_end(pin);
sei(); //Re-enable interrupts now that we're done writing to GECEs
}
void xmas_set_group_address(uint8_t pin)
{
for (int i = 0; i < XMAS_GROUP_COUNT; ++i)
{
for (int k = 0; k < XMAS_GROUP_LIGHT_COUNT; ++k)
{
xmas_set_color(k,XMAS_DEFAULT_INTENSITY,XMAS_COLOR_BLACK,pin);
}
}
}
void xmas_set_all_one_address(uint8_t pin)
{
for (int i = 0; i < XMAS_LIGHT_COUNT; ++i)
xmas_set_color(0,XMAS_DEFAULT_INTENSITY,XMAS_COLOR_BLACK,pin);
}
void setup()
{
delay(10);
Serial.begin(57600);
delay(10);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
pinMode(XMAS_PIN, OUTPUT);
digitalWrite(XMAS_PIN, 0);
xmas_set_group_address(XMAS_PIN);
sync = false;
}
void wait_for_serial()
{
while ( ! Serial.available() > 0 ) { }
}
int renardReadBytes( uint8_t *bytes, uint8_t bytes_size )
{
int in_byte = 0;
int bytes_read;
for ( bytes_read = 0; bytes_read < bytes_size; )
{
wait_for_serial();
in_byte = Serial.read();
switch (in_byte)
{
case(0x7E): // We saw the sync byte, start over!
sync = true;
return bytes_read;
case(0x7D): // Skip the pad byte
continue;
case(0x7F): // Escape character, we need to read one more byte to get our actual data
wait_for_serial();
in_byte = Serial.read();
switch (in_byte)
{
case(0x2F): // renard wants an 0x7D
in_byte = 0x7D;
case(0x30): // renard wants an 0x7E
in_byte = 0x7E;
case(0x31): // renard wants an 0x7F
in_byte = 0x7F;
}
}
bytes[bytes_read++] = in_byte;
}
return bytes_read;
}
int renardRead( uint8_t *bytes, uint8_t byte_count )
{
int in_byte = 0;
while ( ! sync )
{
wait_for_serial();
in_byte = Serial.read();
if ( in_byte == 0x7E ) // Sync byte signifies start of packet
sync = true;
}
if ( sync )
{
sync = false;
wait_for_serial();
in_byte = Serial.read();
if ( in_byte == 0x80 ) // Read from here
{
return renardReadBytes(bytes, byte_count);
}
}
return 0;
}
void loop()
{
//int nbr_bytes = XMAS_GROUP_LIGHT_COUNT * 4;
uint8_t bytes[24], bytes_read;
bytes_read = renardRead(&bytes[0], 24);
if ( bytes_read == 24 )
{
// We have now received 4 bytes of data per string, do something with them!
uint8_t red0 = bytes[0];
uint8_t green0 = bytes[1];
uint8_t blue0 = bytes[2];
uint8_t white0 = bytes[3];
uint8_t red1 = bytes[4];
uint8_t green1 = bytes[5];
uint8_t blue1 = bytes[6];
uint8_t white1 = bytes[7];
uint8_t red2 = bytes[8];
uint8_t green2 = bytes[9];
uint8_t blue2 = bytes[10];
uint8_t white2 = bytes[11];
uint8_t red3 = bytes[12];
uint8_t green3 = bytes[13];
uint8_t blue3 = bytes[14];
uint8_t white3 = bytes[15];
uint8_t red4 = bytes[16];
uint8_t green4 = bytes[17];
uint8_t blue4 = bytes[18];
uint8_t white4 = bytes[19];
uint8_t red5 = bytes[20];
uint8_t green5 = bytes[21];
uint8_t blue5 = bytes[22];
uint8_t white5 = bytes[23];
red0 = ( red0+(white0/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : red0+(white0/3) );
green0 = ( green0+(white0/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : green0+(white0/3) );
blue0 = ( blue0+(white0/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : blue0+(white0/3) );
xmas_set_color(0,XMAS_DEFAULT_INTENSITY,XMAS_COLOR((red0>>4),(green0>>4),(blue0>>4)),XMAS_PIN);
red1 = ( red1+(white1/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : red1+(white1/3) );
green1 = ( green1+(white1/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : green1+(white1/3) );
blue1 = ( blue1+(white1/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : blue1+(white1/3) );
xmas_set_color(1,XMAS_DEFAULT_INTENSITY,XMAS_COLOR((red1>>4),(green1>>4),(blue1>>4)),XMAS_PIN);
red2 = ( red2+(white2/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : red2+(white2/3) );
green2 = ( green2+(white2/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : green2+(white2/3) );
blue2 = ( blue2+(white2/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : blue2+(white2/3) );
xmas_set_color(2,XMAS_DEFAULT_INTENSITY,XMAS_COLOR((red2>>4),(green2>>4),(blue2>>4)),XMAS_PIN);
red3 = ( red3+(white3/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : red3+(white3/3) );
green3 = ( green0+(white3/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : green3+(white3/3) );
blue3 = ( blue0+(white3/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : blue3+(white3/3) );
xmas_set_color(3,XMAS_DEFAULT_INTENSITY,XMAS_COLOR((red3>>4),(green3>>4),(blue3>>4)),XMAS_PIN);
red4 = ( red4+(white4/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : red4+(white4/3) );
green4 = ( green4+(white4/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : green4+(white4/3) );
blue4 = ( blue4+(white4/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : blue4+(white4/3) );
xmas_set_color(4,XMAS_DEFAULT_INTENSITY,XMAS_COLOR((red4>>4),(green4>>4),(blue4>>4)),XMAS_PIN);
red5 = ( red5+(white5/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : red5+(white5/3) );
green5 = ( green5+(white5/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : green5+(white5/3) );
blue5 = ( blue5+(white5/3) >= (XMAS_CHANNEL_MAX<<4) ? (XMAS_CHANNEL_MAX<<4) : blue5+(white5/3) );
xmas_set_color(5,XMAS_DEFAULT_INTENSITY,XMAS_COLOR((red5>>4),(green5>>4),(blue5>>4)),XMAS_PIN);
}
}
Bookmarks