ShiftOutCode

First time user, working my way through the tutorials and I've struck a problem with assigning hex values to an array. Using the ShifOut script as a basis, I can successfully run the project. If I try to define the dataArrayRED in one line (code below) I get no response from the LEDs

  //Arduino doesn't seem to have a way to write binary straight into the code 
  //so these values are in HEX.  Decimal would have been fine, too. 
  int dataArrayRED[] = {0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xE0};

  //Arduino doesn't seem to have a way to write binary straight into the code 
  //so these values are in HEX.  Decimal would have been fine, too. 
  dataArrayGREEN[0] = 0xFF; //11111111
  dataArrayGREEN[1] = 0x7F; //01111111
  dataArrayGREEN[2] = 0x3F; //00111111
  dataArrayGREEN[3] = 0x1F; //00011111
  dataArrayGREEN[4] = 0x0F; //00001111
  dataArrayGREEN[5] = 0x07; //00000111
  dataArrayGREEN[6] = 0x03; //00000011
  dataArrayGREEN[7] = 0x01; //00000001
  dataArrayGREEN[8] = 0x00; //00000000
  dataArrayGREEN[9] = 0x07; //00000111

Note, the dataArrayGREEN LEDs respond as you would expect, leading me to believe there's an issue with int dataArrayRED[] = {0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xE0};

Any advice appreciated :)

  //Arduino doesn't seem to have a way to write binary straight into the code

Yes, it does. 0bnnnnnnnn instead of 0xnn.

Any advice appreciated

You might try posting your snippets at http://snippets-r-us.com.

I just knew I shouldn't have pasted the darned comments :P The snippet is from the link provided;

Darce: Using the ShifOut script as a basis, I can successfully run the project.

Thanks for the advice, but why would defining the array in one line be different from individual statements?

but why would defining the array in one line be different from individual statements?

It shouldn't. But, seeing only snippets doesn't allow us to determine what else your code is doing (wrong).

The sketch in it’s entirety.

//**************************************************************//
//  Name    : shiftOutCode, Predefined Dual Array Style         //
//  Author  : Carlyn Maw, Tom Igoe                              //
//  Date    : 25 Oct, 2006                                      //
//  Version : 1.0                                               //
//  Notes   : Code for using a 74HC595 Shift Register           //
//          : to count from 0 to 255                            //
//****************************************************************

//Pin connected to ST_CP of 74HC595
int latchPin = 9;
//Pin connected to SH_CP of 74HC595
int clockPin = 10;
////Pin connected to DS of 74HC595
int dataPin = 8;

//holders for infromation you're going to pass to shifting function
byte dataRED;
byte dataGREEN;
byte dataArrayRED[10];
byte dataArrayGREEN[10];

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  Serial.begin(9600);
  //modified section, attempting to define array in one line, results in only one shift register displaying
  int dataArrayRED[] = {0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xE0};
  //if array is defined as below, over multiple lines, the sketch works over two shift registers
  dataArrayGREEN[0] = 0xFF; //11111111
  dataArrayGREEN[1] = 0x7F; //01111111
  dataArrayGREEN[2] = 0x3F; //00111111
  dataArrayGREEN[3] = 0x1F; //00011111
  dataArrayGREEN[4] = 0x0F; //00001111
  dataArrayGREEN[5] = 0x07; //00000111
  dataArrayGREEN[6] = 0x03; //00000011
  dataArrayGREEN[7] = 0x01; //00000001
  dataArrayGREEN[8] = 0x00; //00000000
  dataArrayGREEN[9] = 0x07; //00000111

  //function that blinks all the LEDs
  //gets passed the number of blinks and the pause time
  blinkAll_2Bytes(2,500); 
}

void loop() {


  for (int j = 0; j < 10; j++) {
    //load the light sequence you want from array
    dataRED = dataArrayRED[j];
    dataGREEN = dataArrayGREEN[j];
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //move 'em out
    shiftOut(dataPin, clockPin, dataGREEN); 

    //*************************This is outputting only zeros with the modified array statement *******  
    shiftOut(dataPin, clockPin, dataRED);
    //**********************************************************************************************

    //*************************Serial monitor displays valid values for green, zeros for red*************
    Serial.print(dataGREEN);Serial.println(dataRED);
    //**********************************************************************************************  

    //return the latch pin high to signal chip that it 
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    delay(300);
  }
}



// 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);
}


//blinks the whole register based on the number of times you want to 
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkAll_2Bytes(int n, int d) {
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  digitalWrite(latchPin, 1);
  delay(200);
  for (int x = 0; x < n; x++) {
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 255);
    shiftOut(dataPin, clockPin, 255);
    digitalWrite(latchPin, 1);
    delay(d);
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 0);
    digitalWrite(latchPin, 1);
    delay(d);
  }
}

Again, the code works if I leave the individual array statements (green works, red doesn’t).

Again, the code works if I leave the individual array statements (green works, red doesn't).

Maybe because of this:

byte dataArrayRED[10];
  int dataArrayRED[] = {0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xE0};

It's REALLY a bad idea to have global and local variables of the same name.

Correct, when I declare the array globally, it works fine.

byte dataArrayRED[10]= {0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xE0}; //global
 //local code commented out  int dataArrayRED[] = {0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xE0};

So I guess the question now is; "How do I modify/redefine a global array from within a local routine?"

i.e. This fails;

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;

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

Don’t worry, 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];
  }

Works like a charm, cheers

Don't worry, got it....

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

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

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.

No. You can use memcpy() to copy a large array "into" a small array, and it will happily crap all over the place.

I love it ! (when someone appropriately injects humor into a serious instructional statement causing you to think about it.more) Robert