Monday, 2 April 2012

My DIY Arduino MIDI controller - 5. Finding more pins, part III: the shift register

As I said in a previous post, I might need to expand the digital outs as well as the analog ins, so I followed Grumpy_Mike's advice on the Arduino forums and got a 74HC595 shift register to control my LEDs instead of the 4051. The 8 bit shift register is a very convenient way to drive 8 LEDs with only 3 digital pins: you just send it a series of 8 HIGHs or LOWs and it lights on/off the LEDs accordingly when you tell it so. Looks exactly like what I need. I followed this ShiftOut tutorial to learn how to handle the chip, then I modified the second code example from the tutorial to make something like this:



This is the circuit:


And the code I came up with, slightly modified from the tutorial:

/*
  Shift Register Example
 for 74HC595 shift register

 This sketch turns reads serial input and uses it to set the pins
 of a 74HC595 shift register.

 Hardware:
 * 74HC595 shift register attached to pins 2, 3, and 4 of the Arduino,
 as detailed below.
 * LEDs attached to each of the outputs of the shift register

 Created 22 May 2009
 Created 23 Mar 2010
 by Tom Igoe
 
 Modified 1 Apr 2012 by Yann Guillermou

 */

//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;

// the bits you want to send (a byte is 8 bits, one per LED)
byte bitsToSend = 0;

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}

void loop() {
  for (int i = 0; i < 8; i++) {
    registerToggle(i);
    delay(100);
  }
}

// This method sends bits to the shift register:
void registerToggle(int pin) {
  //  turn of the output so the pins don't light up
  //  while we're shifting bits
  digitalWrite(latchPin, LOW);
  
  // read bit state
  int state = bitRead(bitsToSend, pin);
  
  // change bit state
  state = -state + 1;
  
  // toggle the bit in bitsToSend:
  bitWrite(bitsToSend, pin, state);
  
  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);

  // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);
}

The mod' consisted in making the bitsToSend variable global because I wanted to be able to toggle an LED without affecting the others, and above all keep track of each LED state. I also replaced the registerWrite() function by this registerToggle() function, just to check if I had understood well enough how to do.

This code only loops and toggles the LEDs on then off but with the registerToggle() and registerWrite() functions you can easily tell the chip which LED to turn on or off, this way it is as easy as a digitalWrite().

Next post will be about MIDI out, as I got a couple of breadboard friendly MIDI connectors!

<< Previous: 4. Finding more pins, part II + LDR Calibration

4 comments:

  1. its very cool but can i use this code to set register input for some for an fpga and how to do it

    ReplyDelete
  2. Syntax error on line 1 "its very cool but can i use this code to set register input for some for an fpga and how to do it".

    ReplyDelete
  3. i want to set register input for bga chips
    its SOC "sti7111"
    how can i do that with arduino and ur code

    ReplyDelete
  4. I googled "arduino STI7111" and from the results I got I assumed it is not possible. Don't mistake me for a search engine though.

    ReplyDelete