problem with array in library

Hi,

I'm trying to make an Arduino library with the tutorial. http://www.arduino.cc/en/Hacking/LibraryTutorial. The only thing that doesn't work is to use an Array. I don't get compile errors, but the values that I get back don't seem to come from the array. Probably its something with a pointer, but I've no idea how to solve that.

The problem is in the _dim_curve[] array, that I'd like to use as a lookup table. That works perfect in a normal Arduino sketch (http://www.kasperkamperman.com/blog/arduino/arduino-programming-hsb-to-rgb/), but in the library that doesn't work.

My .cpp code:

#include "WProgram.h"
#include "MoodLight.h"

MoodLight::MoodLight()
{	
 
}


int _dim_curve[] = {
    0,   1,   1,   2,   2,   2,   2,   2,   2,   3,   3,   3,   3,   3,   3,   3,
    3,   3,   3,   3,   3,   3,   3,   4,   4,   4,   4,   4,   4,   4,   4,   4,
    4,   4,   4,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   6,   6,   6,
    6,   6,   6,   6,   6,   7,   7,   7,   7,   7,   7,   7,   8,   8,   8,   8,
    8,   8,   9,   9,   9,   9,   9,   9,   10,  10,  10,  10,  10,  11,  11,  11,
    11,  11,  12,  12,  12,  12,  12,  13,  13,  13,  13,  14,  14,  14,  14,  15,
    15,  15,  16,  16,  16,  16,  17,  17,  17,  18,  18,  18,  19,  19,  19,  20,
    20,  20,  21,  21,  22,  22,  22,  23,  23,  24,  24,  25,  25,  25,  26,  26,
    27,  27,  28,  28,  29,  29,  30,  30,  31,  32,  32,  33,  33,  34,  35,  35,
    36,  36,  37,  38,  38,  39,  40,  40,  41,  42,  43,  43,  44,  45,  46,  47,
    48,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,
    63,  64,  65,  66,  68,  69,  70,  71,  73,  74,  75,  76,  78,  79,  81,  82,
    83,  85,  86,  88,  90,  91,  93,  94,  96,  98,  99,  101, 103, 105, 107, 109,
    110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144,
    146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190,
    193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255,
};

void MoodLight::setHSB(int hue, int sat, int val) { 
  /* convert hue, saturation and brightness ( HSB/HSV ) to RGB
     The dim_curve is used only on brightness/value and on saturation (inverted).
     This looks the most natural.      
  */
  
  val = _dim_curve[val];
  Serial.println(val);
  //sat = 255-_dim_curve[255-sat];
  
  int r;
  int g;
  int b;
  int base;
  
  if (sat == 0) { // Acromatic color (gray). Hue doesn't mind.
  
    _red   = val;
    _green = val;
    _blue  = val; 
   
  } else  { 
    
    base = ((255 - sat) * val)>>8;
  
    switch(hue/60) {
	case 0:
		r = val;
		g = (((val-base)*hue)/60)+base;
		b = base;
	break;
	
	case 1:
		r = (((val-base)*(60-(hue%60)))/60)+base;
		g = val;
		b = base;
	break;
	
	case 2:
		r = base;
		g = val;
		b = (((val-base)*(hue%60))/60)+base;
	break;
	
	case 3:
		r = base;
		g = (((val-base)*(60-(hue%60)))/60)+base;
		b = val;
	break;
	
	case 4:
		r = (((val-base)*(hue%60))/60)+base;
		g = base;
		b = val;
	break;
	
	case 5:
		r = val;
		g = base;
		b = (((val-base)*(60-(hue%60)))/60)+base;
	break;
    }
      
    _red   = r;
    _green = g;
    _blue  = b; 
  }   

}

int MoodLight::getRed(){

  return _red;

}

int MoodLight::getGreen(){

  return _green; 

}

int MoodLight::getBlue(){

  return _blue;

}

And in the .h

#ifndef MoodLight_h
#define MoodLight_h

#include "WProgram.h"

class MoodLight
{
  public:
    MoodLight();
    void setHSB(int,int,int);
    int getRed();
    int getGreen();
    int getBlue();
    
  private:
    int _dim_curve[];
    //int _getCurve(int);
    int  _red;
    int  _green;
    int  _blue;
};

#endif

but in the library that doesn't work

Please, don't keep us in suspense any longer. How does the array not work?

Can you also post your testing sketch?

make the array public and just loop through it from your testsketch to see it works..

Hi,

Here the library in the zip-file. In the example the debugging code :
http://dl.dropbox.com/u/1147392/MoodLight.zip

@Coding Badly

if I do this :
var test = ml._dim_curve[254];
Serial.println(test);

I expect to see: 248 (the value on index number 254).

I get back a lot of zero's or other strange numbers that aren't in the array.
Putting the array in my 'normal' code works perfectly.

@robtillaart.
I've made the array public (as you can see in the example) but I get the same broken value's.

The array that you have defined as a member variable, and the array that you have defined and initialized as a global variable are NOT the same array.

If you were indeed to initialize the member variable, then when you reference the member variable, you might get better results.

Try this:

in MoodLight.h declare:

int* _dim_curve;

in MoodLight.cpp declare a global array dc and initialize it (consider making the type uint8_t)

int dc[256] = {
0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
...
193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255
};

Change the constructor so the member accesses the global array.

MoodLight::MoodLight()
{
_dim_curve = dc;
}

should work ...

Thanks this works. However I still wonder why I couldn't use the global array directly?

After you're example I tried it in my old way, and it works.

Probably this int dc[256] was the issue. I forgot to set the length of the array..

Whats the benefit to make the type in an unsigned int ? : uint8_t

Whats the benefit to make the type in an unsigned int ? : uint8_t

RANGE:
int = -32768..32767
unsigned int = 0..65535
uint8_t = 0..255 // unsigned in 8 bits

FOOTPRINT
int array[256]; takes 256 x int = 2 bytes = 512 bytes
uint8_t array[256] takes 256 x 1 byte = 256 bytes.

As you only have 2048 bytes of RAM this differs 12.5%

Could you post your working code for all who find this thread interesting?

Clear. In my other examples i've used the byte type for this.

I've put the library online in my blog:
http://www.kasperkamperman.com/blog/arduino-moodlight-library/

If there are any issues please let my know.

Probably this int dc[256] was the issue. I forgot to set the length of the array..

Probably not. If you don't define a length, the compiler will determine the length based on the number of initializers present.

What you were doing was initializing the global array, but not the member variable. You were then referencing the member variable (var test = ml._dim_curve[254];), which was never initialized.