incrementally declaring variables

I am trying to create what is effectively a sequential shift light (as RPM increases, more LEDs light up). I would like to make this code as configurable as possible. i.e. instead of declaring LED pins like the following:

int led1 = 22;
int led2 = 23;
int led3 = 24;
int led4 = 25;

etc etc for how ever many LEDs you want

I would like to enter it like below:

int ledstartpin = 22;
int shiftleds = 10;

With that info I would like to use a while loop to initialize all of the required variables (led1=22, led2=23, led3=24 etc for 10 pins.). this may or may not be possible. i would think you need to add strings “led” + “1”, “led” + “2”, “led” + “3” etc… I am just unfamiliar enough with what you can and cant do with this language, especially strings and the like.

Any suggestions? I don’t even know what this process/idea is called so I don’t know what to search for!

Use a for loop and an array to hold all the LED pins

Don’t need an array for that if the pins are sequential. A loop using the ledstartpin as an offset will do.

char ledstartpin = 22;
char shiftleds = 10;


void setup(){

  for( char idx = 0x00 ; idx < shiftleds ; ++idx ){
    
    pinMode( ledstartpin + idx, OUTPUT );
  }
}

cplrampage:
i would think you need to add strings "led" + "1", "led" + "2", "led" + "3" etc...

You can't do this with C/C++ because all the variable names must be known at compile time.

You can get much the same effect with an array

byte ledPin[10]; // creates space for 10 led pin numbers

ledPin[3] = 7; // makes 7 the pin number for the 4th led (arrays count from 0).

You will be required to define the size of the array in your code - it can't be extended afterwards.

...R

Alright, so I set up the array, and I decided to make it hold not only what pin it is but what RPM it should turn on at. it compiles fine as is, but now I am trying to pass the array and the current RPM to a function (this function will do the actual turning on and off of the LEDs) I keep getting errors to the effect of “undeclared identifiers” regardless of what I do with brackets etc. though research i think I have to do something with pointers or the like but I am having a hard time understanding how to implement them. here are the chunks of code I have so far, just assume RPM is a 4 digit int.

//Sequential shift light starting pin, number of LEDs, starting RPM, shift RPM
int shiftpin1 = 22;
int shiftwidth = 10;
int startrpm = 5000;
int shiftrpm = 7500;

//Critical values (RPM and MPH) refresh rate in milliseconds
int refreshrate = 500;

// setup shift light pins and shift light set points with array first col is pin and second col is rpm to light up at
  int shiftleds [shiftwidth] [2];
  for (int i = 0; i < shiftwidth; i++){
  	shiftleds[i] [0] = shiftpin1 + i;
  	shiftleds[i] [1] = (int)(startrpm + ((shiftrpm - startrpm) / shiftwidth) * i);
  	pinMode(shiftleds [i] [0], OUTPUT);
  	digitalWrite(shiftleds [i] [0], LOW);
  }
void loop() {

  //calculate RPM and MPH, display and reset values
  if (timeold+refreshrate < millis()) { 
    rpm = 30*1000/(millis() - timeold)*rpmpulses;
    spd = 1000/(millis() - timeold)*spdpulses;
    timeold = millis();
    rpmpulses = 0;
    spdpulses = 0;
    printRPM(rpm, rpmcol, rpmrow); //print to LCD, ignore
    printSPD(spd, spdcol, spdrow);  //print to LCD, ignore
    shiftlight(rpm, shiftleds);
  }

//Funtion to output RPM to sequential shift light
void shiftlight(int rpm, int ledconfig[]){
	
}

as you can see I haven’t even written the code to display the LEDs, I cant even get the data to the function!

If you are interested in seeing the entirety of the code and would like to compile it etc, it can be found here: https://codebender.cc/sketch:36971

Any help is appreciated!

I wrote this code this morning to make a test, and I believe, that can help you in this context:

#define LENGTH 4
int output[] = {31, 33, 35, 37};
int count;

void setup() {
  for (int i=0; i<LENGTH; i++) {
     pinMode(output[i], OUTPUT);
  }
}

void loop() {
  if (count < LENGTH) {
     digitalWrite(output[count], HIGH);
  }
  else {
     digitalWrite(output[2*LENGTH-count-1], LOW);
  }
  
  if (++count >= 2*LENGTH) {
     count = 0;
  }
  
  delay (500);
}

luisilva:
I wrote this code this morning to make a test, and I believe, that can help you in this context:

#define LENGTH 4

int output = {31, 33, 35, 37};
int count;

void setup() {
  for (int i=0; i<LENGTH; i++) {
     pinMode(output[i], OUTPUT);
  }
}

void loop() {
  if (count < LENGTH) {
     digitalWrite(output[count], HIGH);
  }
  else {
     digitalWrite(output[2LENGTH-count-1], LOW);
  }
 
  if (++count >= 2
LENGTH) {
     count = 0;
  }
 
  delay (500);
}

Thanks, I think this covers some of my earlier questions, but I have already solved that issue. Now i am trying to pass an entire array to a function and I cant figure out how to make it work.

You could also do something like this.

byte tmp[]={1,2,3,4};
#define SIZE(x) sizeof(x)/sizeof(x[0])  /* This should be added to the core library */

void setup()
{
  Serial.begin(115200);
  for(byte i = 0, j = SIZE(tmp); i < j; i++)
    Serial.println(tmp[i]);
}
void loop() {}

Output:

1
2
3
4

So, I believe that you are asking for something like this:

#define LENGTH 8
int output[] = {31, 33, 35, 37, 39, 41, 43, 45};
int count;
boolean forward = true;
boolean none = false;

void setOutputs(int outputNumber, int outputPins[]) {
  for (int i=0; i<outputNumber; i++) {
     pinMode(outputPins[i], OUTPUT);
  }
}

void setValue (int value, int outputNumber, int outputPins[]) {
   
  for (int i=0; i<outputNumber; i++) {
     if (i<value) {
        digitalWrite(outputPins[i], HIGH);
     }
     else{
        digitalWrite(outputPins[i], LOW);
     }
  }
}

void setup() {
   setOutputs(LENGTH, output);
}

void loop() {
  if (!none) {
     setValue (count, LENGTH, output);
  }
  
  if (forward) {
     count++;
     if ( count >= LENGTH ) {
        forward = false;
     }     
  }
  else {
     count--;
     if ( count <= 0 ) {
        forward = true;
     }     
  }
  delay (100);
}

cplrampage:
Now i am trying to pass an entire array to a function and I cant figure out how to make it work.

Make life simple and create the array as a global variable.

It's not as if you are trying to write a 50,000 line PC program where you might get confused.

...R

Robin2:

cplrampage:
Now i am trying to pass an entire array to a function and I cant figure out how to make it work.

Make life simple and create the array as a global variable.

It's not as if you are trying to write a 50,000 line PC program where you might get confused.

...R

I thought about that, and I can always fall back to that. But i would like to learn how to do it the right way, even if it doesn't really matter here it might matter somewhere else down the road.

cplrampage:

Robin2:

cplrampage:
Now i am trying to pass an entire array to a function and I cant figure out how to make it work.

Make life simple and create the array as a global variable.

It's not as if you are trying to write a 50,000 line PC program where you might get confused.

...R

I thought about that, and I can always fall back to that. But i would like to learn how to do it the right way, even if it doesn't really matter here it might matter somewhere else down the road.

And I believe that is not very hard. Do you see my code? Do you understand it? Can you adapt it to your project?

void setValue (int value, int outputNumber, int outputPins) {

for (int i=0; i<outputNumber; i++) {
if (i<value) {
digitalWrite(outputPins[ i ], HIGH);
}
else{
digitalWrite(outputPins[ i ], LOW);
}
}
}

This is what he needs to use but instead of constantly making the pins HIGH or LOW, it should see if the value has first changed or not.

He could also get rid of “int outputNumber” if the code is changed to use what I did here.

#define SIZE(x) sizeof(x)/sizeof(x[0]) /* This should be added to the core library */

void setup()
{
Serial.begin(115200);
for(byte i = 0, j = SIZE(tmp); i < j; i++)

Robin2:
You will be required to define the size of the array in your code - it can't be extended afterwards.

Not that I'm advocating it, but if the array size absolutely had to be dynamic then it could be allocated from the heap.

PeterH:

Robin2:
You will be required to define the size of the array in your code - it can't be extended afterwards.

Not that I'm advocating it, but if the array size absolutely had to be dynamic then it could be allocated from the heap.

Or the stack, if program flow allows it.

void RunFeature( const int elements ){
  int data[ elements ];
  DoStuffWithArray( data, elements );
}

luisilva:
And I believe that is not very hard. Do you see my code? Do you understand it? Can you adapt it to your project?

I believe I understand your code, although I am not sure how it would be implemented in my case? I think my issues are derived from how I am initializing and loading up the array? can some one comment on the following method:

  // setup shift light pins and shift light set points with array first col is pin and second col is rpm to light up at
  int shiftleds [shiftwidth] [2];
  for (int i = 0; i < shiftwidth; i++){
  	shiftleds[i] [0] = shiftpin1 + i;
  	shiftleds[i] [1] = (int)(startrpm + ((shiftrpm - startrpm) / shiftwidth) * i);
  	pinMode(shiftleds [i] [0], OUTPUT);
  	digitalWrite(shiftleds [i] [0], LOW);
  }

Assuming the following:

//Sequential shift light starting pin, number of LEDs, starting RPM, shift RPM
int shiftpin1 = 22;
int shiftwidth = 10;
int startrpm = 5000;
int shiftrpm = 7500;

the values in my array should be:

[22, 5000]
[23, 5250]
[24, 5500]
[25, 5750]
[26, 6000]
[27, 6250]
[28, 6500]
[29, 6750]
[30, 7000]
[31, 7250]
[32, 7500]

Is that correct? they are all ints right?

As you use this:

int shiftwidth = 10;

to set the dimension of the array, I believe that can’t be int.
I try to compile your code and I get the error: “error: array bound is not an integer constant”. You must change it to const int or make a #define.

The rest of the code, should work, but I don’t like it. If I was in your place I will do something like:

//Sequential shift light starting pin, number of LEDs, starting RPM, shift RPM
const int shiftwidth = 10;
int shiftpin1 = 22;
int startrpm = 5000;
int shiftrpm = 7500;

struct type_led_rpm {
   int ledPin;
   int rpmValue;
};

struct type_led_rpm shiftleds [shiftwidth];

void initLedRpm(int width, struct type_led_rpm led_rpm[]) {
   for (int i = 0; i < shiftwidth; i++){
      led_rpm[i].ledPin = shiftpin1 + i;
      led_rpm[i].rpmValue = (int)(startrpm + ((shiftrpm - startrpm) / shiftwidth) * i);
      pinMode(led_rpm[i].ledPin, OUTPUT);
      digitalWrite(led_rpm[i].ledPin, LOW);
   }
}

void setup() {
   initLedRpm(shiftwidth, shiftleds);
}

(...)

luisilva:
As you use this:

int shiftwidth = 10;

to set the dimension of the array, I believe that can’t be int.
I try to compile your code and I get the error: “error: array bound is not an integer constant”. You must change it to const int or make a #define.

The rest of the code, should work, but I don’t like it. If I was in your place I will do something like:

//Sequential shift light starting pin, number of LEDs, starting RPM, shift RPM

const int shiftwidth = 10;
int shiftpin1 = 22;
int startrpm = 5000;
int shiftrpm = 7500;

struct type_led_rpm {
   int ledPin;
   int rpmValue;
};

struct type_led_rpm shiftleds [shiftwidth];

void initLedRpm(int width, struct type_led_rpm led_rpm) {
   for (int i = 0; i < shiftwidth; i++){
      led_rpm[i].ledPin = shiftpin1 + i;
      led_rpm[i].rpmValue = (int)(startrpm + ((shiftrpm - startrpm) / shiftwidth) * i);
      pinMode(led_rpm[i].ledPin, OUTPUT);
      digitalWrite(led_rpm[i].ledPin, LOW);
   }
}

void setup() {
   initLedRpm(shiftwidth, shiftleds);
}

(…)

I don’t really know what a struct is, it looks like a 1 dimensional array that can be comprised of different data types? I am not positive what your code is doing, but this is what I interpreted:

lines 7-10 create a struct that has 2 ints (the pin number and the rpm, but these are empty at this point)

Not sure what line 12 does

line 14 creates a function with the width of the display and the struct as inputs?
line 15 creates a loop for how ever wide the display is
lines 16-19 do the same thing as my code

so are you making an array of structs? if so, why is this beneficial over an array that is 2D? Feel free to correct my terminology if I used it incorrectly.

Thanks alot for all the help so far!

cplrampage, your interpretation of the code is correct. Now that I’ve read your comment, I realise that I’ve one error.
The line:

   for (int i = 0; i < shiftwidth; i++){

must be:

   for (int i = 0; i < width; i++){

The number of elements that are written must be given by the variable that is given to the function, and not by the global variable.

Answering to your questions:

so are you making an array of structs?

Yes, instead of have a 2D array of int's I have a 1D array of struct type_led_rpm.

if so, why is this beneficial over an array that is 2D?

Is better because you can read better the code. If we give to someone the line:

shiftleds[i] [0] = shiftpin1 + i;

only with this information he or she don’t know what this line do. But if we do this with “my line”:

led_rpm[i].ledPin = shiftpin1 + i;

everybody knows that I’m “configuring” the led pin of my stripe of led rpm. The beneficial is the reading and understanding.

Note that even you, a few year from now you must need to understand what you do in this code. Even you with the line:

shiftleds[i] [0] = shiftpin1 + i;

will have some trouble to understand it, I believe.

The lines:

struct type_led_rpm {
   int ledPin;
   int rpmValue;
};

is where I define the elements that my structure will have (is almost the same that create a new type of data like int, or char, float, etc.).

In the line:

struct type_led_rpm shiftleds [shiftwidth];

I create a new variable of the type “struct type_led_rpm”, in this case an array of elements of this type of data.

Another good thing that have structs, is that you don’t need to have all the elements of the same type (like I have the 2 elements of the type int). In some other applications may be an advantage.

Is there any specific reason why you made it a function, if I am only ever going to run this once in the setup section of the code can I just put it in there?

supposing I make the changes above, and now have an array of structs that defines my LED pins and RPMs, how do I go about passing that to a function that actually turns on the LEDs at the appropriate time. I would need to pass the RPM int, as well as the struct array.

i.e.

void loop ()  {
  shiftlight(rpm, "CORRECT SYNTAX TO PASS STRUCT ARRAY")
}

void shiftlight(int currentRPM, "FILL IN HERE"){
	"CODE  TO DISPLAY LEDS"
}

Don't worry about the actual code to turn on the LEDs, I am just trying to get the data to the function at this point... I tried a few things but i have not figured it out yet.