Array problems

I wrote a simple program to output colors on an RGB LED. I have the LED hooked up to pins 3, 5, and 6, but hardware is nto the problem.
Here is my code:

#include "Colors.h"

int color[3];
int redP= 6;
int greenP= 5;
int blueP = 3;
void setup () {

  Serial.begin(9600);
}

void loop() {
  delay(2000);
[glow]  color[3] = yellow;[/glow]
  analogWrite(redP, color[0]);
  analogWrite(greenP, color[1]);
  analogWrite(blueP, color[2]);

}

And Colors.h:

#define red {255,0,0}
#define green {0,255,0}
#define blue {0,0,255}
#define off {0,0,0}
#define white {255,255,255}
#define orange {255,127,0}
#define brown {153, 102, 51}
#define cyan {0,255,255}
#define magenta {255,0,255}
#define purple {127,0,127}
#define yellow {255,255,0}

And it returns:

colors.cpp: In function 'void loop()':
colors:13: error: expected primary-expression before '{' token
colors:13: error: expected `;' before '{' token

I highlighted the problem.

You have color defined as an array that can hold 3 integers. The indexes range from 0 to 2.

Then, you are trying to store in the 4th position of the array something that is not an integer.

color[3] = yellow; is equivalent to color[3] = {255,255,0}; which clearly is not reasonable.

You will need to alter your Colors.h file, so that yellow is defined like so:

int yellow[] = {255,255,0};

(with corresponding changes to other colors.

Then, you set color like so:

color[0] = yellow[0];
color[1] = yellow[1];
color[2] = yellow[2];

Unfortunately, there are no shortcuts like you are trying to invent.

OK. But why won't #define work?

#define creates name/value pairs. The preprocess substitutes the value portion wherever the name appears in the code, before passing the code to the compiler.

Nowhere in your code is a direct substitution of that value appropriate.

Could I get it to work?

this compiles and runs

#define YELLOW {255,255,0}

int ar[] = YELLOW;

void setup()
{
  Serial.begin(19200);
}

void loop()
{
  Serial.println(ar[0]);
  Serial.println(ar[1]);
  Serial.println(ar[2]);
  delay(1000);
}

this compiles and runs

But, you can not dynamically assign a new value to ar where that value is the value part of a #define name/value statement.

You are right, Paul!

this doesn’t compile or run

#define YELLOW {255,255,0}
#define RED {255,0 ,0}

int ar[] = YELLOW;

void setup()
{
  Serial.begin(19200);
}

void loop()
{
  Serial.println(ar[0]);
  Serial.println(ar[1]);
  Serial.println(ar[2]);
  delay(1000);
 [glow] ar = RED;[/glow]  // << compile error!
}

I understand. How I hate the preprocessor.
How about this:

#define BLUE {0,0,255}
#define GREEN {0,255,0}
int color = BLUE
int new_color = color
new_color = GREEN

Will not compile as color and new_color are no arrays and
new_color = GREEN is the same kind of error I had in my last post.

That said, you could have compiled this in the IDE in seconds and found the answer yourself - at least that it will not compile.

Intrigued by the question, you could define all colors into a long and use some bit-fiddling to extract the R,G, or B component.

(this rather ugly code is compiling and running)

#define YELLOW (255 *65536L + 255 *256L + 0)
#define RED (255 *65536L  + 0 *256L + 0)

unsigned long color = YELLOW;

void setup()
{
  Serial.begin(19200);
}

void loop()
{
  Serial.println((color & 0x00FF0000) >> 16);
  Serial.println((color & 0x0000FF00) >> 8);
  Serial.println(color & 0x000000FF);
  delay(1000);
  color = RED;
}

Advice: Better develop a color or RGB class

baum,

You are hating on the wrong thing. The preprocessor is not the problem. The problem is a little misunderstanding about C/C++ syntax. Here's the deal:

The C programming language allows you to declare an array. When you declare an array, you can put the size (number of elements) of the array in square brackets, after the array name:int color_array[3];

That says you want an array named 'color_array', and you want it to contain 3 integers.

In C, you can also set the initial values of the array elements when you declare it. Your program can change these values while it is running, but when your program starts, the array will have the values you put in the declaration:int color_array[3] = {1,2,3};

Sadly, C does not allow you to change the values for a whole array with one statement. For example, this will not compile:

void loop()
{
   color_array[3] = {4,5,6);  // Syntax error!
}

However, you can accomplish the same thing with three statements:

color_array[0] = 4;  // this will work correctly
color_array[1] = 5;
color_array[2] = 6;

Note that the first element of the array is numbered 0. The number of the element is called the subscript. The subscript for the last element in an array is always one less than the size of the array, so for an array that is 3 elements long, the subscript of the third and final element is 2.

I hope you find this information helpful.

Regards,

-Mike

I know that. I don't like the fact that I can use #define to define variables that might change. (Such as my program mentioned above).

baum,

I know just what you mean. I don't like carving knives because I can use them to cut my finger off. So, I just gnaw meat off the bone. :wink:

Regards,

-Mike

A little more work and you have:

// <http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1292162480>

#define kRED        0xFF, 0x00, 0x00
#define kGREEN      0x00, 0xFF, 0x00
#define kBLUE       0x00, 0x00, 0xFF
#define kOFF        0x00, 0x00, 0x00
#define kWHITE      0xFF, 0xFF, 0xFF
#define kORANGE     0xFF, 0x7F, 0x00
#define kBROWN      0x99, 0x66, 0x33
#define kCYAN       0x00, 0xFF, 0xFF
#define kMAGENTA    0xFF, 0x00, 0xFF
#define kPURPLE     0x7F, 0x00, 0x7F
#define kYELLOW     0xFF, 0xFF, 0x00

struct rgb_t
{
    int     _r, _g, _b;
    
    rgb_t()                     : _r(0), _g(0), _b(0)                   {}
    rgb_t(const rgb_t& rgb)     : _r(rgb._r), _g(rgb._g), _b(rgb._b)    {}
    rgb_t(int r, int g, int b)  : _r(r), _g(g), _b(b)                   {}
    
    rgb_t& operator= (const rgb_t& rhs)
    {
        if ( this != &rhs )
        {
            _r = rhs._r; _g = rhs._g; _b = rhs._b;
        }

        return *this;
    }
};

enum { pinRed = 6, pinGreen = 5, pinBlue = 3 };

rgb_t color = rgb_t(kRED);

rgb_t colors[]  =
{
      rgb_t(kRED)
    , rgb_t(kGREEN)
    , rgb_t(kBLUE)
    , rgb_t(kOFF)
    , rgb_t(kWHITE)
};

void loop()
{
    delay(2000);

    color      = rgb_t(kYELLOW);
    colors[3]  = color;

    analogWrite(pinRed, color._r);
    analogWrite(pinGreen, color._g);
    analogWrite(pinBlue, color._b);
}

void setup()
{
    Serial.begin(9600);
}

OK. Thanks!
On a side note:
I recently received this

from sparkfun. The leads fell off immediately as the soldering job was the worst ever. I wanted to make sure nothing was broken by the missing wire, so I tried just touching a jumper to the solder bulb... and it didn't work. I though it was broken, but it turns out the solder was actually just non-conductive. Are they [the manufactures] crazy?