595 patterns

Hello all, this is the first time I have ever posted a question on a forum so forgive me if I am out of order in anyway.

I am trying to setup a various set of LED pattern, using a 595 Shift Register. I got the original code off of an instructables tutorial ( http://www.instructables.com/id/8-LED-Chaser-with-74HC595-8-Bit-Shift-Register/?ALLSTEPS ).

The Original Code is a "Larson Scanner" type pattern. I wanted to break the patterns down and place them in their own individual functions. Once I did that however, the Arduino seems to hang up.

The Wiring for the Instructables code works fine, so I know its a coding issue.

Any help would be appreciated. Thank you. my coding is below

//595 LED Patterns
//G Cheng 1/5/13
//Filename Various595Patterns
//Code for Using a 74HC595 Shift Register

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
////Pin connected to single LED for display purposes
int led = 4;

/////595 Patterns
byte LarsonScannerPattern[30] = {
B00000001, 100,
B00000010, 100,
B00000100, 100,
B00001000, 100,
B00010000, 100,
B00100000, 100,
B01000000, 100,
B10000000, 100,
B01000000, 100,
B00100000, 100,
B00010000, 100,
B00001000, 100,
B00000100, 100,
B00000010, 100
};


byte AscendingPattern[16] = {
B00000001, 100,
B00000010, 100,
B00000100, 100,
B00001000, 100,
B00010000, 100,
B00100000, 100,
B01000000, 100,
B10000000, 100
};

byte DescendingPattern[16] = {
B10000000, 100,
B01000000, 100,
B00100000, 100,
B00010000, 100,
B00001000, 100,
B00000100, 100,
B00000010, 100,
B00000001, 100
};


void setup() 
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(led, OUTPUT);
}

void loop()
{
  digitalWrite(led, HIGH);  //light when loop starts
  LarsonScanner();
  //displayLED();
  //ascending();
  //displayLED();
  //descending();
  //displayLED();
  digitalWrite(led, LOW);  //dim at end of loop
  delay(100);
}

void displayLED()
{
  for(int count = 0; count < 4; count++)
  {
   digitalWrite(led, HIGH);
   delay(200);
   digitalWrite(led,LOW);
   delay(200);
  }
}


void LarsonScanner()
{
  int index = 0;
  int count = sizeof(LarsonScannerPattern) / 2;
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, LarsonScannerPattern[index*2]);
  digitalWrite(latchPin, HIGH);
  delay(LarsonScannerPattern[(index * 2) + 1]);
  //delay(50);
  index++;
  if (index >= count){
    index = 0;
  }
}

void ascending()
{
  int index = 0;
  int count = sizeof(AscendingPattern) / 2;
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, AscendingPattern[index*2]);
  digitalWrite(latchPin, HIGH);
  //delay(patterns[(index * 2) + 1]);
  delay(25);
  index++;
  if (index >= count){
    index = 0;
  }
}

void descending()
{
  int index = 0;
  int count = sizeof(DescendingPattern) / 2;
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, DescendingPattern[index*2]);
  digitalWrite(latchPin, HIGH);
  //delay(patterns[(index * 2) + 1]);
  delay(25);
  index++;
  if (index >= count){
    index = 0;
  }
}

Modify that post to include code tags. If you don't know what that means then read:- http://arduino.cc/forum/index.php/topic,97455.0.html

Your array LarsonScannerPattern[30] has only 28 elements defined and you have given it a dimension of 30.

I suspect that it is not hanging but that the line delay(LarsonScannerPattern[(index * 2) + 1]); is accessing an uninitialised memory location and giving a long delay that you are mistaking for hanging.

Thank you I will check that link. And try a fixed delay number and let you know.

void LarsonScanner()
{
int index = 0;

The issue is that index is initialized to 0 each time LarsonScanner is called. So you are only showing the very first pattern.

Make it static and your code will work.

Before submitting the post I had tried making index and count global variables. That didn't work either.

That didn't work either.

If you know why your current code failed, you would know why making those variable global didn't fix it.

The fix involves inserting one word in to your current code.

chengmania:
Thank you I will check that link.

Still waiting for you to modify that first post. Hit the modify tag, select the code, hit the # icon and save the changes.

Done. Thank you for informing me of the proper protocol. I will remember. I will be work on this project tonight

Thank you both for your input. I figured it out and actually feel quite silly. Still being an Arduino noob I tend to forget the loop() function actually loops. I had to add a do..while loop to contain the light pattern in the function. Otherwise the 595 was getting shiftouted to with I am guessing strange info.

So my LarsonScanner code now look like this

void LarsonScanner()
{
  int index = 0;
  int count = sizeof(LarsonScannerPattern) / 2;
  do{
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, LarsonScannerPattern[index*2]);
    digitalWrite(latchPin, HIGH);
  
    delay(100);
    index++;
    //detect end of loop
    if (index >= count){
       index = 0;
       }
    }while (index != 0);
}

again thank you. Hopefully I can move forward with my education and project and perhaps someone else can learn from my mistake by reading this.

I had to add a do..while loop to contain the light pattern in the function.

Not necessary.

The fix requires inserting one word into your original code.

Hi everyone!

I am new to Arduino and this Forum. I am retired military and like to program uMicroProcessors & build robots/projects
that actually do something. Who says you can't teach an old dog new tricks!

I have been working on a project very similar to this thread. Using 74HC595 shift register to control Christmas lights.
I had already written programs in Basic for other uProcessors, so I have been trying to port those programs to Arduino.
I have not worked with C before, so this has been very interesting.

My goal is to construct very small control units to control multiple strings of LED Christmas lights.

Attached is one of my first sketch to implement this goal. ( It functions properly. )
For testing, I have the shift register connected to 8 LEDs of a 10 LED bar graph, so I can visualize the patterns.
I have also tested this sketch with my relay boards.

In this sketch, I pass a pattern array, and its size, to a function for display through a shift register.
I have been trying to use the utility function 'sizeof()' without success.
Every time I have used 'sizeof()', it returns the value '2' regardless of the size of the array.
The C programming tutorials that I have been studying says in passing an array to a function, you need to pass the size of the array as well.

Am I missing something? Is there a issue with 'sizeof()' ?
Could someone show me an example of proper use of 'sizeof()' that actually returns the correct size of an array?
If I can get 'sizeof()' to work, I can simplify my function & sketch.

I apologize in advance for any breach of protocol. Just let me know what I need to do to comply with Forum standards.

P.S. I Love this stuff !!

//======================= this line is 80 chars long ==========================
//-----------------------------------------------------------------------------
/*
  Program Name: _74HC595
        Author: Paul Fogle
          Date: 01/05/2013
      Modified: 01/10/2013
          Goal: Use 74HC595 shift register to control Christmas light relays.
                Input pattern array number and pass to ChristmasLightRelay()
                function .
 */
//-----------------------------------------------------------------------------
  byte Pattern_0[2] = {0xAA, 0x55};
  // every other, alternate
  byte Pattern_1[4] = {0x18,0x24,0x42,0x81};
  // middle out
  byte Pattern_2[6] = {0x81,0x42,0x24,0x18,0x24,0x42};
  // ends to middle, bounce single
  byte Pattern_3[9] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
  // left to right, all on repeat
  byte Pattern_4[15] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0x7f,0x3f,
                        0x1f,0x0f,0x07,0x03,0x01};
  // left to right, all on exit right
  byte Pattern_5[15] = {0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff,0xfe,0xfc,0xf8,
                        0xf0,0xe0,0xc0,0x80};
  // opposite of Pattern 4
  byte Pattern_6[30] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0x7f,0x3f,0x1f,
                        0x0f,0x07,0x03,0x01,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,
                        0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80};
  // left to right bounce right to left
  byte Pattern_7[7] = {0x81,0xc3,0xe7,0xff,0xe7,0xc3,0x81};
  // ends to middle, all on
//-----------------------------------------------------------------------------
  byte sizePattern_0 = 2;   // size of pattern 0
  byte sizePattern_1 = 4;   // size of pattern 1
  byte sizePattern_2 = 6;   // size of pattern 2
  byte sizePattern_3 = 9;   // size of pattern 3
  byte sizePattern_4 = 15;  // size of pattern 4
  byte sizePattern_5 = 15;  // size of pattern 5
  byte sizePattern_6 = 30;  // size of pattern 6
  byte sizePattern_7 = 7;   // size of pattern 7

  int delayDur = 150;       // display speed in light pattern
  int latchpin = 8;         // green connect to pin 12 on shift register
  int clockpin = 12;        // white connect to pin 11 on shift register
  int datapin = 11;         // black connect to pin 14 on shift register
//-----------------------------------------------------------------------------
void setup()
{
   Serial.begin(9600);        // com to computer
   Serial1.begin(9600);       // pin 18 ModernDevice Lcd
   pinMode(latchpin, OUTPUT); // pin 12, shift register
   pinMode(clockpin, OUTPUT); // pin 11, shift register
   pinMode(datapin, OUTPUT);  // pin 14, shift register
   SetupLcd();
}
//-----------------------------------------------------------------------------
void loop()
{
  LightRelay(Pattern_6, sizePattern_6);    // call function to output pattern
}
//-----------------------------------------------------------------------------
// I have tried to use the sizeof() utility without success, it always returns
// 2 on every array that I have tried, so I pass a size variable (tempSize) to
// the function.
//
//
void LightRelay(byte *temp, byte tempSize) // output pattern to shift register
{  for (byte x = 0; x < tempSize; x++)
  {
    digitalWrite(latchpin, LOW);                    // enable data write
    shiftOut(datapin, clockpin, MSBFIRST, temp[x]); // data write
    digitalWrite(latchpin, HIGH);                   // disable data write
    delay(delayDur);                                // display speed
    Serial1.print("?x00?y0Size of array: ?x15");    // print to lcd
    Serial1.print(tempSize);                        // print to lcd
  }
}
//-----------------------------------------------------------------------------
void SetupLcd()
{
  Serial1.print("?G420?c0?f?x05?y3HELLO PAUL"); // print to lcd
  delay(2000);                                  // pause so I can read my name
}
//-----------------------------------------------------------------------------

_74HC595.ino (3.88 KB)

Heh, your data is in hex. I asked about that, because I thought that I could compress more data in that way, but it turns out that it doesnt matter if its bin, or hex because it gets compiled with the program.

I constructed my patterns in binary first, then convert to hex.
I got tired of scrolling thru lines of data.
Using hex data only saves space in your code, not the compiled sketch.

Example:

data[] = {0000 0000, // = 0x00
1000 0001, // = 0x81
0100 0010, // = 0x42
0010 0100, // = 0x24
0001 1000, // = 0x18
. . . . . . . .}

data[] = {0x00,0x81,0x42,0x24,0x18, . . };

Some of my patterns have 30 elements.

One line of data versus 32 lines makes easier code reading.

Every time I have used 'sizeof()', it returns the value '2' regardless of the size of the array.

depending on how you called sizeof(), 2 may or may not be the right answer.

Thanks for your reply.

I narrowed my issue somewhat.
When sizeof() is used directly on an array, it returns the correct size.

However, when I pass an array to a function THEN use sizeof(), it returns 2.
I am thinking that sizeof() is returning the size of the pointer. Not sure about this.

Reading online C tutorials concerning passing arrays to functions, they say in passing an array
to a function you are in fact passing a pointer. Still learning about pointers.

My goal is for this program to receive a single input using a keypad or button to input a pattern selection.
Currently, I am modifying my code so the input function will take a number, in a limited range, using switch . . . case.
Switch . . . case assigns a pointer to the specified pattern array, sizes the array then passes pointer and size to the output function.

As I stated in a previous post, I am new to this programming language.

I am having so much fun learning this language.
I can see so many possibilities that were not available when I was using various flavors of Basic.

Thanks again for your help!

Paul

However, when I pass an array to a function THEN use sizeof(), it returns 2.

In that case, you are getting the size of a pointer to a byte array.

Thanks for confirming my suspicion. I appreciate your feedback.

I seem to learn best by trial and error, also known as fumbling around !

I am a disabled veteran. One thing I have a lot of is time.

Programming helps take my mind off of negative things.