0

Issue with 2 types of 32 x 64 RGB matrix p6
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Issue with 2 types of 32 x 64 RGB matrix p6

by LEDLIT1 on Tue Jun 29, 2021 4:33 pm

Hi Adadfruit,

I have purchased 20 Adafruit 64x32 RGB LED Matrix - 6mm pitch PID: 2276 . An issue started happening. Some of them have random glitchy flickering LEDs and some don't. After troubleshooting and swapping around I found the issue would follow certain panels, and not others. Then I noticed the back of the panels were not all the same even though the part number on the back was. I can see 2 types. Most noticeably was the difference is the colored Q. C. sticker. The panels with the White Q.C. stickers did not have the issue. The panels with the Purple Q.C. stickers have the issue. Please see attached photo.

Everything works great with the White Q.C. sticker type, but I can't figure out how to get more of those type. Also, I don't know what to do with all the glitchy ones I have.

Can you help?
I am stuck and I don't know how to go about resolving this.

I don't believe it's a code issue, but maybe it is. So, here's my code is below if needed. I am using a feather doubler with an Adafruit Huzzah ESP32.

Code: Select all | TOGGLE FULL SIZE
// 4/4/2021 delayWithFire() added so the fire effect does not freeze.
// 3/26/2021

// Libraries
#include <FastLED.h>
#include <Adafruit_Protomatter.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSerifItalic12pt7b.h>

// PIN NAMES & ASSIGNMENT
#define DATA_PIN 4
#define OpSensor 39
#define ResetButton 32
#define StartButton 33

#define NUM_LEDS  91  // Number of LEDs in strip

// leds Arrays
CRGB leds[NUM_LEDS];
CRGB savedPixels[90];

// Store/Load arrays
CRGB copyLed[90];   // Internal

// The BLUE FEATHERWING for Adafruit ESP32 Feather Huzzah32 CONVERTED
uint8_t rgbPins[]  = {25, 5, 15, 27, 26, 21};
uint8_t addrPins[] = {22, 18, 23, 19};
uint8_t clockPin   = 13; // Must be on same port as rgbPins
uint8_t latchPin   = 16;
uint8_t oePin      = 17;

// Variables for timing of CheckButtons function
unsigned long CheckButtons_previousMillis = 0;   // stored time for next CheckButtons
unsigned long CheckButtons_currentMillis = 0;    //

// This number is how many milliseconds pass before the program is allowed to call the CheckButtons function
const int CheckButtons_intervalTime = 5;

// Variables for timing of check_OpSensor function
unsigned long check_OpSensor_previousMillis = 0;   // stored time for next
unsigned long check_OpSensor_currentMillis = 0;    //

// This number is how many milliseconds pass before the program is allowed to call the check_OpSensor function
const int check_OpSensor_intervalTime = 5;

// Variables for timing of updateScoreboard function
unsigned long updateScoreboard_previousMillis = 0;   // stored time for next updateScoreboard
unsigned long updateScoreboard_currentMillis = 0;    //

// This number is how many milliseconds pass before the program is allowed to call the updateScoreboard function
const int updateScoreboard_intervalTime = 5;

// Variables for timing of refreshFireEffect function
unsigned long refreshFireEffect_previousMillis = 0;   // stored time for next refreshFireEffect
unsigned long refreshFireEffect_currentMillis = 0;    //

// This number is how many milliseconds pass before the program is allowed to call the refreshFireEffect function
const int refreshFireEffect_intervalTime = 5;

Adafruit_Protomatter matrix(
  64,          // Matrix width in pixels
  6,           // Bit depth -- 6 here provides maximum color options
  1, rgbPins,  // # of matrix chains, array of 6 RGB pins for each
  4, addrPins, // # of address pins (height is inferred), array of pins
  clockPin, latchPin, oePin, // Other matrix control pins
  true);       // HERE IS THE MAGIG FOR DOUBLE-BUFFERING!
// Matrix Variables

int16_t  textX_A = 3, // Current text position (X)Horizontal Right++, Left--
         textY_A = 20; // Current text position (Y)Vertical Up--, Down++
char     str_A[50];   // Buffer to hold scrolling message text

int16_t  textX_B = 3; // Current text position (X)Horizontal
int16_t  textY_B = 59; // Current text position (Y)Vertical (Y)Vertical Up++, Down--
char     str_B[50];                // Buffer to hold scrolling message text


int8_t minutes = 1, seconds = 0; // Variables for minutes and seconds
unsigned long milliTime; // Interval for seconds
bool timeChange = true;

// Coordinance of individual LED scoreboard on Hoop concept
uint8_t ONE = 42;
uint8_t TWO = 35;
uint8_t THREE = 49;
uint8_t FOUR = 28;
uint8_t FIVE = 56;
uint8_t ONE_SHIFTED = 46;
uint8_t TWO_SHIFTED = 38;
uint8_t THREE_SHIFTED = 53;
uint8_t FOUR_SHIFTED = 31;

//Fire variables
uint8_t R_Max = 255;
uint8_t R_Min = 64;
uint8_t G_Max = 32;
uint8_t G_Min = 0;
uint8_t B_Max = 0;
uint8_t B_Min = 0;
uint8_t Fire_Timer_Max = 120;
uint8_t Fire_Timer_Min = 60;
unsigned long fire_timer;

//Global variables
uint8_t hue = 0;
uint8_t BRIGHTNESS = 255; // For FastLED Brightness for remote variable
uint8_t color_num = 0;
bool OpSensor_Flag = HIGH;
bool score_Flag = false;
bool rebound_Flag = false;
bool reverseBrightness = false;
bool resfreshMainDisplay = true;
bool blinkScore = false;
uint8_t score = 0;
uint8_t sixty = 60;
uint8_t five = 5;
uint8_t playingState = 0;
unsigned long startTime;
unsigned long value;// RF value
const unsigned long TimerInterval = 1000;
bool resetGame = true;

void setup() {
  Serial.begin(9600);
  pinMode(OpSensor, INPUT_PULLUP);
  pinMode(ResetButton, OUTPUT);
  pinMode(StartButton, OUTPUT);
  digitalWrite(ResetButton, HIGH);
  digitalWrite(StartButton, HIGH);
  LEDS.addLeds<WS2813, DATA_PIN, GRB>(leds, NUM_LEDS);
  LEDS.setBrightness(BRIGHTNESS);

  ProtomatterStatus status = matrix.begin();// Initialize matrix...
  Serial.print("Protomatter begin() status: ");
  Serial.println((int)status);
  if (status != PROTOMATTER_OK) {
    for (;;); // DO NOT CONTINUE if matrix setup encountered an error.
  }
  matrix.setRotation(3);// Rotate to vertical with input at bottom
  put60secondsOnTheBoard();
  updateScoreboard();
}
void put60secondsOnTheBoard() {
  matrix.fillRect(0, 0, 32, 32, matrix.color565(0, 0, 0));//fillRect( x, y, w,  h,  color)
  int16_t  x1_A, y1_A;
  uint16_t w_A, h_A;
  sprintf(str_A, "%2d", 60);
  matrix.setFont(&FreeSans12pt7b); // Use nice bitmap font
  matrix.setTextColor(0xFFFF);         // White
  matrix.getTextBounds(str_A, 0, 0, &x1_A, &y1_A, &w_A, &h_A);
  matrix.setCursor(textX_A, textY_A);
  matrix.print(str_A);
  matrix.show();
  minutes = 1;
}
void refreshFireEffect() {
  doFireEffect();
  CheckButtons();
  check_OpSensor();
}

void doFireEffect() {
  if ( millis() > fire_timer ) {
    fire_timer = millis() + random(Fire_Timer_Min, Fire_Timer_Max);
    for (uint8_t i = 0; i < NUM_LEDS; i++) {// Update with a new set of randomised colors
      leds[i] = CRGB(random(R_Min, R_Max), random(G_Min, G_Max), random(B_Min, B_Max));
    }
    FastLED.show();
  }
}

void delayWithFire(unsigned long delayAmt) {
  unsigned long beginTime = millis();
  while(millis() < beginTime + delayAmt)
    doFireEffect();
}

void countDownToStart() {
  matrix.fillRect(0, 0, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
  int16_t  x1_A, y1_A;
  uint16_t w_A, h_A;
  sprintf(str_A, "%2d", 5);
  matrix.setFont(&FreeSans12pt7b); // Use nice bitmap font
  matrix.setTextColor(0xFFFF);         // White
  matrix.getTextBounds(str_A, 0, 0, &x1_A, &y1_A, &w_A, &h_A);
  matrix.setCursor(textX_A, textY_A);
  matrix.print(str_A);
  matrix.show();
  delayWithFire(1000);
 
  matrix.fillRect(0, 0, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
  sprintf(str_A, "%2d", 4);
  matrix.setFont(&FreeSans12pt7b); // Use nice bitmap font
  matrix.setTextColor(0xFFFF);         // White
  matrix.getTextBounds(str_A, 0, 0, &x1_A, &y1_A, &w_A, &h_A);
  matrix.setCursor(textX_A, textY_A);
  matrix.print(str_A);
  matrix.show();
  delayWithFire(1000);
 
  matrix.fillRect(0, 0, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
  sprintf(str_A, "%2d", 3);
  matrix.setFont(&FreeSans12pt7b); // Use nice bitmap font
  matrix.setTextColor(0xFFFF);         // White
  matrix.getTextBounds(str_A, 0, 0, &x1_A, &y1_A, &w_A, &h_A);
  matrix.setCursor(textX_A, textY_A);
  matrix.print(str_A);
  matrix.show();
  delayWithFire(1000);
 
  matrix.fillRect(0, 0, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
  sprintf(str_A, "%2d", 2);
  matrix.setFont(&FreeSans12pt7b); // Use nice bitmap font
  matrix.setTextColor(0xFFFF);         // White
  matrix.getTextBounds(str_A, 0, 0, &x1_A, &y1_A, &w_A, &h_A);
  matrix.setCursor(textX_A, textY_A);
  matrix.print(str_A);
  matrix.show();
  delayWithFire(1000);
 
  matrix.fillRect(0, 0, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
  sprintf(str_A, "%2d", 1);
  matrix.setFont(&FreeSans12pt7b); // Use nice bitmap font
  matrix.setTextColor(0xFFFF);         // White
  matrix.getTextBounds(str_A, 0, 0, &x1_A, &y1_A, &w_A, &h_A);
  matrix.setCursor(textX_A, textY_A);
  matrix.print(str_A);
  matrix.show();
  delayWithFire(1000);
 
  matrix.setTextWrap(false);           // Allow text off edge
  matrix.fillRect(0, 0, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
  strcpy(str_A, "GO");
  matrix.setFont(&FreeSerifItalic12pt7b); // Use nice bitmap font
  matrix.setTextColor(0xFFFF);         // White
  matrix.getTextBounds(str_A, 0, 0, &x1_A, &y1_A, &w_A, &h_A);
  matrix.setCursor(textX_A - 4, textY_A);
  matrix.print(str_A);
  matrix.show();
  delayWithFire(1000);
 
  put60secondsOnTheBoard();
  score = 0;  // Reset score tally
}

void Matrix60ShotClock(void) {
  matrix.fillRect(0, 0, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
  matrix.setFont(&FreeSans12pt7b); // Use nice bitmap font
  matrix.setTextColor(0xFFFF);         // White
  matrix.setCursor(textX_A, textY_A);
  // This changes timeChange to false every second.
  // You're probably going to set timeChange to false in an interrupt handler instead.
  if (millis() - milliTime >= 1000) {
    milliTime += 1000;
    timeChange = false;
  }
  if (!timeChange) {// Whenever timeChange is false, the counter goes up by 1.
    subtractSeconds(1); // Count down is 1, count up is -1
    timeChange = true;
  }
  matrix.print(str_A);
  matrix.show();  // AFTER DRAWING, A show() CALL IS REQUIRED TO UPDATE THE MATRIX!
}
bool subtractSeconds(int8_t second) {
  bool finish = false;
  seconds -= second;
  while (seconds < 0) {
    minutes--;
    seconds += 60; // How many seconds are going to count down
  }
  while (seconds >= 60) {
    minutes++;
    seconds -= 60;
  }
  if (minutes < 0 || (minutes == 0 && seconds <= 0)) {
    minutes = seconds = 0;
    finish = true;
  }
  sprintf(str_A, "%2d", seconds + 60 * minutes);
  int16_t  x1_A, y1_A;
  uint16_t w_A, h_A;
  matrix.getTextBounds(str_A, 0, 0, &x1_A, &y1_A, &w_A, &h_A); // How big is it?
  return finish;
}

void check_OpSensor()
{
  check_OpSensor_currentMillis = millis();
  if (check_OpSensor_currentMillis - check_OpSensor_previousMillis > check_OpSensor_intervalTime)
  {
    check_OpSensor_previousMillis = millis();
    bool SetResetflag = digitalRead(OpSensor); // if it's low now, but it was high before
    if ((SetResetflag && !OpSensor_Flag) || score_Flag) { //
      if (playingState == 2) // Stop counting points after clock is at 0
        score++;
       
      updateScoreboard();
      uint8_t a = 44;
      for (uint8_t dot = 43;
           dot < 90;
           dot++) {
        leds[dot] = CRGB::Green;
        leds[a] = CRGB::Green;
        delayWithFire(4);
        FastLED.show();  // This is the speed of the dual cylons
        a--;
        for (uint8_t i = 0;
             i < NUM_LEDS;
             i++)
        { // Update with a new set of randomised colors
          leds[i] = CRGB(random(G_Min, G_Max), random(R_Min, R_Max), random(B_Min, B_Max));
        }
      }
      Serial.print("Score Total = ");
      Serial.println(score);
      score_Flag = LOW;
    }
    OpSensor_Flag = SetResetflag;

  }
  else
  {
    return;
  }
}

void updateScoreboard()
{
  updateScoreboard_currentMillis = millis();
  if (updateScoreboard_currentMillis - updateScoreboard_previousMillis > updateScoreboard_intervalTime)
  {
    updateScoreboard_previousMillis = millis();
    matrix.fillRect(0, 32, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
    matrix.setFont(&FreeSans12pt7b); // Use nice bitmap font
    matrix.setTextColor(0xF800);
    matrix.setCursor(textX_B, textY_B);
    sprintf(str_B, "%2d", score);
    int16_t  x1_B, y1_B;
    uint16_t w_B, h_B;
    matrix.getTextBounds(str_B, 0, 0, &x1_B, &y1_B, &w_B, &h_B);
    matrix.print(str_B);
    matrix.show();
  }
  else
  {
    return;
  }
  CheckButtons();
}

void displayTotal() {
  for (uint8_t x = 1; x < 4; x++ ) {
    matrix.fillRect(0, 32, 32, 32, matrix.color565(0, 0, 0)); //fillRect( x, y, w,  h,  color)
    matrix.show();
    delayWithFire(500);
    CheckButtons();
    updateScoreboard();
    delayWithFire(500);
    CheckButtons();
  }
}
void CheckButtons() {
  CheckButtons_currentMillis = millis();
  if (CheckButtons_currentMillis - CheckButtons_previousMillis > CheckButtons_intervalTime)
  {
    CheckButtons_previousMillis = millis();
    bool StartGame = digitalRead (StartButton);
    if (!StartGame && playingState == 0) {
      playingState = 1;
      Serial.println("Start Game");
    }
    resetGame = digitalRead (ResetButton);
  }
}

void loop() {
  CheckButtons();
  updateScoreboard();
  refreshFireEffect();
  if (playingState == 0) {
    resetGame = true;
  }
  if (playingState == 1) {
    countDownToStart();
    playingState = 2;
    startTime = millis();
    milliTime = startTime;
  } else if (playingState == 2) {
    CheckButtons();
    if (!resetGame) {
      resetGame = true;
      while (!(seconds == 0 && minutes == 0))
        subtractSeconds(1);
      startTime = millis() - 60501;
    }
    check_OpSensor();
    updateScoreboard();
    refreshFireEffect();
    Matrix60ShotClock();
    if (millis() - startTime > 60500)  { //Time in milliseconds (extra 1/2 second for airtime)
      playingState = 0;
      displayTotal();
    }
  }
}
Attachments
Adafruit 64 x 32 matrix display comparison 20210629_130835.jpg
Photo of the back of both panels with arrows point to differences
Adafruit 64 x 32 matrix display comparison 20210629_130835.jpg (756.96 KiB) Viewed 181 times

LEDLIT1
 
Posts: 103
Joined: Mon Oct 17, 2016 11:14 am

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by LEDLIT1 on Wed Jun 30, 2021 2:27 pm

addendum:

Hi Adafruit,
I can make a video if you like. I don't know how to get it to you because this forum won't accept mp4 format uploaded. Please let me know if you need anything more from me because I really need help with this. Thank you.

LEDLIT1
 
Posts: 103
Joined: Mon Oct 17, 2016 11:14 am

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by adafruit_support_mike on Fri Jul 02, 2021 8:31 pm

Post a photo showing your connections bewteen the displays and the microcontroller please. 800x600 images usually work best.

adafruit_support_mike
 
Posts: 63716
Joined: Thu Feb 11, 2010 2:51 pm

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by LEDLIT1 on Wed Jul 07, 2021 12:24 pm

Here are the requested images. If you need more please let me know.
Attachments
20210706_092732_resized.jpg
Front view of circuit plugged in and powered up.
20210706_092732_resized.jpg (235.92 KiB) Viewed 144 times
20210706_092703_resized.jpg
Back view of circuit plugged in and powered up.
20210706_092703_resized.jpg (206.45 KiB) Viewed 144 times
circuit diagram.jpg
basic circuit drawing
circuit diagram.jpg (192.6 KiB) Viewed 144 times

LEDLIT1
 
Posts: 103
Joined: Mon Oct 17, 2016 11:14 am

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by LEDLIT1 on Wed Jul 07, 2021 2:25 pm

Hi Adafruit,

The flickering is not the entire display, but only the top half. The flickering is better described this way. On the top half of the display around the 60 second shot clock random LEDs blinking quick and random. Not the numbers. the numbers stay solid.

Important question:
If you have some of the white Q.C. sticker type I stock, how can I get them? That would be one way to resolve this quickly. I have a customer deliverable on hold because of this issue.
Attachments
20210416_165238 low rez.jpg
All 4 daisy chained together enterprise method
20210416_165238 low rez.jpg (272.84 KiB) Viewed 141 times

LEDLIT1
 
Posts: 103
Joined: Mon Oct 17, 2016 11:14 am

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by LEDLIT1 on Thu Jul 08, 2021 8:06 pm

Note: A recent discovery. If I power the Feather ESP32 from a separate power source like the USB or Lipoly battery , the flicker effect is reduced significantly but not completely.

LEDLIT1
 
Posts: 103
Joined: Mon Oct 17, 2016 11:14 am

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by adafruit_support_mike on Thu Jul 08, 2021 9:56 pm

It sounds like you're getting signal interference from noise on the supply rails.

Try adding a large capacitor at the point where power connects to each matrix.. like these:

https://www.adafruit.com/product/1589

Logic chips use thresholds based on their supply voltage. If the supply voltage in unstable, the thresholds are also unstable. If you're getting significant voltage spikes when the current load changes as the LEDs turn on and off, it's easy to get spurious data.

adafruit_support_mike
 
Posts: 63716
Joined: Thu Feb 11, 2010 2:51 pm

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by LEDLIT1 on Mon Jul 19, 2021 8:13 pm

Sorry for the delayed reply. I am back now.

Thank you for pointing out the possibility of signal inference and incorporating the capacitor to smooth it out. I will update you tomorrow when I get the cap in the mail.

May I have a recommendation for this project. It's regarding the matrix shield and controller because it is so time consuming cutting traces and soldering jumpers in order to use the ESP32 Hazzah to control the 64 x 32 RGB matrix.

What shield and controller board would you use to control a 64 x 32 RGB matrix and WS2815 12V LED strip with Fastled?

LEDLIT1
 
Posts: 103
Joined: Mon Oct 17, 2016 11:14 am

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by adafruit_support_mike on Mon Jul 19, 2021 10:58 pm

I've never worked with WS2815s, so I can't offer any advice on those.

If it's a 12V device, it will probably also use 12V data signals. You'll need level shifting for that, and can't connect it directly to a 5V LED Matrix. I'd suggest using something like a CD4504B

https://octopart.com/search?q=cd4504b&c ... SD&specs=0

It's a buffer with two different supply pins, one for the input side and one for the output side.

You can probably use a single 12V power supply and get your 5V rail with a step-down converter. Those operate at high efficiency, and the math of voltage reduction works out in your favor.. 1A @ 12V drops to a theoretical value of 2.4A @ 5V, with realistic values around 2.3A for a 95% efficient converter.

The step-down converters we carry only provide about 1A, but you can get higher-power devices from Pololu:

https://www.pololu.com/category/131/ste ... regulators

adafruit_support_mike
 
Posts: 63716
Joined: Thu Feb 11, 2010 2:51 pm

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by LEDLIT1 on Wed Jul 21, 2021 10:00 am

FYI: The WS2815 data signal works great with 3.3v sent to it.

The reason I asked was to have less trace cutting and jumper soldering, which I do a lot of converting the Adafruit RGB Matrix Featherwing Kit - For M0 and M4 Feather to work with the Adafruit ESP32 Huzzah feather.

My project would work would be so much easier if the Adafruit Matrix Portal accepted the Fastled library in the Arduino IDE.

If you or someone at Adafruit sent a request to Fastled asking to include the Adafruit Matrix Portal in their library it would be a huge deal for me. Could you do that for me?

LEDLIT1
 
Posts: 103
Joined: Mon Oct 17, 2016 11:14 am

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by adafruit_support_mike on Thu Jul 29, 2021 3:13 pm

LEDLIT1 wrote:FYI: The WS2815 data signal works great with 3.3v sent to it.

Hmm.. good to know. Thank you.

LEDLIT1 wrote:If you or someone at Adafruit sent a request to Fastled asking to include the Adafruit Matrix Portal in their library it would be a huge deal for me. Could you do that for me?

I can pass on a request, but we don’t have more standing with them than any other user. We certainly don’t have ‘oh my gosh, do this now!’ status.

adafruit_support_mike
 
Posts: 63716
Joined: Thu Feb 11, 2010 2:51 pm

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by LEDLIT1 on Thu Jul 29, 2021 3:29 pm

The LED strip manufacturer told me 3.3v to 5.5v will work with their the WS2815 strip even though the specs say 5v. I tried it and 3.3v worked great, and I haven't looked back. Of course I power it with 12v and a big cap for protection per the Adafruit Uberguide recommendation.

Regarding Fastled request for the Adafruit Matrix Portal. Thank you.

What LED library would you use with the Adafruit Matrix Portal if you incorporated a neopixel strip with a 32 x 64 matrix?

LEDLIT1
 
Posts: 103
Joined: Mon Oct 17, 2016 11:14 am

Re: Issue with 2 types of 32 x 64 RGB matrix p6

by adafruit_support_mike on Sun Aug 01, 2021 4:09 am

If I had to use NeoPixels and an LED matrix array, I’d break the system down into modules with independent microcontrollers.

A Trinket M0 can drive a few thousand NeoPixels, so I’d give each NeoPixel strip one and treat the assembly as its own device:

https://www.adafruit.com/product/3500

The same is true for the LED matrices. They have tight timing requirements, so any other task has to be arranged to fit in the cracks. Anything complicated will probably involve frustrating work to find a brittle solution, and I recognize that as a poor design strategy. Throwing hardware at the problem makes each piece simpler and more stable, and has other benefits like separation of concerns.

That means I need to weigh the economic cost of each option. Choosing a single-board approach would save me $9 for a Trinket M0, but would probably cost hours of tweaking to make things work. Choosing a multi-board approach would cost $9 per Trinket M0 and would save me hours of probably-frustrating work.

Then I apply two questions from the “pay yourself minimum wage” policy: “would I take this job if someone offered me minimum wage to do it?”, (no) and “how long can I work at minimum wage before cost of labor outweighs the cost of the other solution?” (maybe 90 minutes)

I don’t think I could build a good single board solution in 90 minutes, so the multi-board solution wins on design, cost, and minimum profanity.

NeoPixel code tends to leave plenty of time for other work between updates, so it probably wouldn’t be difficult to let the Trinket M0 handle things like sensor readings and communication with other devices. That would change its function from ‘NeoPixel driver’ to ‘system control node’, meaning it could take some processing load off the board that drives the LED matrix. Being able to offload some of the work to another board would make it easier to add code that fits in the gaps of the LED matrix signal timing.

If I wanted a central point of control for the whole system, I could add one more board that talks to the Trinket M0 in each subsystem.

If I found myself needing more than the Trinket M0’s 5 GPIO pins, the Seesaw is available and inexpensive:

https://www.adafruit.com/product/3657

Together, a Trinket M0 and a Seesaw cost a bit less than a Feather M0, so that’s probably a decent tradeoff.

adafruit_support_mike
 
Posts: 63716
Joined: Thu Feb 11, 2010 2:51 pm

Please be positive and constructive with your questions and comments.