Song and led increment problem

Hi,
I am trying to light up some leds while playing a song. The idea is that for every note a led will light up and then when all leds are lit, they should blink and then turn off. The song should continue playing and the leds will do another loop.

Problems: The if loop within the for loop does not seem to work. Also, only every second led lights with a faint glow. There are no hardware issues.


int ledPins= 3;
int allPins[] = {3,4,5,6,7,8};

#include "pitches.h"
           
// notes in the melody:
int melody[] = {
  NOTE_G4, NOTE_E5, NOTE_D5,NOTE_C5, NOTE_G4, NOTE_G4, NOTE_E5,NOTE_D5,NOTE_C5,NOTE_A4,
  
  NOTE_A4, NOTE_F5, NOTE_E5,NOTE_D5, NOTE_B4, NOTE_G5, NOTE_G5,NOTE_F5,NOTE_D5,NOTE_E5,
  
  NOTE_G4, NOTE_E5, NOTE_D5,NOTE_C5, NOTE_G4, NOTE_G4,NOTE_E5,NOTE_D5,NOTE_C5,NOTE_A4,
  
   NOTE_A4, NOTE_F5,NOTE_E5, NOTE_D5, NOTE_G5,NOTE_G5,NOTE_G5,NOTE_G5,NOTE_G5,NOTE_A5,NOTE_G5,NOTE_F5,NOTE_D5,NOTE_C5,NOTE_D5,
  
  NOTE_E5, NOTE_E5, NOTE_E5,NOTE_E5, NOTE_E5, NOTE_E5,NOTE_E5,NOTE_G5,NOTE_C5,NOTE_D5,NOTE_E5,
  
  NOTE_F5, NOTE_F5, NOTE_F5,NOTE_F5, NOTE_F5, NOTE_F5,NOTE_E5,NOTE_E5,NOTE_E5,NOTE_E5,NOTE_E5,NOTE_D5,NOTE_D5,NOTE_E5,NOTE_D5,NOTE_G5,

  NOTE_E5, NOTE_E5, NOTE_E5,NOTE_E5, NOTE_E5, NOTE_E5,NOTE_E5,NOTE_G5,NOTE_C5,NOTE_D5,NOTE_E5,
  
  NOTE_F5, NOTE_F5, NOTE_F5,NOTE_F5, NOTE_F5, NOTE_F5,NOTE_E5,NOTE_E5,NOTE_E5,NOTE_E5,NOTE_G5,NOTE_G5,NOTE_F5,NOTE_D5,NOTE_C5
};


// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  8,8,8,8,2,8,8,8,8,2,
  8,8,8,8,2,8,8,8,8,2,
  8,8,8,8,2,8,8,8,8,2,
  8,8,8,8,8,8,8,16,16,8,8,8,8,4,4,
  8,8,4,8,8,4,8,8,8,8,2,
  8,8,8,16,16,8,8,8,16,16,8,8,8,8,4,4,
  8,8,4,8,8,4,8,8,8,8,2,
  8,8,8,16,16,8,8,8,16,16,8,8,8,8
};
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(allPins, OUTPUT);
}

void loop() {
  {
  // iterate over the notes of the melody:
  for (int thisNote = 0; thisNote < 98; thisNote++ && ledPins++ ) {

    // to calculate the note duration, take one second
    // divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(13, melody[thisNote], noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration +50;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(13);
   
   
if (ledPins < 9) {
   digitalWrite(ledPins, HIGH);
   }
   else{
  delay(10);
  digitalWrite(allPins, LOW);
  delay(20);
  digitalWrite(allPins, HIGH);
  delay(20);
  digitalWrite(allPins, LOW);
  int ledPins = 3;
  }

    Serial.println (ledPins);
  }
}
  // put your main code here, to run repeatedly:

}

Right there

and

        digitalWrite(allPins, LOW);
        delay(20);
        digitalWrite(allPins, HIGH);
        delay(20);
        digitalWrite(allPins, LOW);

Can you explain :)?

allPins is an array

So what is the best way to digital write several ports with a simple command? I understand now that you cannot digitalWrite an array or put a whole array as output.

And thank you

Thank you

The easiest way is to iterate through the array using a for loop and set the pinMode or output of each pin in the array.
There are other ways depending on which pins you are using

So adding a for loop within the for loop?

Yes, that's one way.

Better to put the for loop that deals with the pins in a function and call that with a parameter that indicates the required state

I am new to this, do you have the time to give an example? I would really appreciate it, with the function part I mean

for (auto& pin :allPins)
  pinMode (pin, OUTPUT);

Something like this (untested)

void setPinStates(byte state)
{
  byte numberOfPins = sizeof(allPins) / sizeof(allPins[0]);
  for (int p = 0; p < numberOfPins; p++)
  {
    pinMode(allPins[p], state);
  }
}

Call it like this

setPinStates(LOW);  //or HIGH, of course

aaaaaa so clever! So the second void function is an state iterator that sequence through the array when called in the first void loop?

You can call it from wherever you like.

Why is the byte part needed?

If you mean

 byte numberOfPins = sizeof(allPins) / sizeof(allPins[0]);

It calculates how many entries there are in the array so if you were to add another one the function would still work.

As it is, you have declared the array as ints when the values it holds will never be larger than 255 so it could be an array of bytes. The calculation of the number of entries works with any data type

...except you wouldn't normally call pinMode with a value of LOW.