Pages: [1] 2   Go Down
Author Topic: Reference: ShiftOut() versus SPI.h  (Read 2661 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 82
Uno momento
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My project requires the use of a pair of cascaded 595 shift registers. And I need to consider the method that features least power consumption and also runs the fastest.  Speed is marginally preferable to power efficiency in my case...

So my first port of call is the ShiftOut() documentation, which is great, but then that links me, tantalisingly(!) to the SPI library pages.

It says that the SPI library uses "hardware" rather than software.  How exciting I thought, however sadly that's where the description stops.  It does not suggest whether or not SPI is more or less efficient because it uses hardware.  The curious reader is left nonplussed and uncertain as to which course of action to commit to.

Also the examples are uneven.  Sure shiftout() has very good example code and also some (very) low resolution circuit diagrams but there is nothing comparable on the SPI side.  Can we have an SPI example that drives a pair of shift registers like the ShiftOut() examples do?

Also, in the SPI docs, the concept of "Slave Select" is not clear.  That needs to be explained in detail with an example (perhaps an arduino talking to 2 separate (non cascading) shift registers).

Phrasing: "Typically there are three lines common to all the devices..." - this then goes on to name 4 items, not 3.  Is the last item not applicable?

The pin usage differences between the ShiftOut examples and the SPI examples are not adequately explained.

Can someone please revise those sections please?

Cheers smiley
« Last Edit: February 15, 2011, 04:00:12 pm by wossname » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8453
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

From what I've seen much of the documentation needs some work.

Using the SPI hardware will be a LOT more efficient than shiftOut, but limited to the 3 (or 4) hardware pins.

If you are talking to SRs then SS is not relevant, that is used by a slave and in this case the Arduino is a master.

There is no obvious benefit to seperating the SRs though and it causes other issues, do you have a good reason to do so?
______
Rob
« Last Edit: February 15, 2011, 08:33:28 pm by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 439
Posts: 23782
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Rob,
I think you would still need the SS pin to act as the latch (or clock) for the output stage of the shift registers.

If you had multiple non-cascaded shift registers than each would need its own SS pin (assuming they share the clock & data pins).

One would assume that similar to hardware RX/TX being faster than Soft(ware) Serial, SPI would be similarly faster than Software Shiftout.
With the exception of needing to handle the SS in software still:
Code:
  // start up SPI to talk to the MAX7221
  SPI.begin(); // nothing in () because we are the master
  pinMode(SS, OUTPUT);  // Slave Select for SPI  <--- Need this here before any SPI writes?

  //  MAX7221: write shutdown register 
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data, 0x00 = Outputs turned off
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
 

thus I could see replacing shiftout with this for sending 1 byte to a shift register
Code:
  SPI.transfer(your_data);  // shift out the 1 byte
  digitalWrite(SS,LOW);  // take the RCK pin lo/ho to move the data to the output register
  digitalWrite(SS,HIGH);   // in a 74HC595 or TPIC6B595 for example
Robert
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 82
Uno momento
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There is no obvious benefit to seperating the SRs though and it causes other issues, do you have a good reason to do so?
______
Rob

Well, that example is actually from a circuit where I had two displays both driven by a separate shift register, they both have to be driven very fast but never both at the same time.  I'd be writing to one or the other at any given moment, but each only requires 8 bits of output.  If you really must know it was a pie in the sky idea for a 3D heads up display, driven by an arduino.  I think it's technically possible but at the moment is waaaay beyond my technical skill level.  The design is flawed actually and needs a re-think before serious consideration is applied to actually building it.

Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 509
Posts: 31472
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
"Typically there are three lines common to all the devices..." - this then goes on to name 4 items, not 3.  Is the last item not applicable?

There are 4 wires used, but three of them are common to all devices, then each separate device needs it's own enable pin (unless it uses internal addressing like the 23S17)
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 82
Uno momento
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, it's very clear that there are several people knowledgable on this subject - could we perhaps collaborate and get a nice bit of code and a circuit diagram together that shows idiots like me how to drive one 595 shift register using SPI.h functions?  Then we can add quite a bit of value to the online docs by adding something that actually makes sense smiley

I can drive a single SR using the "less efficient" ShiftOut() functionality (because it's docs very sensibly give actual pin numbers for BOTH Arduino and the 595) - but I'm having some real problems making the same thing happen using SPI.h.  It's just not clear which arduino pin should be connected to the SR, the information assumes too much prior-knowledge in the reader.  Simple and clear instructions get the project finished faster.  The sooner people can get a project running the more enjoyment they derive from achieving something!  

Enjoyment is the main point of Arduino right? smiley

Then, once that is done, we can explain that the system can be extended by adding a second (third, fourth...) SR by chaining them together, the circuitry changes are already detailed in the ShiftOut() page.

I'll volunteer for guinea pig duty - send some code and a circuit diagram my way and I'll hook up my Uno and see if we can come up with some explanatory text to make it moron proof, this moron will work for free smiley
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 82
Uno momento
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I need this SPI/dual shift register stuff for my own project so I'll figure it out and try to document it with pinouts and perhaps a photo or two.  Maybe others will have a use for it.
Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 439
Posts: 23782
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Try this for starters, 2 examples.
One with common controls.
One with 3 parts sharing data, clock, but separate output register clock.

Will try some code next.
What will you hook up to the outputs to show the blinding speed we'l achieve?


* SPI_shiftout.jpg (99.42 KB, 960x720 - viewed 63 times.)
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16523
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A good starting reference for SPI theory and usage is the AVR datasheet manual for the 328 processor.
Section 18 covers the topic well and even gives classic assembly and C coding examples.

http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 82
Uno momento
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Erk!  I'm gonna need some more breadboard jumpers!

A noobie question: on the right-hand circuit - the separate "out clock (Slave Selects)" lets you latch any single Shift Register of the three, independantly of the other two?  In what situation would you use this functionality?  Does the SS pin affect both the shifting-in of data AND latching or just latching?  

Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 82
Uno momento
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What will you hook up to the outputs to show the blinding speed we'l achieve?

192 high candela blue LEDs, running at a rate of about 40 frames per second (something near 7800 * 16 shifted bits per second).  It's not all that fast, but it will probably give you a headache if you stare at it for too long.
Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 439
Posts: 23782
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Does the SS pin affect both the shifting-in of data AND latching or just latching?
The SS pin is used to latch data on the output register when shifting out, and to latch data into the incoming parallel latch when shifting in.
This will need to  be confirmed with a specific shift in register.

I only showed the two examples to show that more pins would be used for multiple independent parts.  All would get the same data shifted in, but only 1 would have its data shifted into the output stage.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 439
Posts: 23782
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#include <SPI.h>
// SPI library sets up pins 11, 12, 13
int SS1 = 10;  // need for SPI
byte register1 = 0;
byte register2 = 0;
byte register3 = 0;
byye pinPWM = 3;

void setup() // stuff that runs once before looping forever
{
  // start up SPI to talk to the MAX7221
  SPI.begin(); // nothing in () because we are the master
  pinMode(SS1, OUTPUT);  // Slave Select for SPI  <--- Need this here before any SPI writes

  //  write out the data
  SPI.transfer(register1);  // 1st byte
  SPI.transfer(register2);  // 2nd byte
  SPI.transfer(register3);  // 3rd byte 
  digitalWrite(SS1,LOW);  // take the SS pin low,
  digitalWrite(SS1,HIGH);   // take the SS pin high to latch data into output register
}

void loop (){
  // tricky part - making it do something
 
}
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 82
Uno momento
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Crossroads: I tried the first of your two diagrams and it looks like it works fine, but I'm unsure about why you've connected PWM1 (Pin3 according to your code sample) to the SR.  I've tried setting it high or low at various times but it doesn't seem to do anything, as soon as I set SS high and then low again the bits get pushed onto the outputs (and my LEDs light up).  So basically I can control both chained SRs just using 3 pins on the arduino...

Code:
My pinout:
ARDUINO UNO Pin 13 (SPI:SCK)                    --->  74HC595 Pin 11 (SCK "Shift register clock input")
ARDUINO UNO Pin 11 (SPI:MOSI)                   --->  74HC595 Pin 14 (SER "Serial Data Input")
ARDUINO UNO Pin 10 (generic digital output)     --->  74HC595 Pin 12 (RCK "Storage register clock input")
ARDUINO UNO Pin GND                             ---> provides sink for circuit's GND rail
ARDUINO UNO Pin 5V                              ---> provides source for circuit's +5V rail


For the diagram I just used the one from the ShiftOut tutorial that uses 2 shift registers...
http://arduino.cc/en/uploads/Tutorial/ShftOut_Schm2.gif

My code (flashes each of the 16 LEDs in turn)...

Code:
#include <SPI.h>

#define SHIFT_REGISTER_LATCH_SS (10)

void setup()

  //initialize SPI: 
  SPI.setBitOrder(LSBFIRST);
  SPI.begin();
  pinMode(SHIFT_REGISTER_LATCH_SS, OUTPUT);

  //clear both shift registers so that all output pins go low
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  digitalWrite(SHIFT_REGISTER_LATCH_SS, LOW);
  digitalWrite(SHIFT_REGISTER_LATCH_SS, HIGH);
 
  for (unsigned short int level = 1 ; level < 0x10000 ; level <<= 1)
  {
    UpdateDisplayPinFlags( (level >> 8) & 0xff, level & 0xff);
    delay(100);
  }
 
  UpdateDisplayPinFlags(0, 0);
}

void loop()
{
}

int UpdateDisplayPinFlags(byte high, byte low)
{
  SPI.transfer(low);
  SPI.transfer(high);
  digitalWrite(SHIFT_REGISTER_LATCH_SS, LOW);
  digitalWrite(SHIFT_REGISTER_LATCH_SS, HIGH);
}


This seems to work nicely (Although the code needs tidying up and commenting a bit) but there is always about 1 second where the first shift register (connected directly to the arduino) has a few bits high at startup.  This happens before my code to zero them out executes.  I can't seem to stop this in code.  I've double checked my wiring against the diagram and I don't think I've missed anything.  Any ideas?
« Last Edit: February 20, 2011, 11:34:06 am by wossname » Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 439
Posts: 23782
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, I had the PWM pin in there so you could play around with fading the LEDs. Give that a try.

Where do you have the OE/s wired to now? Try wiring it with a pullup resistor, and then pull it low after you've clocked some good data in.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Pages: [1] 2   Go Up
Jump to: