Wortuhr Qlock2 Arduino Uno Code gesucht

Hallo zusammen,
folgendes Anliegen: vor einigen Jahren hat mein Vater eine Wortuhr gebastelt, welche ich geerbt habe. Bis vor kurzem lief sie auch recht stabil (mit 5min Differenz). Leider habe ich von der Materie keine Ahnung und die Uhr beim Versuch auf Sommerzeit umzustellen platt gemacht. Ich habe bereits ausgiebig in den Foren gesucht - es gibt ja hierzu genug - leider finde ich nicht den passenden Sketch zu meiner Uhr... Ein Backup des Codes steht leider auch nicht mehr zur Verfügung.
Hier die Infos, soweit ich es herausfinden konnte: Es handelt sich um eine einfache Ausführung nach dem Design QlockTwo, mit Arduino Uno, RTC Modul (Typ?), keine Funkuhr, WLAN oder sonstiges. Habe einige Fotos angefügt, aus der hoffentlich alle Details hervorgehen.
Es wäre super, wenn mir jemand helfen könnte, den passenden Sketch zu finden bzw. eine Anleitung, wie ich die Uhr wieder zum Laufen kriege. Sorry für meine Ahnungslosigkeit, aber ich hänge sehr an der Uhr, da es ein Erinnerungsstück an meinen verstorbenen Vater ist!
Danke im Voraus
Desiree

Das entscheidende Foto ist ziemlich schlecht, ich meine aber ein RTC Modul zu erkennen. Dieses kannst du mit jedem Arduino stellen. Falls noch nicht vorhanden, nimm dieses: DS3231
Weiteres hier:

Hallo,
was hast du gemacht?
Was funktioniert nicht mehr ?
Welche Untersuchungen hast du bereits durchgeführt?
und viele weiteren Fragen

desirose:
Ich habe bereits ausgiebig in den Foren gesucht - es gibt ja hierzu genug - leider finde ich nicht den passenden Sketch zu meiner Uhr...

Versuche mal diese Beschreibung mit dem angehängten Programm. Eventuell müssen Pinnummern angepaßt werden.

Wordclock_basic.ino (12.5 KB)

agmue:
Versuche mal diese Beschreibung mit dem angehängten Programm. Eventuell müssen Pinnummern angepaßt werden.

Vielen Dank schon mal für die hilfreichen Antworten.
Habe schon mal mit dem Programm einen schnellen Versuch gestartet, läuft aber noch nicht. Die Feinheiten sind mir noch nicht ganz klar. Das Programm ist etwas anders; # der LEDs etc.

FASTLED_USING_NAMESPACE
#define DATA_PIN    1
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS    114      // Gesamtanzahl der WS2812 LEDs
CRGB leds[NUM_LEDS];

Welcher ist Data Pin? Habe hier jetzt 1 drin stehen, #LEDs habe ich angepasst (110 in Reihe, plus 4 in den Ecken)
Ist es entscheidend welcher LED Typ? Finde hier bei mir keine Info, ob das der richtige ist.
Sonst habe ich die Positionen geändert

//***HIER LED POSITIONEN EINTRAGEN***//
int EsIst[]     = {0, 1, 2, 4, 5, 6};

int Eins[]      = {63, 64, 65, 66};
int Ein[]       = {64, 65, 66};
int Zwei[]      = {56, 57, 58, 59};
int Drei[]      = {67, 68, 69, 70};
int Vier[]      = {74, 75, 76, 77};
int Fuenf[]     = {52, 53, 54, 55};
int Sechs[]     = {84, 85, 86, 87, 88};
int Sieben[]    = {89, 90, 91, 92, 93};
int Acht[]      = {78, 79, 80, 81};
int Neun[]      = {104, 105, 106, 107};
int Zehn[]      = {107, 108, 109, 110};
int Elf[]       = {50, 51, 52};
int Zwoelf[]    = {95, 96, 97, 98, 99};
int MZwanzig[]  = {12, 13, 14, 15, 16, 17, 18};
int MFuenf[]    = {8, 9, 10, 11};
int MZehn[]     = {19, 20, 21, 22};

int Viertel[]   = {27, 28, 29, 30, 31, 32, 33};
int Vor[]       = {42, 43, 44};
int Nach[]      = {34, 35, 36, 37};
int Halb[]      = {45, 46, 47, 48};
int Uhr[]       = {100, 101, 102};
int Und[]       = {16, 17, 18, 19, 20};

Letzte Zeile "Und" gibt es bei mir nicht, würde ich einfach löschen...?!
Soweit erstmal meine Fragen.
Danke im Voraus.

desirose:
... läuft aber noch nicht.

Das ist zu ungenau, um Dir helfen zu können.

desirose:
Welcher ist Data Pin?

Da ist der LED-Streifen angeschlossen. Leider kann ich auf Deinem Foto nicht erkennen, wo das ist. Pin 0 oder 1 sind auf jeden Fall falsch. Es geht um das grüne Kabel vom Streifen, das zum braunen wird.

desirose:
Ist es entscheidend welcher LED Typ?

Ja, WS2812b könnte aber stimmen.

desirose:
Sonst habe ich die Positionen geändert

Leider gibt es Zweideutigkeiten, da hast Du Dich vertan.

desirose:
Letzte Zeile "Und" gibt es bei mir nicht, würde ich einfach löschen...?!

Nee, so einfach nicht. Folgende Zeile muß auch noch verschwinden:

SwitchLED(Und, (sizeof(Und)/2));

Da ich Deine Hardware nicht habe, kann ich die LED-Positionen nicht überprüfen. Folgendes Programm läßt aber bei mir ein paar LEDs leuchten.

Test_Forum.ino (12.9 KB)

1000 Dank, es blinkt wieder was :slight_smile:

Den richtigen Data Pin (5), und schon tut sich wieder was. Aber du hast recht, die Positionen stimmen noch nicht: um 21 Uhr zeigt er mir komisches an...da muss ich nochmal tüffteln.

Hier nochmal die LED Anordnung

desirose:
1000 Dank, es blinkt wieder was :slight_smile:

Sehr gut!

desirose:
... da muss ich nochmal tüffteln.

Ich sehe, daß sich verschiedene Wörter überschneiden, beispielsweise "dreiviertel" und "viertel", oder "elf" und "fünf". Das muß in der Tabelle entsprechend berücksichtigt werden, das wußte ich nicht.

Man muss wohl mit Position 0 anfangen, nicht mit 1. Das habe ich jetzt gemacht. Passt auch außer bei ES IST, da leuchten immer das "K" dazwischen. Wenn ich eine Position lösche, geht immer Position 6, also "T" aus..?! Muss man hier einen Platzhalter oder sowas eintragen?

//***HIER LED POSITIONEN EINTRAGEN***//
int EsIst[]     = {0, 1, 2, 3, 4, 5};

int Eins[]      = {62, 63, 64, 65};
int Ein[]       = {63, 64, 65};
int Zwei[]      = {55, 56, 57, 58};
int Drei[]      = {66, 67, 68, 69};
int Vier[]      = {73, 74, 75, 76};
int Fuenf[]     = {51, 52, 53, 54};
int Sechs[]     = {83, 84, 85, 86, 87};
int Sieben[]    = {88, 89, 90, 91, 92, 93};
int Acht[]      = {79, 78, 79, 80};
int Neun[]      = {103, 104, 105, 106};
int Zehn[]      = {106, 107, 108, 109};
int Elf[]       = {49, 50, 51};
int Zwoelf[]    = {94, 95, 96, 97, 98};
int MZwanzig[]  = {11, 12, 13, 14, 15, 16, 17};
int MFuenf[]    = {7, 8, 9, 10};
int MZehn[]     = {18, 19, 20, 21};

int Viertel[]   = {26, 27, 28, 29, 30, 31, 32};
int Vor[]       = {41, 42, 43};
int Nach[]      = {33, 34, 35, 36};
int Halb[]      = {43, 44, 45, 46};
int Uhr[]       = {99, 100, 101};


int EinsM[]     = {110}; //Minuten Punkt 1
int ZweiM[]     = {113}; //Minuten Punkt 2
int DreiM[]     = {111}; //Minuten Punkt 3
int VierM[]     = {112}; //Minuten Punkt 4
//**********************************//

Sonst scheint es zu gehen, allerdings eine Stunde vor. Wie kann ich das korrigieren?

20210408_220143[1].jpg

Da agmue wohl gerade nicht greifbar ist, versuche ich mich mal:
Für das "Es ist" sollen ja nur die ersten beiden, dann eine nicht und dann wieder drei LEDs leuchten. Deshalb musst Du die "2" aus der Liste rausnehmen:

const uint8_t EsIst[]     = {0, 1, 3, 4, 5};

Und bitte die 'int' durch 'const uint8_t' (oder 'const byte') ersetzen.
Begründung:
Die ändern sich nie (deshalb const) und es sind weniger als 256 (da reicht dann das Byte).

desirose:
Man muss wohl mit Position 0 anfangen, nicht mit 1.

Ja, Programmierer sind seltsam, sie fangen bei 0 an.

desirose:
Passt auch außer bei ES IST, da leuchten immer das "K" dazwischen.

Möglicherweise muß man die Funktion SwitchLED umstricken. Das schaue ich mir morgen an :sleeping:

desirose:
Sonst scheint es zu gehen, allerdings eine Stunde vor. Wie kann ich das korrigieren?

Das Uhrenmodul per Programm stellen oder eine automatische Sommer-Winterzeitumstellung einbauen.

Danke auch hierfür, leider bekomme ich hier beim kompilieren einen Fehler:

Wordclock_basic_Desi_Vers3:112:37: error: cannot convert 'const uint8_t* {aka const unsigned char*}' to 'int*' for argument '1' to 'void SwitchLED(int*, int)'

SwitchLED(EsIst, (sizeof(EsIst)/2));

Außerdem ist hier irgendwas faul, wenn ich die "2" rausnehme, dann geht das "T" aus..?! Habe schon alles mögliche probiert...
Danke für weitere Vorschläge, für heute mache ich Schluss!
Gute Nacht

agmue:
Möglicherweise muß man die Funktion SwitchLED umstricken. Das schaue ich mir morgen an :sleeping:

Habe gerade nochmal draufgeschaut. Es werden ja vorher alle gelöscht und (jedenfalls beim "Es ist") müssen die LEDs nicht zwingend zusammenhängend eingeschaltet werden. Wie wäre dann das hier:

for (int i = 0; i < n; i++) {
      leds[MyArray[i]] = 0xFFC58F;                         // HEX Warmweiß ...

@desirose:
Das mit dem int und dem byte ist mir auch gerade aufgefallen.
Wenn Du int lässt geht es. Wenn Du Speicher sparen willst und die Arrays auf Byte umstellst, musst Du die Signatur von SwitchLED auch passend sein (ist aber im Sketch aus #5 schon richtig):

void SwitchLED(const uint8_t MyArray[], int n) {...

Und eigentlich dürften dann bei den Aufrufen von SwitchLED() die Anzahl (Arraygröße) nicht durch 2 geteilt werden.

EDIT: Habe den modifizierten Sketch mal angehangen.

Test_Forum-Modified.ino (12.9 KB)

wno158:
EDIT: Habe den modifizierten Sketch mal angehangen.

Vielen Dank, habe es nochmal angepasst und ausprobiert, läuft auch ohne Error, allerdings leuchten nun die ersten 7 LEDs, also "ES K IST A". Es ist also noch eine dazu gekommen...
Datei anbei.

Test_Forum-Modified_DG.ino (12.9 KB)

Hallo Desiree, hallo Walter,

ich habe mich noch nie mit einer Wortuhr, nur mal mit einer LED-Uhr beschäftigt. Mir ging es erstmal nur darum, daß irgendwas angezeigt wird. Das funktioniert, der Rest ist aus meiner Sicht nicht so wild. Das von mir gefundene Beispiel scheint mir noch nicht wirklich gut, das kann man aber verbessern.

Die Funktion CheckDST ändert die Winter- in die Sommerzeit, daher sollte das Uhrenmodul auf MEZ, also Winterzeit stehen.

wno158:
Habe gerade nochmal draufgeschaut. Es werden ja vorher alle gelöscht und (jedenfalls beim "Es ist") müssen die LEDs nicht zwingend zusammenhängend eingeschaltet werden. Wie wäre dann das hier:

for (int i = 0; i < n; i++) {

leds[MyArray[i]] = 0xFFC58F;                         // HEX Warmweiß ...

Wenn man die Position für das Leerzeichen ausläßt, dann bleibt diese LED dunkel. Ja, so funktioniert das :slight_smile:

Ich bin einen anderen Weg gegangen und habe die Wörter aufgeteilt:

const uint8_t Es[]        = {0, 1};
const uint8_t Ist[]       = {3, 4, 5};

Test_Forum.ino (12.5 KB)

agmue:
Ich bin einen anderen Weg gegangen und habe die Wörter aufgeteilt:

const uint8_t Es[]        = {0, 1};

const uint8_t Ist[]       = {3, 4, 5};

Super, das hat geklappt! Manchmal sind die einfachen Wege, die besten!
Das mit der Winterzeit habe ich auch rausgekriegt, läuft also jetzt auch.
Letzte Baustelle (hoffentlich): Das Ausgangsprg. sieht ja die Darstellung "FünfUNDzwanzig nach/vor" vor, ich habe aber kein UND, das hatte ich rausgelöscht. Das gibt jetzt natürlich ein Problem. Ich brauche die Darstellung "Fünf vor/nach halb". Ersteres (5 vor halb) habe ich irgendwie hingekriegt:

if (((Minute>24) && (Minute<30))) { 
    SwitchLED(MFuenf, (sizeof(MFuenf))); 
    SwitchLED(Vor, (sizeof(Vor)));
    SwitchLED(Halb, (sizeof(Halb)));
   Serial.print("5 vor halb ");

"5 nach halb" klappt noch nicht, da zeigt er mir " 5 vor nach halb" an, weiß nicht, wo ich das "vor" rauskriege:

 } 
    if (((Minute>34) && (Minute<40))) { 
    SwitchLED(MFuenf, (sizeof(MFuenf))); 
    SwitchLED(Nach, (sizeof(Nach)));
    SwitchLED(Halb, (sizeof(Halb)));
   Serial.print("5 nach halb ");

Test_Forum_2.ino (12.6 KB)

desirose:
"5 nach halb" klappt noch nicht, da zeigt er mir " 5 vor nach halb" an, weiß nicht, wo ich das "vor" rauskriege:

Ich glaube das liegt an Zeile 308.
Da wird im else-Zweig - wenn die Minute >= 35 ist - bedingungslos das "vor" eingeschaltet.

255:     if ((Minute > 29) && (Minute < 35)) {
...
306:     }
307:     else {
308:       SwitchLED(Vor, (sizeof(Vor)));
309:       Serial.print("vor ");
310:       switch (Stunde) {

Diese if/switch-Orgie (wo immer die Stunden nochmal hinkopiert sind) gefällt mir noch nicht; das dauert aber einen Moment das zu begradigen (vielleicht schaffe ich das am Sonntag wenn dann noch nötig).

Vielleicht reicht es schon, die obere Minutengrenze in Zeile 255 zu ändern - alles andere ist ja oben schon eingeschaltet:

255:     if ((Minute > 29) && (Minute < 40)) {

wno158:
Vielleicht reicht es schon, die obere Minutengrenze in Zeile 255 zu ändern - alles andere ist ja oben schon eingeschaltet:

255:     if ((Minute > 29) && (Minute < 40)) {

Hallo Walter,
vielen dank und ja das hat geklappt! Perfekt! Herzlichen Dank an euch beide für die schnelle Hilfe, echt super! :slight_smile:

Falls ihr nach der Pflicht, noch Lust auf die Kür habt, hätte ich noch folgende Fragen (muss aber echt nicht sein, weiß, wieviel Zeit es in Anspruch nehmen kann);

  1. Die Helligkeit der LEDs konnte ich nicht anpassen. Es strahlt noch etwas in Nachbarbereiche über, meine Abschirmung ist wohl nicht gut genug. Das war früher nicht so, LED Farbe war auch etwas anders (nicht warmweiß). Das sollte man doch hier einstellen können:
const uint8_t maxBrightness     = 35;  // Wenn Fotoresistor benutzt wird, hier min. Helligkeit eintragen (0=Off->255=max)
const uint8_t minBrightness     = 210;   // Wenn Fotoresistor benutzt wird, hier max. Helligkeit eintragen (0=Off->255=max)
const uint8_t AmbientLightPin   = 0;    // Fotoresistor Pin
uint8_t BRIGHTNESS              = 120;  // Wenn kein Fotoresistor benutzt wird hier dauerhafte Helligkeit eintragen
  1. Eine Spielerei von meinem Vater war, dass zur vollen Stunde alle LEDs wild geflackert haben :slight_smile: Mein kleiner Sohn hat sich darüber immer so gefreut. Falls ihr ne´ Idee dazu habt... wie gesagt, nur falls ihr Spaß dran habt.

Ansonsten nochmal vielen Dank für alle Tipps und Hilfen! Ich werde mich jetzt auch mal intensiver mit der Materie befassen!
Viele Grüße aus Wiesbaden
Desiree

desirose:
... das hat geklappt!

:smiley:

Zu 1) An A0 bis A3 sehe ich keinen lichtempfindlichen Widerstand angebracht, daher hatte ich diesen Bereich (86 bis 93) im Programm unwirksam gemacht. Die ersten drei Zeilen sind daher wirkungslos, die vierte kann einen Wert 0 bis 255 einnehmen, wobei 0 für Schwarz natürlich sinnlos wäre.

Die Zeile leds[MyArray[ i ]] = 0xFFC58F; legt die Farbe als Additive Farbmischung von Rot Grün Blau fest. Du hast die freie Wahl!

Zu 2) Da wäre sicherlich was möglich, braucht nur etwas Zeit, da ich gerade eine Programmbibliothek teste. Ich lasse aber Walter den Vortritt, wenn er möchte.

Auf dem Foto sehe ich an Pin 11 einen Sensor für eine Infrarot-Fernbedienung, existiert die noch?