32x32 RGB LED Matrix Panel DCF77

Hello,

I want combine a DCF77 Modul with the 32x32 RGB LED Matrix Panel - 4mm Pitch (PRODUCT ID: 607 adafruit)
Only isolated systems works.

I get the signals from DCF77 and I can interpret the signal in “0” and “1”. (see picture “Es_ist”)
In the next step I want save it in an array (line 85). But if I activate the array the RGB doesn’t work (see picture “red_line”). Without line 85 (array) the RGB works (see picture “Es_ist”).
If I activate more lines with Serial.print(“ “); the RGB also doesn’t work.
My problem is to save the digital numbers in an array or variable because then the RGB doesn’t work.

What can I do better?

Michael

#include <Adafruit_GFX.h>   // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library
 
#define BLINKPIN 13
#define DCF77PIN 12

#define CLK 8  // MUST be on PORTB! (Use pin 11 on Mega)
#define OE  9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2
#define D   A3

RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);

int SignalHIGHStart = 0;
int SignalHIGHEnde = 0;
int SignalHIGHZeit = 0;
int SignalLOWStart = 0;
int SignalLOWEnde = 0;
int SignalLOWZeit = 0;
int stunde = 0;
int minute = 0;
int sekunde = 0;
int wochentag = 0;
int tag = 0;
int monat = 0;
int jahr = 0;

int array[60];
int a;

bool Signal = false;
bool neueMinute = false;
int bitnr = -1;

void setup() 
{
  Serial.begin(9600);
  pinMode(DCF77PIN, INPUT);
  pinMode(BLINKPIN, OUTPUT);
  
  matrix.begin(); 
  // fill the screen with 'black'
  matrix.fillScreen(matrix.Color333(0, 0, 0));
  delay(100);
}

void loop() 
{   
  int pinValue = digitalRead(DCF77PIN); //Wert am PIN einlesen
  
  if (pinValue == HIGH && Signal == false) 
  { //PIN ist HIGH, vorher war kein HIGH
    Signal = true; 
    SignalHIGHStart = millis(); 
    SignalLOWEnde = SignalHIGHStart;  
    SignalLOWZeit = SignalLOWEnde - SignalLOWStart;
   
    //Serial.println(SignalHIGHStart);
    //Serial.println(SignalLOWZeit);
    
 
    //DEBUG Ausgabe nach Serial    
  }
  
  if (pinValue == LOW && Signal == true) 
  { //PIN ist LOW vorher war HIGH
    Signal = false; 
    SignalHIGHEnde = millis();  
    SignalLOWStart = SignalHIGHEnde; 
    SignalHIGHZeit = SignalHIGHEnde - SignalHIGHStart; 
     
    //Serial.println(SignalLOWStart);
    //Serial.println(SignalHIGHZeit); 
    
      bitnr = bitnr + 1;
      a = SignalHIGHZeit; 
      Auswertung();  
      Serial.println(bitnr);
      Serial.println(a);
          
      //array[bitnr] = a;  //without it's works
    
    
    //Serial.print("array[");
    //Serial.print(a);
    //Serial.print("] ist: ");
    //Serial.print(a);
    //Auswertung();
    //Serial.print(" wird jetzt: ");
    //Serial.println(a);
    
    
    
  } //ENDE (pinValue == LOW && Signal == true)
  
  if (SignalLOWZeit >= 1750)
  {
   bitnr = -1; 
   neueMinute = true;
   } 
  
  
  if (neueMinute) 
    {
      ESIST();      
    }
  
    
} //END LOOP

//Gebe den Wert zurück den das Bit aufgrund der HIGH Zeit-Länge haben muss 
int werteBitAus (int SignalHIGHZeit) 
{
  //mit den Zeiten ein wenig größzügig sein, die schwanken um den Optimalwert
   if (SignalHIGHZeit >= 0 && SignalHIGHZeit <= 140) {return 0;} 
   if (SignalHIGHZeit >= 141 && SignalHIGHZeit <= 220) {return 1;}
}
 
//Wenn LOW Zeit größer 1750ms dann neue Minute BitNummer auf 0 setzen, 
//ansonsten BitNummer hochzählen
void feststellenObNeueMinute (int SignalLOWZeit) 
{
  //auch hier ein wenig Luft lassen bei der Zeit.
  if (SignalLOWZeit >= 1750) {bitnr = 0; neueMinute = true;} else {bitnr++; }
}

void Auswertung()
{  
  if (a >= 0 && a <= 140) 
   {
    a = 0;
   } 
  if (a >= 141 && a <= 220)  
   {
    a = 1;
   }   
}

void Kreis()
{
  matrix.drawCircle(16, 20, 7, matrix.Color333(0, 0, 1));
  delay(500);  
}

void ESIST()
{
  //E
  matrix.drawLine(7, 0, 7, 4, matrix.Color333(1, 0, 0));
  matrix.drawLine(8, 0, 9, 0, matrix.Color333(1, 0, 0));
  matrix.drawPixel(8, 2, matrix.Color333(1, 0, 0));
  matrix.drawLine(8, 4, 9, 4, matrix.Color333(1, 0, 0));  
  
  //S
  matrix.drawLine(11, 0, 13, 0, matrix.Color333(1, 0, 0));
  matrix.drawLine(11, 1, 11, 2, matrix.Color333(1, 0, 0));
  matrix.drawPixel(12, 2, matrix.Color333(1, 0, 0));
  matrix.drawLine(13, 2, 13, 4, matrix.Color333(1, 0, 0));
  matrix.drawLine(11, 4, 12, 4, matrix.Color333(1, 0, 0));

  //I
  matrix.drawLine(16, 0, 16, 4, matrix.Color333(0, 1, 0));
  
  //S
  matrix.drawLine(18, 0, 20, 0, matrix.Color333(0, 1, 0));
  matrix.drawLine(18, 1, 18, 2, matrix.Color333(0, 1, 0));
  matrix.drawPixel(19, 2, matrix.Color333(0, 1, 0));
  matrix.drawLine(20, 2, 20, 4, matrix.Color333(0, 1, 0));
  matrix.drawLine(18, 4, 19, 4, matrix.Color333(0, 1, 0));
  
  //T
  matrix.drawLine(22, 0, 24, 0, matrix.Color333(0, 1, 0));
  matrix.drawLine(23, 1, 23, 4, matrix.Color333(0, 1, 0));
}

      //array[bitnr] = a;  //without it's worksHave you got any limits on the value of bitnr ?

Yes, the limt for bitnr are 60 (60 second).

I defined it as int variable.

Michael

Does bitnr ever reach 60 ?

The reason I ask is because

int array[60];

creates an array with 60 elements numbered from 0 to 59

If you execute

     //array[bitnr] = a;  //without it's works

with bitnr equal to 60 then you will be writing to memory that you don't own and could be overwriting something important.

The code of the DCF77 signals change every 60 seconds. I interpret the code and I get the Information for the exact time (minutes, hour, weekday and the date).

I measure the time second to second. It changes between 100ms and 200ms. 100ms is “0” and 200ms is “1”. Well, it is important to overwrite the bitnr every 60 second.

I get the code for minutes in second 21 to 27. The second is equal bitnr. For example (hour:16 minutes) is in DCF77-code:

21 = 0
22 = 1
23 = 1
24 = 0
25 = 1
26 = 0
27 = 0

Of course the bitnr is exactly 0 to 59.

It is better to use: int array[59]; ?

Is it the reason for red lines?

Michael

Hi, what Arduino are you using? Uno?

I think this may be incorrect:

RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);

I think the above may be correct for a 16x32 panel but for a 32x32 panel it should be:

RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false, 32);

If I am correct then right now the matrix library is not allocating enough ram for its own use and therefore using memory taken by your array[] variable. As long as you do not write anything into your array, it works.

Be careful when you change the code as I suggested. This will use 1.5K of the 2K available on Uno, so you must use ram sparingly. For example does your array[] need to be int or would byte be ok? That would save 60 precious bytes.

Paul

It is better to use: int array[59]; ?

Definitely not. If you need room for elements numbered 0 to 59 you need the array to be declared as having 60 elements.

Yes, I use Arduino UNO.

I use in a new sketch

RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false, 32);

but the result is not changing.

I have the same problem, if I use only one or 60 variables.

In the moment I store something the matrix doesn’t work.

I think the examples by adafruit need similar RAM-volume and I think to work step by step an UNO can do this.

Michael

Hi Michael,

Try making your "matrix" object the last variable to be declared in the sketch, i.e. move it to just before "void setup()" like this:

#include <Adafruit_GFX.h>   // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library
 
#define BLINKPIN 13
#define DCF77PIN 12

#define CLK 8  // MUST be on PORTB! (Use pin 11 on Mega)
#define OE  9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2
#define D   A3

int SignalHIGHStart = 0;
int SignalHIGHEnde = 0;
int SignalHIGHZeit = 0;
int SignalLOWStart = 0;
int SignalLOWEnde = 0;
int SignalLOWZeit = 0;
int stunde = 0;
int minute = 0;
int sekunde = 0;
int wochentag = 0;
int tag = 0;
int monat = 0;
int jahr = 0;

int array[60];
int a;

bool Signal = false;
bool neueMinute = false;
int bitnr = -1;

RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false, 32);

void setup() 
{
  Serial.begin(9600);
  pinMode(DCF77PIN, INPUT);
  pinMode(BLINKPIN, OUTPUT);
  
  matrix.begin(); 
  // fill the screen with 'black'
  matrix.fillScreen(matrix.Color333(0, 0, 0));
  delay(100);
}

void loop() 
{   
  int pinValue = digitalRead(DCF77PIN); //Wert am PIN einlesen
  
  if (pinValue == HIGH && Signal == false) 
  { //PIN ist HIGH, vorher war kein HIGH
    Signal = true; 
    SignalHIGHStart = millis(); 
    SignalLOWEnde = SignalHIGHStart;  
    SignalLOWZeit = SignalLOWEnde - SignalLOWStart;
   
    //Serial.println(SignalHIGHStart);
    //Serial.println(SignalLOWZeit);
    
 
    //DEBUG Ausgabe nach Serial    
  }
  
  if (pinValue == LOW && Signal == true) 
  { //PIN ist LOW vorher war HIGH
    Signal = false; 
    SignalHIGHEnde = millis();  
    SignalLOWStart = SignalHIGHEnde; 
    SignalHIGHZeit = SignalHIGHEnde - SignalHIGHStart; 
     
    //Serial.println(SignalLOWStart);
    //Serial.println(SignalHIGHZeit); 
    
      bitnr = bitnr + 1;
      a = SignalHIGHZeit; 
      Auswertung();  
      Serial.println(bitnr);
      Serial.println(a);
          
      //array[bitnr] = a;  //without it's works
    
    
    //Serial.print("array[");
    //Serial.print(a);
    //Serial.print("] ist: ");
    //Serial.print(a);
    //Auswertung();
    //Serial.print(" wird jetzt: ");
    //Serial.println(a);
    
    
    
  } //ENDE (pinValue == LOW && Signal == true)
  
  if (SignalLOWZeit >= 1750)
  {
   bitnr = -1; 
   neueMinute = true;
   } 
  
  
  if (neueMinute) 
    {
      ESIST();      
    }
  
    
} //END LOOP

//Gebe den Wert zurück den das Bit aufgrund der HIGH Zeit-Länge haben muss 
int werteBitAus (int SignalHIGHZeit) 
{
  //mit den Zeiten ein wenig größzügig sein, die schwanken um den Optimalwert
   if (SignalHIGHZeit >= 0 && SignalHIGHZeit <= 140) {return 0;} 
   if (SignalHIGHZeit >= 141 && SignalHIGHZeit <= 220) {return 1;}
}
 
//Wenn LOW Zeit größer 1750ms dann neue Minute BitNummer auf 0 setzen, 
//ansonsten BitNummer hochzählen
void feststellenObNeueMinute (int SignalLOWZeit) 
{
  //auch hier ein wenig Luft lassen bei der Zeit.
  if (SignalLOWZeit >= 1750) {bitnr = 0; neueMinute = true;} else {bitnr++; }
}

void Auswertung()
{  
  if (a >= 0 && a <= 140) 
   {
    a = 0;
   } 
  if (a >= 141 && a <= 220)  
   {
    a = 1;
   }   
}

void Kreis()
{
  matrix.drawCircle(16, 20, 7, matrix.Color333(0, 0, 1));
  delay(500);  
}

void ESIST()
{
  //E
  matrix.drawLine(7, 0, 7, 4, matrix.Color333(1, 0, 0));
  matrix.drawLine(8, 0, 9, 0, matrix.Color333(1, 0, 0));
  matrix.drawPixel(8, 2, matrix.Color333(1, 0, 0));
  matrix.drawLine(8, 4, 9, 4, matrix.Color333(1, 0, 0));  
  
  //S
  matrix.drawLine(11, 0, 13, 0, matrix.Color333(1, 0, 0));
  matrix.drawLine(11, 1, 11, 2, matrix.Color333(1, 0, 0));
  matrix.drawPixel(12, 2, matrix.Color333(1, 0, 0));
  matrix.drawLine(13, 2, 13, 4, matrix.Color333(1, 0, 0));
  matrix.drawLine(11, 4, 12, 4, matrix.Color333(1, 0, 0));

  //I
  matrix.drawLine(16, 0, 16, 4, matrix.Color333(0, 1, 0));
  
  //S
  matrix.drawLine(18, 0, 20, 0, matrix.Color333(0, 1, 0));
  matrix.drawLine(18, 1, 18, 2, matrix.Color333(0, 1, 0));
  matrix.drawPixel(19, 2, matrix.Color333(0, 1, 0));
  matrix.drawLine(20, 2, 20, 4, matrix.Color333(0, 1, 0));
  matrix.drawLine(18, 4, 19, 4, matrix.Color333(0, 1, 0));
  
  //T
  matrix.drawLine(22, 0, 24, 0, matrix.Color333(0, 1, 0));
  matrix.drawLine(23, 1, 23, 4, matrix.Color333(0, 1, 0));
}

It still appears to me to be a problem with use of the same ram memory by more than one object. Perhaps this change will prove it.

I think you have enough ram on Uno for the sketch above, but you must be fairly close to the limit, so if you add more variables to the sketch, you must try to use the smallest sizes for variables that can hold the largest value needed.

Your array[] is currently declared as int, so takes 120 bytes. But you only ever store 0 or 1 in each element. If you used byte, it would need 60 bytes. If you did not use an array, but instead used an unsigned long long variable, it would only take 4 bytes. An unsigned long long is 64 bits. Unfortunately you can not read the individual bits with bitWrite() and bitRead(), because they don't work with unsigned long long. You would have to use bit manipulation like << >> & etc.