Showing posts with label arduino 74LS595 shift register relay I/O computer control. Show all posts
Showing posts with label arduino 74LS595 shift register relay I/O computer control. Show all posts

Wednesday, 7 September 2011

48 bit Shift Register

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);
  }
}