Neotrellis + Audio Board I2C Lock Up

Leetut

Member
I’m making a step sequencer, using a teensy4.0 + audio board + flash chip, and an adafruit neotrellis board connected via i2c to trigger flash chip raw samples, unfortunately it all locks up / freezes if playing audio while i have a moving LED on the neotrellis,
if i rename the raw files in the sketch to file names that don't exist (so no sound is played) the problem never happens,
if i use the moving LED to trigger pads the sound is distorted until the lock up happens then sounds play without distortion,
but its all locked up, cant be stopped and needs a reboot,
anyone experience this? or have any idea what is going on?



Code:
// Step Sequencer Sample Player
// Teensy 4.0 + audio board + adafruit neotrellis rgb
// uses adafruit seesaw library https://github.com/adafruit/Adafruit_Seesaw

#include <Audio.h>
//#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include "Adafruit_NeoTrellis.h"


// to do: audio
// to do: pink traveller + fast tempo + play pads fast causes freeze up, could be  spi transfer problem
// to do: pink traveller + slow tempo + play pads causes freeze up less often

// ----------------------------------------FOOTSWITCH 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);
// ----------------------------------------FOOTSWITCH 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


Adafruit_NeoTrellis trellis;

int FSW2 = 2;  // Start/stop footswitch
int FSW2State = HIGH;
int button1 = 3; // tap footswitch
int pad = -1;
int ssLedState = -1; //this variable tracks the startStop LED, negative if off, positive if on
int ttLedState = LOW; // ledState used to set the tempo LED
int lastTapState = LOW;  //the last tap button state
int activeButton = 0;
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 500;    // the debounce time; increase if the output flickers
unsigned long currentTimer[2] = { 750, 750 };  // array of most recent tap counts
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 lastTap = 0; //this vairable determines the time of the most recent tap, used when recording data when button is pressed
unsigned long indicatorTimeout; //variable used to determine the duration of the led blinks on state
unsigned long indicatorTimeout2; //variable used to determine the duration of the pad X4 blinks on state

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,};


elapsedMillis button_hold_counter = 0;
int8_t held_button_id = -1;

int latchingMode = false;

int currentPad;

/****************************************************************************************************************/

void setup() {
  Serial.begin(9600);
  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( button1, INPUT_PULLUP );   //tap tempo button
  pinMode(FSW2, INPUT_PULLUP);
  Serial.println("NeoPixel Trellis started");

  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);

  //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);
  }
}

/****************************************************************************************************************/
void loop() {
  trellis.read();
  delay(10); // stops freeze up in stop mode when playing pads quickly
  startStopFSW();
  runSeq();
}

/****************************************************************************************************************/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void playSamples() {
  // if pad has a pattern, play that pads sample when pink traveller hits a latched pad
  // on main screen only, blink samples pad led everytime its sample is triggered
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/****************************************************************************************************************/

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 runSeq() { // tap tempo & pink traveller
  if (ssLedState > 0) { // if footswitch start
    int tapState = digitalRead( button1 );   // button is first pressed down
    if ( tapState == LOW && tapState != lastTapState ) {
      currentTimer[1] = currentTimer[0];    // this takes the tap time done before it (measured in millis), sets it one back in the array,
      currentTimer[0] = millis() - lastTap;     // and then sets the other slot of the array to the length of the most recent tap time
      lastTap = millis();
      timeoutTime = 0;
      timeoutTime2 = 0;
    }

    lastTapState = tapState; //variable used to determine the most recent state of the button

    if ( millis() >= timeoutTime )  {     //checks to see if it is time to turn on the tap fsw LED
      indicatorTimeout = millis() + 150;  //determines the length of time that the LED is on
      //this will set the new tempo
      timeoutTime = millis() + ((currentTimer[0] + currentTimer[1]) / 2);
    }

    if ( millis() >= timeoutTime2 )  {    //checks to see if it is time to turn on the trellis LEDs
      indicatorTimeout2 = millis() + 150;  //determines the length of time that the trellis LED is on
      //this will set the new tempo
      timeoutTime2 = millis() + ((currentTimer[0] + currentTimer[1]) / 8); // Divide by 8 to make it 4 times faster
      pad++;
      pad %= 16;
    }

    //turns on tempo led for the length of indicatorTimeout and then turns it off
    if ( millis() < indicatorTimeout ) {
      pixels.setPixelColor(0, 0, 255, 255); // Tempo LED on
      pixels.show();
    }

    pixels.setPixelColor(0, 0, 0, 0);  // Tempo LED off
    pixels.show();


    //turns on trellis led for the length of indicatorTimeout, then turns it off, then moves to next led
    if ( millis() < indicatorTimeout2 ) {
      if (pad == held_button_id && latchingMode == true) {
        trellis.pixels.setPixelColor(held_button_id, 0, 255, 0);  //  Make held LED green as pink traveller passes
        trellis.pixels.show();

      } else {

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        trellis.pixels.setPixelColor(pad, 220, 20, 60); // The Pink Traveller
        trellis.pixels.show();
        // playSound(1); // not distorted
        // playSamples();
        // when  pink traveller lands on a pad, read pattern arrays, then play any latched on sample here!!!
        // pink pad on = read that pads saved Pattern array, play that pads sample when pink traveller lands on a latched pad
        // if current Pads pattern
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      }
    }

    if (currentPattern[pad] == 1 && latchingMode == true) {
      trellis.pixels.setPixelColor(pad, 0x0000ff); // make latched LEDs Blue again after pink traveller passes
      playSound(1); // distorted with pink traveller, but not after trellis lockup ?
      delay(5);
    }
    else {
      trellis.pixels.setPixelColor(pad, 0);  //  Turn off pink traveller after it passes
    }
  }
}


/****************************************************************************************************************/

void startStopFSW() {
  FSW2State = digitalRead(FSW2);   //sample the state of the button - is it pressed or not?

  if ( (millis() - lastDebounceTime) > debounceDelay) {   //filter out any noise by setting a time buffer
    if ( (FSW2State == LOW) && (ssLedState < 0) ) {     //if the button has been pressed, lets toggle the LED from "off to on" or "on to off"
      pixels.setPixelColor(1, 124, 252, 0);       // start LED lawn green:
      pixels.show();
      // runSeq();  // START runSeq FUNCTION
      Serial.println("Start");
      pad = -1;
      ssLedState = -ssLedState; //now the LED is on, we need to change the state
      lastDebounceTime = millis(); //set the current time
    }

    else if ( (FSW2State == LOW) && (ssLedState > 0) ) { // Start/Stop LED State, starts & stops runSeq
      pixels.setPixelColor(1, 220, 20, 60);       // stop LED Red
      pixels.show();
      Serial.println("Stop");

      //      for (uint16_t i = 0; i < trellis.pixels.numPixels(); i++) {
      //        trellis.pixels.setPixelColor(i, 0); // stray pink traveller off when stopped
      //        trellis.pixels.show();
      //      } // causes some latched leds to turn off, possibly caused by ending runSeq abruptly?

      ssLedState = -ssLedState; //
      lastDebounceTime = millis(); //set the current time
    }
  } //close if
}


/****************************************************************************************************************/

void clearTrellis() {

  for (uint16_t i = 0; i < trellis.pixels.numPixels(); i++) {
    trellis.pixels.setPixelColor(i, 0); // 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 (evt.bit.NUM >= 0 && evt.bit.NUM <= 15) {
      playSound(evt.bit.NUM);
      delay(10);
    }

    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 loadPattern(byte patternToLoad)
{
  Serial.print("loading pattern "); Serial.println(patternToLoad);
  for (byte ii = 0; ii < 15; 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 < 15; 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;
}
 
Hi @Leetut

a quick one to try - can you make the delay in the loop a bit longer and see if that helps, I found neotrellis locks up if polled any quicker than 12ms.

I used a loop of 20ms for reading the keys and let everything else run as quick as possible rather than using delay() in loop(), something like:
Code:
#define LOOP1_DURATION 20   // interval time in millis for slow loop
elapsedMillis loop1_timer;


void loop() {

// slow loop - 20 millis for knobs and buttons / trellis etc.
  if (loop1_timer >= LOOP1_DURATION) {
    loop1_timer = 0;
    // check the button pad - trellis has a limit of about 12ms between reads
    trellis.read();
    // update the button pad leds
    update_display();

  }  // end of slow loop (20 ms)

  // Everything else as fast as possible
  // here

}  // end of main loop

cheers, Paul
 
Thanks Paul, was worth a try but that made it worse
(upload, press play, press any pad, immediate freeze up)
tried up to 100ms everywhere i can think of

also tried using the neotrellis int pin, made no difference

when i first started the project my plan was to connect the neotrellis to the other i2c port (sda1 scl1) pins 16-17
but i couldnt figure out how to do that code wise, and PaulS told me on FB to connect to the same port as the audio board (sda0 scl0) pins 18-19
not sure if using a separate i2c port would make a difference anyway
 
Blind guess... can you connect a voltmeter to monitor at the power input? Perhaps with Teensy 4.1 and the LEDs and audio shield you might be running right at the limit of your power supply. Then using the SD card might be adding more power consumption.

If you see a steady 5 volts at the VIN or VUSB pin, then my guess was completely off and a little time was wasted hooking up a multimeter. But if you see 5V when Teensy is loading code, then it starts fluctuating into the mid-to-low 4V range when the LEDs change and your program tries do things, that's a strong sign you might a stronger power supply to run everything. Ordinary multimeters read DC voltage slowly so they can reject AC interference, so if you see fluctuating voltage on the slow updates, odds are the actual changes could be larger voltage over shorter time scales than a voltmeter can show.
 
I get the same freezing using a 2 amp wall wart type psu, so im guessing its not that?
also using a teensy 4.0,
my start/stop foot switch still controls their LEDs when it freezes so im guessing its the neotrellis thats freezing up not the teensy,
but if i rename the .RAW files in the code to .ZRAW it doesn't freeze
also doesn't freeze if i just play samples using the pads, without the Pink chase LED (my runSeq() function)
 
Please understand I'm guessing trying to figure out what's wrong over the internet without access to your hardware... so here's another blind guess.

I see you have Adafruit_NeoPixel library in use. Looks like Adafruit_NeoTrellis might also have Adafruit_NeoPixel internally? I don't understand why 2 different pixel.show(). The main point is Adafruit_NeoPixel is a blocking library with a long history of messing up audio, even if only a single instance is used. It disables all interrupts while sending data to the LEDs. Normally this just causes the audio to glitch or distort, so the expected problem doesn't really fit your observation of a lock up. Still, it's my next guess because we most projects using audio with WS2812 LEDs usually need to use a non-blocking library.

WS2812Serial is usually the easiest path. It's meant to be able to drop-in replace Adafruit_NeoPixel. But together with Adafruit_NeoTrellis, I'm not sure. I just don't know much about Adafruit_NeoTrellis. If possible, can you delete all the Adafruit_NeoTrellis.pixels.show() stuff, and then use WS2812Serial instead of Adafruit_NeoPixel. Since WS2812Serial has compatible functions, usually this can be done by just deteting the Adafruit_NeoPixel instance and creating a WS2812Serial with the same "pixels" name.

However, WS2812Serial is limited to transmitting with only certain pins. See any of the WS2812Serial examples or WS2812Serial page for details.
 
pixels.show(); Sends data to 2 WS2812 LEDs above my footswitches
trellis.pixels.show(); Sends data to the neotrellis board
I appreciate any suggestions Paul, although i have already tried removing all the neopixel code from the sketch
 
The Neotrellis library code is blocking and depending on what you may be trying to do, painfully slow and is probably the culprit messing up audio.
My Midi controller project has an ILI9341 screen, 18 encoders and two hardware buttons wired to a T4.0. The whole thing fell into a heap when I tried to add 8x8 Neotrellis.
Long story, short answer, I added another T4.0 as a Neotrellis "bridge" communicating with the main T4.0 via Serial and the Neotrellis via the usual I2C.
 
For the PCB, Adafruit Product ID 3954, and the Silicone elastomer 4x4 button keypad Product ID 1611. A couple of strategically placed elastic bands can be used to to strap the two parts together for experimentation.

If you want to play with 8x8 Neotrellis then you need 4 x each of the above. Fiddly with elastic and cardboard so perhaps think of Adafruit 4x4 Trellis Feather Acrylic enclosure Product ID 4339. Still fiddly but better end result.
 
yes thats what im using, connected to the JST socket and teensy 3v for its power
the samples im using in the sketch, and some build images are here:
 
I think the distorted sound is my codes fault,
I think the sound is triggered over and over again while the pad is lit, instead of just playing it once
 
fixed the distorted sound, neotrellis still locks up


Latest
Code:
// 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: read all arrays, play all latched samples
// to do: make tempo led blink 4x slower than pink traveller
// to do:

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SerialFlash.h>
#include "Adafruit_NeoTrellis.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



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] = { 500, 500 };  /* array of most recent tap counts */
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;

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};


/****************************************************************************************************************/

void setup() {
  Serial.begin(9600);
  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);
  //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);
  }
}

int pad = -1;



/****************************************************************************************************************/


void loop() {
  trellis.read();
  delay(10); // stops freeze up in stop mode when playing pads quickly
  startStopFSW();
  runSeq();
}


/****************************************************************************************************************/

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");
      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");
      ledState2 = -ledState2; //
      lastDebounceTime = millis(); //set the current time
    }
  }
}


/****************************************************************************************************************/


void runSeq() {
  if (ledState2 > 0) // if footswitch start
  {
    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 */
    //    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 ))
    //      {
    //        /* lets hard code a 1/10 delay...
    //           you can use this to trigger other things as well */
    //
    //        //      pixels.setPixelColor(1, 20, 55, 155);
    //        //      pixels.show();
    //
    //        currentTimer[0] = currentTimer[1] = 100; /* make sure they get averaged to be equal */
    //        rescheduleTimer(); /* start the timer */
    //        pressTimeout = true; /* make sure we don't get called again during this press */
    //      }
    //    }




    lastTapState = tapState; /* keep track of the last state, for transition detection */



    /* 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 LED + Trellis */
    if ( millis() < indicatorTimeout)
    {
      //      pixels.setPixelColor(0, 0, 255, 255); // Tempo LED on aqua
      //      pixels.show();
      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 {
      //      pixels.setPixelColor(0, 0, 0, 0);  // Tempo LED off
      //      pixels.show();
      trellis.pixels.setPixelColor(pad, 0);  //  Turn off pink traveller after it passes
    }

  } // if footswitch start
}


/****************************************************************************************************************/


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

  pad++;
  pad %= 16;
  Serial.println(pad);
  if (currentPattern[pad] == 1) // if pad is latched on in array
  {
    playSamples(); // causes neotrellis lock up.....
    Serial.println("playing sample");
  }
}


/****************************************************************************************************************/


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 (evt.bit.NUM >= 0 && evt.bit.NUM <= 15) { // push pads = sounds
      playSound(evt.bit.NUM);
      delay(10);
    }

    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 playSamples() {
  playSound(held_button_id);

  // to do: if pad has a pattern, play that pads sample when pink traveller hits a latched pad
  // to do: on main screen only, blink samples pad led everytime its sample is triggered
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/****************************************************************************************************************/


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;
}
 
Which Teensyduino are you using? 1.59 beta #4 has a fix for issues discovered with a different processor-based I²C slave - it might be worth a shot. Discussion on the other hardware can be found in this thread. You may also need to check if the Adafruit library checks for error codes returned from TwoWire::endTransmission(), as it's still likely to lock up if they get ignored!
 
tried installing 1.59 beta #4 there isnt a version for high sierra 10.13.6
installed Mojave version instead, on arduino 1.8.13
nothing will compile now


Code:
/private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware -hardware /Users/lee/Documents/Arduino/hardware -tools /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/tools-builder -tools /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/tools/avr -built-in-libraries /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/libraries -libraries /Users/lee/Documents/Arduino/libraries -fqbn=teensy:avr:teensy40:usb=serial,speed=150,opt=o2std,keys=en-us -ide-version=10819 -build-path /var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/arduino_build_814091 -warnings=none -build-cache /var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/arduino_cache_53016 -verbose /Users/lee/Desktop/tap1_leds_seq_audioWithTraveller/tap1_leds_seq_audioWithTraveller.ino
/private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware -hardware /Users/lee/Documents/Arduino/hardware -tools /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/tools-builder -tools /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/tools/avr -built-in-libraries /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/libraries -libraries /Users/lee/Documents/Arduino/libraries -fqbn=teensy:avr:teensy40:usb=serial,speed=150,opt=o2std,keys=en-us -ide-version=10819 -build-path /var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/arduino_build_814091 -warnings=none -build-cache /var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/arduino_cache_53016 -verbose /Users/lee/Desktop/tap1_leds_seq_audioWithTraveller/tap1_leds_seq_audioWithTraveller.ino
Using board 'teensy40' from platform in folder: /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/teensy/avr
Using core 'teensy4' from platform in folder: /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/teensy/avr
Detecting libraries used...
/private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=158 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=150000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4 /var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/arduino_build_814091/sketch/tap1_leds_seq_audioWithTraveller.ino.cpp -o /dev/null
Error while detecting libraries included by /var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/arduino_build_814091/sketch/tap1_leds_seq_audioWithTraveller.ino.cpp
Generating function prototypes...
/private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=158 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=150000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4 /var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/arduino_build_814091/sketch/tap1_leds_seq_audioWithTraveller.ino.cpp -o /var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/arduino_build_814091/preproc/ctags_target_for_gcc_minus_e.cpp
dyld: lazy symbol binding failed: Symbol not found: ____chkstk_darwin
  Referenced from: /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ (which was built for Mac OS X 10.15)
  Expected in: /usr/lib/libSystem.B.dylib

dyld: Symbol not found: ____chkstk_darwin
  Referenced from: /private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ (which was built for Mac OS X 10.15)
  Expected in: /usr/lib/libSystem.B.dylib

signal: abort trap
/private/var/folders/kz/yg8fjhp53c3201sw0bhpccy40000gn/T/AppTranslocation/DE8A204B-EB4F-45E6-910B-C7E537C62F73/d/Teensyduino.app/Contents/Java/arduino-builder returned 255
Error compiling for board Teensy 4.0.
 
Ah, I have zero experience with recent MacOS… Arduino 1.8.13 is not the most recent, but again don’t know what’s compatible with your setup.

A search for dyld: lazy symbol binding failed: Symbol not found: ____chkstk_darwin turns up stuff, but it makes no sense to me … maybe it does to you?
 
A search for dyld: lazy symbol binding failed: Symbol not found: ____chkstk_darwin turns up stuff, but it makes no sense to me … maybe it does to you?

This error means the gcc toolchain doesn't work with MacOS older than 10.14 (Mojave). It definitely does *not* work with 10.13.6 (High Sierra).

Teensyduino 1.57 and older had gcc 5.4 which worked on old MacOS all the way back to 10.7 (Lion).

Teensyduino 1.58 was the first to use gcc 11.3, which abandoned support for old MacOS. Everything else about Teensyduino still works back to MacOS 10.7 (Lion) if you have an old enough version of Arduino IDE. So you can run the IDE on those older systems, but then it fails to compile code with this error.
 
Last edited:
Back
Top