SPI.transfer() on 74HC595 - problem (Solved)

Hello guys, im begging for help.

I want to use 74HC595 shift registor to read push buttons state. So far, I cant even get all outputs HIGH for attachInterrupt() function.

Im using Arduino Mega 2560. My scheme is on the picture. My code is:

#include <SPI.h>

//Pin connected to ST_CP of 74HC595
int latchPin = 4;
//Pin connected to SH_CP of 74HC595
int clockPin = 13;
////Pin connected to DS of 74HC595
int dataPin = 11;

void setup(){

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.begin();

  digitalWrite(latchPin, LOW);
  SPI.transfer(B11111111);
  digitalWrite(latchPin, HIGH);
 
}


void loop() {

}

My problem is in SPI.transfer. It seems not working at all. Ive got multimeter at pin Q1. The only thing that bring all pins to HIGH is:

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
digitalWrite(latchPin, HIGH);

SPI.transfer(B11111111);”, as well as “SPI.transfer(0xFF);” and “SPI.transfer(255);” instead of shiftout does not work :frowning:

To bring all pins LOW - If I use “SPI.transfer(B00000000);”, first time of sketch upload - nothing happens, second time of upload, it brings all pins LOW. Shiftout function works well, as a charm, all the time.

My steps for debugging:
I tripple checked my wirings.
I tryied delay(5000); everywhere. (Because I dont have any capacitor)
I tryied slow things down by SPI.setClockDivider(SPI_CLOCK_DIV128);
I tryied another shift registor (Ive got 10 pcs)

Iam out of ideas, please help me find my mistake…

Thank you very much!

A 595 shift register is output only. As fat as I know you can not read from it. One would use a 74165 parallel in/ serial out shift register to read switches.

74165.pdf (73.3 KB)

That SR is only for outputs. Try a '165.

EDIT: Oh I see you are pulling some sort of flanker by feeding the outputs back to an input. I'll have to study that.


Rob

Actually, I dont need to read the registor itself. I plan to cycle outputs 0 to 7 one by one HIGH and read their state on pin2 at Arduino...

Anyway Im still stuck at getting all pins output HIGH so far, which should no be any problem.. :(

OK I gotta ask, why are you doing it this way?


Rob

Well, Iam extremely new to arduino.

This is the simpliest and most effective way I find so far. My project will contain 126 momentary push buttons...

I got the idea by https://www.youtube.com/watch?v=nXl4fb_LbcI

You have '595 pins OE connected to GND and MRCLR connected to +5?

Get rid of these. They are all taken care of by SPI.begin();

//Pin connected to SH_CP of 74HC595 int clockPin = 13; ////Pin connected to DS of 74HC595 int dataPin = 11; pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT);

Move these to after SPI.begin() : SPI.setBitOrder(MSBFIRST); // don't even need - this is default setting SPI.setDataMode(SPI_MODE0); // don't even need - this is default setting SPI.setClockDivider(SPI_CLOCK_DIV2);

Add this: byte spiModePin = 10; pinMode (spiModePin, OUTPUT); // needed for device to be SPI master, if an input and it goes low device becomes SPI slave

Ok, so now my code looks like this:

#include <SPI.h>

int latchPin = 4; 
byte spiModePin = 10;

void setup(){

  pinMode(latchPin, OUTPUT);
  pinMode (spiModePin, OUTPUT); // needed for device to be SPI master, if an input and it goes low device becomes SPI slave 

  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  
  digitalWrite(latchPin, LOW);
    delay(500);
    SPI.transfer(B11111111);
    delay(500);
  digitalWrite(latchPin, HIGH);
 
}


void loop() {

}

But the result is still the same. :frowning: No pin goes HIGH with SPI.transfer(B11111111);. For pins to go LOW it takes to twice load the sketch with SPI.transfer(B00000000);

OE is connected to GND and MR(10th pin on '595) goes to +5V. (no change here, I just checked it again)

For amusement, I tried to connect pin10 on Arduino Mega to +5V to make it master, no change as well.

EDIT:

Ok, now it takes to twice load the sketch for pins to go HIGH or LOW by shiftOut(dataPin, clockPin, MSBFIRST, B11111111); (or B00000000)

Gotta be something in your setup then - I do that very same thing with this card to write to 12 shift registers, and have daisy chained up to 3 cards for 33 shift registers without issue:
Schematic:


This shift register uses the same signal names, but on different pins, don’t let that confuse you. It has PWM on the OE (G) pin, that can be connected to Gnd instead if no dimming is planned.

Ha, Ive got it!

The default pins for MOSI and SCK on Arduino Mega 2560 seems to be different than on Arduino Uno.

On Mega, its pins 51 and 52 instead of 11 and 13.

But anyway, thank you for your help. I appreciate it very much :)

So it was your setup then. I missed that you were using a Mega. Too tied up in the code issues.

Yes. Iam a programmer in PHP in my free time, so by my experience I was quite sure its a man made mistake (by me :wink: ) I just needed a right direction where to look for it :slight_smile:

man made mistake

Yeah, these darn computers, only doing what we tell them instead of what we intended ;)