SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By mrmeval
#38892
http://mrmeval.is-a-geek.net/~jcaldwel/images/4794.pdf

This is pretty crappy as I'm unfamiliar with GEDA and hand drew the chip and connections.

I do not know why but the LED example from the arduino site seems to have the bits backwards. It all works though.

You can daisy chain more of these but I am unsure of exactly how many. Four IC's would get you 32 controllable outputs. I'm sure it's possible to make a matrix but it will probably take one of these ICS for row/column but a different kind of IC for column/row.

I was stuck on single bit control so these examples reflect that. You can redo these so that any 16 bit number can be sent to the chips though I've not done the work on sending a 16 bit number serially since it requires sending and reading two bytes.

Please share your code if you make something.
/* Dual hef4794 knightrider toy
Public Domain, Mr. Meval

hacked and completely redone based on info from

http://www.arduino.cc/en/Tutorial/LEDDriver

* (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 = 5;

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 single bits, useful as single bit I/O, someone else will have to modify to directly accept a 16 bit value.
*/

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 thuse
a=16 b=32 c=64 d=128 e=256 f=512 g=1024 h=2048 i=4096 j=8192 k=16384 l=32768

zero sets them all to 0, tilda sets them all on.