// tone sequencer version 1
// https://forum.arduino.cc/t/how-to-setup-array-structure-for-melody-sequences/1404240
// - char arrays are flat (one long string, no comma separators)
// - thisnote = row * column + column
// - rows must be the same length
#include <avr/pgmspace.h> // offload arrays from RAM to PROGMEM
bool firstTime = 1; // flag for printing Loop Time
// s or 6 = 1/16, e or 8 = 1/8, q or 4 = 1/4, t or 3 = 1/3, h or 2 = 1/2, w or 1 = 1/1, r = rest
unsigned long columnSpeed = 50; // milliseconds per element - speed control
const char startup[] PROGMEM = { // single-dimension array of sequenced elements
".q...." // G4 using q for quarter note
"...qq." // F4
"..q..q" // E4
"q....." // C4
};
const char shutdown[] PROGMEM = {
"....4." // G4 using 4 for quarter note
".44..." // F4
"4..4.." // E4
".....4" // C4
};
void setup() {
pinMode(tonePin, OUTPUT);
}
void loop() {
sequencer(startup, sizeof(startup));
sequencer(shutdown, sizeof(shutdown));
}
void sequencer(char list[], int listLength) {
for (int col = 0; col < listLength; col++) {
for (int row = 0; row < ledCount; row++) {
switch (pgm_read_byte(&list[row * listLength + col])) { // locate element with row and column
case '*': digitalWrite(ledPin[row], HIGH); break; // turn LED ON
case '.': digitalWrite(ledPin[row], LOW); break; // turn LED OFF
case '6':
case 's': duration = 1000 / 16; break;
case '4':
case 'q': duration = 1000 / 4; break;
case '8':
case 'e': duration = 1000 / 8; break;
case '3':
case 't': duration = 1000 / 3; break;
case '2':
case 'h': duration = 1000 / 2; break;
case '1':
case 'w': duration = 1000 / 1; break;
default: break;
}
tone (tonePin, note, duration)
}
delay(columnSpeed); // regulate the speed of the sequence
}
}