Go Down

Topic: Help with passing arrays to flashLEDs (Read 546 times) previous topic - next topic

DanMan1

Hello,

I have a set of programmable LEDs and a function flash_pattern.
It works fine when the specific array is passed to it, but I'd like to provide the ability for a user to select which array they wan to pass to it so that their specific light sequence flashes.

Below is a subset of the code in which I need help with.
I haven't done any coding in ages, so thank you in advance!

Dan



//Purpose of this program is to allow a user to select a color pattern, which then sets the variable gift_color.  Each choice of gift color corresponds to a different LED array pattern that will flash when that pattern is passed to the function flash_pattern(LED_pattern)


int gift_color = 0;

CRGB LED_pattern[] = {off, off, off, off, off, off, off, off, off, off, off, off,
                    off, off, off, off, off, off, off, off, off, off, off, off,
                    off, off, off, off, off, off, off, off, off, off, off, off,
                    off, off, off, off, off, off, off, off, off, off, off, off,
                    off, off};

CRGB color_choce1_leds[]= {red, off, off, off, off, off, off, off, off, off,
                           red, off, off, off, off, off, off, off, off, off,
                           red, off, off, off, off, off, off, off, off, off,
                           red, off, off, off, off, off, off, off, off, off,
                           red, off};

                   
// color_choice2 lights only the GREEN bulbs (in same poistion as when all lit)
CRGB color_choice2_leds[]= {off, off, green, off, off, off, off, off, off, off,
                            off, off, green, off, off, off, off, off, off, off,
                            off, off, green, off, off, off, off, off, off, off,
                            off, off, green, off, off, off, off, off, off, off,
                            off, green};

// color_choice3 lights only the BLUE bulbs (in same poistion as when all lit)
CRGB color_choice3_leds[]= {off, off, off, off, blue, off, off, off, off, off,
                            off, off, off, off, blue, off, off, off, off, off,
                            off, off, off, off, blue, off, off, off, off, off,
                            off, off, off, off, blue, off, off, off, off, off,
                            off, off};

// color_choice1 lights only the ORANGE bulbs (in same poistion as when all lit)
CRGB color_choice4_leds[]= {off, off, off, off, off, off, orange, off, off, off,
                            off, off, off, off, off, off, orange, off, off, off,
                            off, off, off, off, off, off, orange, off, off, off,
                            off, off, off, off, off, off, orange, off, off, off,
                            off, off};

get_user_gift_color(); //returns one of 4 user specified values in the variable gift color  (Function not shown here)

//  The lights matching the color of the item selected now start flashing and then go off
  if (gift_color = 1){
      LED_pattern[] = color_choice1_leds[];
  }
  else if (gift_color = 2){
      LED_pattern[] = color_choice2_leds[];
  }
  else if (gift_color = 3){
      LED_pattern[] = color_choice3_leds[];
  }
  else if (gift_color = 4){
      LED_pattern[] = color_choice4_leds[];
  }
 
// Now flash the bulbs matching the color selected 7 times; each function call consists of 4 sec ON and 4 sec OFF; ending in OFF
flash_pattern(LED_pattern[]);

/////////////////////////////////////////////////////////
void flash_pattern(LED_pattern) {
  memcpy (leds, LED_pattern, sizeof LED_pattern);
  FastLED.show();
  delay(4000);

  memcpy (leds, off_leds, sizeof off_leds);
  FastLED.show();
  delay(4000);
  }

Blackfin

Quote
I have a set of programmable LEDs and a function flash_pattern.
Please post that code with code tags.

DanMan1

Code tags added.


Code: [Select]

//Purpose of this program is to allow a user to select a color pattern,
/// which then sets the variable gift_color. 
/// Each choice of gift color corresponds to a different LED array pattern that will flash
/// when that pattern is passed to the function flash_pattern(LED_pattern)
   
int gift_color = 0;

CRGB LED_pattern[] = {off, off, off, off, off, off, off, off, off, off, off, off,
                    off, off, off, off, off, off, off, off, off, off, off, off,
                    off, off, off, off, off, off, off, off, off, off, off, off,
                    off, off, off, off, off, off, off, off, off, off, off, off,
                    off, off};

CRGB color_choce1_leds[]= {red, off, off, off, off, off, off, off, off, off,
                           red, off, off, off, off, off, off, off, off, off,
                           red, off, off, off, off, off, off, off, off, off,
                           red, off, off, off, off, off, off, off, off, off,
                           red, off};

                   
// color_choice2 lights only the GREEN bulbs (in same poistion as when all lit)
CRGB color_choice2_leds[]= {off, off, green, off, off, off, off, off, off, off,
                            off, off, green, off, off, off, off, off, off, off,
                            off, off, green, off, off, off, off, off, off, off,
                            off, off, green, off, off, off, off, off, off, off,
                            off, green};

// color_choice3 lights only the BLUE bulbs (in same poistion as when all lit)
CRGB color_choice3_leds[]= {off, off, off, off, blue, off, off, off, off, off,
                            off, off, off, off, blue, off, off, off, off, off,
                            off, off, off, off, blue, off, off, off, off, off,
                            off, off, off, off, blue, off, off, off, off, off,
                            off, off};

// color_choice1 lights only the ORANGE bulbs (in same poistion as when all lit)
CRGB color_choice4_leds[]= {off, off, off, off, off, off, orange, off, off, off,
                            off, off, off, off, off, off, orange, off, off, off,
                            off, off, off, off, off, off, orange, off, off, off,
                            off, off, off, off, off, off, orange, off, off, off,
                            off, off};

get_user_gift_color(); //returns one of 4 user specified values in the variable gift color  (Function not shown here)

//  The lights matching the color of the item selected now start flashing and then go off
  if (gift_color = 1){
      LED_pattern[] = color_choice1_leds[];
  }
  else if (gift_color = 2){
      LED_pattern[] = color_choice2_leds[];
  }
  else if (gift_color = 3){
      LED_pattern[] = color_choice3_leds[];
  }
  else if (gift_color = 4){
      LED_pattern[] = color_choice4_leds[];
  }
 
// Now flash the bulbs matching the color selected 7 times; each function call consists of 4 sec ON and 4 sec OFF; ending in OFF
flash_pattern(LED_pattern[]);

/////////////////////////////////////////////////////////
void flash_pattern(LED_pattern) {
  memcpy (leds, LED_pattern, sizeof LED_pattern);
  FastLED.show();
  delay(4000);

  memcpy (leds, off_leds, sizeof off_leds);
  FastLED.show();
  delay(4000);
  }


Blackfin

Sorry, that doesn't compile.

You said "It works fine when the specific array is passed to it..."

Please post the code that works. It should be possible to expand it to include the functionality you want but you need to give a decent starting point.


DanMan1

ok.  I'll do that.
The code that works is rather long and I'm making multiple changes to it.
Was really asking for more of a syntax kind of question of how to index and pass an array such as "color_choce1_leds[]"  into a function such as "flash_pattern(LED_pattern)"

Dan

Blackfin

ok.  I'll do that.
The code that works is rather long and I'm making multiple changes to it.
Was really asking for more of a syntax kind of question of how to index and pass an array such as "color_choce1_leds[]"  into a function such as "flash_pattern(LED_pattern)"

Dan
You don't pass arrays, you pass pointers to the arrays.

Something along the lines of:

Code: [Select]
#define NUM_ARRAYS  4
#define ARRAY_SIZE  5

int
    Array1[ARRAY_SIZE] = { 1, 2, 3, 4, 5 },
    Array2[ARRAY_SIZE] = { 6, 7, 8, 9, 10 },
    Array3[ARRAY_SIZE] = { 11, 12, 13, 14, 15 },
    Array4[ARRAY_SIZE] = { 16, 17, 18, 19, 20 };

int *pgrArrayPtrs[NUM_ARRAYS] =
{
    Array1,
    Array2,
    Array3,
    Array4
};

int
    *pArrayPtr;
   
void setup( void )
{
    Serial.begin(9600);

    for( int i=0; i<NUM_ARRAYS; i++ )
    {
        pArrayPtr = (int *)pgrArrayPtrs[i];
        flash_pattern( pArrayPtr );
       
    }//for
       
}//setup

void loop( void )
{
           
}//loop

void flash_pattern( int *pPtr )
{
    for( int j=0; j<ARRAY_SIZE; j++ )
    {
        Serial.print( *(pPtr+j) );
        if( j<ARRAY_SIZE-1 )
            Serial.print( ", " );
        else
            Serial.println( "" );
    }//for
       
}//flash_pattern



I don't know off-hand if your proposed use of arrays of CRGB objects will work but this illustrates a basic way to pass the address of an array rather than the array itself.
 

DanMan1

Thank you for the help. I've tried using your code into a full set of working code, but am still somehow messing up the use of the pointers.

Basically its a program that sends an LED light color pattern to a programmable set of 50 LEDs.  The first load is done manually and works.  The attempt to set them using the pointers and the flash function does not yet work.

Eventually I want a user input to decide which color pattern to use (currently I set a varible "i = 2" which should be the value of the pointer to the BlueOnly_LEDs pattern) and send it to the flash function which will set the lights to that color pattern 4 seconds and then turn them off for four seconds (thus flashing). I left the off pattern out of this example to keep it simple, but should be easy enough once I get the index passing correct.

Can you tell me what I am doing wrong?
Thank you.


Code: [Select]

#define NUM_ARRAYS  7
#define ARRAY_SIZE  50

#include <HashMap.h>
#include <Arduino.h>
#include <FastLED.h>

#define DATA_PIN 7  //this is the data pin connected to the LED strip.  If using WS2801 you also need a clock pin
#define NUM_LEDS 50 //change this for the number of LEDs in the strip
#define COLOR_ORDER RGB

CRGB leds[NUM_LEDS];

CRGB red    = CRGB (255, 0, 0);
CRGB green  = CRGB (0, 255, 0);
CRGB blue   = CRGB(0, 0, 255);
CRGB orange = CRGB(255, 165,0);
CRGB white  = CRGB(255,255,255);
CRGB off    = CRGB(0, 0, 0);


// Red, Green, Blue, Orange, White with alternatign offs Sequence
CRGB RGBOW_leds[ARRAY_SIZE]   = {red, off, green, off, blue, off, orange, off, white, off, green, off,
                       red, off, green, off, blue, off, orange, off, white, off, green, off,
                       red, off, green, off, blue, off, orange, off, white, off, green, off,
                       red, off, green, off, blue, off, orange, off, white, off, green, off,
                       red, green};  //Not curretnly Used

CRGB   AllOff_leds[ARRAY_SIZE]= {off, off, off, off, off, off, off, off, off, off, off, off,
                       off, off, off, off, off, off, off, off, off, off, off, off,
                       off, off, off, off, off, off, off, off, off, off, off, off,
                       off, off, off, off, off, off, off, off, off, off, off, off,
                       off, off};

// only the RED bulbs (in same poistion as when all lit)
CRGB RedOnly_leds[ARRAY_SIZE]= {red, off, off, off, off, off, off, off, off, off,off, off,
                       red, off, off, off, off, off, off, off, off, off,off, off,
                       red, off, off, off, off, off, off, off, off, off,off, off,
                       red, off, off, off, off, off, off, off, off, off,off, off,
                       red, off};

                   
// only the GREEN bulbs (in same poistion as when all lit)
CRGB GreenOnly_leds[ARRAY_SIZE]= {off, off, green, off, off, off, off, off, off, off,off, off,
                        off, off, green, off, off, off, off, off, off, off,off, off,
                        off, off, green, off, off, off, off, off, off, off,off, off,
                        off, off, green, off, off, off, off, off, off, off,off, off,
                        off, green};

// only the BLUE bulbs (in same poistion as when all lit)
CRGB BlueOnly_leds[ARRAY_SIZE]= {off, off, off, off, blue, off, off, off, off, off,off, off,
                       off, off, off, off, blue, off, off, off, off, off,off, off,
                       off, off, off, off, blue, off, off, off, off, off,off, off,
                       off, off, off, off, blue, off, off, off, off, off,off, off,
                       off, off};

// only the ORANGE bulbs (in same poistion as when all lit)
CRGB OrangeOnly_leds[ARRAY_SIZE]= {off, off, off, off, off, off, orange, off, off, off, off, off,
                         off, off, off, off, off, off, orange, off, off, off, off, off,
                         off, off, off, off, off, off, orange, off, off, off, off, off,
                         off, off, off, off, off, off, orange, off, off, off, off, off,
                         off, off};

// only the WHITE bulbs (in same poistion as when all lit)
CRGB WhiteOnly_leds[ARRAY_SIZE] = {off, off, off, off, off, off, off, off, white, off, off, off,
                         off, off, off, off, off, off, off, off, white, off, off, off,
                         off, off, off, off, off, off, off, off, white, off, off, off,
                         off, off, off, off, off, off, off, off, white, off, off, off,
                         off, off};

const byte HASH_SIZE = 28;
HashType<char,int> hashRawArray[HASH_SIZE];
HashMap<char,int> charToLed = HashMap<char,int>( hashRawArray , HASH_SIZE );

CRGB *pgrArrayPtrs[NUM_ARRAYS] =
{
    RedOnly_leds,
    GreenOnly_leds,
    BlueOnly_leds,
    OrangeOnly_leds,
    WhiteOnly_leds,
    RGBOW_leds,
    AllOff_leds
};

int
    *pArrayPtr;

int i;
   
void setup( void )
{
    Serial.begin(9600);
    FastLED.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //setting up the FastLED
    //for( int i=0; i<NUM_ARRAYS; i++ )
    //{
    //    pArrayPtr = (int *)pgrArrayPtrs[i];
    //    flash_pattern( pArrayPtr );
    //}
}

void loop( void )
{
  // Set lights manually to RGBOW colors at the start
  memcpy (leds, RGBOW_leds, sizeof RGBOW_leds);
  FastLED.show();
  delay(5000);

  i=2;  // i = 2 means pass thru the RedOnly_leds array
  pArrayPtr = (int *)pgrArrayPtrs[i];
  flash_pattern( pArrayPtr );
  Serial.println( "got here" );
  Serial.println( *pArrayPtr, 2 );       
}

void flash_pattern( int *pPtr ) {  //flash the pattern passed into this function, then off with 4 seconds delay
  memcpy (leds, *pPtr , sizeof *pPtr );
  FastLED.show();
  delay(4000);
  }
void xxflash_pattern( int *pPtr )
{
    for( int j=0; j<ARRAY_SIZE; j++ )
    {
        Serial.print( *(pPtr+j) );
        if( j<ARRAY_SIZE-1 )
            Serial.print( ", " );
        else
            Serial.println( "" );
    }
       
}

david_2018

When you pass the array pointer to a function, the function has no way of determining the size of the array, so you would need to either pass the array size to the function, or use a fixed size inside the function (possible in your case because all arrays are the same size).

Seems to me the code would be a lot simpler if you used a multi-dimensional array, and passed the array index to the function.  Here is an example of that method:

Code: [Select]

#define NUM_ARRAYS  7
#define ARRAY_SIZE  50

//#include <HashMap.h>
#include <Arduino.h>
#include <FastLED.h>

#define DATA_PIN 7  //this is the data pin connected to the LED strip.  If using WS2801 you also need a clock pin
#define NUM_LEDS 50 //change this for the number of LEDs in the strip
#define COLOR_ORDER RGB

CRGB leds[NUM_LEDS];

const CRGB red    = CRGB (255, 0, 0);
const CRGB green  = CRGB (0, 255, 0);
const CRGB blue   = CRGB(0, 0, 255);
const CRGB orange = CRGB(255, 165, 0);
const CRGB white  = CRGB(255, 255, 255);
const CRGB off    = CRGB(0, 0, 0);

//define an enum so patterns can be referred to by their names
enum patterns {
  RedOnly_leds,
  GreenOnly_leds,
  BlueOnly_leds,
  OrangeOnly_leds,
  WhiteOnly_leds,
  RGBOW_leds,
  AllOff_leds,
  NUM_patterns //used to indicate the number of patterns
};

//this array is only needed if you want to print out the names corresponding to the pattern arrays
const char patternNames[][16] = {
  "RedOnly_leds",
  "GreenOnly_leds",
  "BlueOnly_leds",
  "OrangeOnly_leds",
  "WhiteOnly_leds",
  "RGBOW_leds",
  "AllOff_leds"
};

// Red, Green, Blue, Orange, White with alternatign offs Sequence
CRGB patternArrays[NUM_patterns][ARRAY_SIZE] = {


  // only the RED bulbs (in same position as when all lit)
  //RedOnly_leds
  { red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off
  },

  // only the GREEN bulbs (in same poistion as when all lit)
  //GreenOnly_leds
  { off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, green
  },

  // only the BLUE bulbs (in same poistion as when all lit)
  //BlueOnly_leds
  { off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off
  },

  // only the ORANGE bulbs (in same poistion as when all lit)
  //OrangeOnly_leds
  { off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off
  },

  // only the WHITE bulbs (in same poistion as when all lit)
  //WhiteOnly_leds
  { off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off
  },

  //RGBOW_leds
  { red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, green
  },

  //AllOff_leds
  { off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off
  }
};

patterns i;

void setup( void )
{
  Serial.begin(9600);
  FastLED.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //setting up the FastLED
  //for( int i=0; i<NUM_ARRAYS; i++ )
  //{
  //    pArrayPtr = (int *)pgrArrayPtrs[i];
  //    flash_pattern( pArrayPtr );
  //}
}

void loop( void )
{
  // Set lights manually to RGBOW colors at the start
  memcpy (leds, patternArrays[RGBOW_leds], sizeof patternArrays[RGBOW_leds]);
  FastLED.show();
  delay(5000);
  for (i = (patterns)0; i < NUM_patterns; i = (patterns)(i + 1)) {
    //cycles through all the patterns
    //the (pattern) type casting is needed because the compiler doesn't like incrementing an enum directly
    flash_pattern(i);
    Serial.println( "got here" );
    Serial.println( patternNames[i] );
    delay(4000);
  }
}

void flash_pattern( patterns pPtr ) {  //flash the pattern passed into this function, then off with 4 seconds delay
  memcpy (leds, patternArrays[pPtr], sizeof patternArrays[pPtr] );
  FastLED.show();
}


DanMan1

Thank you David.  That worked like a charm.  2 follow up questions:

1) To pass in by index or by pattern name to call a specific pattern, I got the code below to work.  (I'd put the declarations outside the loop for real).  Any comments?

2) When I compile I get the following error.  Any thoughts on how/if to fix this?

Sketch uses 8878 bytes (27%) of program storage space. Maximum is 32256 bytes.
Global variables use 1599 bytes (78%) of dynamic memory, leaving 449 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.


Code: [Select]


// Big thanks to david_2018 on Arduino forum for getting the pointer function to work

#define NUM_ARRAYS  7
#define ARRAY_SIZE  50

//#include <HashMap.h>
#include <Arduino.h>
#include <FastLED.h>

#define DATA_PIN 7  //this is the data pin connected to the LED strip.  If using WS2801 you also need a clock pin
#define NUM_LEDS 50 //change this for the number of LEDs in the strip
#define COLOR_ORDER RGB

CRGB leds[NUM_LEDS];

const CRGB red    = CRGB (255, 0, 0);
const CRGB green  = CRGB (0, 255, 0);
const CRGB blue   = CRGB(0, 0, 255);
const CRGB orange = CRGB(255, 165, 0);
const CRGB white  = CRGB(255, 255, 255);
const CRGB off    = CRGB(0, 0, 0);

//define an enum so patterns can be referred to by their names
enum patterns {
  RedOnly_leds,
  GreenOnly_leds,
  BlueOnly_leds,
  OrangeOnly_leds,
  WhiteOnly_leds,
  RGBOW_leds,
  AllOff_leds,
  NUM_patterns //used to indicate the number of patterns
};

//this array is only needed if you want to print out the names corresponding to the pattern arrays
const char patternNames[][16] = {
  "RedOnly_leds",
  "GreenOnly_leds",
  "BlueOnly_leds",
  "OrangeOnly_leds",
  "WhiteOnly_leds",
  "RGBOW_leds",
  "AllOff_leds"
};

// Red, Green, Blue, Orange, White with alternatign offs Sequence
CRGB patternArrays[NUM_patterns][ARRAY_SIZE] = {


  // only the RED bulbs (in same position as when all lit)
  //RedOnly_leds
  { red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off
  },

  // only the GREEN bulbs (in same poistion as when all lit)
  //GreenOnly_leds
  { off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, green
  },

  // only the BLUE bulbs (in same poistion as when all lit)
  //BlueOnly_leds
  { off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off
  },

  // only the ORANGE bulbs (in same poistion as when all lit)
  //OrangeOnly_leds
  { off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off
  },

  // only the WHITE bulbs (in same poistion as when all lit)
  //WhiteOnly_leds
  { off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off
  },

  //RGBOW_leds
  { red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, green
  },

  //AllOff_leds
  { off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off
  }
};

patterns i;

void setup( void )
{
  Serial.begin(9600);
  FastLED.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //setting up the FastLED
  //for( int i=0; i<NUM_ARRAYS; i++ )
  //{
  //    pArrayPtr = (int *)pgrArrayPtrs[i];
  //    flash_pattern( pArrayPtr );
  //}
}

void loop( void )
{
  // Set lights manually to RGBOW colors at the start
  memcpy (leds, patternArrays[RGBOW_leds], sizeof patternArrays[RGBOW_leds]);
  FastLED.show();
  delay(5000);
  //for (i = (patterns)0; i < NUM_patterns; i = (patterns)(i + 1)) {
    //cycles through all the patterns
    //the (pattern) type casting is needed because the compiler doesn't like incrementing an enum directly
    int user_input1 = 2;
    flash_pattern((patterns)user_input1);
    Serial.println( "got here" );
    Serial.println( patternNames[user_input1] );

 const char   user_input2 = OrangeOnly_leds;
    flash_pattern((patterns)user_input2);
    Serial.println( "got here" );
    Serial.println( patternNames[user_input2] );
    delay(4000);
  //}
}

void flash_pattern( patterns pPtr ) {  //flash the pattern passed into this function, then off with 4 seconds delay
  memcpy (leds, patternArrays[pPtr], sizeof patternArrays[pPtr] );
  FastLED.show();
}


david_2018

Looks ok, except byte would probably be more appropriate than char for user_input2.

You could eliminate the enum entirely, and just define the array names as their integer values, that might be a bit easier to understand:


Code: [Select]

#define RedOnly_leds    0
#define GreenOnly_leds  1
#define BlueOnly_leds   2
#define OrangeOnly_leds 3
#define WhiteOnly_leds  4
#define RGBOW_leds      5
#define AllOff_leds     6



As for the warning about low memory, patterns for LED arrays are usually stored in flash memory (also called program memory) so that they do not use any space in dynamic memory, but if you do that the pattern arrays must be defined as const, and cannot be changed within the sketch (does not appear to be a problem with your intended use). Unfortunately I don't know a way to do that with a CRGB array.
For your code, if you don't need to print out the names of the pattern arrays, eliminating the array where those are stored will reduce the memory usage enough to get rid of the warning, or you can store that array in flash memory, which is a well documented method.

See the reference Putting constant data into program memory (PROGMEM)

   

DanMan1

Thanks.  I tried commenting them out, but I didn't see the warnign go away.

How bad can things get with low memory?

I have a set of functions that reads a 1x4 keypad and displays a two digit su,  It works just fine.
Then I have the code you saw, and it works just fine.
But when I combined them, its like the keypad never gets read.  If I persist, I can eventually get it to read a digit, but its like everything is going really slow.

Is that due to low memory or bad coding?

Code: [Select]


// Big thanks to david_2018 on Arduino forum for getting the pointer fun to work
// 11/16/2019 Added keypad input and display of keypad input
#include <TM1637Display.h>
#define CLK 8
#define DIO 9
TM1637Display display(CLK, DIO);

#define key1 5 //connect wire 1 to pin 2
#define key2 4 //connect wire 2 to pin 3
#define key3 3 //connect wire 3 to pin 4
#define key4 2 //connect wire 4 to pin 5

//  TO DOs::: Add a time for 30 seconds to see if a second 2 digit code is entered
//  This is a safety procaution that allows me to retype the digits in if they are mistyped or miss read.
//  After the 30 seconds times out, then turn off or dim the display

#define NUM_ARRAYS  7
#define ARRAY_SIZE  50

#include <HashMap.h>
#include <Arduino.h>
#include <FastLED.h>

#define DATA_PIN 7  //this is the data pin connected to the LED strip.  If using WS2801 you also need a clock pin
#define NUM_LEDS 50 //change this for the number of LEDs in the strip
#define COLOR_ORDER RGB

CRGB leds[NUM_LEDS];

const CRGB red    = CRGB (255, 0, 0);
const CRGB green  = CRGB (0, 255, 0);
const CRGB blue   = CRGB(0, 0, 255);
const CRGB orange = CRGB(255, 165, 0);
const CRGB white  = CRGB(255, 255, 255);
const CRGB off    = CRGB(0, 0, 0);

//define an enum so patterns can be referred to by their names
enum patterns {
  RedOnly_leds,
  GreenOnly_leds,
  BlueOnly_leds,
  OrangeOnly_leds,
  WhiteOnly_leds,
  RGBOW_leds,
  AllOff_leds,
  NUM_patterns //used to indicate the number of patterns
};

//this array is only needed if you want to print out the names corresponding to the pattern arrays
const char patternNames[][16] = {
  "RedOnly_leds",
  "GreenOnly_leds",
  "BlueOnly_leds",
  "OrangeOnly_leds",
  "WhiteOnly_leds",
  "RGBOW_leds",
  "AllOff_leds"
};

// Red, Green, Blue, Orange, White with alternatign offs Sequence
CRGB patternArrays[NUM_patterns][ARRAY_SIZE] = {


  // only the RED bulbs (in same position as when all lit)
  //RedOnly_leds
  { red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off, off, off, off, off, off, off, off, off, off, off,
    red, off
  },

  // only the GREEN bulbs (in same poistion as when all lit)
  //GreenOnly_leds
  { off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, off, green, off, off, off, off, off, off, off, off, off,
    off, green
  },

  // only the BLUE bulbs (in same poistion as when all lit)
  //BlueOnly_leds
  { off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off, off, off, blue, off, off, off, off, off, off, off,
    off, off
  },

  // only the ORANGE bulbs (in same poistion as when all lit)
  //OrangeOnly_leds
  { off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off, off, off, off, off, orange, off, off, off, off, off,
    off, off
  },

  // only the WHITE bulbs (in same poistion as when all lit)
  //WhiteOnly_leds
  { off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off, off, off, off, off, off, off, white, off, off, off,
    off, off
  },

  //RGBOW_leds
  { red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, off, green, off, blue, off, orange, off, white, off, green, off,
    red, green
  },

  //AllOff_leds
  { off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off, off, off, off, off, off, off, off, off, off, off,
    off, off
  }
};

patterns i;

void setup( void )
{
  Serial.begin(9600);
  FastLED.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //setting up the FastLED

  pinMode(key1, INPUT_PULLUP);// set pin as input
  pinMode(key2, INPUT_PULLUP);// set pin as input
  pinMode(key3, INPUT_PULLUP);// set pin as input
  pinMode(key4, INPUT_PULLUP);// set pin as input

  display.setSegments(0); //Turn off / clear all display segments
  display.setBrightness(7);

}

  int keypressed = 0;
  int keystroke_counter = 0;  // counts how many key strokes have been recorded
  int keypad_total = 0; // this is the total of the keypad entries added as a two digit value
  
void loop( void )
{
  static byte last_key1S = 1;
  static byte last_key2S = 1;
  static byte last_key3S = 1;
  static byte last_key4S = 1;
  byte key1S = digitalRead(key1);// read key1
  byte key2S = digitalRead(key2);// read key2
  byte key3S = digitalRead(key3);// read key3
  byte key4S = digitalRead(key4);// read key4
  
  // Set lights manually to RGBOW colors at the start
  memcpy (leds, patternArrays[RGBOW_leds], sizeof patternArrays[RGBOW_leds]);
  FastLED.show();
  delay(5000);


//
// Read and display user 2 digit input
//
    Serial.println( "got here to key loop" );

  if (key1S != last_key1S) {
    if (key1S == 0) { //went from HIGH to LOW
      Serial.println("key 1 is pressed");
      keypressed = 1;
      keystroke_counter = keystroke_counter + 1;
    }
  }
  last_key1S = key1S;

  if (key2S != last_key2S) {
    if (key2S == 0) { //went from HIGH to LOW
      Serial.println("key 2 is pressed");
      keypressed = 2;
      keystroke_counter = keystroke_counter + 1;
    }
  }
  last_key2S = key2S;

  if (key3S != last_key3S) {
    if (key3S == 0) { //went from HIGH to LOW
      Serial.println("key 3 is pressed");
      keypressed = 3;
      keystroke_counter = keystroke_counter + 1;
    }
  }
  last_key3S = key3S;

  if (key4S != last_key4S) {
    if (key4S == 0) { //went from HIGH to LOW
      Serial.println("key 1 is pressed");
      keypressed = 4;
      keystroke_counter = keystroke_counter + 1;
    }
  }
  last_key4S = key4S;

  Serial.println("keystroke_counter total is ");
  Serial.println(keystroke_counter);
  if (keystroke_counter == 1) {
    keypad_total = keypressed * 10;
  }
  else if (keystroke_counter == 2) {
    keypad_total = keypad_total + keypressed;
  }
  else {
    Serial.println("keypad total is ");
    Serial.println(keypad_total);
  }
 
  if (keystroke_counter == 2) {
    Serial.println("keypad total is ");
    Serial.println(keypad_total);
    // Show decimal numbers with/without leading zeros
    display.showNumberDec(keypad_total, false); // Expect: ___keypad_total
    delay(5000);
    
    Serial.println(" about to subtract 10");
    keypad_total = keypad_total - 10;  //Subtract 10 to get answer between 1 and 4
    display.showNumberDec(keypad_total, false); // Expect: ___keypad_total
    delay(5000);

    keystroke_counter = 0; // 2 Digit keystoke received.  Reset counter to zero
    keypad_total = 0; //// 2 Digit keystoke received.  Reset total to zero
  }

}

void flash_pattern( patterns pPtr ) {  //flash the pattern passed into this function, then off with 4 seconds delay
  memcpy (leds, patternArrays[pPtr], sizeof patternArrays[pPtr] );
  FastLED.show();
}

david_2018

Thanks.  I tried commenting them out, but I didn't see the warnign go away.

How bad can things get with low memory?

I have a set of functions that reads a 1x4 keypad and displays a two digit su,  It works just fine.
Then I have the code you saw, and it works just fine.
But when I combined them, its like the keypad never gets read.  If I persist, I can eventually get it to read a digit, but its like everything is going really slow.

Is that due to low memory or bad coding?


If you are leaving all the delay() statements in the final code, that will definitely cause problems with reading the keypad.  The code only looks at the keypad inputs when it executes the digitalRead() commands, if that doesn't occur while the key is being pressed the code never sees the key press, and the vast majority of the time you are spending in the delay() statements doing nothing.

Another suggestion, whenever you are printing literal text, such as Serial.print("some text") , use the F() macro around the text Serial.print(F("some text")) , that will store the text in program memory instead of dynamic memory.

Just curious, what are you using the HashMap library for?  I can't seem to find the correct library to download for that, and other than including HashMap.h, I don't see where you are actually using it.

DanMan1

Basically I built a version of the stranger things lights:
https://www.instructables.com/id/Arduino-Based-Stranger-Things-Lights/

But now I am adding a toggle switch to start it off, a keypad so I can select from a list of 23 which phrase I want spelled out by the lights, and before it spells things out I flash the lights a few times.  I plan to use it for a small theater show, so I need time delays to allow time for some dialog.

david_2018

I'm having a lot of trouble trying to understand what you are doing with the keypad in the code.  What specifically is each of the keys suppose to do?

DanMan1

The keypad will be used to determine which lights to flash and what words to spell out.  Because the CRBG code was taking up too much memory.  I set that aside for a day and wrote the code that uses the toggle switch and keypad.  I ran it and it works fine.  Now I need to add back all of the LED lights part.

Code: [Select]

// This works like a charm thanks to some help from cattledog on the Audrino forum
//  11/16/19  Added LED display and that works too!
//  This sketch gets 2 digits from the keypad and uses them to identify a color number and an item to spell out
//  Now just add the toggle switch and then the LED light functions

//  TO DOs::: Add a time for 30 seconds to see if a second 2 digit code is entered
//  This is a safety procaution that allows me to retype the digits in if they are mistyped or miss read.
//  After the 30 seconds times out, then turn off or dim the display

// 11/17/2019  Added Get2Digits functiosn to simply the code

#include <TM1637Display.h>
#define CLK 8
#define DIO 9
TM1637Display display(CLK, DIO);

#define key1 5 //connect wire 1 to pin 2
#define key2 4 //connect wire 2 to pin 3
#define key3 3 //connect wire 3 to pin 4
#define key4 2 //connect wire 4 to pin 5

#define NUM_ARRAYS  2
#define ARRAY_SIZE  5

int  Array1[ARRAY_SIZE] = { 1, 2, 3, 4, 5 };
char *Array2[ARRAY_SIZE] = {"dog", "cat", "Horse","Ant", "Firetruck"};
uint8_t BlankDisplay[] = {0x0, 0x0, 0x0, 0x0};  //Used to clear out the display

int SelectPin10 = 10;
int SwitchStatusWas;
int SwitchStatusIs;

int keypressed = 0;
int keystroke_counter = 0;  // counts how many key strokes have been recorded
int keypad_total = 0; // this is the total of the keypad entries added as a two digit value
int UserInput = 0;  //Input from keypad


void setup() {
  pinMode(key1, INPUT_PULLUP);// set pin as input
  pinMode(key2, INPUT_PULLUP);// set pin as input
  pinMode(key3, INPUT_PULLUP);// set pin as input
  pinMode(key4, INPUT_PULLUP);// set pin as input
  pinMode(SelectPin10, INPUT);
 
  Serial.begin(9600);
  display.setSegments(0); //Turn off / clear all display segments
  display.setBrightness(7);

/////
// Turn on xmass lights to default setting
/////
 
}


void loop() {

  // Look for keypad 2 digit entry & validate its correct or re-nter
  static byte last_key1S = 1;
  static byte last_key2S = 1;
  static byte last_key3S = 1;
  static byte last_key4S = 1;
  byte key1S = digitalRead(key1);// read key1
  byte key2S = digitalRead(key2);// read key2
  byte key3S = digitalRead(key3);// read key3
  byte key4S = digitalRead(key4);// read key4

//
// Look for toggle switch to go to ON.  Needed to start the rest of the routine
ToggleSwitchChange();
Serial.println("Toggle Switch Change Detected ");
delay(5000);  // Delay 5 seconds to walk over and unplug fake power cord
// Turn LEDs OFF  (Add code later)

SwitchStatusWas = SwitchStatusIs;  // Toggle has changed,  Set Is/was equal to reset for another toggle test later

// Now wait for two digit item to be entered on the keypad
  UserInput = Get2Digits();           // Get 2 digit entry and diplay
       Serial.print("User Input was ");
       Serial.println(UserInput);
  delay(10000);  // Display key entery for 10 seconds (need to have a loop to re-look at this later)
  display.setSegments(BlankDisplay);  // This clears out the dsiplay and makes it blank

    // Identify color to use and item to use based off 2 digit code
    // Print Color of item selected is 
       Serial.print("Color of item selected is  ");
       Serial.println(Array1[UserInput-1]);

    // Print Item selected is
    Serial.print("Type of item selected is ");
    Serial.println(Array2[UserInput-1]);
    // Serial.println(item_selected[x]);

 // Wait for toggle to go back to OFF
  ToggleSwitchChange();
  Serial.println("Toggle Switch Change Detected ");
  delay(1000); //Pause 1 seconds; make longer to allow perfromer to get ready for light show
  Serial.print("Color of item selected is  ");
  Serial.println(Array1[UserInput-1]);
   
  Serial.println("Color Lights brighten to on ");  //Color Lights brighten to on
  delay(1000); // Pause 5 seconds later make 10
  Serial.println("Color Lights flash on and off 3 times ");  //Color Lights bflash on and off 3 times
  delay(1000); //Pause 5 seconds later make 24 seconds

  Serial.println("Item selected is spelled out in the lights ");  //Item selected is spelled out in the lights
  delay(1000); // Pause 5 seconds later make 10
  Serial.println("All Lights go OFF ");  //All Lights go OFF
 // Stay here until reset somehow.  Currently program loops back to the top   

    keystroke_counter = 0; // 2 Digit keystoke received.  Reset counter to zero
    UserInput = 0; //// 2 Digit keystoke received.  Reset total to zero
    // Problem clearing out the display here.  Look at later.

   delay(60000); //Pause 60 seconds before re-looping.  Replace this later with something else?  Reset??

  }

  //////////////////////////// FUNTIONS  //////////////////////////
  int Get2Digits() {
 
  keypressed = 0;
  keystroke_counter = 0;
  //Serial.println("Inside Get2Digits ");

  // Look for 2 key entery on 1x4 keypad
  while (keystroke_counter < 2) {
  static byte last_key1S = 1;
  static byte last_key2S = 1;
  static byte last_key3S = 1;
  static byte last_key4S = 1;
  byte key1S = digitalRead(key1);// read key1
  byte key2S = digitalRead(key2);// read key2
  byte key3S = digitalRead(key3);// read key3
  byte key4S = digitalRead(key4);// read key4

////// Cahnged keypressed values to be  0 thru 4 eeven though keys say 1-4
 
    if (key1S != last_key1S) {
      if (key1S == 0) { //went from HIGH to LOW
        //Serial.println("key 1 is pressed");
        keypressed = 0;
        keystroke_counter = keystroke_counter + 1;
      }
    }
    last_key1S = key1S;

    if (key2S != last_key2S) {
      if (key2S == 0) { //went from HIGH to LOW
        //Serial.println("key 2 is pressed");
        keypressed = 1;
        keystroke_counter = keystroke_counter + 1;
      }
    }
    last_key2S = key2S;

    if (key3S != last_key3S) {
      if (key3S == 0) { //went from HIGH to LOW
        //Serial.println("key 3 is pressed");
        keypressed = 2;
        keystroke_counter = keystroke_counter + 1;
      }
    }
    last_key3S = key3S;

    if (key4S != last_key4S) {
      if (key4S == 0) { //went from HIGH to LOW
        //Serial.println("key 1 is pressed");
        keypressed = 3;
        keystroke_counter = keystroke_counter + 1;
      }
    }
    last_key4S = key4S;

    if (keystroke_counter == 1) {
      keypad_total = keypressed * 10;
    }
    else if (keystroke_counter == 2) {
      keypad_total = keypad_total + keypressed;
    }
  }

    display.showNumberDec(keypad_total, false); // Expect: ___keypad_total
    display.showNumberDec(keypad_total, false); // Expect: ___keypad_total
    return keypad_total;
}
  ////////////////////////////////////////////////////
void ToggleSwitchChange() {
SwitchStatusWas = digitalRead(SelectPin10);
SwitchStatusIs  = digitalRead(SelectPin10);
    //Serial.print(" Switch Status WAS / IS  ");
    //Serial.print(SwitchStatusWas);
    //Serial.print(SwitchStatusIs);
    //Serial.println();

 while (SwitchStatusIs == SwitchStatusWas) {
  SwitchStatusIs = digitalRead(SelectPin10);
  delay(100);
  }
 }
  ////////////////////////////////////////////////////



Go Up