Pages: [1]   Go Down
Author Topic: Problem using 74HC595 shift registers  (Read 598 times)
0 Members and 1 Guest are viewing this topic.
Pakistan
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm working on a project where I need to control 32 LEDs individually. For starters, I read the documentation for the 595 register on the Arduino site (http://www.arduino.cc/en/tutorial/ShiftOut) and tried implementing it with two shift registers connected (instead of the four that are actually required for 32 outputs). Since I just wanted to test the functionality of the shift register, I only hooked up 2 LEDs to Q0 and Q1 of the first register. I used the code linked on the same page (http://arduino.cc/en/Tutorial/ShftOut13) though I amended the loop function slightly (didn't touch the registerWrite function):

Code:
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 5;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 6;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 4;

char inputString[2];

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("reset");
}

void loop()
{
  int LED0 = 0;
  int LED1 = 1;
  registerWrite(LED0, HIGH);
  registerWrite(LED1, LOW);
}
// This method sends bits to the shift registers:

void registerWrite(int whichPin, int whichState) {
  // the bits you want to send. Use an unsigned int,
  // so you can use all 16 bits:
  unsigned int bitsToSend = 0;   

  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);

  // turn on the next highest bit in bitsToSend:
  bitWrite(bitsToSend, whichPin, whichState);

  // break the bits into two bytes, one for
  // the first register and one for the second:
  byte registerOne = highByte(bitsToSend);
  byte registerTwo = lowByte(bitsToSend);

  // shift the bytes out:
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);

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

The only other difference was that I used pins 5, 6 and 4 instead of 8, 11 and 12 in the tutorial. The problem I'm facing is that both LEDs light up when I set LED0 to HIGH, regardless of what I set LED1 to. Another issue is that when I insert a delay() function anywhere in the loop, neither LED lights up regardless of whether I set it to high or not.

I triple checked all the connections to make sure they all matched the schematic on the tutorial page. If it helps, here are some things I did a bit differently from the schematic:

1) I didn't use the 0.1microfarad capacitor (didn't have it at the time).
2) I was using USB power so there was no external 5V source (the VCC and MR of both registers were connected together though) and I used the GND on the Arduino for grounding.
3) I'm using an Arduino Nano v3.0

Anyone have any idea what I'm doing wrong?

Logged

texas
Offline Offline
God Member
*****
Karma: 27
Posts: 862
old, but not dead
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


I triple checked all the connections to make sure they all matched the schematic on the tutorial page. If it helps, here are some things I did a bit differently from the schematic:

1) I didn't use the 0.1microfarad capacitor (didn't have it at the time).
2) I was using USB power so there was no external 5V source (the VCC and MR of both registers were connected together though) and I used the GND on the Arduino for grounding.
3) I'm using an Arduino Nano v3.0

Anyone have any idea what I'm doing wrong?

Yes, I highlighted it in red.  This is common.
Logged

Experience, it's what you get when you were expecting something else.

Montreal
Offline Offline
Edison Member
*
Karma: 23
Posts: 2486
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I suspect, that you can't use "delay" as it associated with Timer0, same for pins 5 & 6. I'd suggest to move all wiring up on SPI pins, doing this way you get much faster code. look here
http://www.elcojacobs.com/using-shiftpwm-to-control-rgb-leds-with-arduino/
Logged

Pakistan
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm pretty frustrated at the moment. I spent 3 hours pulling apart and rejoining the circuit, but still the problem wouldn't go away (despite using the capacitor too). I tried working on 1 register, but still it didn't work. When I attached 8 LEDs to it, the first 7 lit up and the 8th would NEVER light up. Anyway, later I did a bit more snooping around and realized I'd been an idiot all along. I took this schematic: http://arduino.cc/en/uploads/Tutorial/ShftOut_Schm1.gif
to be identical to the ports on the register viewed top-down, which it isn't; something I realized when I visited this page: http://www.gammon.com.au/forum/?id=11518

I'll try again tomorrow, but in the meanwhile I also found out that the registerWrite function in the tutorial won't work for more than two shift register. Seeing as I'll need four, I'm trying to use the SPI library now. I'll also need to control all 32 LEDs individually (not in a pattern or anything), so I wrote this code to do that:

Code:
//MOSI: 11
//SCK: 13
//SS: 10

#include <SPI.h>

boolean bit_string[32];
const int LATCH = 10;

void setup()
{
  SPI.begin();
  
  //initially setting all LEDs off:
  byte init = 0;
  for(int i=0; i<4; i++)
  { SPI.transfer(init); }
}

void loop()
{
  int LED = 4;
  change_LED(4, true);       //should turn on the 5th LED (counting starts from zero)
}

void change_LED(int LED_number, boolean state)      //LED nubmer and state to set it to, both received as arguments
{
  unsigned int inter=0;
  byte LEDdata[4];                   //number of shift registers = 4
  bit_string[LED_number] = state;
  
  //converting bit_string to an unsigned integer:
  for(int i=0; i<32; i++)
  {
    int power=31;
    if(bit_string[i]==true)
    { inter += pow(2, power); }
    power--;
  }
  
  //extracting the leftmost and rightmost byte of the 4-byte integer:
  LEDdata[0] = highByte(inter);
  LEDdata[3] = lowByte(inter);
  
  //extracting the 2nd and 3rd bytes of the integer using bitshift left and bitshift right operators:
  unsigned int temp;
  temp = inter<<= 8;
  LEDdata[1] = highByte(temp);
  temp = inter>>= 8;
  LEDdata[2] = lowByte(temp);
  
  //transfering the bytes to the register:
  digitalWrite(LATCH, LOW);
  for(int i=3; i<=0; i--)
  { SPI.transfer(LEDdata[i];
  digitalWrite(LATCH, HIGH);
}  
  

Could please just check the change_LED function and let me know if my approach is correct or not?

Thanks
« Last Edit: April 13, 2013, 03:01:55 pm by ali250 » Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 60
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually the 100nf between the latch and ground is not correct. The 100nf should be between the vcc and ground of the chip.

About the code, did you try the code given by the shift out tutorial?
Logged

Montreal
Offline Offline
Edison Member
*
Karma: 23
Posts: 2486
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

FYI, "boolean bit_string[32];"  may be not what you expecting, boolean is an integer 16-bit variable, so you declare 32 x 2 = 64 bytes array
Logged

Pages: [1]   Go Up
Jump to: