Pages: [1]   Go Down
Author Topic: Problem with function  (Read 647 times)
0 Members and 1 Guest are viewing this topic.
Hamburg
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

I can't figure out how to make the function look up the values of the LED array using the variable personsname. It works if a condition is entered directly instead of "personsname", e.g. "Jack" will light up the correct LEDs. The following code is not complete, purely so the problem area is clear... Any help appreciated.

Code:
//DEFINE OUTPUT PINS
int dataPin  = 2; //Yellow wire
int clockPin = 3; //Green wire

//SET NUMBER OF PIXELS
Adafruit_WS2801 strip = Adafruit_WS2801(20, dataPin, clockPin);

//LED PIXEL ARRAYS
byte Pete[] = { 0, 19, 43, 63};
byte Stephen[] = { 25, 32, 37, 59, 60, 63, 71};
byte Jack[] = { 20, 59, 61, 68};



//SETUP
void setup(){
  strip.begin();
  strip.show();
  Serial.begin(9600);
}

//CHECK & UPDATE LOOP
void loop(){
 
      colorFade(Color(0, 0, 255), "Pete");
    }
    delay(10000); //wait 10 seconds before connecting again
  }




// MAIN FUNCTIONS

//Fade to color
void colorFade(uint32_t c, char* personsname) {
  int i, j;
  for (c=0; c < 256; c++) {
    for (i=0; i < sizeof(personsname); i++) { //Can't get this to work. I can't figure out how to make the function look up the values of the pixel array using the variable 'personsname'. It works if a name is entered directly instead of "personsname", e.g. "Jack" will light up the correct LEDs.
      strip.setPixelColor(personsname[i], c); //Same here.
    } 
    strip.show();   // write all the pixels out
    delay(50);
    Serial.print("Fade In: ");Serial.print(personsname);Serial.println("");
  }
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 653
Posts: 50881
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The names of the arrays (Pete, Stephen, Jack) are converted to addresses. At run time, the names don't exist. You can't match a string ("Pete") to the name of an array like you seem to be trying to.

You could do something like:
Code:
byte *arrayPtr = 0;
if(strcmp("Pete", personsname) == 0)
   arrayPtr = Pete;
else if(strcmp("Stephen", personsname) == 0)
   arrayPtr = Stephen;

Then, use the arrayPtr variable to step through the array to get the values.

Keep in mind that there is nothing to stop you from walking off the end of the array, since there is no length defined for the arrays, and no "stop here - its the end of the array" value in the array, like the NULL terminator in a C string.
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You have to provide a look-up table if you want to associate a character string with a data value:

Code:
char (*lookupName)[] =  {"Pete", "Stephen", "Jack"};
byte *lookupArray[] = {Pete, Stephen, Jack};

Then you can compare your string to each of the strings in the first array until you find a match and use the index at which you found the match to get the array pointer from the second array.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Hamburg
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you both for the quick input!
« Last Edit: March 26, 2013, 03:35:00 pm by TSD_80 » Logged

Hamburg
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@johnwasser, could you help me understand your suggestion a little further? I've still a lot to learn with C so I can't yet figure out how I start to implement those look-up comparisons and references. Any tips gratefully received.
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The result would look something like this:
Code:

//DEFINE OUTPUT PINS
int dataPin  = 2; //Yellow wire
int clockPin = 3; //Green wire

//SET NUMBER OF PIXELS
Adafruit_WS2801 strip = Adafruit_WS2801(20, dataPin, clockPin);

//LED PIXEL ARRAYS
const unsigned int NUMBEROFNAMES = 3;
byte Pete[] = {
  0, 19, 43, 63};
byte Stephen[] = {
  25, 32, 37, 59, 60, 63, 71};
byte Jack[] = {
  20, 59, 61, 68};

char *lookupName[NUMBEROFNAMES] =  {
  "Pete", "Stephen", "Jack"};
byte *lookupArray[NUMBEROFNAMES] = {
  Pete, Stephen, Jack};
int lookupArraySize[NUMBEROFNAMES] = {
  4, 7, 4};

//SETUP
void setup(){
  strip.begin();
  strip.show();
  Serial.begin(9600);
}

//CHECK & UPDATE LOOP
void loop() {
  colorFade(Color(0, 0, 255), "Pete");
  delay(10000); //wait 10 seconds before connecting again
}

// MAIN FUNCTIONS

//Fade to color
void colorFade(uint32_t c, char* personsname) {
  int i, j, index;
  for (index = 0; index < NUMBEROFNAMES; index++) {
    if (strcmp(personsname,lookupName[index]) == 0)
      break;
    }
    if (index == NUMBEROFNAMES)  // No match found
      return;

  byte *myArray = lookupArray[index];
  unsigned int myArraySize = lookupArraySize[index];

  for (c=0; c < 256; c++) {
    for (i=0; i < myArraySize; i++) {
      strip.setPixelColor(myArray[i], c); //Same here.
    } 
    strip.show();   // write all the pixels out
    delay(50);
    Serial.print("Fade In: ");
    Serial.print(personsname);
    Serial.println("");
  }
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Hamburg
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

And then there was light.

Thanks for your input. I was scratching my head trying to work out how to define the size of each array - and now it's clear. Great. I'll now dive in to ensure I've understood everything that's going on, and build on it from there. Much appreciated.
Logged

Hamburg
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been playing around with the previously suggested solution and continuing with it. All is well bar one specific area which I've failed to find a work-around for over the last few days...

The colorFade function shows the right colour, but the fade doesn't actually work (the full colour appears immediately). If I swap the 'c' for another int say 'j', the fade works but the colour doesn't. I imagine this is because The 'uint32_t Color' function is creating a 24-bit color that can't be faded up and down? I've found various ways of fading the rgbs for each Array, but none that allow me to fade up to the target colour shown in the colorFade loop... Is there a way around this? Ideally, i would be able to go from starting colour RGB values to target RGB values for every colorFade in the loop (From/To)...

Code:
//CHECK & UPDATE LOOP
void loop(){

      colorFade(Color(160, 160, 160), ( 0, 0, 255), "Pete");

    delay(100); //wait 10 seconds before connecting again
  }


// MAIN FUNCTIONS

//Fade to color
void colorFade(uint32_t c, char* personsname) {
  int i, j, index;
  for (index = 0; index < NUMBEROFNAMES; index++) {
    if (strcmp(personsname, lookupName[index]) == 0)
      break;
    }
    if (index == NUMBEROFNAMES) // No match found
      return;
     
  byte *myArray = lookupArray[index];
  unsigned int myArraySize = lookupArraySize[index];
 
  for (c=0; c < 256; c++) {
    for (i=0; i < myArraySize; i++) {
      strip.setPixelColor(myArray[i], c);  // the colour is correct but the fade "for (c=0; c<256; c++)" doesn't work. If I swap the 'c' for 'j' it fades correctly but doesn't show correct target colour (it's always shades of blue)
    }
    strip.show();   // write all the pixels out
    delay(50);
    Serial.println("Fade In: ");
    Serial.println(personsname);
    Serial.println("");
  }
}

// Create a 24 bit color value from R,G,B
uint32_t Color(byte r, byte g, byte b)
{
  uint32_t c;
  c = r;
  c <<= 8;
  c |= g;
  c <<= 8;
  c |= b;
  return c;
}
Logged

Pages: [1]   Go Up
Jump to: