its inside a for loop i think, inside the rescheduleTimer() function
// Step Sequencer Sample Player
// Teensy 4.0 + audio board + adafruit neotrellis 4x4 rgb
// uses adafruit seesaw library https://github.com/adafruit/Adafruit_Seesaw
// Neotrellis addr (0x2E)
// to do: verify midi clock output works correctly
// to do: blink latched pads on main page
// to do: remove pink traveller on main page
// to do: activate tap LED on main page
// to do:
#include <SD.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SerialFlash.h>
#include "Adafruit_NeoTrellis.h"
#include <MIDI.h>
// ----------------------------------------FSW NEOPIXELS---------------------------------------------
#include <Adafruit_NeoPixel.h>
#define PIXEL_PIN 5 // (Led Pin)
#define PIXEL_COUNT 2
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
// ----------------------------------------FSW NEOPIXELS---------------------------------------------
// Create the Audio components. These should be created in the
// order data flows, inputs/sources -> processing -> outputs
//
AudioPlaySerialflashRaw playFlashRaw0;
AudioPlaySerialflashRaw playFlashRaw1;
AudioPlaySerialflashRaw playFlashRaw2;
AudioPlaySerialflashRaw playFlashRaw3;
AudioPlaySerialflashRaw playFlashRaw4;
AudioPlaySerialflashRaw playFlashRaw5;
AudioPlaySerialflashRaw playFlashRaw6;
AudioPlaySerialflashRaw playFlashRaw7;
AudioPlaySerialflashRaw playFlashRaw8;
AudioPlaySerialflashRaw playFlashRaw9;
AudioPlaySerialflashRaw playFlashRaw10;
AudioPlaySerialflashRaw playFlashRaw11;
AudioPlaySerialflashRaw playFlashRaw12;
AudioPlaySerialflashRaw playFlashRaw13;
AudioPlaySerialflashRaw playFlashRaw14;
AudioPlaySerialflashRaw playFlashRaw15;
AudioMixer4 mix1;
AudioMixer4 mix2;
AudioMixer4 mix3;
AudioMixer4 mix4;
AudioMixer4 mix5;
//AudioOutputAnalog dac;
AudioOutputI2S headphones;
// Create Audio connections between the components
//
AudioConnection patchCord1(playFlashRaw0, 0, mix1, 0);
AudioConnection patchCord2(playFlashRaw1, 0, mix1, 1);
AudioConnection patchCord3(playFlashRaw2, 0, mix1, 2);
AudioConnection patchCord4(playFlashRaw3, 0, mix1, 3);
AudioConnection patchCord5(playFlashRaw4, 0, mix2, 0);
AudioConnection patchCord6(playFlashRaw5, 0, mix2, 1);
AudioConnection patchCord7(playFlashRaw6, 0, mix2, 2);
AudioConnection patchCord8(playFlashRaw7, 0, mix2, 3);
AudioConnection patchCord9(playFlashRaw8, 0, mix3, 0);
AudioConnection patchCord10(playFlashRaw9, 0, mix3, 1);
AudioConnection patchCord11(playFlashRaw10, 0, mix3, 2);
AudioConnection patchCord12(playFlashRaw11, 0, mix3, 3);
AudioConnection patchCord13(playFlashRaw12, 0, mix4, 0);
AudioConnection patchCord14(playFlashRaw13, 0, mix4, 1);
AudioConnection patchCord15(playFlashRaw14, 0, mix4, 2);
AudioConnection patchCord16(playFlashRaw15, 0, mix4, 3);
AudioConnection patchCord17(mix1, 0, mix5, 0);
AudioConnection patchCord18(mix2, 0, mix5, 1);
AudioConnection patchCord19(mix3, 0, mix5, 2);
AudioConnection patchCord20(mix4, 0, mix5, 3);
//AudioConnection patchCord21(mix5, dac);
AudioConnection patchCord22(mix5, 0, headphones, 0);
AudioConnection patchCord23(mix5, 0, headphones, 1);
// Create an object to control the audio shield.
//
AudioControlSGTL5000 audioShield;
const int FlashChipSelect = 6; // digital pin for flash chip CS pin
const int SDchipSelect = 10; // Audio Shield has SD card CS on pin 10
Adafruit_NeoTrellis trellis;
unsigned long previousMillis = 0; // will store last time LED was updated
const int FSW1 = 3; // tap tempo footswitch
const int FSW2 = 2; // Start/stop footswitch
int ledState = LOW; // ledState used to set the tempo LED
int FSW1State = 0; // variable for reading the pushbutton status
int FSW2State = HIGH;
int ledState2 = -1; //this variable tracks the state of the LED, negative if off, positive if on
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 500; // the debounce time; increase if the output flickers
int lastTapState = LOW; /* the last tap button state */
unsigned long currentTimer[2] = { 1000, 1000 }; /* 60 bpm */
unsigned long timeoutTime = 0; /* this is when the timer will trigger next */
unsigned long timeoutTime2 = 0; //this is when the timer will trigger next
unsigned long downTime = 0; /* for our delayed press reset */
unsigned long indicatorTimeout; /* for our fancy "blink" tempo indicator */
unsigned long indicatorTimeout2; //variable used to determine the duration of the pad X4 blinks on state
boolean pressTimeout = false;
unsigned long lastTap = 0; /* when the last tap happened */
elapsedMillis button_hold_counter = 0;
int8_t held_button_id = -1;
int latchingMode = false;
int kitLoadPage = false;
int loadKitNum;
const byte NPATTERNS = 16;
byte patternBank[NPATTERNS][16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int currentPattern[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
MIDI_CREATE_DEFAULT_INSTANCE();
//long bpm = 60.0;
//long tempo = 1000.0 / (bpm / 60.0); // = 1000ms
float prevmillis = 0;
float interval = currentTimer[0] / 24; //interval is the number of milliseconds defined by tempo formula.
float prevblink = 0;
float blinkint = 50;
/****************************************************************************************************************/
void setup() {
MIDI.begin(MIDI_CHANNEL_OMNI);
Serial.begin(115200);
trellis.begin();
trellis.pixels.setBrightness(50);
pixels.begin(); // for start/stop and tempo LEDs
pixels.setBrightness(50);
pixels.setPixelColor(1, 220, 20, 60);
pixels.show();
pinMode(FSW1, INPUT_PULLUP);
pinMode(FSW2, INPUT_PULLUP);
AudioMemory(40);
audioShield.enable();
audioShield.volume(0.9);
// reduce the gain on mixer channels, so more than 1
// sound can play simultaneously without clipping
mix1.gain(0, 0.9);
mix1.gain(1, 0.9);
mix1.gain(2, 0.9);
mix1.gain(3, 0.9);
mix2.gain(0, 0.9);
mix2.gain(1, 0.9);
mix2.gain(2, 0.9);
mix2.gain(3, 1);
mix3.gain(0, 0.9);
mix3.gain(1, 0.9);
mix3.gain(2, 0.9);
mix3.gain(3, 0.7);
mix4.gain(0, 0.9);
mix4.gain(1, 0.9);
mix4.gain(2, 0.9);
mix4.gain(3, 0.9);
mix5.gain(1, 1);
mix5.gain(2, 1);
SPI.setSCK(14); // Audio shield has SCK on pin 14
SPI.setMOSI(7); // Audio shield has MOSI on pin 7
SerialFlash.begin(FlashChipSelect);
SD.begin(SDchipSelect);
//activate momentary pads and set callbacks
for (int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++) {
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
trellis.registerCallback(i, momentary);
}
//do a little animation to show we're on
for (uint16_t i = 0; i < trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, Wheel(map(i, 0, trellis.pixels.numPixels(), 0, 255)));
trellis.pixels.show();
delay(25);
}
for (uint16_t i = 0; i < trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x000000);
trellis.pixels.show();
delay(25);
}
}
int pad = -1;
/****************************************************************************************************************/
void copyFiles() {
delay(100);
Serial.println(F("Copy all files from SD Card to SPI Flash"));
File rootdir;
if (loadKitNum == 0) {
rootdir = SD.open("0"); // "mySamples = 0" "shortSamples = 1" "brushSamples = 2" "amb samples = 3" "/" = root
}
if (loadKitNum == 1) {
rootdir = SD.open("1"); // "mySamples = 0" "shortSamples = 1" "brushSamples = 2" "amb samples = 3" "/" = root
}
if (loadKitNum == 2) {
rootdir = SD.open("2"); // "mySamples = 0" "shortSamples = 1" "brushSamples = 2" "amb samples = 3" "/" = root
}
if (loadKitNum == 3) {
rootdir = SD.open("3"); // "mySamples = 0" "shortSamples = 1" "brushSamples = 2" "amb samples = 3" "/" = root
}
if (loadKitNum == 4) {
rootdir = SD.open("4"); // "mySamples = 0" "shortSamples = 1" "brushSamples = 2" "amb samples = 3" "/" = root
}
if (loadKitNum == 5) {
rootdir = SD.open("5"); // "mySamples = 0" "shortSamples = 1" "brushSamples = 2" "amb samples = 3" "/" = root
}
if (loadKitNum == 6) {
rootdir = SD.open("6"); // "mySamples = 0" "shortSamples = 1" "brushSamples = 2" "amb samples = 3" "/" = root
}
while (1) {
// open a file from the SD card
Serial.println();
File f = rootdir.openNextFile();
if (!f) break;
const char *filename = f.name();
Serial.print(filename);
Serial.print(F(" "));
unsigned long length = f.size();
Serial.println(length);
// check if this file is already on the Flash chip
if (SerialFlash.exists(filename)) {
// delete the copy on the Flash chip, if different
Serial.println(F(" delete file from Flash chip"));
SerialFlash.remove(filename);
}
// create the file on the Flash chip and copy data
if (SerialFlash.create(filename, length)) {
SerialFlashFile ff = SerialFlash.open(filename);
if (ff) {
Serial.print(F(" copying"));
// copy data loop
unsigned long count = 0;
unsigned char dotcount = 9;
while (count < length) {
char buf[256];
unsigned int n;
n = f.read(buf, 256);
ff.write(buf, n);
count = count + n;
Serial.print(".");
if (++dotcount > 100) {
Serial.println();
dotcount = 0;
}
}
ff.close();
if (dotcount > 0) Serial.println();
} else {
Serial.println(F(" error opening freshly created file!"));
}
} else {
Serial.println(F(" unable to create file"));
}
f.close();
}
rootdir.close();
delay(10);
Serial.println(F("Finished All Files"));
kitLoadPage = false;
//clearTrellis();
for (uint16_t i = 0; i < trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, Wheel(map(i, 0, trellis.pixels.numPixels(), 0, 255)));
trellis.pixels.show();
delay(25);
}
for (uint16_t i = 0; i < trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x000000);
trellis.pixels.show();
delay(25);
}
}
/****************************************************************************************************************/
void clockOut() {
unsigned long currentMillis = millis();
if (currentMillis - prevmillis >= interval) {
prevmillis = currentMillis;
MIDI.sendClock();
}
}
/****************************************************************************************************************/
void loop() {
trellis.read();
startStopFSW();
runSeq();
clockOut();
}
/****************************************************************************************************************/
void startStopFSW() {
//sample the state of the button - is it pressed or not?
FSW2State = digitalRead(FSW2);
//filter out any noise by setting a time buffer
if ( (millis() - lastDebounceTime) > debounceDelay) {
//if the button has been pressed, lets toggle the LED from "off to on" or "on to off"
if ( (FSW2State == LOW) && (ledState2 < 0) ) {
// turn LED lawn green:
pixels.setPixelColor(1, 124, 252, 0);
pixels.show();
Serial.println("Start");
//MIDI.sendStart();
pad = -1;
ledState2 = -ledState2; //now the LED is on, we need to change the state
lastDebounceTime = millis(); //set the current time
}
else if ( (FSW2State == LOW) && (ledState2 > 0) ) {
// LED crimson
pixels.setPixelColor(1, 220, 20, 60);
pixels.show();
Serial.println("Stop");
//MIDI.sendStop();
ledState2 = -ledState2; //
lastDebounceTime = millis(); //set the current time
}
}
}
/****************************************************************************************************************/
void loadKitPage() { // Green K landing page
ledState2 = -1;
kitLoadPage = true;
pixels.setPixelColor(1, 220, 20, 60); // start LED off (red)
pixels.setPixelColor(0, 20, 55, 155); // kit LED (blue)
pixels.show();
clearTrellis();
trellis.pixels.setPixelColor(0, 0, 255, 0); // letter "K" (green) Load Kit Page
trellis.pixels.setPixelColor(2, 0, 255, 0);
trellis.pixels.setPixelColor(3, 0, 255, 0);
trellis.pixels.setPixelColor(4, 0, 255, 0);
trellis.pixels.setPixelColor(5, 0, 255, 0);
trellis.pixels.setPixelColor(8, 0, 255, 0);
trellis.pixels.setPixelColor(10, 0, 255, 0);
trellis.pixels.setPixelColor(12, 0, 255, 0);
trellis.pixels.setPixelColor(15, 0, 255, 0);
trellis.pixels.show();
}
/****************************************************************************************************************/
void runSeq() {
int tapState = digitalRead(FSW1);
if ( tapState == LOW && tapState != lastTapState ) /* button up->down */
{
tap(); /* we got a HIGH-LOW transition, call our tap() function */
downTime = millis();
pressTimeout = false;
}
/* press-and-hold detection start */
if ( tapState == LOW ) /* button is down... */
{
/* if we have not triggered before, and the down time is more than 2 seconds... */
/* 2000 = 2000ms = 2 seconds */
if ( !pressTimeout && ((millis() - downTime ) > 1000 ))
{
/* Load Kit Here */
loadKitPage();
/* Load Kit Here */
currentTimer[0] = currentTimer[1]; /* dont let long press change current tempo */
rescheduleTimer(); /* start the timer */
pressTimeout = true; /* make sure we don't get called again during this press */
}
}
/* press-and-hold detection end */
lastTapState = tapState; /* keep track of the last state, for transition detection */
if (ledState2 > 0) // if footswitch start
{
/* check for timer timeout */
if ( millis() >= timeoutTime2 ) // timeoutTime2 is 4x faster than timeoutTime
{
/* timeout happens */
indicatorTimeout = millis() + 20; /* this sets the time when the LED goes off */
rescheduleTimer(); /* and reschedule the timer to keep the pace */
}
/* display the tap blink on Trellis */
if ( millis() < indicatorTimeout)
{
if (pad == held_button_id && latchingMode == true)
{
trellis.pixels.setPixelColor(held_button_id, 0, 255, 0); // Make held trellis LED green as pink traveller passes
trellis.pixels.show();
}
else
{
trellis.pixels.setPixelColor(pad, 220, 20, 60); // The Pink Traveller
trellis.pixels.show();
}
}
if (currentPattern[pad] == 1 && latchingMode == true) // if pad is latched on in array
{
trellis.pixels.setPixelColor(pad, 0x0000ff); // make latched LEDs Blue again after pink traveller passes
}
else {
trellis.pixels.setPixelColor(pad, 0); // Turn off pink traveller after it passes
}
} // if footswitch start
if (ledState2 < 0) // if footswitch stop
{
/* check for timer timeout */
if ( millis() >= timeoutTime ) // timeoutTime2 is 4x faster than timeoutTime
{
/* timeout happens */
indicatorTimeout = millis() + 20; /* this sets the time when the LED goes off */
rescheduleTimer(); /* and reschedule the timer to keep the pace */
}
/* display the tap blink on LED */
if ( millis() < indicatorTimeout)
{
pixels.setPixelColor(0, 0, 255, 255); // Tempo LED on aqua
pixels.show();
}
else {
pixels.setPixelColor(0, 0, 0, 0); // Tempo LED off
pixels.show();
}
}
}
/****************************************************************************************************************/
void tap()
{
/* we keep two of these around to average together later */
currentTimer[1] = currentTimer[0];
currentTimer[0] = millis() - lastTap; /* current = duration since last tap */
lastTap = millis();
timeoutTime = 0; /* force the trigger to happen immediately - sync and blink! */
timeoutTime2 = 0; /* force the trigger to happen immediately - sync and blink! */
}
/****************************************************************************************************************/
void rescheduleTimer()
{
/* set the timer to go off again when the time reaches the
timeout. The timeout is all of the "currentTimer" values averaged
together, then added onto the current time. When that time has been
reached, the next tick will happen...
*/
timeoutTime = millis() + ((currentTimer[0] + currentTimer[1]) / 2); // Neopixel LED speed
timeoutTime2 = millis() + ((currentTimer[0] + currentTimer[1]) / 8); // Neotrellis speed x4 faster
interval = currentTimer[0] / 24;
if (ledState2 > 0) // if footswitch start
{
pad++;
pad %= 16;
if (patternBank[0][pad] == 1) // if pad is latched on in array
{
playSound(0);
trellis.pixels.setPixelColor(0, Wheel(map(0, 0, trellis.pixels.numPixels(), 0, 255))); // LED on
trellis.pixels.show();
unsigned long currentblink = millis();
if (currentblink - prevblink >= blinkint) {
prevblink = currentblink;
trellis.pixels.setPixelColor(0, 0); // Turn off LED
trellis.pixels.show();
}
}
if (patternBank[1][pad] == 1) // if pad is latched on in array
{
playSound(1);
}
if (patternBank[2][pad] == 1) // if pad is latched on in array
{
playSound(2);
}
if (patternBank[3][pad] == 1) // if pad is latched on in array
{
playSound(3);
}
if (patternBank[4][pad] == 1) // if pad is latched on in array
{
playSound(4);
}
if (patternBank[5][pad] == 1) // if pad is latched on in array
{
playSound(5);
}
if (patternBank[6][pad] == 1) // if pad is latched on in array
{
playSound(6);
}
if (patternBank[7][pad] == 1) // if pad is latched on in array
{
playSound(7);
}
if (patternBank[8][pad] == 1) // if pad is latched on in array
{
playSound(8);
}
if (patternBank[9][pad] == 1) // if pad is latched on in array
{
playSound(9);
}
if (patternBank[10][pad] == 1) // if pad is latched on in array
{
playSound(10);
}
if (patternBank[11][pad] == 1) // if pad is latched on in array
{
playSound(11);
}
if (patternBank[12][pad] == 1) // if pad is latched on in array
{
playSound(12);
}
if (patternBank[13][pad] == 1) // if pad is latched on in array
{
playSound(13);
}
if (patternBank[14][pad] == 1) // if pad is latched on in array
{
playSound(14);
}
if (patternBank[15][pad] == 1) // if pad is latched on in array
{
playSound(15);
}
// trellis.pixels.setPixelColor(0, 0); // Turn off LED
// trellis.pixels.show();
}
}
/****************************************************************************************************************/
void clearTrellis() {
for (uint16_t i = 0; i < trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0); // all trellis leds off
}
}
/****************************************************************************************************************/
TrellisCallback momentary(keyEvent evt) { // Trellis Momentary Mode, Main Page, Start Page
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) { // Check is the pad pressed?
Serial.println("NeoPixel Pressed");
if (kitLoadPage == false) {
if (evt.bit.NUM >= 0 && evt.bit.NUM <= 15) { // push pads = sounds
playSound(evt.bit.NUM);
delay(10); // freezes without
}
}
if (kitLoadPage == true) {
if (evt.bit.NUM >= 0 && evt.bit.NUM <= 15) { // push pads = sounds
loadKitNum = evt.bit.NUM;
Serial.println(loadKitNum);
copyFiles();
}
}
trellis.pixels.setPixelColor(evt.bit.NUM, Wheel(map(evt.bit.NUM, 0, trellis.pixels.numPixels(), 0, 255))); //on rising
//reset timer for detecting a long press, which will take us to latching pattern page if held for 0.8secs
button_hold_counter = 0;
held_button_id = evt.bit.NUM;
}
else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) { // or is the pad released?
//Serial.println("NeoPixel Released");
trellis.pixels.setPixelColor(evt.bit.NUM, 0); //off falling
if (held_button_id == evt.bit.NUM) { // if the held button has been released,
if (button_hold_counter >= 800) { // if the button was held for 800 ms
Serial.println("Long press detected");
// *Load pattern input page for pressed pad HERE*
for (int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++) { // Activate latching trellis buttons
trellis.registerCallback(i, latching);
}
latchingMode = true;
loadPattern(held_button_id);
}
else {
held_button_id = -1; // Resetting the held button id means we are no longer tracking that long press.
}
}
}
trellis.pixels.show(); // Turn on/off the neopixels
return 0;
}
/****************************************************************************************************************/
TrellisCallback latching(keyEvent evt) { // Trellis Latching Mode
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) { // if any pad button is pressed
//reset timer for detecting a long press, which will take us to momentary main page if held for 0.8secs
button_hold_counter = 0;
{
if (currentPattern[evt.bit.NUM] == 0) {
trellis.pixels.setPixelColor(evt.bit.NUM, 0x0000FF); // if off latch on
currentPattern[evt.bit.NUM] = 1; // save state to array
savePattern(held_button_id); // save array to array bank
}
else if (currentPattern[evt.bit.NUM] == 1) {
trellis.pixels.setPixelColor(evt.bit.NUM, 0); // if on turn off
currentPattern[evt.bit.NUM] = 0; // save state to array
savePattern(held_button_id); // save array to array bank
}
trellis.pixels.show();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// long press any pad to exit pattern mode without changing current pattern
if (button_hold_counter >= 800) {
Serial.println("Long press detected, loading main page");
if (currentPattern[evt.bit.NUM] == 1) {
currentPattern[evt.bit.NUM] = 0;
savePattern(held_button_id); // save array to array bank
}
else if (currentPattern[evt.bit.NUM] == 0) { // if on turn off
currentPattern[evt.bit.NUM] = 1;
savePattern(held_button_id); // save array to array bank
}
// long press any pad to exit pattern mode without changing current pattern
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
for (int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++) { // Activate momentary trellis buttons
trellis.registerCallback(i, momentary);
}
clearTrellis();
latchingMode = false;
}
trellis.pixels.show();
return 0;
}
/****************************************************************************************************************/
void playSound(int num) {
char fileName[5];
sprintf(fileName, "%d.raw", num);
switch (num) {
case 0: playFlashRaw0.play(fileName); break;
case 1: playFlashRaw1.play(fileName); break;
case 2: playFlashRaw2.play(fileName); break;
case 3: playFlashRaw3.play(fileName); break;
case 4: playFlashRaw4.play(fileName); break;
case 5: playFlashRaw5.play(fileName); break;
case 6: playFlashRaw6.play(fileName); break;
case 7: playFlashRaw7.play(fileName); break;
case 8: playFlashRaw8.play(fileName); break;
case 9: playFlashRaw9.play(fileName); break;
case 10: playFlashRaw10.play(fileName); break;
case 11: playFlashRaw11.play(fileName); break;
case 12: playFlashRaw12.play(fileName); break;
case 13: playFlashRaw12.play(fileName); break;
case 14: playFlashRaw14.play(fileName); break;
case 15: playFlashRaw15.play(fileName); break;
}
}
/****************************************************************************************************************/
void loadPattern(byte patternToLoad)
{
Serial.print("loading pattern "); Serial.println(patternToLoad);
for (byte ii = 0; ii < 16; ii++)
currentPattern[ii] = patternBank[patternToLoad][ii];
for (int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++) { // load stored pattern
if (currentPattern[i] == 1) {
trellis.pixels.setPixelColor(i, 0x0000FF); // stored blue leds on
}
}
trellis.pixels.setPixelColor(held_button_id, 0, 255, 0); // held button green
}
/****************************************************************************************************************/
void savePattern(byte patternToSave)
{
Serial.print("saving pattern "); Serial.println(patternToSave);
Serial.print("held button id "); Serial.println(held_button_id);
for (byte ii = 0; ii < 16; ii++)
patternBank[patternToSave][ii] = currentPattern[ii];
}
/****************************************************************************************************************/
// Input a value 0 to 255 to get a rainbow color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if (WheelPos < 85) {
return trellis.pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if (WheelPos < 170) {
WheelPos -= 85;
return trellis.pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return trellis.pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
return 0;
}
/****************************************************************************************************************/