Arduino Hack – How to Make your Own Knight Rider Scanner!

by max on Wednesday, April 8th, 2009

My old friend Garrett Mace over at MaceTech.com (also @macegr on Twitter) has been tinkering and released his own ShiftBrite RGB LED module.  It’s currently out of stock but he says he will have more of them soon.  (You can also check out Garrett’s previous DIYs he did on Zedomax.com here)

You can make an easy Knight Rider Scanner with these ShiftBrites that Garrett personally made.   The best part about his Knight Rider Scanner (that he made for one of his customers) is the fact that it can use all the colors that RGB can handle, meaning you can make a rainbow too if you wanted to.

Here’s a cool New Years Ball Garrett made with the ShiftBrites, way too cool.  (Garrett, next time you tweet me when you make some cool stuff like this!)

After the soldering, I decided to attack a problem that a customer asked me about. He’s working on a Mustang and wants to use ShiftBrites to make a Knight Rider style scanner (2008 TV show version). I wrote some code, it allows any chain length divisible by two, any solid or mixed color, and custom leading and trailing gradients.

knightridercar

shiftnight

Here’ some video of it:

Click Here to View in Full Screen Mode

Click Here to View in Full Screen Mode

Here’s the video of working on his customer Mustang:

Click Here to View in Full Screen Mode

Here’s the Arduino code used for it (verified that it works):

#define clockpin 13 // DI
#define enablepin 10 // LI
#define latchpin 9 // EI
#define datapin 11 // CI

#define NumLEDs 16
#define CenterWidth 8

int LEDChannels[NumLEDs * 2][3] = {0};
int SB_CommandMode;
int SB_RedCommand;
int SB_GreenCommand;
int SB_BlueCommand;

// these are small so i'll leave them in RAM, larger data should be moved to PROGMEM
int KittLeadingEdge[] = {600, 400, 200};
int KittTrailingEdge[] = {200, 400, 600};

int KittLeadSize = sizeof(KittLeadingEdge) / sizeof(int);
int KittTrailSize = sizeof(KittTrailingEdge) / sizeof(int);
int KittTotalSize = KittLeadSize + KittTrailSize + CenterWidth;

void setup() {

pinMode(datapin, OUTPUT);
pinMode(latchpin, OUTPUT);
pinMode(enablepin, OUTPUT);
pinMode(clockpin, OUTPUT);
SPCR = (1<<SPE)|(1<<MSTR)|(0<<SPR1)|(0<<SPR0);
digitalWrite(latchpin, LOW);
digitalWrite(enablepin, LOW);

}

void SB_SendPacket() {

if (SB_CommandMode == B01) {
SB_RedCommand = 127;
SB_GreenCommand = 127;
SB_BlueCommand = 127;
}

SPDR = SB_CommandMode << 6 | SB_BlueCommand>>4;
while(!(SPSR & (1<<SPIF)));
SPDR = SB_BlueCommand<<4 | SB_RedCommand>>6;
while(!(SPSR & (1<<SPIF)));
SPDR = SB_RedCommand << 2 | SB_GreenCommand>>8;
while(!(SPSR & (1<<SPIF)));
SPDR = SB_GreenCommand;
while(!(SPSR & (1<<SPIF)));

}

void WriteLEDArray() {

SB_CommandMode = B00; // Write to PWM control registers
for (int h = 0;h<NumLEDs*2;h++) {
SB_RedCommand = LEDChannels[h][0];
SB_GreenCommand = LEDChannels[h][1];
SB_BlueCommand = LEDChannels[h][2];
SB_SendPacket();
}

delayMicroseconds(15);
digitalWrite(latchpin,HIGH); // latch data into registers
delayMicroseconds(15);
digitalWrite(latchpin,LOW);

SB_CommandMode = B01; // Write to current control registers
for (int z = 0; z < NumLEDs*2; z++) SB_SendPacket();
delayMicroseconds(15);
digitalWrite(latchpin,HIGH); // latch data into registers
delayMicroseconds(15);
digitalWrite(latchpin,LOW);

}

// Re-use my old array rotating code, but use collapsed fake array to save memory
// (at expense of CPU)
int KittFakeArray(int index) {

if (index >= 0 && index < KittTrailSize) {
return KittTrailingEdge[index];
} else if (index >= KittTrailSize && index < (CenterWidth + KittTrailSize)) {
return 1023;
} else if (index >= (CenterWidth + KittTrailSize) && index < KittTotalSize) {
return KittLeadingEdge[index-CenterWidth-KittTrailSize];
} else {
return 0;
}

}

void NewKittFill(int dir, int FillSpeed, int FadeSteps, int red, int green, int blue) {

int KittFadeFactor = 0;
int revIndex;

for (int FillCount = 0; FillCount < (KittTotalSize+NumLEDs); FillCount++) {

for (int FadeCount = 0; FadeCount < FadeSteps; FadeCount++) {

for (int i = 0; i < NumLEDs; i++) {

KittFadeFactor = ((KittFakeArray(KittTotalSize - FillCount + i)) * (FadeSteps - FadeCount - 1) + (KittFakeArray(KittTotalSize - FillCount - 1 + i)) * (FadeCount)) / (2 * FadeSteps);

if (dir == 0) {

LEDChannels[i][0] = (long) red * KittFadeFactor / 1023;
LEDChannels[i][1] = (long) green * KittFadeFactor / 1023;
LEDChannels[i][2] = (long) blue * KittFadeFactor / 1023;

revIndex = NumLEDs * 2 - i - 1;

LEDChannels[revIndex][0] = LEDChannels[i][0];
LEDChannels[revIndex][1] = LEDChannels[i][1];
LEDChannels[revIndex][2] = LEDChannels[i][2];
} else {

revIndex = NumLEDs - 1 - i;

LEDChannels[revIndex][0] = (long) red * KittFadeFactor / 1023;
LEDChannels[revIndex][1] = (long) green * KittFadeFactor / 1023;
LEDChannels[revIndex][2] = (long) blue * KittFadeFactor / 1023;

LEDChannels[NumLEDs + i][0] = LEDChannels[revIndex][0];
LEDChannels[NumLEDs + i][1] = LEDChannels[revIndex][1];
LEDChannels[NumLEDs + i][2] = LEDChannels[revIndex][2];
}

}

WriteLEDArray();
delay(FillSpeed);

}

}

}

void loop() {

for (int cycles = 1; cycles < 10; cycles++) {

NewKittFill(0, 12, 8, 1023, 0, 0);
delay(200);
NewKittFill(1, 10, 7, 1023, 0, 0);
delay(200);

}

NewKittFill(0, 10, 7, 0, 1023, 0);
delay(300);
NewKittFill(1, 10, 7, 0, 1023, 0);
delay(300);

NewKittFill(0, 10, 7, 0, 0, 1023);
delay(300);
NewKittFill(1, 10, 7, 0, 0, 1023);
delay(300);

NewKittFill(0, 10, 7, 800, 0, 1023);
delay(300);
NewKittFill(1, 10, 7, 800, 0, 1023);
delay(300);

NewKittFill(0, 10, 7, 200, 0, 0);
delay(300);
NewKittFill(1, 10, 7, 200, 0, 0);
delay(300);

}

Rate

1 Star2 Stars3 Stars4 Stars5 Stars
Loading ... Loading ...

tokyoflash
ad ad
ad ad


20,000 GPS POI's $9.99

Related News and Resources

Other Interesting News From Our Friends

blog comments powered by Disqus
If you like this post then please subscribe to my full feed RSS.

You can also subscribe by E-mail by filling out your name and E-mail below:

Name: Email:


Got a new hack, DIY, howto, or gadget? Tip us here.

Try Goohack to find a new Hack:


Featured Sites From Zedomax Blog Network