Arduino Projekt: LED Matrix Uhr

Mit zwei (oder mehr) MAX7219 lässt sich relativ einfach und schnell eine LED Uhr erzeugen. Als Zeitgeber verwende ich ein RTC Modul DS3231.

Benötigte Bauteile

Für den Ausbau verwende ich folgende Bauteile:

Das Shield MAX7219

Das Shield gibt es bei eBay.de aufgebaut und nicht aufgebaut zu kaufen, wenn man sich mit dem Lötkolben gut auskennt, dann kann ich das Kit zum selber aufbauen empfehlen.

Aufbau

Das Projekt besteht aus 2x MAX7219 LED Matrix Shields sowie einer RTC und dem Arduino UNO.

Modul Arduino UNO
 MAX7219 LED Matrix Shield
VCC  5V
GND  GND
DIN  digitaler PIN 9
 CS  digitaler PIN 10
CLK  digitaler PIN 11
RTC DS3231
VCC  5V
GND  GND
 SDA  analoger PIN A4
 SCL  analoger PIN A5
Aufbau der Schaltung für die LED Matrix Uhr
Aufbau der Schaltung für die LED Matrix Uhr

Der Anschlussplan für dieses Projekt sieht wie folgt aus:

Anschlussplan für MAX7219 LED Matrix Uhr mit RTC
Anschlussplan für MAX7219 LED Matrix Uhr mit RTC

Quellcode

Der nachfolgende Quellcode ist nur ein Auszug, es werden noch die Dateien „statics.h“, „rtc_functions.h“ sowie „max7219_functions.h“ benötigt (Diese sind am Ende de Tutorials als Paket zum Download bereitgestellt.) Des Weiteren wird die Bibliothek für das Max7219 Shield und die Wire.h Bibliothek benötigt.

//Die Bibliotheken 
#include <MaxMatrix.h>
#include <avr/pgmspace.h>
#include <Wire.h>
#define RTC_I2C_ADDRESS 0x68 // I2C Adresse des RTC  DS3231

int data = 8;    // DIN Pin vom MAX7219 Shield
int load = 9;    // CS Pin vom MAX7219 Shield
int clock = 10;  // CLK Pin vom MAX7219 Shield

int maxInUse = 2;    //Dieser Wert bestimmt wieviele MaxMatrix Shields hintereinander (kaskadiert) verwendet werden.

MaxMatrix m(data, load, clock, maxInUse); // Definiert nun ein Objekt der Klasse MaxMatrix.
//Ausgelagerte CHAR Arrays damit dieser Code übersichtlicher bleibt.
#include "statics.h" 
//Funktionen für die RTC DS3231
#include "rtc_functions.h"
//Funktionen für das MAX7219 Shield
#include "max7219_functions.h"

//Die Nachricht welche auf dem Shield dargestellt
//werden soll als Char Array.
char msg[] = {""};

void setup(){
  Wire.begin(); //Kommunikation über die Wire.h bibliothek beginnen.
  m.init(); // Das Max7219 initialisieren.
  m.setIntensity(1); // LED Leucht intensität, Werte von 0-15 sind hier erlaubt.
  Serial.begin(9600); // Übertragungsgeschwindigeit der seriellen Verbindung
}

void loop(){
  //Lesen der aktuellen Zeit
  rtcReadTime();
  String dateTime = getRTCDateTime();
  //Umwandeln des String wertes in ein Char Array.
  dateTime.toCharArray(msg, dateTime.length());
  //Schreibt die Message auf die Max LED Matrix, mit einer wiederholungsgeschwindigkeit von 75ms.
  printStringWithShift(msg, 75);

  //Es muss einmalig die Zeit gesetzt werden, dazu also die Funktion "setRTCTime" auskommentieren
  //und auf dem Seriellen Monitor mit set DD.MM.YYY HH:mm:ss das Datum nd die Uhrzeit einmalig setzen
  //setRTCTime();
}

//Gibt einen Zeitstempel auf der Seriellen Schnittstelle aus.
String getRTCDateTime(){
  char linebuf[60];
  int dOW = calcDayOfWeek(jahr, monat, tag);
  String wochentagC = daysInWeek[dOW];
  String monatC = monthInYear[monat-1];
 
  String result = "";
  if(tag<10) { result += "0"; }
  result += tag;
  result += ".";
  if(monat<10) { result += "0"; }
  result += monat;
  result += " ";  
  result += jahr;  
  result += " "; 
  if(stunde<10) { result += "0"; }
  result += stunde;  
  result += ":";  
  if(minute<10) { result += "0"; }
  result += minute;  
  result += ":"; 
  if(sekunde<10) { result += "0"; }
  result += sekunde;  
  result += "  "; 
  return result; 
}
 
//Manuelles setzen der Uhrzeit über den Seriellen Monitor der IDE.
void setRTCTime(){
  char linebuf[30];
  byte counter;
  if (Serial.available()){
    delay(100); // Warte auf das Eintreffen aller Zeichen vom seriellen Monitor
    memset(linebuf,0,sizeof(linebuf)); // Zeilenpuffer löschen
    counter=0; // Zähler auf Null
    while (Serial.available()){
      linebuf[counter]=Serial.read(); // Zeichen in den Zeilenpuffer einfügen
      if (counter<sizeof(linebuf)-1) counter++; // Zeichenzähler erhöhen
    }
    // Wenn in der gelesenen Zeile das Wort 'set' vorkommt dann...
    //(Hier muss man bedenken das die Suche nach 'set' auch nach x Zeichen ein positives Ergebnis liefern wird, zbsp. 123set 09.01.2016 12:00:00)
    if (strstr(linebuf,"set")==linebuf){ 
      tag=getIntFromString (linebuf,1);
      monat=getIntFromString (linebuf,2);
      jahr=getIntFromString (linebuf,3);
      stunde=getIntFromString (linebuf,4);
      minute=getIntFromString (linebuf,5);
      sekunde=getIntFromString (linebuf,6);
    } else {
      Serial.println("Befehl unbekannt.");
      return;
    }
    // Ausgelesene Werte einer groben Plausibilitätsprüfung unterziehen:
    if (!checkDateTime(jahr, monat, tag, stunde, minute, sekunde)){
      Serial.println(linebuf);
      Serial.println("Fehlerhafte Zeitangabe im 'set' Befehl");
      Serial.println("Beispiel: set 28.08.2013 10:54");
      return;
    }
    rtcWriteTime(jahr, monat, tag, stunde, minute, sekunde);
    Serial.println("Zeit und Datum wurden auf neue Werte gesetzt.");
  }
}
 
//Prüft das eingegebene Datum auf korrektheit.
boolean checkDateTime(int jahr, int monat, int tag, int stunde, int minute, int sekunde){
   boolean result = false;
   if(jahr>2000){
     result = true;  
   } else {
     return false;
   }
   // Schaltjahr prüfen
   if(jahr % 400 == 0 || (jahr % 100 != 0 && jahr % 4 == 0)){
     //Wenn es ein Schaltjahr ist dann den Wert 29 in das Array an der Stelle 1 für den Monat Februar schreiben.
     daysInMonth[1]=29;
   }
   
   //Monat muss kleiner 13 sein.
   if (monat<13){
      if( tag <= daysInMonth[monat-1] ){
        result = true;
      }
   } else {
     return false;
   }
    
  //Wert für Stunde muss zwischen 0 und 24 liegen,
  //Wert für Minute und sekunde muss zwischen 0 und 59 liegen
  if(stunde <24 && minute <60 && sekunde <60 && stunde >= 0 && minute >=0 && sekunde >=0){
        result = true;
  } else {
     return false;
   }
   
   return result;
}

Video

Arduino LED Uhr mit Max7219 Shield

Download

14 Kommentare

    1. Hallo zusammen,
      gibt es hier mittlerweile eine Lösung damit die ANzeige auch wieder sauber von links nach rechts läuft?

      Gruß Hansi

      1. Hi,

        ich habe bisher noch keine Zeit gehabt mich damit zu beschäftigen.
        Das steht jedoch ziemlich weit oben auf meiner ToDo Liste.

        Gruß,

        Stefan

    1. Hi,

      die Zeit kann zbsp. über den seriellen Monitor der Arduino IDE gesetzt werden.
      Wenn dieses Fenster geöffnet wird und der Microcontroller gestartet wird, sollte ein Text erscheinen welcher den Befehl erläutert.

      Beispiel: set 28.08.2013 10:54

      Gruß,

      Stefan

      1. Hallo Stefan,

        Fenster geöfnet aber leer, Ich habe zeit gegeben und gesendet aber funktioniert nicht, ich mache ein fehler aber wo..?

        Grüß

        Alex

        1. Hi Alex,

          leider verstehe ich dein Problem nicht.
          Gerne kannst du auch in englisch schreiben wenn es für dich einfacher ist.
          Dein Sketch kannst du mir gerne per E-Mail senden, dann schaue ich mir es mal an.

          Gruß,

          Stefan

        1. Hi,

          ich verstehe nicht welchen Sketch. Auf dem Chip des Bausatzes ist bereits ein fertiges Sketch / Programm drauf.

          Gruß,

          Stefan Draeger

  1. Hi,
    Ich habe jetzt ne Stunde rumgespielt und kann die Zeit immernoch nicht einstellen.
    Wenn ich setRTCTime auskommentiere kommt ein Fehler beim überprüfen.
    Der serielle Monitor zeigt nichts.
    Könntest du es bitte erklären (für dumme).
    Hier mal die Stelle im Code:
    //Manuelles setzen der Uhrzeit über den Seriellen Monitor der IDE.
    void setRTCTime(){
    char linebuf[30];
    byte counter;
    if (Serial.available()){
    delay(100); // Warte auf das Eintreffen aller Zeichen vom seriellen Monitor
    memset(linebuf,0,sizeof(linebuf)); // Zeilenpuffer löschen
    counter=0; // Zähler auf Null
    while (Serial.available()){
    linebuf[counter]=Serial.read(); // Zeichen in den Zeilenpuffer einfügen
    if (counter<sizeof(linebuf)-1) counter++; // Zeichenzähler erhöhen
    _____________________________________________________________________
    Gruß
    Rob

    1. Hi Robert,

      ich habe gemerkt das so einige ein Problem mit diesem Beitrag haben, daher habe ich mich entschlossen einen erweiterten Beitrag zu verfassen wo ich hoffentlich alle Fragen abschließend klären kann.

      Gruß,

      Stefan Draeger

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert