One of the problems with running a model railroad from a microcontroller is the need for lots of digital output pins. There are a variety of things that need turning on and off - signals, track sections/blocks, house lights, even driving stepper motors!
This simple circuit uses 6 x 74LS595 chips to make a total of 48 bits of digital output using only 3 digital outs on my Arduino.
Here's video of it in action. I've hooked up my el-cheapo opto-isolated relay card to the lower 4 bits just to demonstrate it working.
You can see the entire setup above - the Arduino, the breadboard with the 6 chips and my relay board.
Below you can see a little detail of the first few chips.
There is a really good Arduino tutorial here: http://www.arduino.cc/en/Tutorial/ShiftOut
The real pain in the a*#e is the amount of fiddly little wires I have had to cut, strip and place to make this work. It has to be made on a PCB before I do anything else!
And here is the source for my test program. I can feel an Arduino library coming one...
//Pin connected to ST_CP of 74HC595
int latchPin = 10;
//Pin connected to SH_CP of 74HC595
int clockPin = 11;
////Pin connected to DS of 74HC595
int dataPin = 9;
#define BITS_PER_BYTE 8
#define NUM_BYTES 4
byte bitset[NUM_BYTES];
void
BitsetClear()
{
int i;
for (i = 0; i< NUM_BYTES; i++)
bitset[i] = 0;
}
void
BitsetSet()
{
int i;
for (i = 0; i< NUM_BYTES; i++)
bitset[i] = 0xFF;
}
void
BitsetSetBit(int n)
{
int index;
int bit_num;
index = n/BITS_PER_BYTE;
bit_num = n % BITS_PER_BYTE;
Serial.print("S: ");
Serial.print(n);
Serial.print(" : ");
Serial.print(index);
Serial.print(", ");
Serial.println(bit_num);
bitset[index] = bitset[index] | (0x01 << bit_num);
}
void
BitsetClearBit(int n)
{
int index;
int bit_num;
index = n/BITS_PER_BYTE;
bit_num = n % BITS_PER_BYTE;
Serial.print("C: ");
Serial.print(n);
Serial.print(" : ");
Serial.print(index);
Serial.print(", ");
Serial.println(bit_num);
bitset[index] = bitset[index] & ~(0x01 << bit_num);
}
void
BitsetDisplay()
{
int i;
for (i = NUM_BYTES; i > 0; i--)
{
digitalWrite(latchPin, LOW);
// shift out the bits:
shiftOut(dataPin, clockPin, MSBFIRST, bitset[i-1]);
//take the latch pin high so the LEDs will light up:
digitalWrite(latchPin, HIGH);
Serial.print(" ");
Serial.print(bitset[i - 1], BIN );
}
Serial.println(".");
}
void setup() {
Serial.begin(9600);
//set pins to output so you can control the shift register
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
BitsetSet();
BitsetDisplay();
}
void loop() {
int i;
int num_bits = 4;// NUM_BYTES * 8;
for( i = 0; i < num_bits ; i++)
{
if (i==0)
{
BitsetSetBit(num_bits - 1);
BitsetClearBit(i);
BitsetDisplay();
}
else
{
BitsetSetBit(i - 1);
BitsetClearBit(i);
BitsetDisplay();
}
delay(200);
}
}


