74HC595 two ics not working

Hi,
I have been working on a uno with mr gammons code, but it does not seem to work reliably, especially after resting all 16 bits to zero.
The two ic (16 bit) shift registers are constructed exactly as per the diagram on this page.

http://www.gammon.com.au/forum/bbshowpost.php?id=11518

I have added a 10uf and 0.1uf in parallel on the 5v power supply from the uno board which is powered by by the USB.

I have tested the code and it says it is outputting the correct states (by using Serial.print statements) to the serial monitor up to the bit out.

I am using pins 3,4,5 as I need to leave the SPI pins free for later using RF24 library.

I have only included the code to send data to pins via refreshLEDs ()
and using byte BB_SPITransfer (byte c) to set bits on the interface to transfer the data.

I have checked the physical board with the interface and the software code, but it is still unreliable when sending instructions from the serial interface.

Wiring: 
         (SS) to ST_CP (pin 12) of all 74HC595 chips
         (MOSI) to DS (pin 14) of the first 74HC595 chip
         (SCK) to SH_CP (pin 11) of all 74HC595 chips
*/

// bit banged SPI pins
// http://forum.arduino.cc/index.php?topic=100997.15
const byte BB_MOSI   = 3;  // Pin 3
const byte MSPIM_SCK = 4;  // Pin 4
const byte MSPIM_SS  = 5;  // Pin 5
const byte LATCH = MSPIM_SS;
const byte c = 0;
// control speed of programming
const byte BB_DELAY_MICROSECONDS = 40;
const byte numberOfChips = 2;
const byte maxLEDs = numberOfChips * 8;
byte LEDdata [numberOfChips] = { 0 };  // initial pattern
unsigned long delayAmount = 100;

// Bit Banged SPI transfer
byte BB_SPITransfer (byte c)////based on this code http://arduino.cc/en/Tutorial/ShftOut11
{ 

const byte d = c;
 byte bit;
 for (bit = 0; bit < 8; bit++) 
   {
     digitalWrite (BB_MOSI, LOW);
     digitalWrite (MSPIM_SCK, LOW);
   if (c & 0x80)
   {
     //  BB_MOSI_PORT |= _BV (BB_MOSI_BIT);
      digitalWrite (BB_MOSI, HIGH);

   }
   else
   {
       digitalWrite (BB_MOSI, LOW);

   }
   c <<= 1;
 // clock high
   digitalWrite (MSPIM_SCK, HIGH);
  // digitalWrite (BB_MOSI, LOW);
   // delay between rise and fall of clock
   delayMicroseconds (BB_DELAY_MICROSECONDS);
   // clock low
   digitalWrite (MSPIM_SCK, LOW);
   delayMicroseconds (BB_DELAY_MICROSECONDS);
       delayMicroseconds (BB_DELAY_MICROSECONDS);
   }
    digitalWrite (BB_MOSI, LOW);
 return c;
 }  // end of BB_SPITransfer 



void refreshLEDs ()
 {
  // Latch disable so no show leds before change
 digitalWrite (LATCH, LOW);
 for (int i = numberOfChips - 1; i >= 0; i--)
 {
 // Do all chips from zero to numberofchips -1
 BB_SPITransfer (LEDdata [i]);
 delay (20);
 }
 // Latch data into storage register after 16 bits written to shift register
 // Display LEDs
 digitalWrite (LATCH, HIGH);
  delayMicroseconds (BB_DELAY_MICROSECONDS);
  // Latch disable
 digitalWrite (LATCH, LOW);

 } // end of refreshLEDs
 
void setup ()
 { 
 // Always,Always set pins used
 pinMode (LATCH, OUTPUT);
 pinMode (MSPIM_SCK, OUTPUT);
 pinMode (MSPIM_SS, OUTPUT);
 digitalWrite (LATCH, LOW);
 digitalWrite (MSPIM_SCK, LOW);
 digitalWrite (MSPIM_SS, LOW); 
 
 Serial.begin (115200);
 Serial.println ("");
 Serial.println ("Starting Bit Out");
 Serial.println ("C: clearLED");
 Serial.println ("S: setLED");
 Serial.println ("I: invertLED");
 Serial.println ("D: setDelay");
 Serial.println ("P: pause");
 Serial.println ("R: rotateRight");
 Serial.println ("L: rotateLeft");
 Serial.println ("N': numberout"); 

//clear initial setup to zero 
 clearLED (0);// Clear data array
 refreshLEDs ();// Clear LED(s)
 } // end of setup

You’ll notice that the last part of your code is missing some square brackets around an i and turned into italics. This is why we have the rule here that you must always use code tags(</> button on the toolbar) when you post code or error/warning messages and other output. The reason is that the forum may interpret some of your text as forum markup, as happened here, which causes confusion, wastes our time, and makes it less likely that you will get help. You should also always use Tools > Auto Format on your code before posting it to the forum. You can edit your post to make these changes.

Few notes from barely looking at the code (undoable without the code tags).

adamsstephen:
but it does not seem to work reliably, especially after resting all 16 bits to zero.

So, what happens then?

adamsstephen:
I have added a 10uf and 0.1uf in parallel on the 5v power supply from the uno board which is powered by by the USB.

The 100nF should be placed as close to the 595 as possible. On a breadboard usually it's the easiest to just place it over the hip. It also needs to be a ceramic capacitor to be useful.

And are the chips indeed driving led's? If so, which color and with what value of resistor?

adamsstephen:
I am using pins 3,4,5 as I need to leave the SPI pins free for later using RF24 library.

That's BS :wink: If the RF24 library is designed the right way it should not pose any problem to put another device on the bus as long as it uses another SS/CS pin. That's where buses are for. But granded, software SPI should work for simply blinking some LEDs. But why not use the build in library? shiftOut() is already made for you :wink:

const byte MSPIM_SS  = 5;  // Pin 5
const byte LATCH = MSPIM_SS;

What the...

const byte c = 0;

A name like c is not useful at all....

Also, you really like to mix and match the style of your variable names. It get's more readable if you just use one style. Arduino standard is thisVariable (lowerCamelCase), ThisConstVariable (UpperCamelCase), THIS_MACRO (ALL_CAP).

const byte d = c;

Are you serious????

I have corrected the code listing error, this is my first post!

Should I have pull-or pull down resistors on Arduino ports?

I tried shift-in/out, but I am still having the same problems, which is why I use digitalwrite.

Some of the code is copied from elsewhere which is why the small c is used.

Copying c to d was just for debugging.

The RF library defines the pins to be used including pin 2, 7,8,11,12 and 13 for the hardware SPI.

So I need to avoid them if I want to put the output received out to the shift registers, to create more ports to control relays.

This part of a bigger project, but if I cannot transfer data from uno to shift registers accurately it is a waste of time.

I have attached the interface diagram as a pdf file.

serial out for Nano - Schematic.pdf (20.4 KB)

adamsstephen:
I have corrected the code listing error, this is my first post!

That's why there is a great fat sticky in each forum called How to use the forum to get you up and running quick :wink:

adamsstephen:
Should I have pull-or pull down resistors on Arduino ports?

On which pins? The pins driving the 595? No, you are driving them, no need for a pull x there.

adamsstephen:
I tried shift-in/out, but I am still having the same problems, which is why I use digitalwrite.

Shift in isn't going to help you here :stuck_out_tongue: But shiftOut() works just fine. So please switch back to that. I (and I think all here) hate debugging code that does exactly the same as a (build in) library :wink:

But a more important question here is, why do you find you have a problem? My crystal ball is still out for service (those damn IoT balls...). So what DOES happen? And what do you EXPECT to happen?

adamsstephen:
Some of the code is copied from elsewhere which is why the small c is used.

That's no excuse. Now it's your code and you would make it a whole lot easier for yourself (and us) to use meaningful variable names styled in the same way.

adamsstephen:
Copying c to d was just for debugging.

And did it help? I think it's a good idea to clean up your code and repost it :slight_smile:

adamsstephen:
The RF library defines the pins to be used including pin 2, 7,8,11,12 and 13 for the hardware SPI.

So?

adamsstephen:
So I need to avoid them if I want to put the output received out to the shift registers, to create more ports to control relays.

Not if the library is designed the right way and you pick another pin as CS or as for the 595 another LATCH/STCP :wink: Then you can let them share the MOSI, MISO en SCLK. That's why it's called a bus.

adamsstephen:
This part of a bigger project, but if I cannot transfer data from uno to shift registers accurately it is a waste of time.

Tons of people have done it before so it's just a problem in your implementation (in code or hardware).

adamsstephen:
I have attached the interface diagram as a pdf file.

Thanks!

But did you read my comment about the caps?

And the question about what you're driving?

And ow, R1 is useless...

And you have a weird loop for the !OE pin (which is wrongly displayed as an output) for the top 595. It circles around the bottom one instead of straight to GND.

And what's the C1 you talk about? I don't see any....

The code included below does work, tested on the board in the pdf. http://arduino.cc/en/Tutorial/ShftOut11 does not.

It does not latch the data into the 595 with the clock signal which is required, see the datasheet.
http://www.st.com/content/ccc/resource/technical/document/datasheet/cc/d3/42/d5/f3/44/4d/9f/CD00000339.pdf/files/CD00000339.pdf/jcr:content/translations/en.CD00000339.pdf

//Pin connected to ST_CP Pin 12 of 74HC595
int latchPin = 5;
//Pin connected to SH_CP Pin 11 of 74HC595
int clockPin = 4;
//Pin connected to DS Pin 14 of 74HC595
int dataPin = 3;

const int BB_DELAY_MICROSECONDS = 10;
const int n = 0;

// Integer n is the 16 bit number you pass to the function to output to the LED's on the 595's.
void shiftOut1(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, int n)
{
// replaces shiftOut with a working 16 bit version
  digitalWrite(latchPin,LOW);
  digitalWrite(clockPin,LOW);
  digitalWrite(dataPin,LOW);
// shift out highbyte
  BB_SPITransfer((n >> 8)); 
// shift out lowbyte
  BB_SPITransfer(n);
//Latch data to output pins
// increments data display
    digitalWrite(latchPin,HIGH);
    delay (10);
    digitalWrite(latchPin,LOW);
}

// Bit Banged SPI transfer
// Outputs 8 bit version to each 595 chip.
void BB_SPITransfer (byte c)
{ 
  // changed to make it work, as original shiftOut function does not work on 74HC595 chips
      digitalWrite (dataPin, LOW);
      digitalWrite (clockPin, LOW);
      digitalWrite(latchPin,LOW); 
  byte bit = 0;
  for (bit = 0; bit <8; bit++) 
    {
    if (c & 0x80)
     {
        digitalWrite (dataPin, HIGH);
     }
    else
     {
       digitalWrite (dataPin, LOW);
     }
  // clock high
    digitalWrite (clockPin, HIGH);
    digitalWrite(latchPin,HIGH);
    // delay between rise and fall of clock
    delayMicroseconds (BB_DELAY_MICROSECONDS);
    // clock low
    digitalWrite (clockPin, LOW);
    digitalWrite(latchPin,LOW);
    delayMicroseconds (BB_DELAY_MICROSECONDS);
    // next bit rotate
    c <<= 1;
    }
    // necessaary to latch bits into correct position
    digitalWrite (clockPin, HIGH);
    digitalWrite(clockPin,LOW);
     digitalWrite (dataPin, LOW);
   }  // end of BB_SPITransfer

adamsstephen:
The code included below does work, tested on the board in the pdf. http://arduino.cc/en/Tutorial/ShftOut11 does not.

It does not latch the data into the 595 with the clock signal which is required, see the datasheet.
http://www.st.com/content/ccc/resource/technical/document/datasheet/cc/d3/42/d5/f3/44/4d/9f/CD00000339.pdf/files/CD00000339.pdf/jcr:content/translations/en.CD00000339.pdf

Instead of making URLs bold, make them clickable instead by using the chain links icon on the toolbar:

This makes it easier for people to visit those links and thus you are more likely to get/provide help.

It looks like very similar example code to the one from the tutorial you linked is found on the shiftOut() reference page.