Go Down

Topic: Determining the Number of Shift Registers Connected to Arduino (Read 536 times) previous topic - next topic

csapidus

Hello!

I have a project that involves connecting multiple board modules. Each module has a shift register (74HC595) on it, and the user can connect as many together as they please. The shift register drives a display device. I am currently designing these board modules, and am looking for a way to recognize how many modules/shift-registers the user has attached. That will in effect influence the operations of the Arduino.

Some additional information:
The shift registers (and their parent module boards) are daisy chained. Clock to clock, latch to latch, and the data-lines feed into Q8 pins, except for the first shift register, which connects to the Arduino MEGA 2560.

I have been recommended using I2C chips, but I am wondering if someone could explain a possible solution using just shift registers and the Arduino.

Thanks!

dougp

The first thing that comes to mind is jumpers like those used to set hard drives.

Everything we call real is made of things that cannot be regarded as real.  If quantum mechanics hasn't profoundly shocked you, you haven't understood it yet. - Niels Bohr

No private consultations undertaken!

Riva

Assuming your daisy chaining them together then maybe have a connection from the last shift registers QH' pin back to an arduino input pin.
In setup you clock out enough zeros to cover max possible chain length and then clock out a 1 bit and count how many clocks it takes for the 1 to show up on the QH' input.
Don't PM me for help as I will ignore it.

Paul__B

Assuming your daisy chaining them together then maybe have a connection from the last shift registers QH' pin back to an Arduino input pin.
Sounds cool, but this involves some way to loop that connection back to the processor board.

If you are going to do that, you might as well just set the DIP switches - or tell the software.

The original question needs some clarification - why does it matter how many boards are chained?

hammy

Why not just use a few digital lines passing through the boards and use those and forget the shift registers - each wire having a pull up - three boards connected pulls up three digitals . You maybe able to multiplex and get a more neat solution.

csapidus

the why in short: making a tube calculator that adapts rounding of output based on number of display modules attached

you're right though, getting the loop back to the microcontroller will be difficult with my set-up, though I may be able to get it to work with some finagling.


there might be up to eight modules on either side, so having eight wires ready seems kind of troublesome

csapidus

Assuming your daisy chaining them together then maybe have a connection from the last shift registers QH' pin back to an arduino input pin.
In setup you clock out enough zeros to cover max possible chain length and then clock out a 1 bit and count how many clocks it takes for the 1 to show up on the QH' input.
I have a set-up here with 74HC595s on a bread-board connected to an UNO; I am trying to get what you are suggesting to work. I am fairly new with shift-registers, so be patient with me! If I understand correctly, I would digitalWrite(clockPin, LOW) at least as many times as needed for the number of modules, then write in a digitalWrite(clockPin, HIGH), and count the number of clock pulses? How would I count the number of clock pulses using Arduino code?

CrossRoads

If you can bring the output of the last shift register back to the Ardiuno, then you can use SPI to write & read at the same time, as MISO is read in while MOSI goes out.

So you can do something like this:

digitalWrite (ssPin, LOW);
misoIn = SPI.tranfer(0xAA);
digitalWrite (ssPin, HIGH);

if (misoIn == 0xAA) then you know the data has gone thru all of them and made it back.
Wrap the transfer in some counter code so you know how many SPI,transfers if took,
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Riva

you're right though, getting the loop back to the microcontroller will be difficult with my set-up, though I may be able to get it to work with some finagling.
How are the modules connected to each other. If you had a connector like a 3.5mm jack socket (plus a few other pins) where inserting a plug breaks a connection this would allow daisy chaining without user intervention because the break point would be the QH' return.
If your using normal PCB edge connectors (like in #1) then a jumper would do the trick on the last module. A user would need to remove the jumper to join another module on the end but the last module would just keep the jumper on.
Don't PM me for help as I will ignore it.

Paul__B

If you use PCF8574 instead or even PCF8575, you could give each a different address on the eight boards, use the 2 pin I2C bus and the I2C library will tell you which are and are not connected (but not in which order).

csapidus

Thank you all for the recommendations. Hardware wise, I figured out a way that follows recommendation 2 (essentially a jumper) mentioned in #9. I essentially have termination blocks that need to be put at the end of however many models are attached, in order to feed that info back to the main board/uController.

I am struggling with the code however. This is where I am at. Currently, I am simply getting a reading of zero from input pin readPin. Note, readPin is connected to Q7'


Code: [Select]


//**************************************************************//
// TESTING SHIFT REGISTER CHAINING
//****************************************************************

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

int readPin = 2;
int readIT = 0;

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);
 
 pinMode(readPin, INPUT);
}

void loop() {
 
 readPin = digitalRead(reading);
 Serial.print("reading: ");
 Serial.println(readPin);

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

 readPin = digitalRead(reading);
 Serial.print("reading: ");
 Serial.println(readPin);

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

 readPin = digitalRead(reading);
 Serial.print("reading: ");
 Serial.println(readPin);
}


csapidus

If you can bring the output of the last shift register back to the Ardiuno, then you can use SPI to write & read at the same time, as MISO is read in while MOSI goes out.

So you can do something like this:

digitalWrite (ssPin, LOW);
misoIn = SPI.tranfer(0xAA);
digitalWrite (ssPin, HIGH);

if (misoIn == 0xAA) then you know the data has gone thru all of them and made it back.
Wrap the transfer in some counter code so you know how many SPI,transfers if took,
@CrossRoads, thanks for the suggestion! I actually just managed to get the set-up you recommended using SPI.transfer working. I am currently using those SPI pins elsewhere, but will try to configure a two-slave set-up

dougp

I am struggling with the code however. This is where I am at. Currently, I am simply getting a reading of zero from input pin readPin. Note, readPin is connected to Q7'
Can you verify that the output data is getting latched into the individual registers?
Everything we call real is made of things that cannot be regarded as real.  If quantum mechanics hasn't profoundly shocked you, you haven't understood it yet. - Niels Bohr

No private consultations undertaken!

Paul__B

Can you verify that the output data is getting latched into the individual registers?
Actually, the elegance of this is that while determining the number of shift registers, you do not latch any data from the registers, so the outputs - apart from the carry - are not altered.

You would start by shifting out the initialisation - presumably zeros - to more then the anticipated number of registers and latching that to the outputs, then shift 0x01 or 0xff through until it is detected at the final carry output, but without latching.  After that, always shift out as many bytes as there are registers (unless it is appropriate to ripple the displays).

dougp

then shift 0x01 or 0xff through until it is detected at the final carry output, but without latching.
This is what I was, clumsily, driving at.  I can't see how the posted code shifts a value which would turn on the second stage QH with two bytes sent.

Everything we call real is made of things that cannot be regarded as real.  If quantum mechanics hasn't profoundly shocked you, you haven't understood it yet. - Niels Bohr

No private consultations undertaken!

Go Up