Attempting to make function with switch case and millis timer reusable

Hello,

I have a light pattern working with the function Pattern_A_State(); but to use it for hundreds of different patterns would mean that I ned to repeat the switch case in each. I tried to make a modular function but cannot get it to work.

Any suggestions appreciated.

Thank you.

#include <ShiftRegister74HC595.h>

unsigned long currentMillis = 1;

const byte lightPins[] = {99, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, 1, 2, 3, 4, 5, 6, 7, 8};
// 99 not used but hack to avoid unfilled array groups returning 0 and lighting first pin

byte numberOfShiftRegisters = 3; // number of shift registers attached in series
byte serialDataPin = 51; // blue wire
byte clockPin = 52; // yellow wire
byte latchPin = 53; // green wire

#define ArrayCount(array) (sizeof array / sizeof array[0])

ShiftRegister74HC595 sr (numberOfShiftRegisters, serialDataPin, clockPin, latchPin);

int state = 1; // anyway to not have these be global variables?
int i = 0; // stat and i? // It would be great to either pass them in the function call or have them declared in the switch case block
unsigned long previousLed_A_Millis = millis(); // needs to be kept track of for each simultaneous light pattern but can it be not be global so I don't need a seperate counter for each pattern?

const byte numberOfLights = 49; // number of light strings 48 in testing 96 in production
byte numberOfArduinoPins = 25; // 24 in testing 66 in production
byte numberOfShiftRegisterPins = 25; // 24 in testing 30 in production

void setup () {
  //Set each pin connected to light string to output mode
  for (byte i = 0; i <= numberOfArduinoPins; i++)
  {
    pinMode(lightPins[i], OUTPUT);
  }

  // Prevent relays from starting up engaged
  for (byte i = 0; i <= numberOfArduinoPins; i++)
  {
    digitalWrite(lightPins[i], LOW);
  }

  // Prevent shift register controled relays from starting up engaged
  for (byte i = 0; i <= numberOfShiftRegisterPins; i++)
  {
    sr.set(i, HIGH); // HIGH in testing rig relays but LOW in production
  }
  // randomSeed(analogRead(0)); // gets a random analog read each time sketch runs

}

void loop() {
  currentMillis = millis();
  Pattern_A_State(200, 400);
  //pattern1Call();

}

void Pattern_A_State(int interval1, int interval2)
{

  int lightGroups[6][20] = {   {20, 21, 28, 29} , {11, 12, 13, 14, 22, 30, 38, 37, 36, 35, 27, 19} , {2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 46, 45, 44, 43, 42, 34, 26, 18, 10} , {1, 9, 17, 25, 33, 41, 8, 16, 24, 32, 40, 48} , {2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 46, 45, 44, 43, 42, 34, 26, 18, 10} , {11, 12, 13, 14, 22, 30, 38, 37, 36, 35, 27, 19} };

  /// seams inefficient to repeat everything below for eacht pattern.  Is there a way to make the below a function and pass each different lightGroups to it?

  int numRows = ArrayCount(lightGroups);
  int numColumns = ArrayCount(lightGroups[i]);
  switch ( state )
  {

    case 1:
      for (int j = 0; j < numColumns; j++) {
        lightcontrolon(lightGroups[i][j]);
      }

      if (currentMillis - previousLed_A_Millis >= interval1)
      {
        previousLed_A_Millis = currentMillis;
        state = 2;
      }
      break;

    case 2:
      for (int j = 0; j < numColumns; j++) {
        lightcontroloff(lightGroups[i][j]);
      }
      if (currentMillis - previousLed_A_Millis >= interval2)
      {
        previousLed_A_Millis = + currentMillis;
        i++;
        if (i >= numRows) {
          i = 0;
        }
        state = 1;
      }
      break;

      break;
  }
}

void makeReusableFunctionAttempt (int interval1, int interval2, int lightGroups[6][20], unsigned long previousLed_A_Millis  )
{
  /// seams inefficient to repeat everything below for eacht pattern.  Is there a way to make the below a function and pass each different lightGroups to it?

  int numRows = ArrayCount(lightGroups);
  int numColumns = ArrayCount(lightGroups[i]);


  switch ( state )
  {

    case 1:
      for (int j = 0; j < numColumns; j++) {
        lightcontrolon(lightGroups[i][j]);
      }

      if (currentMillis - previousLed_A_Millis >= interval1)
      {
        previousLed_A_Millis = currentMillis;
        state = 2;
      }
      break;

    case 2:
      for (int j = 0; j < numColumns; j++) {
        lightcontroloff(lightGroups[i][j]);
      }
      if (currentMillis - previousLed_A_Millis >= interval2)
      {
        previousLed_A_Millis = currentMillis;
        i++;
        if (i >= numRows) {
          i = 0;
        }
        state = 1;
      }
      break;

      break;
  }
}

void pattern1Call()
{
  int lightGroups[6][20] = {   {20, 21, 28, 29} , {11, 12, 13, 14, 22, 30, 38, 37, 36, 35, 27, 19} , {2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 46, 45, 44, 43, 42, 34, 26, 18, 10} , {1, 9, 17, 25, 33, 41, 8, 16, 24, 32, 40, 48} , {2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 46, 45, 44, 43, 42, 34, 26, 18, 10} , {11, 12, 13, 14, 22, 30, 38, 37, 36, 35, 27, 19} };
  makeReusableFunctionAttempt(200, 400, lightGroups[6][20], 30);

}

// turns lights on by pin and turns shift registers on by pin if greater than number of light pins
void lightcontrolon(byte lightno) {
  if (lightno < (numberOfArduinoPins + 1)) {
    digitalWrite(lightPins[lightno], HIGH); // HIGH trigger relays
  } else {
    byte shiftno = lightno - numberOfArduinoPins;
    sr.set(shiftno, LOW); // LOW in testing rig relays but HIGH in production
  }
}

// turns lights off by pin and turns shift registers off by pin if greater than number of light pins
void lightcontroloff(byte lightno) {
  if (lightno < (numberOfArduinoPins + 1)) {
    digitalWrite(lightPins[lightno], LOW); // HIGH trigger relays
  } else {
    byte shiftno = lightno - numberOfArduinoPins;
    sr.set(shiftno, HIGH); // HIGH in testing rig relays but LOW in production
  }

}

passing an array into a function

void pattern1Call()
{
  int lightGroups[6][20] = {   {20, 21, 28, 29} , {11, 12, 13, 14, 22, 30, 38, 37, 36, 35, 27, 19} , {2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 46, 45, 44, 43, 42, 34, 26, 18, 10} , {1, 9, 17, 25, 33, 41, 8, 16, 24, 32, 40, 48} , {2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 46, 45, 44, 43, 42, 34, 26, 18, 10} , {11, 12, 13, 14, 22, 30, 38, 37, 36, 35, 27, 19} };
  makeReusableFunctionAttempt(200, 400, lightGroups, 30);
}

when passing an array to the function you only need the name.
Try this :slight_smile:
Z