ShiftOut Function(s) Why are there two ?

So I started playing around with a 74hc595 because there was a chapter in my Sainsmart Starter Kit on it and when I researched
on the forum it looked like there was quite a lot to be said about using it. I started on this page here:
http://arduino.cc/en/Reference/shiftOut#.UwKUGPldV8E

and clicked on a link there and wound up here :

Started breadboarding the circuits and running examples and then when I ran the first example I saw this statement:

 shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);

The ShiftOut function was obviously built into the Arduino IDE which seemed convenient but when I looked at this
example:

I noticed that it had a shiftOut funtion defined:

 // the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first, 
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut?
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights. 
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result 
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000 
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {	
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 0);
}

and this function had 3 arguments whereas the builtin one had 4.
All the code seemed to originate from the same authors but I couldn’t find any explanation for why:

  1. they needed to write the second function.
  2. how the IDE knows which function it’s running if they are spelled the same (does the second one supercede the first ?)
  3. Why the first one takes a format argument (MSBfirst/LSBfirst) whereas the second one omits that argument ?
  4. Is there a reason why you would still want to use the second function even if you didn’t care about the MSB/LSB order ?

After playing around with (using) the second function a little I discovered that it was really easy to use
and I was able to create a Knight Rider type display (attached) using an array and the second function . Researching online
I found an example program on the Nudatech website that does the same display using the first function. (attached)
When I researched on the forum I found this thread about arrays:

where the OP posted this:

i.e. This fails;
Code:
byte dataArrayRED[10]; //global
int dataArrayRED = {0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xE0}; //local
whereas this works, with the array being loaded with values below;
Code:
byte dataArrayRED[10];//global
dataArrayRED[0] = 0xFF;
dataArrayRED[1] = 0xFE;
dataArrayRED[2] = 0xFC;
dataArrayRED[3] = 0xF8;
dataArrayRED[4] = 0xF0;
dataArrayRED[5] = 0xE0;
dataArrayRED[6] = 0xC0;
dataArrayRED[7] = 0x80;
dataArrayRED[8] = 0x00;
dataArrayRED[9] = 0xE0; //local

and then later happily posted this , saying “nevermind , I got it”:

  byte ArrayRED[] = {0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xE0};
  for (int i =0;i<=sizeof(ArrayRED);i++)
  {
    dataArrayRED[i]=ArrayRED[i];
  }

to which someone replied this:

So, you successfully re-invented the memcpy() function. Except without any bounds checking.

to which the OP replied this:

I take it memcpy() eliminates the need for bounds checking?

to which the other person replied this:

I take it memcpy() eliminates the need for bounds checking?
No. You can use memcpy() to copy a large array “into” a small array, and it will happily crap all over the place.

All this because the OP did want to do this :

 whereas this works, with the array being loaded with values below;
Code:
byte dataArrayRED[10];//global
  dataArrayRED[0] = 0xFF; 
  dataArrayRED[1] = 0xFE; 
  dataArrayRED[2] = 0xFC; 
  dataArrayRED[3] = 0xF8; 
  dataArrayRED[4] = 0xF0; 
  dataArrayRED[5] = 0xE0; 
  dataArrayRED[6] = 0xC0; 
  dataArrayRED[7] = 0x80; 
  dataArrayRED[8] = 0x00; 
  dataArrayRED[9] = 0xE0; //local

because it is not as “elegant”

All of this is about the proper way to declare and call arrays and two dimensional arrays , which seems to be quite
relevant to how I should write programs for the 74c595, which while great for led displays, also has a more useful
function of adding I/O to an arduino with little overhead and a $5 chip. (or less), which I definitely need to know
how to do. So my 5th and final question is,
5. Is the way I did it in my program that used the second function (the one not built into the IDE, that only has 3 args)
the correct way to do it ?
byte mydata[15] ={ 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; 

Is it functionally the same as this : ?

 whereas this works, with the array being loaded with values below;
Code:
byte dataArrayRED[10];//global
  dataArrayRED[0] = 0xFF; 
  dataArrayRED[1] = 0xFE; 
  dataArrayRED[2] = 0xFC; 
  dataArrayRED[3] = 0xF8; 
  dataArrayRED[4] = 0xF0; 
  dataArrayRED[5] = 0xE0; 
  dataArrayRED[6] = 0xC0; 
  dataArrayRED[7] = 0x80; 
  dataArrayRED[8] = 0x00; 
  dataArrayRED[9] = 0xE0; //local

Which method is most useful for General Purpose I/O (Panel Indicator Leds, Relays, turning on/off motors (fans) and other
GPIO you would expect to find on a piece of industrial equipment ?
(unlike most posters, this is not about solving a problem, but about learning how to do things correctly so I won’t have
any , (problems).
PaulS ,
If you’re out there I know you have the answers.

My_Shift_Register_ARRAY_Knight_Rider.ino (4.69 KB)

Nudatech_shift_register_74CH595N_Knight_Rider.ino (1.71 KB)

PaulS ,
If you're out there I know you have the answers.

Not always, but in this case I do. The shiftOut() function has not always been part of the Arduino tool set. Now it is.

The compiler knows which version to call, based on whether there is a sketch method of a given name, or not. Local functions trump library functions.

  1. Why the first one takes a format argument (MSBfirst/LSBfirst) whereas the second one omits that argument ?

Requirements creep. Some devices expect the data in one order. Others expect it in the other order. Sometimes it makes sense to define the data opposite of what the using device expects.

Thanks !

Wow, all that, and you haven't discovered SPI.transfer() yet.
Check it out.

What makes you think that?

I don't see it in your discussion at all.

Forum protocol dictates that the posts should be relevant to the post title, which is specific to functions written for the 74hc595.
I am interested in learning about all the ways to maximize use of the Arduino I/O , which includes SPI (which I use to program
ATtiny85s,
http://forum.arduino.cc/index.php?topic=206429.msg1518628#msg1518628
http://forum.arduino.cc/index.php?topic=208057.msg1540281#msg1540281

6-digit , 7-segment display
http://forum.arduino.cc/index.php?topic=205446.msg1513292#msg1513292

MCP4162s
I interfaced six digital pots to an arduino but during my experimentation I shorted one of the pots and wound
up with only five when I finally got the code worked out. It cycled them up and down using 5 leds to display the
potentiometer state.

I prefer I2c because it doesn't require chip selects but ways to expand I/O using either SPI or I2C I/O expanders is
something I am interested in. As long as the application isn't too time critical I could see using an arduino to control
quite a bit more than 14 + 6 I/O lines but I haven't been keeping track of RAM memory usage and I truthfully don't
know how close I am coming to reaching the limit of program size. I think there are ways to expand the memory
but I haven't looked into that yet. In any case, I have and do use SPI and I2C but this post is not about SPI , it's
about the 74hc595 and the "shiftOut" function.
Speaking of SPI, remember you recommended the DIP MICRO ATmega328 with OPTIBOOT LOADER ? I bought two
of those and I have one of them running the "Basic Use " example of the TLC5940 Library using a SPI interface.
I've used that breadboarded ATmega328 for a lot of things and it was a great investment of $5. Thanks for
recommending that !
Robert

Glad the dipmicro chip worked out for you.
Didn't intend to hijack the thread. It irks me that so many libraries bit bang the interface when performance is so much better with SPI.
shiftOut requires as many pins as SPI.transfer; I'll go with the hardware interface every time just for the speed. I won't use I2C for the same reason, too slow, unless I2C is the only interface available. I've even gone as far as 4 chip selectst to 4 MAX7219s just to avoid having to pass along a bunch of bytes when only the 4th device needed an update.
Need more IO? Use a '1284P, 32 IO total, plenty of pins for direct port manipulation for chip selects without having to add expander chips.

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162,keypads,
DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

I don't see Atmega1284P in your list - time to expand :slight_smile:
http://www.crossroadsfencing.com/BobuinoRev17/
Placing material orders now for another batch of kits, sold off the last 25 already. Hopefully parts prices haven't gone up.

Are you saying the UNO Screw Shield kit with Phoenix connectors is $14.50 +$3 shpg ?

most folks go with offboard FTDI module to 6-pin header. $5.25 for USPS mailing to US address.

Can you please explain the function of the off/board FTDI when connected to an UNO that already has built-in
FTDI ? Is it for programming attiny85's or what ? I'm not seeing the purpose.
Is that an alternative to the Mikroe USB module that is not included ?

Yes.
paypal to cardinalflyer at comcast dot net.
Snowing pretty heavy here, can have in tomorrow’s mail. Maybe late this afternoon if it lets up - 7" forcecasted for this afternoon tho.

Just to clarify,
If the off-board FTDI module is an alternative to the On-board MIKROE USB Module, then the photo of them both connected at the
same time would not normally occur , right ?(it would be either On-board OR Off-board but probably not both). Is there a reason why you would have both connected as shown in the photo ?

Yes, you would only use one or the other.
I only had 1 board assembled at the time and needed to check the functionality of both, so connecters were put in place to allow either.

Thanks, that had me a little confused seeing both connected at the same time.

I don't think I posted both connected - just the MIKROE plugged into a header, and the offboard pins underneath it.
I find the MIKROE sits kind of high on a header, so I've been mounting it on the board instead, and removing its 3-pin voltage select header and jumpering it for 5V instead so as not to interfere with a shield.

Then what’s this ?
Isn’t that both connected or am I mis-interpreting something ?

The small card is the FTDI device, the big grey box with the green lights is an AVRISP MK II (SPI Programmer) The AVRISP is for loading the bootloader. The FTDI device is for programming a bootloaded chip... ONLY... And
The Bobuino board is one most nice board for those that have 'outgrown' the ATMega328P-PU's 32K flash limits... it also has 2 UARTS, 131K of flash and 16K of sram. I bought two of them and will be buying a third in May...
I really like the Bobuino because I can use the Uno shields I have laying about... Great use for an Uno GLCD shield... and the UTFT class from Henning Karlsen...

Doc

So the OFF-board FTDI module referred to here:

most folks go with offboard FTDI module to 6-pin header.

is NOT the device plugged into the 6-pin header referred to in that comment but rather the MkII , and the infamous
OFF-BOARD FTDI ($5.95) is actually not shown in the photograph below which the aforementioned comment is shown ?

Correct. The Mikroe Electronica module is the one I selected to be able to mount to the board.
The FTDI Basic type modules, such as
http://www.tinyosshop.com/index.php?route=product/product&product_id=600
are not really set up for mounting to anything, more to be used as a plug on/plug off kind of device.

are not really set up for mounting to anything, more to be used as a plug on/plug off kind of device.

most folks go with offboard FTDI module to 6-pin header.

So what this means in so many words is that people buy the FTDI module that is similar to the one in the link and
make their own cable with a 6-pin inline male-male header at the FTDI end and a FEMALE 6-pin Dual Inline IDE
type (two rows of 3 like the arduino) connector at the uC end. (because the FTDI doesn't come with such a cable)
Correct ?

The FTDI module has a mini-USB connector, just plug in a cable and connect to PC.
(Rats - forgot the cable when I took the pictures!)
How the FTDI module connects depends on how the header was wired - I usually wire for cleanest routing, and not pay attention so much to the overall orientation.