Led Matrix Flicker

Using the below code, a genuine Arduino Nano, DS3231 RTC, and FC16 8x32 LED Matrix. I am getting momentary random brightness flicker in the time display and I cannot find the problem.
Any help would be greatly appreciated. I checked the SPI signal using my saleae logic analyzer and the signal looks fine. I think it is in the code. This is my source from manjuhm mostly unaltered.(GitHub - manjuhm/LED-Matrx-Clock) and his youtube post is here (DIY Arduino LED Clock using MAX7219 LED Matrix Display and DS3231 RTC module | Arduino LED Clock - YouTube)
Thanks
Rick

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Wire.h>
#include <DS3231.h>
#include "Font_Data.h"

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW             //ICSTATION_HW for green!! //FC16_HW for red
#define MAX_DEVICES 4
#define CLK_PIN   13         // SCK Serial Clock 
#define DATA_PIN  11         // MOSI DIN send data. The LED Matrix uses SPI without a MISO Pin
#define CS_PIN    10         // SS or Slave select
#define USE_PAROLA_HW   0
#define SPEED_TIME 75 
#define PAUSE_TIME  0  
#define MAX_MESG  20

MD_Parola P = MD_Parola(HARDWARE_TYPE,CS_PIN, MAX_DEVICES);
DS3231 Clock;  // The clock chip uses I2C and pins A4 & A5 for Data and Clock respectively on the Nano

bool Century=false;
bool h12;
bool PM;
byte  dd,mm,yyy;
uint16_t  h, m, s;

char szTime[9];    
char szMesg[MAX_MESG+1] = "";

uint8_t degC[] = { 6, 3, 3, 56, 68, 68, 68 }; 
uint8_t degF[] = { 6, 3, 3, 124, 20, 20, 4 };

char *mon2str(uint8_t mon, char *psz, uint8_t len)

{
  static const __FlashStringHelper* str[] =
  {
    F("Jan"), F("Feb"), F("Mar"), F("Apr"),
    F("May"), F("Jun"), F("Jul"), F("Aug"),
    F("Sep"), F("Oct"), F("Nov"), F("Dec")
  };

  strncpy_P(psz, (const char PROGMEM *)str[mon-1], len);
  psz[len] = '\0';

  return(psz);
}

char *dow2str(uint8_t code, char *psz, uint8_t len)
{
  static const __FlashStringHelper*  str[] =
  {
  F("Sunday"), F("Monday"), F("Tuesday"),
  F("Wednesday"), F("Thursday"), F("FriYay!!!"),
  F("Saturday"), F("Sunday")
  };

  strncpy_P(psz, (const char PROGMEM *)str[code-1], len);
  psz[len] = '\0';

  return(psz);
}

void getTime(char *psz, bool f = true)

{
  s = Clock.getSecond();
  m = Clock.getMinute();
    sprintf(psz, "%02d%c%02d", h, (f ? ':' : ' '), m);
    if (Clock.getHour(h12,PM)>=13 || Clock.getHour(h12,PM)==0)
  {
    h = Clock.getHour(h12,PM) - 12;
  }
  else
  {
    h = Clock.getHour(h12,PM);
  }
}

void getDate(char *psz)

{
   char  szBuf[10];
   dd=Clock.getDate();
   mm=Clock.getMonth(Century); 
   yyy=Clock.getYear();
   sprintf(psz, "%d %s %04d",dd , mon2str(mm, szBuf, sizeof(szBuf)-1),(yyy + 2000));
}

void setup(void)

{
  Wire.begin();
  
  P.begin(2);
  P.setInvert(false); 
  P.setZone(0,  MAX_DEVICES-4, MAX_DEVICES-1);
  P.setZone(1, MAX_DEVICES-4, MAX_DEVICES-1);
  P.displayZoneText(1, szTime, PA_CENTER, SPEED_TIME, PAUSE_TIME, PA_PRINT, PA_NO_EFFECT);
  P.displayZoneText(0, szMesg, PA_CENTER, SPEED_TIME, 0,PA_PRINT , PA_NO_EFFECT);
  P.addChar('$', degC);
  P.addChar('&', degF);
}

void loop(void)

{
  static uint32_t lastTime = 0; 
  static uint8_t  display = 0;  
  static bool flasher = false;  

  P.setIntensity(2);

  P.displayAnimate();
  
   if (P.getZoneStatus(0))
  {
    switch (display)
    {
      case 0:
         
      P.setPause(0,1000);
      P.setTextEffect(0, PA_MESH, PA_BLINDS);
      display++;    
      dtostrf(Clock.getTemperature(), 3, 1, szMesg);
      strcat(szMesg, "$");
      
      break;

      case 1:
       
      P.setTextEffect(0, PA_OPENING, PA_GROW_DOWN);
      display++;
      dtostrf((1.8 *Clock.getTemperature() )+32, 3, 1, szMesg);
      strcat(szMesg, "&");
        
      break;

      case 2:
     
      P.setFont(0, numeric7Seg);
      P.setTextEffect(0, PA_PRINT, PA_NO_EFFECT);
      P.setPause(0,0);

     if (millis() - lastTime >= 500)  //changed the timing of the flashing : between the hr and min
    {
      lastTime = millis();
      getTime(szMesg, flasher);
      flasher = !flasher;
    }
      if(s==00&& s<=30){
      display++;
      P.setTextEffect(0, PA_PRINT, PA_SCROLL_UP);
    }       
    
      break;
      
      case 3: 
       
      P.setFont(0,nullptr);
      P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
      display++;
      dow2str(Clock.getDoW()+1, szMesg, MAX_MESG); // Added +1 or +2 to get correct Day of Week

      break;
       
      default:  
        
      P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
      display = 0;
      getDate(szMesg);
        
      break;
    }

    P.displayReset(0);  
  }
}

Your post was MOVED to its current location as it is more suitable.

Thank you

If this does not correlate with any patterns in your program flow, you might have a wiring issue.

Everything hooked up solid and adequately powered?

Does the original unaltered program your are modifying perform well?

What is the nature of the changes you are making?

a7

Hi alto
The only change other than reorganizing the code a bit to make it easier to follow was adding P.setIntensity(0,0); because the display is rather bright. thats when the problems started. I am guessing there is some interaction with the case break section but I don't know what it is. I have tried moving the setIntensity command arround but it dosen't help. I have 5 of these built and they all do exactly the same thing.

I also uploaded a short video to youtube so everyone can see what I am talking about.
https://youtu.be/5kEQrTop8bU

Did you have a working version of the code

reorganiz[ed ] a bit    

before you started

 adding P.setIntensity(0,0);

or other features features? It may be that you have to go back to code you didn't write that works, then take smaller careful steps away.

But it does sounding like a software issue. I'll try to throw something at it when I get back. To this. :expressionless:

As for LEDs that are too bright, you are the first to complain. Usually ppl need them to be brighter. But I know what you mean, half blind myself from looking at neopizels, they be hella-bright.

My own solution is free of any code issues: I use neutral grey photographic gel - you can get it in huge sheets at various densities. Not terribly spendy. :wink:

I will say that sometimes pixels under the gel look better than software dimmed. The downside is you display always more current.

a7

Move setIntensity() to setup(). In loop() it is being set thousands of times a second which causes comms to the ICs which stops them displaying while that happens.

Hi Marco
This is a very interesting problem. I moved P.setIntensity(0); to the bottom of the void setup(void) section and it cleared up almost completely. You have to watch very carefully but it will still do it occasionally. Is this because the command P.setIntensity(0); gets resent from time to time or something in the hardware? Thanks for your help.
Rick

Inchestin'.

Do you have an original sketch you could watch as carefully? If something is happened periodically behind the scene presumably it would happen to everyone.

Which is why I don't like that idea. I double intensify or whatever is being issued at random times by "the hardware".

Except for the intensity thing, I don't see anything in your code that would cause the effect you observe.

a7

Hello a7
Thanks again you have great suggestions. Marco's answer was perfect. I did try everything you said. I laser cut some bronze acrylic as a ND filter and thats helps alot. My wife likes it totally dark in the bedroom at night. It will flicker a tiny bit 'and I am being VERY picky here'. ""presumably it would happen to everyone it probably does but they don't notice it."" I used to work in an electronics lab and we had to repeat experiments ad nauseam and I could find a glitch in a glass of water sitting still on a desk LOL..

I consider the problem solved now.
Thank you for the help it was greatly appreciated.
Rick

When one of the MAX7219 ICs changes, the entire string needs to be updated. I assume that the IC is not doing its scanning of the LEDs when this is happening, so you can expect very occasionally to notice the 'glitch' in the LED update if the comms happens at an inopportune time in the scan. The glitch would be more noticeable for a long string of devices (longer time to send update) or if the intensity is low. In your case I think the LED would actually noticeably dim (to off) compared to a much brighter LED that would just dim a little bit to a less bright display and not be noticed. One way to test is to set a higher intensity and see if you still see the issue.