I've taken two HEF4794B latching shift registers with LED output and made a 16 LED knight rider toy. There may be need for bypass capacitors but I've found this works on a breadboard with no other parts but what is indicated on the schematic.
Following this is remote serial control program for bits. I have not investigated reading two bytes from the serial to display them yet.
I hate doing this as a pdf but can't seem to get the gEDA output to look right. I'm pretty sure I've badly misused that software package but it's what I have.
ICs HEF4794B
Resistors 220 ohms
LEDs are digikey 160-1677-ND aka LTL2P3KGKNN green water clear and the same variant in red whose part number I've lost. Both are awesome and cheap.
http://mrmeval.is-a-geek.net/~jcaldwel/images/4794.pdf
Feel free to redact or masticate the code as needed I'm placing both in the public domain. I would appreciate you releasing your code.
[edit]I forgot to mention that pin 13 is used as an indcator and can be left out. I also forgot to credit the LED driver tutorial from the Arduino site.[/edit]
/*
Dual hef4794 knightrider toy
by Mr. Meval public domain 11/25/2007Inspired by the works of the following
but changed beyond recognition I think.
- (copyleft) 2005 K3, Malmo University
- @author: David Cuartielles, Marcus Hannerstig
- @hardware: David Cuartielles, Marcos Yarza
- @project: made for SMEE - Experiential Vehicles
*/int data = 9;
int strob = 8;
int clock = 10;
int oe = 11;
int count = 0;
int dato = 0;
int ack = 13;void setup()
{
pinMode(data, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(strob, OUTPUT);
pinMode(oe, OUTPUT);
pinMode(ack, OUTPUT);
digitalWrite(oe, LOW);
}void loop()
{
digitalWrite(ack, HIGH);
dato = 1;
for (int i = 0 ; i < 16 ; i++){
shiftOut(data, clock, LSBFIRST, dato>>8);
shiftOut(data, clock, LSBFIRST, dato);
dato = dato<<1;
digitalWrite(oe, LOW);
digitalWrite(strob, HIGH);
digitalWrite(oe, HIGH);
digitalWrite(strob, LOW);
delay(50); // waits for a moment
digitalWrite(ack, LOW);
}
dato = 32768;
for (int i = 16 ; i > 0 ; i--){
shiftOut(data, clock, LSBFIRST, dato>>8);
shiftOut(data, clock, LSBFIRST, dato);
dato = unsigned (dato)>>1;
digitalWrite(oe, LOW);
digitalWrite(strob, HIGH);
digitalWrite(oe, HIGH);
digitalWrite(strob, LOW);
delay(50); // waits for a moment
digitalWrite(ack, LOW);
}}
/*
Serially control one of 16 bits
by Mr. Meval, public domain 11/25/2007
*/int data = 9;
int strob = 8;
int clock = 10;
int oe = 11;
int count = 0;
int ack = 13;
int incomingByte;void setup()
{
pinMode(data, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(strob, OUTPUT);
pinMode(oe, OUTPUT);
pinMode(ack, OUTPUT);
digitalWrite(oe, LOW);
Serial.begin(9600);
}void write16(int x) {
shiftOut(data, clock, LSBFIRST, x>>8);
shiftOut(data, clock, LSBFIRST, x);
digitalWrite(oe, LOW);
digitalWrite(strob, HIGH);
digitalWrite(oe, HIGH);
digitalWrite(strob, LOW);
}void loop()
{
digitalWrite(ack, HIGH);if (Serial.available() > 0) {
incomingByte = Serial.read();
Serial.println(incomingByte);
switch (incomingByte) {
case 49:
write16 (1);
break;case 50:
write16 (2);
break;case 52:
write16 (4);
break;case 56:
write16 (8);
break;case 97:
write16 (16);
break;case 98:
write16 (32);
break;case 99:
write16 (64);
break;case 100:
write16 (128);
break;case 101:
write16 (256);
break;case 102:
write16 (512);
break;case 103:
write16 (1024);
break;case 104:
write16 (2048);
break;case 105:
write16 (4096);
break;case 106:
write16 (8192);
break;case 107:
write16 (16384);
break;case 108:
write16 (32768);
break;case 48:
write16 (0);
break;case 126:
write16 (65535);
break;default:
write16 (0);
break;
}
delay(50);
}
}/*
Since I can't seem to read two bytes in a row, I encode the bits with letters
1 = 1, 2 = 2, 4 = 4, 8 = 8, a=16, b=32, c=64, d=128, e=256, f=512, g=1024, h=2048, i=4096, j=8192, k=16384, l=32768zero sets them all off
tilda sets them all on*/