Matrix7219 displays scrambled display on ESP32C mini

Hi everybody,
today I would like to solve a strange problem with 7219Matrix displays which I am using on several projects and often get the same problem: The output on the Matrix gets scrambled after a few minutes working well. Actually on my NANO processors they work pretty fine but on any ESP32 processor I get this strange effect which I show on the pictures below: First the working Version on a ATmega 328P NANO:



code for this Version is

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DS3231.h>
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiAvrI2c.h>

int pinMin = 10;
int pinHour = 9;
int pinLight = 5; 
int GetBtn = 6; // left button
int SetBtn = 7; // right button
//Din connects to pin 11
//CLK connects to pin 13

int numberOfHorizontalDisplays = 10;
int numberOfVerticalDisplays = 1;

int HourPosRect5[4] = {41,51,61,71};
int HourPosRect1[4] = {1,11,21,31};

int MinPosBars[11] = {40,43,46,51,54,57,62,65,68,73,76};
int MinPosRect[4] = {1,11,21,31};
int yPos = 0;
int Hori = 2; // 2 for bars 8 for rectangle
int Vert = 8;
int numHour5;
int numHour1;
int numMinBars;
int numMinRect;
int H5rect;
int H1rect;
int Mbar;
int Mrect;

unsigned long currentMillis;
unsigned long startTimer;
bool LightON;
byte Year ;
byte Month ;
byte Date ;
byte DoW ;
byte Hour ;
byte Minute ;
byte Second ;
bool Century=false;
bool h12 ;
bool PM ;

const char *WeekDay[] = { "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado","Domingo" };
//const char *Mon[] = {"XXX", "ENE", "FEB", "MAR", "ABR", "MAY", "JUN", "JUL", "AGO", "SEP", "OCT", "NOV", "DIC"};
bool END;
int Block[7];
int dispPos=0;
int setVal=0;

#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES  20
#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define pinMin    10  // Minute Matrix
#define pinHour    9  // Hour Matrix

SSD1306AsciiAvrI2c win;
Max72xxPanel matMin = Max72xxPanel(pinMin, numberOfVerticalDisplays, numberOfHorizontalDisplays);
Max72xxPanel matHour = Max72xxPanel(pinHour, numberOfVerticalDisplays, numberOfHorizontalDisplays);

DS3231 Clock;

void setup() 
{
  pinMode(pinLight, OUTPUT);
  pinMode(GetBtn, INPUT);
  pinMode(SetBtn, INPUT);
  
  matMin.setIntensity(2);
  matMin.setRotation(0);
  matHour.setIntensity(2);
  matHour.setRotation(0);

  matMin.fillScreen(LOW); matMin.write();
  matHour.fillScreen(LOW); matHour.write();


  Wire.begin();
   win.begin(&SH1106_128x64, 0x3c);
   win.setFont(System5x7);
   win.clear();
   
 Clock.setClockMode(false);
 
 //Clock.setSecond(0);
 //Clock.setMinute(54);
 //Clock.setHour(18);
 
    Block[0] = Clock.getYear(), DEC;
    Block[1] = Clock.getMonth(Century), DEC;
    Block[2] = Clock.getDate(), DEC;
    Block[3] = Clock.getDoW(), DEC;
    Block[4] = Clock.getHour(h12,PM), DEC;
    Block[5] = Clock.getMinute(),DEC;
    Block[6] = Clock.getSecond(),DEC;

   win.println("RTC hora actual es ");
   win.println("---------------------");
  
   if(Block[2]<10) {win.print("0");}
   win.print(Block[2]);
   win.print(".");
   if(Block[1]<10) {win.print("0");}
   win.print(Block[1]);
   win.print(". 20");
   win.print(Block[0]);
   win.print(" ");
   //Clock.setClockMode(false);
   win.print(Block[4]); 
   win.print(":");
   win.print(Block[5]);
   win.print(":");
   win.println(Block[6]);
   win.println(" ");
   win.println("<- Boton: ajuste hora");
   win.println(" ");
   win.println("Boton -> start reloj"); 

  while (!digitalRead(GetBtn) && !digitalRead(SetBtn)) {;}

  if(digitalRead(SetBtn)) {analogWrite(pinLight, 100);}

// **************** NOW INPUT DATA *******************
   if (digitalRead(GetBtn))
   {
    win.clear();
    delay(200);
    InputData();
   }
  win.clear();

 // Set Clock Condition
 
 //analogWrite(pinLight, 100);

 delay(1000); 
}

void loop() 
{
  startTimer=millis();
  if (startTimer > currentMillis+1000)
   {
    showTime();
    if (LightON)
     { LightON=false; analogWrite(pinLight, 0);}
    else
     { LightON=true; analogWrite(pinLight, 100);} 
    currentMillis=millis(); 
   }
   

  matMin.fillScreen(LOW);
  matHour.fillScreen(LOW);
  
  Hour = Clock.getHour(h12,PM);
  Minute = Clock.getMinute();

  // calculate Hour fields
  numHour5 = Hour/5;
  numHour1 = Hour-(numHour5*5);
   
  //calculate Minute bars
  numMinBars = Minute/5;
  numMinRect = Minute-(numMinBars*5);

  // draw Hour bars and fields
  Hori=8;
   for(H5rect=0; H5rect<numHour5; H5rect++)
   {
    matHour.drawRect(yPos, HourPosRect5[H5rect], Vert, Hori,HIGH);
    matHour.drawRect(yPos+1, HourPosRect5[H5rect]+1, Vert-2, Hori-2,HIGH);
   }  
    for(H1rect=0; H1rect<numHour1; H1rect++)
   {
    matHour.drawRect(yPos, HourPosRect1[H1rect], Vert, Hori,HIGH);
    matHour.drawRect(yPos+1, HourPosRect1[H1rect]+1, Vert-2, Hori-2,HIGH);
   }  
  Hori = 2;
  for(Mbar=0; Mbar < numMinBars; Mbar++)
   {
    matMin.drawRect(yPos, MinPosBars[Mbar], Vert, Hori,HIGH);
   }
  Hori=8;
  for(Mrect=0; Mrect<numMinRect; Mrect++)
   {
    matMin.drawRect(yPos, MinPosRect[Mrect], Vert, Hori,HIGH);
    matMin.drawRect(yPos+1, MinPosRect[Mrect]+1, Vert-2, Hori-2,HIGH);
   } 
   matMin.write();
   matHour.write();
}

void InputData()
  {
       while (setVal<7) // input date/time values
        {
        if (digitalRead(GetBtn)) // ajust actual value
         {
          Block[setVal]++ ;
          if (Block[0] > 32) {Block[0] = 22;}
          if (Block[1] > 12) {Block[1] = 1;}
          if (Block[2] > 31) {Block[2] = 1;}
          if (Block[3] > 7 ) {Block[3] = 1;}
          if (Block[4] > 23) {Block[4] = 0;}
          if (Block[5] > 59) {Block[5] = 0;}
          if (Block[6] > 59) {Block[6] = 0;}      
          
          delay(100);      
         }
         
         if (digitalRead(SetBtn)) // set value and goto next 
         {
          setVal++;
          delay(100);
         }  
         showInput();
         delay(200);    
        } // ready input date/time values 0 to 5
     
    win.clear();
    win.setCursor(0,1);
    win.print("Ajuste Hora listo");
    while(!digitalRead(SetBtn)) {;}
    
    SetClock();
  }


void showInput()
 {
  win.home();
  win.setFont(System5x7);
  win.println("ingresar fecha/hora");
  win.println("---------------------");

  win.setCursor(0,2);
  win.println("Ano   Mes  Dia  Sem");
  for (dispPos=0; dispPos<4; dispPos++)
  {
    win.setCursor((dispPos*34),3);
    if (dispPos==setVal) {win.setInvertMode(true);} else {win.setInvertMode(false);}
    win.setFont(cp437font8x8);
    if (Block[dispPos] < 10) {win.print("0"); win.print(Block[dispPos]);} else  {win.print(Block[dispPos]);}
    win.setFont(System5x7);
  }
  win.setInvertMode(false);
  win.setCursor(0,5);
  win.print("Hora Minuto Segundo");
    for (dispPos=4; dispPos<7; dispPos++)
  {
  win.setCursor(((dispPos-4)*36),6);

  if (dispPos==setVal) {win.setInvertMode(true);} else {win.setInvertMode(false);}
  win.setFont(cp437font8x8);
  if (Block[dispPos] < 10) {win.print("0"); win.print(Block[dispPos]);} else  {win.print(Block[dispPos]);}
  win.setFont(System5x7);
  //delay(100);
  }
  win.setInvertMode(false);
 } 

void SetClock()
  {
   Clock.setClockMode(false);  // set to 24h
   Clock.setSecond(Block[6]);
   Clock.setMinute(Block[5]);
   Clock.setHour(Block[4]);
   Clock.setDoW(Block[3]);
   Clock.setDate(Block[2]);
   Clock.setMonth(Block[1]);
   Clock.setYear(Block[0]);

   win.setCursor(30,3);
   win.print("* LISTO *");
   delay(1000);
   win.clear();      
  }

void showTime()
{
    
   win.setFont(cp437font8x8);
   win.setCursor(0,0);
   win.print(Clock.getDate(), DEC);
   win.print(".");
   win.print(Clock.getMonth(Century), DEC);
   win.print(".");
   //win.print(Clock.getYear(), DEC);
   win.print("             ");
   win.setCursor(60,0);
   win.print(WeekDay[Clock.getDoW()-1]);

   win.setFont(fixed_bold10x15);
   win.setCursor(20,4);
   if ((Clock.getHour(h12, PM)) < 10){win.print("0");}
   win.print(Clock.getHour(h12, PM));
   win.print(":");
   if ((Clock.getMinute()) < 10){win.print("0");} 
   win.print(Clock.getMinute());
   win.print(":");
   if ((Clock.getSecond()) < 10){win.print("0");}
   win.print(Clock.getSecond());
   win.print("  ");
}

The ESP32 Version is this one:


#include <SPI.h>
#include <Adafruit_GFX.h>
#include <SH1106Wire.h>
#include <Max72xxPanel.h>
#include <DS3231.h>
#include <Wire.h>
int pinMin = 7;
int pinHour = 10;
int pinLight = 2; 
int GetBtn = 0; // left button
int SetBtn = 1; // right button
//Din connects to pin 6
//CLK connects to pin 4

int numberOfHorizontalDisplays = 10;
int numberOfVerticalDisplays = 1;

int HourPosRect5[4] = {41,51,61,71};
int HourPosRect1[4] = {1,11,21,31};

int MinPosBars[11] = {40,43,46,51,54,57,62,65,68,73,76};
int MinPosRect[4] = {1,11,21,31};
int yPos = 0;
int Hori = 2; // 2 for bars 8 for rectangle
int Vert = 8;
int numHour5;
int numHour1;
int numMinBars;
int numMinRect;
int H5rect;
int H1rect;
int Mbar;
int Mrect;

unsigned long timer1;
unsigned long timer2;
bool LightON;
byte Year ;
byte Month ;
byte Date ;
byte DoW ;
byte Hour ;
byte Minute ;
byte Second ;
bool Century=false;
bool h12 ;
bool PM ;

const char *WeekDay[] = { "Lun", "Mar", "Mie", "Jue", "Vie", "Sab","Dom" };
const char *Mon[] = {"XXX", "ENE", "FEB", "MAR", "ABR", "MAY", "JUN", "JUL", "AGO", "SEP", "OCT", "NOV", "DIC"};
bool END;
int Block[7];
int dispPos=0;
int setVal=0;
int cy;
int cx;
int line = 10;
int chra = 7;
int cleft = 15;


//SSD1306AsciiAvrI2c win;
SH1106Wire win(0x3c, SDA, SCL);
Max72xxPanel matMin = Max72xxPanel(pinMin, numberOfVerticalDisplays, numberOfHorizontalDisplays);
Max72xxPanel matHour = Max72xxPanel(pinHour, numberOfVerticalDisplays, numberOfHorizontalDisplays);

DS3231 Clock;

void setup() 
{
  pinMode(pinLight, OUTPUT);
  pinMode(GetBtn, INPUT);
  pinMode(SetBtn, INPUT);
  
  matMin.setIntensity(2);
  matMin.setRotation(0);
  matHour.setIntensity(2);
  matHour.setRotation(0);

  matMin.fillScreen(LOW); matMin.write();
  matHour.fillScreen(LOW); matHour.write();


  Wire.begin();

   win.init();
   win.flipScreenVertically();
   win.setContrast(255);
   win.setColor(WHITE);
   win.cls();

   //win.setFont(ArialMT_Plain_10);
   //win.setTextAlignment(TEXT_ALIGN_LEFT);
   
 Clock.setClockMode(false);
 
 //Clock.setSecond(0);
 //Clock.setMinute(54);
 //Clock.setHour(18);
 
    Block[0] = Clock.getYear(), DEC;
    Block[1] = Clock.getMonth(Century), DEC;
    Block[2] = Clock.getDate(), DEC;
    Block[3] = Clock.getDoW(), DEC;
    Block[4] = Clock.getHour(h12,PM), DEC;
    Block[5] = Clock.getMinute(),DEC;
    Block[6] = Clock.getSecond(),DEC;

   cx=cleft;cy=0;win.drawString(cx,cy,"RTC actual time is :");
   cy=line;win.drawString(cx,cy,"---------------------------------");
   showTime();

   cy=5*line;cx=cleft-15;
   win.drawString(cx,cy,"<- adjust Hour:Start Clock ->");
   win.display();
  while (!digitalRead(GetBtn) && !digitalRead(SetBtn)) {;}

  if(digitalRead(SetBtn)) {analogWrite(pinLight, 100);}

// **************** NOW INPUT DATA *******************
   if (digitalRead(GetBtn))
   {
    win.cls();
    delay(200);
    InputData();
   }
  //win.cls();

 // Set Clock Condition
 
 //analogWrite(pinLight, 100);

 delay(1000); 
}

void loop() 
{
  timer2=millis();
  if (timer2 > timer1+1000)
   {
    win.clear();
    showTime();
    win.display();
    if (LightON)
     { LightON=false; analogWrite(pinLight, 0);}
    else
     { LightON=true; analogWrite(pinLight, 100);} 
    timer1=millis(); 
   }

 
  matMin.fillScreen(LOW);
  matHour.fillScreen(LOW);
  
  Hour = Clock.getHour(h12,PM);
  Minute = Clock.getMinute();

  // calculate Hour fields
  numHour5 = Hour/5;
  numHour1 = Hour-(numHour5*5);
   
  //calculate Minute bars
  numMinBars = Minute/5;
  numMinRect = Minute-(numMinBars*5);

  // draw Hour bars and fields
  Hori=8;
   for(H5rect=0; H5rect<numHour5; H5rect++)
   {
    matHour.drawRect(yPos, HourPosRect5[H5rect], Vert, Hori,HIGH);
    matHour.drawRect(yPos+1, HourPosRect5[H5rect]+1, Vert-2, Hori-2,HIGH);
   }  
    for(H1rect=0; H1rect<numHour1; H1rect++)
   {
    matHour.drawRect(yPos, HourPosRect1[H1rect], Vert, Hori,HIGH);
    matHour.drawRect(yPos+1, HourPosRect1[H1rect]+1, Vert-2, Hori-2,HIGH);
   }  
  Hori = 2;
  for(Mbar=0; Mbar < numMinBars; Mbar++)
   {
    matMin.drawRect(yPos, MinPosBars[Mbar], Vert, Hori,HIGH);
   }
  Hori=8;
  for(Mrect=0; Mrect<numMinRect; Mrect++)
   {
    matMin.drawRect(yPos, MinPosRect[Mrect], Vert, Hori,HIGH);
    matMin.drawRect(yPos+1, MinPosRect[Mrect]+1, Vert-2, Hori-2,HIGH);
   } 
   matMin.write();
   matHour.write();
 
}

void InputData()
  {
       while (setVal<7) // input date/time values
        {
        if (digitalRead(GetBtn)) // ajust actual value
         {
          Block[setVal]++ ;
          if (Block[0] > 32) {Block[0] = 22;}
          if (Block[1] > 12) {Block[1] = 1;}
          if (Block[2] > 31) {Block[2] = 1;}
          if (Block[3] > 7 ) {Block[3] = 1;}
          if (Block[4] > 23) {Block[4] = 0;}
          if (Block[5] > 59) {Block[5] = 0;}
          if (Block[6] > 59) {Block[6] = 0;}      
          
          delay(100);      
         }
         
         if (digitalRead(SetBtn)) // set value and goto next 
         {
          setVal++;
          delay(100);
         }  
         showInput();
         win.display();
         delay(200);    
        } // ready input date/time values 0 to 5
     
    win.cls();
    cx=2*chra; cy=line;
    win.drawString(cx,cy,"adjust hour ready");
    win.display();
    while(!digitalRead(SetBtn)) {;}
    
    SetClock();    
  }


void showInput()
 {
  win.clear();
  cx=chra; cy=0;
  win.drawString(cx,cy,"input date and time");
  cx=chra; cy=line; win.drawString(cx,cy,"---------------------");

  cx=chra; cy=2*line;
  win.drawString(cx,cy,"Year    Mon    Day   DoW");
  for (dispPos=0; dispPos<4; dispPos++)
  {
    cx=dispPos*30+chra+8; cy=3*line; //    win.setCursor((dispPos*34),3);
    //if (dispPos==setVal) {win.setColor(WHITE);} else {win.setColor(BLACK);}
    if (dispPos==setVal) {win.drawRect(cx-2,cy+1,16,11);}
    if (Block[dispPos] < 10) {win.drawString(cx,cy,"0"); cx+=chra; win.drawString(cx,cy,String(Block[dispPos]));} else  {win.drawString(cx,cy,String(Block[dispPos]));}
  }
  cx=chra; cy=4*line; //win.setCursor(0,5);
  win.drawString(cx,cy,"Hour   Minute   Second");
    for (dispPos=4; dispPos<7; dispPos++)
     {
      cx=(dispPos-4)*40+chra; cy=5*line; //win.setCursor(((dispPos-4)*36),6);
      if (dispPos==setVal) {win.drawRect(cx-2,cy+1,16,11);}
      //win.setFont(cp437font8x8);
      if (Block[dispPos] < 10) {win.drawString(cx,cy,"0"); cx+=chra; win.drawString(cx,cy,String(Block[dispPos]));} else  {win.drawString(cx,cy,String(Block[dispPos]));}
      //win.setFont(System5x7);
      //delay(100);
     }
 } 

void SetClock()
  {
   Clock.setClockMode(false);  // set to 24h
   Clock.setSecond(Block[6]);
   Clock.setMinute(Block[5]);
   Clock.setHour(Block[4]);
   Clock.setDoW(Block[3]);
   Clock.setDate(Block[2]);
   Clock.setMonth(Block[1]);
   Clock.setYear(Block[0]);

   win.cls();
   cx=2*chra; cy=0;   //win.setCursor(30,3);
   win.drawString(cx,cy,"* Clock time set to : *");
   showTime();
   win.display();
   delay(2000); 
  }

void showTime()
{
   cx=cleft;cy=2*line;
   win.drawString(cx,cy,WeekDay[Clock.getDoW()]);cx+=3*chra;
   if(Clock.getDate()<10) {win.drawString(cx,cy,"0");cx+=chra;}
   win.drawString(cx,cy,String(Clock.getDate()));
   if(Clock.getDate()>9) {cx+=chra;}
   cx+=chra;win.drawString(cx,cy,".");
   cx+=chra; win.drawString(cx,cy,Mon[Clock.getMonth(Century)]);cx+=2*chra;
   if(Block[1]>9) {cx+=chra;}   
   cx+=2*chra;win.drawString(cx,cy,String(Clock.getYear()+2000));

   cy=3*line+5;cx=cleft+20;
   if(Clock.getHour(h12,PM)<10) {win.drawString(cx,cy,"0");cx+=chra;}
   win.drawString(cx,cy,String(Clock.getHour(h12,PM)));
   if(Clock.getHour(h12,PM)>9) {cx+=chra;}
   cx+=chra;win.drawString(cx,cy,":");
   if(Clock.getMinute()<10) {cx+=chra;win.drawString(cx,cy,"0");}
   cx+=chra;win.drawString(cx,cy,String(Clock.getMinute()));
   if(Clock.getMinute()>9) {cx+=chra;}
   cx+=chra;win.drawString(cx,cy,":");
   if(Clock.getSecond()<10) {cx+=chra;win.drawString(cx,cy,"0");}
   cx+=chra;win.drawString(cx,cy,String(Clock.getSecond()));

   //win.display();
}

Just for understanding this strange project is a special clock unique in the world which you can find in the city of Berlin.

I know that NANO works with 5V and ESP with 3.3V
I know that these Matrix displays work with 5V powersupply and 5V logic signal level
I know that these Matrix displays need to be powered externally with a strong powersupply (I am using a 5V 3A powersupply but these displays are pretty small and on the NANO it works with a simple 2A cellphone charger)
I know that the GND of processor and matrix devices need to be connected together
I am also using a levelshifter for the SPA signals. Actually with or without levelshifter there is the same issue.

Somebody has an idea what this strange issue is about ?

Your compiler does not mind the re-definition of Nano pinMin and pinHour?

pinMin and pinHour are the Chipselectlines for the two separated Matrixdisplays for Minutes and Hours. I don´t see where they are defined more than once.

You have been staring at your code too long. Enjoy a bicycle ride.

Ohh yes you are right, the #define Block is from some tests with the display and accidently keeps in the program. But the compiler does not care

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.