Variable speed LED array- revisited

Hi , would like to extend this sketch to allow for 4 patterns to be controlled individually.
Each pattern using the 4 bit truth table.
Each pattern using a different variation (sequence)
Each pattern using a pot to vary speed.
I'm using an Arduino Due.
I imagine this to run all 4 patterns over and over all in the one loop.
Is this possible?
What tutorial would assist me?
Thanks for listening.

int potPin = A0;
int potValue;
int delayValue;

//  LED patterns here

unsigned char led_pattern[] = {

  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,



};

void setup() {

  // set pin 8 to 11 as outputs
  for (int i = 8; i <= 11; i++) {
    pinMode(i, OUTPUT);
  }
}

void loop() {

  potValue = analogRead(A0);
  delayValue = map(potValue, 0, 1023, 25, 500);

  DisplayPattern(led_pattern, sizeof(led_pattern));
  delay(delayValue);
}

void DisplayPattern(unsigned char *pattern, int num_patterns)
{
  static int pattern_num = 0; // keeps count of patterns
  unsigned char mask = 1;     // for testing each bit in pattern

  // LEDs on pin 8 to pin 11
  for (int i = 8; i <= 11; i++) {
    // check if bit in pattern is set or not and switch LED accordingly
    if (pattern[pattern_num] & mask) {
      digitalWrite(i, HIGH);
    }
    else {
      digitalWrite(i, LOW);
    }
    mask <<= 1;   // adjust mask for checking next bit in pattern
  }
  pattern_num++;  // move to next pattern for next function call
  // keep pattern within limits of pattern array
  if (pattern_num >= num_patterns) {
    pattern_num = 0;
  }
}

Are they all using the same pattern ?
At the same speed ?

Hi , thanks for the reply.
Yes , using the same pattern , at this stage.
Speed would be varied for each array via each pot.

looks like this works
each call to Displaypattern() sets the 4 LEDs to the lower 4 bits of each led_pattern [] value.

don't understand what 4 arrays you're referring to

ok, let’s start by making 4 arrays, even though you want them to be the same pattern, that will inevitably change in the future…

Somewhere you’re going to find another 22 pins for the additional LEDs.
Then you’re going to give them meaningful names rather than using pin numbers..

Pattern_num can refer to the four (unique) patterns, but the index into the pattern array…. that can be LED_index or something more relevant.

Your sequencing and bit shifting can stay mostly the same.

You may like to think about smart LED strips, which can give you a lot more display options… colours, brightness etc, and a new project.

What is that?

Hi , aarg--- typo.

lastchancename and gcjr thanks for your input.

I have edited the original post.
Hopefully this will make more sense.
Best regards.

To make them all run independently, you need to look at the Blink Without Delay example in the IDE (File->examples->02.digital->Blink Without Delay) to get rid of the delay() call. You can not use delay() and have 4 things happening "simultaneously".

Thanks blh64 , so its doable.
So the pots will change millis not delay.
Best regards

They will modify four separate mS values… not millis() itself !

Look into arrays and structs to collect all the loose chaff into manageable blocks

This sketch allowed 4 LED's to be controlled , each with their own variable mS values.

// each "event" (LED) gets their own tracking variable
unsigned long previousMillisLED8 = 0;
unsigned long previousMillisLED9 = 0;
unsigned long previousMillisLED10 = 0;
unsigned long previousMillisLED11 = 0;

// different intervals for each LED
int intervalLED8 = 250;
int intervalLED9 = 500;
int intervalLED10 = 750;
int intervalLED11 = 1000;

// each LED gets a state varaible
boolean LED8state = false;     // the LED will turn ON in the first iteration of loop()
boolean LED9state = false;     // need to seed the light to be OFF
boolean LED10state = false;     // the LED will turn ON in the first iteration of loop()
boolean LED11state = false;

void setup() {
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

}
void loop() {
 potValue = analogRead(A0);
 intervalValue = map(potValue, 0, 1023, 25, 500);
  
  
  // get current time stamp
  // only need one for both if-statements
  unsigned long currentMillis = millis();

  // time to toggle LED on Pin 8?
  if ((unsigned long)(currentMillis - previousMillisLED8) >= intervalLED8) {
    LED8state = !LED8state;
    digitalWrite(8, LED8state);
    // save current time to pin 8's previousMillis
    previousMillisLED8 = currentMillis;
  }

  // time to toggle LED on Pin 9?
  if ((unsigned long)(currentMillis - previousMillisLED9) >= intervalLED9) {
    LED9state = !LED9state;
    digitalWrite(9, LED9state);
    // save current time to pin 9's previousMillis
    previousMillisLED9 = currentMillis;
  }

  // time to toggle LED on Pin 10?
  if ((unsigned long)(currentMillis - previousMillisLED10) >= intervalLED10) {
    LED10state = !LED10state;
    digitalWrite(10, LED10state);
    // save current time to pin 10's previousMillis
    previousMillisLED10 = currentMillis;
  }

  // time to toggle LED on Pin 11?
  if ((unsigned long)(currentMillis - previousMillisLED11) >= intervalLED11) {
    LED11state = !LED11state;
    digitalWrite(11, LED11state);
    // save current time to pin 11's previousMillis
    previousMillisLED11 = currentMillis;
  }
}
// different intervals for each LED
int intervalLED8 = 250;
int intervalLED9 = 500;
int intervalLED10 = 750;
int intervalLED11 = 1000;


The original quest was to have 4 sets of 4 LED's each with it's own Pattern that could be varied in speed via a pot.

int potPin = A0;
int potValue;
int delayValue;

//  LED patterns here

unsigned char led_pattern[] = {

  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,



};

void setup() {

  // set pin 8 to 11 as outputs
  for (int i = 8; i <= 11; i++) {
    pinMode(i, OUTPUT);
  }
}

void loop() {

  potValue = analogRead(A0);
  delayValue = map(potValue, 0, 1023, 1, 50);

  DisplayPattern(led_pattern, sizeof(led_pattern));
  delay(delayValue);
}

void DisplayPattern(unsigned char *pattern, int num_patterns)
{
  static int pattern_num = 0; // keeps count of patterns
  unsigned char mask = 1;     // for testing each bit in pattern

  // LEDs on pin 8 to pin 11
  for (int i = 8; i <= 11; i++) {
    // check if bit in pattern is set or not and switch LED accordingly
    if (pattern[pattern_num] & mask) {
      digitalWrite(i, HIGH);
    }
    else {
      digitalWrite(i, LOW);
    }
    mask <<= 1;   // adjust mask for checking next bit in pattern
  }
  pattern_num++;  // move to next pattern for next function call
  // keep pattern within limits of pattern array
  if (pattern_num >= num_patterns) {
    pattern_num = 0;
  }
}

The above sketch worked great for one set of 4 LED's , but as pointed out by blh64 in #8 ,it had no chance of having 4 things happen simultaneously, while using "delay".
The ideal for me ,would be to have 4 sets of 4 LED's , each with their own pattern and own pot controlling the rate of change.
My first sketch had one set.
Can this be done by removing delay and replacing it with millis?

Yes.

arrays are your friends...

#define SETS 4
const int LEDpins[SETS] = { 8, 9, 10, 11 };
const int potPins[SETS] = { A0, A1, A2, A3 };


// each "event" (LED) gets their own tracking variable
unsigned long previousMillis[SETS];

// different intervals for each LED
unsigned int interval[SETS];

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

void loop() {

  unsigned long currentMillis = millis();

  for ( int i = 0; i < SETS; ++i ) {
    int potValue = analogRead( potPins[i]);
    interval[i] = map(potValue, 0, 1023, 25, 500);

    if (currentMillis - previousMillis[i] >= interval[i]) {
      digitalWrite(LEDpins[i], !digitalRead(LEDpins[i]));
      previousMillis[i] = currentMillis;
    }
  }
}

For this sketch to work, you will need 4 pots attached to A0...A3

blh64 thanks for your help.

The original sketch x 4 is the quest.
That way i have only 4 pots controlling a total of 16 LED's.
A different pattern can be set for each set of 4 LED's.
The problem is "delay".
Can the original sketch be modified to use "millus" instead of delay?

int potPin = A0;
int potValue;
int delayValue;

//  LED patterns here

unsigned char led_pattern[] = {

  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,



};

void setup() {

  // set pin 8 to 11 as outputs
  for (int i = 8; i <= 11; i++) {
    pinMode(i, OUTPUT);
  }
}

void loop() {

  potValue = analogRead(A0);
  delayValue = map(potValue, 0, 1023, 1, 50);

  DisplayPattern(led_pattern, sizeof(led_pattern));
  delay(delayValue);
}

void DisplayPattern(unsigned char *pattern, int num_patterns)
{
  static int pattern_num = 0; // keeps count of patterns
  unsigned char mask = 1;     // for testing each bit in pattern

  // LEDs on pin 8 to pin 11
  for (int i = 8; i <= 11; i++) {
    // check if bit in pattern is set or not and switch LED accordingly
    if (pattern[pattern_num] & mask) {
      digitalWrite(i, HIGH);
    }
    else {
      digitalWrite(i, LOW);
    }
    mask <<= 1;   // adjust mask for checking next bit in pattern
  }
  pattern_num++;  // move to next pattern for next function call
  // keep pattern within limits of pattern array
  if (pattern_num >= num_patterns) {
    pattern_num = 0;
  }
}

Again thanks for your help.

Yes it can. Give it a try. See how far you get and where you run into trouble. Reply to this thread with your best attempt, and any errors you may get. Then, folks will help.