# How to efficiently reuse a function for multiple pins?

In order to control mulitple pins, I created an array with 14 positions for all possible pins on my Uno. I want to make it a bit more memory efficient. The only way I know, is to make the array shorter and create another array with pins I actually want to control (they’re not 0, 1, 2, but 9, 10 and 11). That would require some extra setup effort, which isn’t so nice when I want to reuse the code in a library.

As far as I know, arrays can’t be defined with a non constant variable.

The code in question is this sketch with a pretty nice breathing and fading effect for LEDs. Would there be a better way to manage multiple instances of the setBreath() function?

``````#include <SoftwareSerial.h>
#include <math.h>

#define PIN_GREEN 9
#define PIN_YELLOW 10
#define PIN_RED 11

const int NumberOfFadingLEDs = 14; // I would like to make this more dynamic, as it takes 99 bytes of memory more than if I use 3 instead.

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

// LED pins
pinMode(PIN_GREEN, OUTPUT);
pinMode(PIN_YELLOW, OUTPUT);
pinMode(PIN_RED, OUTPUT);

}
// Calculate next brightness value during breath cycle:
float breath( float fadeSpeed = 1, long offset = 0, int sign = HIGH){
// fadeSpeed: 1.0 is a good default, 0.75 a good sleep mode, 3 is pretty fast
// offset: if lED has to fade in/out, we need to do a phase shift to allign the function with millis()
long offsetMillis = millis() - offset;
float phaseShift = (-1+2*sign)*6;  // Aligned with fade in speed. For phase shift aligned with 0: (-1+2*sign)*3*PI/2
return 108.0*(exp(sin( (fadeSpeed*offsetMillis/2000.0*PI) + phaseShift) - 0.36787944));
}
// Calculate next brightness value during fade:
if( millis() > previousFadeStep + 25UL){
}
return brightness;
}
// Start or end the breathing cycle with a fade:
void setBreath( int pin, float fadeSpeed = 1.0, int toggle = HIGH){

if (toggle == HIGH){// fade in and start breath
if (init[pin] == 0){
if ( brightness[pin] < 56){
}
else{
offset[pin] = millis() ;
init[pin] = 1;
}
}
else{
brightness[pin] = breath( fadeSpeed, offset[pin] );
}
}
else{ // fade out and stop breath
if (brightness[pin] > 5){
}
if ( brightness[pin] < 5 ){
brightness[pin] = 0;
}
}
analogWrite(pin, brightness[pin]);
}

void loop(){
long currentMillis = millis();

if (currentMillis < 3000){
setBreath(PIN_YELLOW, 4, HIGH);
}
if (currentMillis > 8000)  {
setBreath(PIN_YELLOW, 0.5, LOW);
}
if ((currentMillis > 1000) && ( currentMillis < 14000)){
setBreath(PIN_RED, 1, HIGH);
}
if ((currentMillis > 16000) && ( currentMillis < 99000)){
setBreath(PIN_RED, 1, LOW);
}
setBreath(PIN_GREEN, 1.2, HIGH);
}
``````

As far as I know, arrays can't be defined with a non constant variable.

A variable is by definition not a constant (hence the name).

What you may want to look at is using a structure to define the data that needs to be used to control a LED. A structure is like a database record - it groups related data of different types together and allows you to manipulate it as a logical unit. In you case this could be the pin number, true/false state, fading time, etc. You can then pass the data to the function with one parameter (or just pass a pointer to the structure). Search for references to this related to C and C++.

Structures are related to classes in C++ - basically a class is a structure with related code. If you want to take it one step further you could define a class for the LED you want to animate and have both the data and a local instance of the code (ie, an object) defined together.

Structures can be initialised using static data and class instances are initialise through their constructor parameters.

Alright I just got to learn more C++. Thanks for the pointers!