How to trigger scrolling text with a button

My name is Justin and I have a little project I’m doing with a 64x32 led matrix and a teensy 3.6. I found the code online and got it all working and scrolling the text I wanted but not when I want.
I tried to setup a interrupt on pin 39 pulled low to start the scrolling text layer but get errors. I know Pin 39 is interrupt capable. I work with wiring, circuits, automotive engine conversions and reverse engineer CanBus Data but not good at coding.
So my question is in this code how can I start the scrolling text layer to scroll “WELCOME” anytime I push the button pulled low on pin 39?
Or is trying to use a interrupt the correct way to do this? Any help would be appreciated.


#include <MatrixHardware_Teensy3_ShieldV4.h>  // comment out this line for if you're not using SmartLED Shield V4 hardware (this line needs to be before #include <SmartMatrix3.h>)
#include <SmartMatrix.h>
#include <FastLED.h>

#define COLOR_DEPTH 24                  // This sketch and FastLED uses type `rgb24` directly, COLOR_DEPTH must be 24
const uint8_t kMatrixWidth = 64;        // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 32;       // known working: 16, 32, 48, 64
const uint8_t kRefreshDepth = 36;       // known working: 24, 36, 48
const uint8_t kDmaBufferRows = 4;       // known working: 2-4, use 2 to save memory, more to keep from dropping frames and automatically lowering refresh rate
const uint8_t kPanelType = SMARTMATRIX_HUB75_32ROW_MOD16SCAN; // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels, or use SMARTMATRIX_HUB75_64ROW_MOD32SCAN for common 64x64 panels
const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_NONE);      // see for options
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);
const uint8_t kScrollingLayerOptions = (SM_SCROLLING_OPTIONS_NONE);

SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);
SMARTMATRIX_ALLOCATE_SCROLLING_LAYER(scrollingLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kScrollingLayerOptions);

// The 32bit version of our coordinates
static uint16_t x;
static uint16_t y;
static uint16_t z;

// We're using the x/y dimensions to map to the x/y pixels on the matrix.  We'll
// use the z-axis for "time".  speed determines how fast time moves forward.  Try
// 1 for a very slow moving effect, or 60 for something that ends up looking like
// water.
// uint16_t speed = 1; // almost looks like a painting, moves very slowly
//uint16_t speed = 20; // a nice starting speed, mixes well with a scale of 100
 uint16_t speed = 5;  //----------------------------------------------------------------------------------------------- BACKGROUND SPEED
// uint16_t speed = 100; // wicked fast!

// Scale determines how far apart the pixels in our noise matrix are.  Try
// changing these values around to see how it affects the motion of the display.  The
// higher the value of scale, the more "zoomed out" the noise iwll be.  A value
// of 1 will be so zoomed in, you'll mostly see solid colors.

// uint16_t scale = 1; // mostly just solid colors
// uint16_t scale = 4011; // ------------------------------------------------------------------------------------ SCALE very zoomed out and shimmery
uint16_t scale = 31;

// This is the array that we keep our computed noise values in
uint8_t noise[kMatrixWidth][kMatrixHeight];

void setup() {
  // uncomment the following lines if you want to see FPS count information
  // Serial.begin(38400);
  // Serial.println("resetting!");


  // Initialize our coordinates to some random values
  x = random16();
  y = random16();
  z = random16();

  // -----------------------------------------------------------------------------------------------------------Show off smart matrix scrolling text
  scrollingLayer.setColor({0x50, 0x50, 0x50});
  scrollingLayer.start("WELCOME", -1);
  scrollingLayer.setOffsetFromTop((kMatrixHeight/2) - 8);

// Fill the x/y array of 8-bit noise values using the inoise8 function.
void fillnoise8() {
  for(int i = 0; i < kMatrixWidth; i++) {
    int ioffset = scale * i;
    for(int j = 0; j < kMatrixHeight; j++) {
      int joffset = scale * j;
      noise[i][j] = inoise8(x + ioffset,y + joffset,z);
  z += speed;

void loop() {
  static uint8_t circlex = 0;
  static uint8_t circley = 0;

  // if sketch uses swapBuffers(false), wait to get a new backBuffer() pointer after the swap is done:

  rgb24 *buffer = backgroundLayer.backBuffer();

  static uint8_t ihue=0;
  for(int i = 0; i < kMatrixWidth; i++) {
    for(int j = 0; j < kMatrixHeight; j++) {
      // We use the value at the (i,j) coordinate in the noise
      // array for our brightness, and the flipped value from (j,i)
      // for our pixel's hue.
      buffer[kMatrixWidth*j + i] = CRGB(CHSV(noise[j][i],255,noise[i][j]));

      // You can also explore other ways to constrain the hue used, like below
      // buffer[kMatrixHeight*j + i] = CRGB(CHSV(ihue + (noise[j][i]>>2),255,noise[i][j]));

  backgroundLayer.fillCircle(circlex % kMatrixWidth,circley % kMatrixHeight,6,CRGB(CHSV(ihue+128,255,255)));
  circlex += random16(2);
  circley += random16(2);

  // buffer is filled completely each time, use swapBuffers without buffer copy to save CPU cycles
  //matrix.countFPS();      // print the loop() frames per second to Serial

I tried to setup a interrupt on pin 39 pulled low to start the scrolling text layer but get errors

I assume you mean that the button is connected to pin 39.

There should be no need to use an interrupt to detect a button pressed by a human - humans are very sllooowwww and interrupts are only needed for very fast things.

The code in your Original Post has no reference to pin 39 and you have not posted the error message that you are getting so it is a bit difficult to know what the problem is.

The program has a couple of interleaved FOR loops which are probably a bad idea if you want a responsive program. Nothing can happen until the FOR loops complete their tasks. For a responsive program it is much better to use IF and allow loop() to do the repetition.

Have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.