SmartMatrix Shield V4 Buffer Overflow?


#1

I’m hoping somebody can help me with this issue.

I’m using a V4 shield with a Teensy 3.2 following this guide to create a Pinball DMD: http://docs.missionpinball.org/en/latest/hardware/smartmatrix/index.html

It works perfectly fine when displaying text and static images. But when my pinball programs attempts to play animations (gif) or videos, the display flickers and turns off within the first few seconds of the animation starting.

The above guide was written for earlier versions of the shield and nobody has had problems playing video or gifs with the earlier shields. So I’m guessing something has changed from V3 to V4 that’s causing my Teensy to crash.

Some have suggested that the animations are causing a buffer overflow. How can I increase the number of buffers? Or is there likely some other way of preventing this issue? Has anything changed in the shield from V3 to V4 that might be causing this problem?

I’m quite new to all of this so my understanding is pretty limited at the moment.

Here’s the code I’m using if it helps:

/*
    SmartMatrix Pinball DMD code for Teensy, based on:
    SmartMatrix Features Demo - Louis Beaudoin (Pixelmatix)
    This example code is released into the public domain
*/

#include <SmartLEDShieldV4.h> // this line must be first
#include <SmartMatrix3.h>
#include <usb_serial.h>

#define COLOR_DEPTH 24                  // known working: 24, 48 - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24
const uint8_t kMatrixWidth = 128;       // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 32;       // known working: 16, 32, 48, 64
const uint8_t kRefreshDepth = 24;       // 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
const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_NONE);      // see http://docs.pixelmatix.com/SmartMatrix for options
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);

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

//const int defaultBrightness = 100*(255/100);    // full brightness
const int defaultBrightness = 25*(255/100);    // dim: 15% brightness

const int defaultScrollOffset = 6;
const rgb24 defaultBackgroundColor = {0, 0, 0};

// Teensy 3.0 has the LED on pin 13
const int ledPin = 13;

boolean frameOn = false;
int dataPos = 0;
int dataExpected = 0;


// the setup() method runs once, when the sketch starts
void setup() {
  // initialize the digital pin as an output.
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  Serial.begin(2500000); // according to the Teensy docs this doesn't actually matter, will use USB speed

  matrix.addLayer(&backgroundLayer);
  matrix.begin();

  matrix.setBrightness(defaultBrightness);
  
  // clear screen
  backgroundLayer.fillScreen(defaultBackgroundColor);
  backgroundLayer.swapBuffers();
}


// the loop() method runs over and over again,
// as long as the board has power
uint16_t frameCount = 0;
void loop() {
  char* buffer = (char*)backgroundLayer.backBuffer();
  int bytesAvail = Serial.available();
  boolean swap = false;
  
  if ((bytesAvail > 1) && (dataPos > 0))
  {
    if (bytesAvail > dataExpected) bytesAvail = dataExpected;
    int count = Serial.readBytes(&buffer[dataPos], bytesAvail);
    dataPos += count;
    dataExpected -= count;
    if (dataExpected == 0) {
      swap = true;
    }
  }
  else if (bytesAvail) {
    char val = Serial.read();
    if ( val == 1 )
    {
      backgroundLayer.swapBuffers(true);
      dataPos=0;
      dataExpected = kMatrixWidth * kMatrixHeight * 3;
      digitalWrite(ledPin, HIGH);
    }
    else {
      buffer[dataPos++] = val;
      dataExpected--;
      if (dataExpected == 0) {
        swap = true;
      }
    }
  }

  if (swap) {
    frameCount++;
    char frameText[12];
    itoa(frameCount, frameText, 10);
    backgroundLayer.swapBuffers(true);
    dataPos = 0;
    dataExpected = kMatrixWidth * kMatrixHeight * 3;
    digitalWrite(ledPin, frameOn);
    frameOn = !frameOn;
  }
}

#2

32x128 pixels on a Teensy 3.2 is using up a lot of RAM. There’s likely not enough left to run your sketch. Yes, something may have changed with the SmartMatrix Library that uses more RAM.

Try changing kDmaBufferRows to 3 or 2, which will reduce the RAM used by the library. You could also upgrade to a Teensy 3.5 or 3.6 that has more RAM.