–ACHTUNG LESEN–

In diesem Beitrag fehlen derzeit die Videos.

Lange Zeit nichts mehr passiert, die Zeit rennt und die Projekte liegen unfertig im Arbeitszimmer.
Mit diesem Beitrag beende ich ein Projekt was schon länger bei mir auf der ToDo Liste stand: Einen Alexa Timer Visualisieren.

Ich werde versuchen euch aufzuzeigen was alles benötigt wird, es müssen nur kleine Handgriffe von euch ausgeführt werden.

Wegen der Übersicht verpacke ich wieder alles in aufklappbare Boxen:

-Video-Erklärung-
Anhand meiner grandiosen Videokünsten, könnt ihr euch über das gezeigte ergötzen und hoffentlich Visuell meinen Worten in diesem Beitrag folgen.

-VIDEO-?

-Was geht und was nicht geht, alles über Preise-

Frage:         Wie viele Timer können angezeigt werden?
Antwort:    Es ist nur möglich einen Timer anzuzeigen, pro Setup.

Frage:        Was passiert wenn ich zwei unterschiedliche Timer setze?
Antwort:   Nach Ablauf des ersten Timers, wird auf dem Display anschließend der zweite und dritte etc Timer gepusht.

Frage:        Kann ich selbst Zeiten pushen?
Antwort:   Ja das geht sehr einfach, der Datenpunkt : timer/set/zeit kann hier benutzt werden um Sekunden ( nur Sekunden ) an die Anzeige zu schicken.

60 Sekunden = 1 Min.
120 Sekunden = 2 Min.

Ich denke vom Prinzip her verstanden 😉

Frage:        Kann ich mit jedem Echo einen Timer setzen und mir anzeigen lassen?
Antwort:    Bedingt!
Das Setup ist tatsächlich erstmal so Softwaremäßig an einem Echo gebunden ( Im Setup wird die ID des Echos benötigt bzw. ein Datenpunkt eines Echos ), wer allerdings Lust hat kann den Timer Befehl sniffen ( History ) und die Zeit vom Echo abrufen von wo der Befehl gekommen ist. Anschließend dann auf dem Display anzeigen lassen.

Was aber geht, wenn im Wohnzimmer ein Timer für, sagen wir , die Küche gesetzt wird: Alexa: Stell einen Timer in Küche für 5 Minuten.
Wenn der Aufbau in der Küche steht ( und mit dem Echo verknüpft  ist ) zeigt er nun die verbleibende Zeit an.

Frage:        Ist das Setup günstiger als eine Wall-Clock oder der Echo mit Display?
Antwort:  Die Rechnung sieht folgendermaßen aus:

Ein Wemos D1 mini beim deutschen Händler ( Ebay ) kostet ( Stand 21.01.2022 ) genau 4,65€ inkl. Versand. Amazon liegt hier bei: 5,50€ inkl.
Das TM1637 kostet bei Ebay ca 3,30€ inkl. bei Amazon ca. 4,29€ inkl.
Die MAX 7219 ( 8 x 8 ) liegen bei Amazon im 3er SET ( Günstiger als 2 x 1 ) im schnitt bei 12€ inkl.
Bei Ebay ( Makershop ) bei 8,8€ inkl. bei 2 x 1 Modulen.

Ebay: 16,75€ ( ohne 3D Druck ohne Jumper )
Amazon: 21,79€ ( ohne 3D Druck ohne Jumper )

Die Echo Wall Clock für Alexa, tja, nicht verfügbar und der alte Preis lag wohl bei
30€ +/- . Bei Ebay werden die gerade ( Stand 21.01.2022 ) für sagenhafte 50€ + verkauft.

Der Echo mit Display liegt hier bei ca 40€. Bedenke, der Echo ist mit dabei, bzw die Uhr ist beim Echo mit dabei 😉

Trotzdem für mich eine super Zusatzanzeige, die ich persönlich da hinstellen/hängen kann wo ich Sie benötige und nicht gleich den Echo auch da haben will/möchte !

-Voraussetzungen-
Welche Voraussetzungen werden gefordert? 

Meine Lösung :
Es muss zwingend IoBroker eingesetzt werden.
Es muss zwingend der Adapter Alexa 2 installiert und lauffähig sein.
Ein MQTT Server muss lauffähig sein.

Eine lauffähige Arduino-IDE. ( Flashen )

Optional einen 3D Drucker, einen Freund mit einem Drucker, Druckservice etc. 🙂
Gehäuse sollte in „weiß“ gedruckt werden, da die Displays verdeckt verbaut werden, sieht einfach schöner aus.Gehäuse

-Materialliste-
Welches Material muss angeschafft/verwendet werden? 

2 x MAX7219*
1 x TM1637*
1 x Wemos D1 mini*

Obligatorisch werden folgende Sachen auch benötigt: 
Paar Jumperkabel, einen Lötkolben, Lötzinn, Heißkleberpistole.

* mit einem Stern gekennzeichneten Links werden in einem neuen Fenster geöffnet und sind Partnerlinks.

-Benötigter Code-

Wir müssen als erstes Hilfsvariablen anlegen, ohne diese ist es nicht möglich weiterzuarbeiten:

IoBroker sieht hier dafür unter Objekte: 0_userdata eigene Variablen vor:

Wir aktivieren den Experten Modus:
Experten Modus aktivieren
Anschließend erstellen wir einen Ordner ( Dient nur der Übersicht! )
Ordner anlegenIch habe diesen Ordner „timer“ genannt, in diesem Ordner erstellen wir wieder einen Ordner der „zeiten“ heißt ( Dient nur der Übersicht! ).

Jetzt legen wir drei neue Variablen an (benötigt!):

aktuell
sekbisende
zeitbisende

Variablen AnlegenDie MQTT Variablen werden automatisch vom Wemos D1 mini beim ersten mal benutzen gesetzt!

timer/set/zeit
timer/set/rssi
timer/set/verbleibend ( in Sekunden! ) falls jemand diese in seiner VIS weiterverarbeiten möchte!

Welche Bibliotheken werden benötigt?

 

#include <ESP8266WiFi.h>
#include <TM1637Display.h>
#include <PubSubClient.h>
#include "LedControl.h"

So, nachdem nun alle Voraussetzungen erfüllt sind, hier die Codes für das Javascript / Blockly und der Arduino Sketch:

Javascript:

Wir wechseln zu „Skripte“ und möchten eine Javascript Datei erstellen:

( Ich habe diese umrechnen genannt )

on({id: "0_userdata.0.timer.zeiten.aktuell", change: "any"}, function(obj)
// id = die ID eurer Variable wenn diese nicht sogenannt wurde wie erklärt! 
{

var aktuell = getState("0_userdata.0.timer.zeiten.aktuell").val;
// id = die ID eurer Variable wenn diese nicht sogenannt wurde wie erklärt! 
var akt = new Date(aktuell);


 
function time(){
// aktuelle Zeit holen
   var zeitbisende = getState("0_userdata.0.timer.zeiten.zeitbisende").val;
   //id = die ID eurer Variable wenn diese nicht sogenannt wurde wie erklärt! 
   var alexatime = new Date(zeitbisende);
 
// Differenz berechnen
   var diff = alexatime.getTime() - akt.getTime();
 
// Werte berechnen
   var tag = Math.floor(diff / (1000*60*60*24));
   diff = diff % (1000*60*60*24);
   var std = Math.floor(diff / (1000*60*60));
   diff = diff % (1000*60*60);
   var min = Math.floor(diff / (1000*60));
   diff = diff % (1000*60);
   var sec = Math.floor(diff / 1000);
    
  //DEBUG
  //console.log(tag);
  //console.log(std);
  //console.log(min);
  //console.log(sec);

  //Rechne alles in Minuten um: 
 //Rechne alles zusammen und wir haben die differenz in Minuten:
var zusammen = sec + 60 * min + 60 * 60 * std + 60 * 60 * 24 * tag;
//Setzen doch auf Sekunden! 
//var zusammen = zusammen/60;
//console.log(zusammen);

setState("0_userdata.0.timer.zeiten.sekbisende", zusammen);
// id = die ID eurer Variable wenn diese nicht sogenannt wurde wie erklärt! 
  }
time();

});

Blockly:

Hier ist es wichtig, den Echo auszuwählen welcher für den Timer genutzt wird!

Alle Variablen müssen einmal angeklickt werden und neu gesetzt werden bzw angepasst werden!

<xml xmlns="https://developers.google.com/blockly/xml">
  <block type="on" id="wj*%HS2~M!Wq^xBVk`|?" x="-12" y="-12">
    <field name="OID">alexa2.0.Echo-Devices.G090VC09916XXX.Timer.nextTimerDate</field>
    <field name="CONDITION">any</field>
    <field name="ACK_CONDITION"></field>
    <statement name="STATEMENT">
      <block type="controls_if" id="VEoCZS}#qRK+3y#`!C^Z">
        <mutation else="1"></mutation>
        <value name="IF0">
          <block type="logic_compare" id="}vH+ul3)#U^iW6/lBIpZ">
            <field name="OP">EQ</field>
            <value name="A">
              <block type="get_value" id="cILO28{=S*LCN2!Lec,W">
                <field name="ATTR">val</field>
                <field name="OID">alexa2.0.Echo-Devices.G090VC09916XXX.Timer.nextTimerDate</field>
              </block>
            </value>
            <value name="B">
              <block type="math_number" id="9b`u2F;AWnla1Q0=Ne#y">
                <field name="NUM">0</field>
              </block>
            </value>
          </block>
        </value>
        <statement name="DO0">
          <block type="update" id=")[@e8LT(d(vke9H/X.$(">
            <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
            <field name="OID">0_userdata.0.timer.zeiten.zeitbisende</field>
            <field name="WITH_DELAY">FALSE</field>
            <value name="VALUE">
              <block type="math_number" id="O0b_?(pFGG8].mdM4N^D">
                <field name="NUM">0</field>
              </block>
            </value>
            <next>
              <block type="update" id="~dG*E1V.5]kw6WB6X@F}">
                <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                <field name="OID">0_userdata.0.timer.zeiten.aktuell</field>
                <field name="WITH_DELAY">FALSE</field>
                <value name="VALUE">
                  <block type="math_number" id="_(eMABHH7yDsVLh5/tOE">
                    <field name="NUM">0</field>
                  </block>
                </value>
                <next>
                  <block type="update" id="fse9~k5/qLEz07Vl~l.7">
                    <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                    <field name="OID">0_userdata.0.timer.zeiten.sekbisende</field>
                    <field name="WITH_DELAY">FALSE</field>
                    <value name="VALUE">
                      <block type="math_number" id="Fs!IKseM?ou@T4iyRjq5">
                        <field name="NUM">0</field>
                      </block>
                    </value>
                  </block>
                </next>
              </block>
            </next>
          </block>
        </statement>
        <statement name="ELSE">
          <block type="update" id="lOjCp#-JOuvc=7@%Zax1">
            <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
            <field name="OID">0_userdata.0.timer.zeiten.zeitbisende</field>
            <field name="WITH_DELAY">FALSE</field>
            <value name="VALUE">
              <block type="convert_from_date" id="rco99G6.)zMa(]NvKr;i">
                <mutation xmlns="http://www.w3.org/1999/xhtml" format="true" language="false"></mutation>
                <field name="OPTION">custom</field>
                <field name="FORMAT">JJJJ.MM.TT SS:mm:ss</field>
                <value name="VALUE">
                  <block type="get_value" id="N#_Bm%wVximV5R[aQ(sx">
                    <field name="ATTR">val</field>
                    <field name="OID">alexa2.0.Echo-Devices.G090VC09916XXX.Timer.nextTimerDate</field>
                  </block>
                </value>
              </block>
            </value>
            <next>
              <block type="update" id="eN!wjn|dZb8)D8@p2y,g">
                <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                <field name="OID">0_userdata.0.timer.zeiten.aktuell</field>
                <field name="WITH_DELAY">FALSE</field>
                <value name="VALUE">
                  <block type="time_get" id="-OH6Ud,zocD|7;fKy`jz">
                    <mutation xmlns="http://www.w3.org/1999/xhtml" format="true" language="false"></mutation>
                    <field name="OPTION">custom</field>
                    <field name="FORMAT">JJJJ.MM.TT SS:mm:ss</field>
                  </block>
                </value>
              </block>
            </next>
          </block>
        </statement>
      </block>
    </statement>
  </block>
</xml>

 

Der Arduino Sketch:

Euere SSID und Passwort für Wlan müssen angepasst werden!
Passwort für den MQTT Server muss angepasst werden!
Unter Setup() bitte hier euren MQTT Port eintragen:

MQTT_PORT HIER EINSETZEN

#include <ESP8266WiFi.h>
#include <TM1637Display.h>
#include <PubSubClient.h>
#include "LedControl.h"
char ssid[] = "SSID WLAN";  //  your network SSID (name)
char pass[] = "PASSWORT WLAN";       // your network password
const char* mqtt_server = "IP DES MQTT SERVER"; //Broker IP Address
const char* mqttUser = "BENUTZER";
const char* mqttPassword = "PASSWORT";
WiFiClient espClient;
PubSubClient client(espClient);
//Antimationsvariablen
int animation1 = 0;
int animation2 = 0;
//Counter Variablen
unsigned long dyncount = 0;
//Variablen für millis();
unsigned long previousMillisTM = 0;
unsigned long previousMillisTMD = 0;
//8 x 8 Display
unsigned long previousMillis72191 = 0;
unsigned long previousMillis72192 = 0;
//Counter = 1000 = Sekunden
//Counter = 60000 = Minuten
/*
   Wir rechnen in Sekunden geben aber Minuten aus, wenn jedoch Minute = 5 oder kleiner 5 ist, setzen wir wieder auf Sekunden um es schöner anzuzeigen.

*/
const long intervalTM = 1000;
// Counter / 2 = DOT
//Setze auf dynamischen Interval, je nachdem wie viele Sekunden reinkommen, errechnet sich der Intervl vom Display 1 und 2!
const long intervalTMD = 500;
const long interval7219 = 800;
// Hilfsvariablen
char tmp[50];
char* tmpp[50];
bool fertig = false;
int row = 0;
int gotor;

LedControl lc = LedControl(D7, D5, D6, 2);

int tellstate = 0;
int CLK = D1;
int DIO = D2;
TM1637Display display(CLK, DIO);
/* we always wait a bit between updates of the display */
unsigned long delaytime = 1000;
int count = 0;
int i = 0;
int i1 = 0;
const uint8_t STOP[] = {
  SEG_A | SEG_C | SEG_D | SEG_G | SEG_F,           // S
  SEG_F | SEG_D | SEG_E | SEG_G,                   // T
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
  SEG_A | SEG_B | SEG_E | SEG_G | SEG_F            // P
};

const uint8_t DONE[] = {
  SEG_B | SEG_C | SEG_D | SEG_E | SEG_G,           // d
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
  SEG_C | SEG_E | SEG_G,                           // n
  SEG_A | SEG_D | SEG_E | SEG_F | SEG_G            // E
};
const uint8_t wait[] = {
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
};

//Display AUS

const uint64_t inlin[] = {
  0xffffffffffffffff
};
const int IMAGES_inl = sizeof(inlin)/8;

const uint64_t IMAGES[] = {
  /*
  0xffffffffffffffff, 0x7fffffffffffffff, 0x3fffffffffffffff, 0x3f7fffffffffffff, 0x3f7f7fffffffffff, 0x3f3f7fffffffffff, 0x1f3f7fffffffffff, 0x0f3f7fffffffffff, 0x0f1f7fffffffffff, 0x0f1f3fffffffffff, 0x0f1f3f7fffffffff, 0x0f1f3f7f7fffffff, 0x0f1f3f3f7fffffff,
  0x0f1f1f3f7fffffff, 0x0f0f1f3f7fffffff, 0x070f1f3f7fffffff, 0x030f1f3f7fffffff, 0x03071f3f7fffffff, 0x03070f3f7fffffff, 0x03070f1f7fffffff, 0x03070f1f3fffffff, 0x03070f1f3f7fffff, 0x03070f1f3f7f7fff, 0x03070f1f3f3f7fff, 0x03070f1f1f3f7fff, 0x03070f0f1f3f7fff,
  0x0307070f1f3f7fff, 0x0303070f1f3f7fff, 0x0103070f1f3f7fff, 0x0003070f1f3f7fff, 0x0001070f1f3f7fff, 0x0001030f1f3f7fff, 0x000103071f3f7fff, 0x000103070f3f7fff, 0x000103070f1f7fff, 0x000103070f1f3fff, 0x000103070f1f3f7f, 0x000103070f1f3f3f, 0x000103070f1f1f3f,
  0x000103070f0f1f3f, 0x00010307070f1f3f, 0x00010303070f1f3f, 0x00010103070f1f3f, 0x00000103070f1f3f, 0x00000003070f1f3f, 0x00000001070f1f3f, 0x00000001030f1f3f, 0x0000000103071f3f, 0x0000000103070f3f, 0x0000000103070f1f, 0x0000000103070f0f, 0x000000010307070f,
  0x000000010303070f, 0x000000010103070f, 0x000000000103070f, 0x000000000003070f, 0x000000000001070f, 0x000000000001030f, 0x0000000000010307, 0x0000000000010303, 0x0000000000010103, 0x0000000000000103, 0x0000000000000003, 0x0000000000000001, 0x0000000000000000
  */
  0x7fffffffffffffff, 0x3fffffffffffffff,0x3f7fffffffffffff, 0x3f7f7fffffffffff, 0x3f3f7fffffffffff, 0x1f3f7fffffffffff, 0x0f3f7fffffffffff, 0x0f1f7fffffffffff, 0x0f1f3fffffffffff, 0x0f1f3f7fffffffff, 0x0f1f3f7f7fffffff, 0x0f1f3f3f7fffffff,
  0x0f1f1f3f7fffffff, 0x0f0f1f3f7fffffff, 0x070f1f3f7fffffff, 0x030f1f3f7fffffff, 0x03071f3f7fffffff, 0x03070f3f7fffffff, 0x03070f1f7fffffff, 0x03070f1f3fffffff, 0x03070f1f3f7fffff, 0x03070f1f3f7f7fff, 0x03070f1f3f3f7fff, 0x03070f1f1f3f7fff,
  0x03070f0f1f3f7fff, 0x0307070f1f3f7fff, 0x0303070f1f3f7fff, 0x0103070f1f3f7fff, 0x0003070f1f3f7fff, 0x0001070f1f3f7fff, 0x0001030f1f3f7fff, 0x000103071f3f7fff, 0x000103070f3f7fff, 0x000103070f1f7fff, 0x000103070f1f3fff, 0x000103070f1f3f7f,
  0x000103070f1f3f3f, 0x000103070f1f1f3f, 0x000103070f0f1f3f, 0x00010307070f1f3f, 0x00010303070f1f3f, 0x00010103070f1f3f, 0x00000103070f1f3f, 0x00000003070f1f3f, 0x00000001070f1f3f, 0x00000001030f1f3f, 0x0000000103071f3f, 0x0000000103070f3f,
  0x0000000103070f1f, 0x0000000103070f0f, 0x000000010307070f, 0x000000010303070f, 0x000000010103070f, 0x000000000103070f, 0x000000000003070f, 0x000000000001070f, 0x000000000001030f, 0x0000000000010307, 0x0000000000010303, 0x0000000000010103,
  0x0000000000000103, 0x0000000000000003, 0x0000000000000001, 0x0000000000000000
};
const int IMAGES_LEN = sizeof(IMAGES) / 8;
const uint64_t IMAGES1[] = {
  0x8000000000000000, 0x0040000000000000, 0x0000200000000000, 0x0000001000000000, 0x0000000008000000, 0x0000000000000200, 0x0000000000000001, 0x8000000000000001, 0x0040000000000001, 0x0000200000000001, 0x0000001000000001, 0x0000000008000001, 0x0000000000040001, 0x0000000000000201,
  0x0000000000000003, 0x8000000000000003, 0x0040000000000003, 0x0000200000000003, 0x0000001000000003, 0x0000000008000003, 0x0000000000040003, 0x0000000000000203, 0x0000000000000103, 0x8000000000000103, 0x0040000000000103, 0x0000200000000103, 0x0000001000000103, 0x0000000008000103,
  0x0000000000040103, 0x0000000000000303, 0x8000000000000303, 0x0040000000000303, 0x0000200000000303, 0x0000001000000303, 0x0000000008000303, 0x0000000000040303, 0x0000000000000703, 0x0000000000000307, 0x8000000000000307, 0x0040000000000307, 0x0000200000000307, 0x0000001000000307,
  0x0000000008000307, 0x0000000000040307, 0x0000000000020307, 0x0000000000010307, 0x8000000000010307, 0x0040000000010307, 0x0000200000010307, 0x0000001000010307, 0x0000000008010307, 0x0000000000050307, 0x0000000000030307, 0x8000000000030307, 0x0040000000030307, 0x0000200000030307,
  0x0000001000030307, 0x0000000008030307, 0x0000000000070307, 0x0000000000030707, 0x8000000000030707, 0x0040000000030707, 0x0000200000030707, 0x0000001000030707, 0x0000000008030707, 0x0000000000070707, 0x8000000000070707, 0x0040000000070707, 0x0000200000070707, 0x0000001000070707,
  0x0000000008070707, 0x0000000004070707, 0x0000000002070707, 0x0000000001070707, 0x8000000001070707, 0x0040000001070707, 0x0000200001070707, 0x0000001001070707, 0x0000000009070707, 0x0000000001070f07, 0x000000000107070f, 0x800000000107070f, 0x004000000107070f, 0x000020000107070f,
  0x000000100107070f, 0x000000000907070f, 0x000000000507070f, 0x000000000307070f, 0x800000000307070f, 0x000020000307070f, 0x000000100307070f, 0x000000000b07070f, 0x00000000030f070f, 0x0000000003070f0f, 0x8000000003070f0f, 0x0040000003070f0f, 0x0000200003070f0f, 0x0000001003070f0f,
  0x000000000b070f0f, 0x0000000007070f0f, 0x8000000007070f0f, 0x0040000007070f0f, 0x0000200007070f0f, 0x000000000f070f0f, 0x00000000070f0f0f, 0x80000000070f0f0f, 0x00400000070f0f0f, 0x00002000070f0f0f, 0x00000010070f0f0f, 0x000000000f0f0f0f, 0x800000000f0f0f0f, 0x004000000f0f0f0f,
  0x000020000f0f0f0f, 0x000000100f0f0f0f, 0x000000080f0f0f0f, 0x000000040f0f0f0f, 0x000000020f0f0f0f, 0x000000010f0f0f0f, 0x800000010f0f0f0f, 0x004000010f0f0f0f, 0x000020010f0f0f0f, 0x000000011f0f0f0f, 0x000000010f1f0f0f, 0x000000010f0f1f0f, 0x000000010f0f0f1f, 0x800000010f0f0f1f,
  0x004000010f0f0f1f, 0x000020010f0f0f1f, 0x000000110f0f0f1f, 0x000000090f0f0f1f, 0x000000030f0f0f1f, 0x800000030f0f0f1f, 0x004000030f0f0f1f, 0x000020030f0f0f1f, 0x000000130f0f0f1f, 0x000000031f0f0f1f, 0x000000030f0f1f1f, 0x800000030f0f1f1f, 0x004000030f0f1f1f, 0x000020030f0f1f1f,
  0x000000130f0f1f1f, 0x0000000b0f0f1f1f, 0x000000070f0f1f1f, 0x800000070f0f1f1f, 0x004000070f0f1f1f, 0x000020070f0f1f1f, 0x000000071f0f1f1f, 0x000000070f1f1f1f, 0x800000070f1f1f1f, 0x004000070f1f1f1f, 0x000020070f1f1f1f, 0x000000170f1f1f1f, 0x0000000f0f1f1f1f, 0x8000000f0f1f1f1f,
  0x0040000f0f1f1f1f, 0x0000200f0f1f1f1f, 0x0000001f0f1f1f1f, 0x0000000f1f1f1f1f, 0x8000000f1f1f1f1f, 0x0000200f1f1f1f1f, 0x0000001f1f1f1f1f, 0x8000001f1f1f1f1f, 0x0040001f1f1f1f1f, 0x0000201f1f1f1f1f, 0x0000101f1f1f1f1f, 0x0000081f1f1f1f1f, 0x0000041f1f1f1f1f, 0x0000021f1f1f1f1f, 
  0x0000011f1f1f1f1f, 0x8000011f1f1f1f1f, 0x0040011f1f1f1f1f, 0x0000013f1f1f1f1f, 0x0000011f3f1f1f1f, 0x0000011f1f3f1f1f, 0x0000011f1f1f3f1f, 0x0000011f1f1f1f3f, 0x8000011f1f1f1f3f, 0x0040011f1f1f1f3f, 0x0000211f1f1f1f3f, 0x0000111f1f1f1f3f, 0x0000091f1f1f1f3f, 0x0000051f1f1f1f3f,
  0x0000031f1f1f1f3f, 0x8000031f1f1f1f3f, 0x0040031f1f1f1f3f, 0x0000231f1f1f1f3f, 0x0000033f1f1f1f3f, 0x0000031f3f1f1f3f, 0x0000031f1f3f1f3f, 0x0000031f1f1f3f3f, 0x8000031f1f1f3f3f, 0x0040031f1f1f3f3f, 0x0000231f1f1f3f3f, 0x0000131f1f1f3f3f, 0x0000071f1f1f3f3f, 0x8000071f1f1f3f3f,
  0x0040071f1f1f3f3f, 0x0000271f1f1f3f3f, 0x0000073f1f1f3f3f, 0x0000071f3f1f3f3f, 0x0000071f1f3f3f3f, 0x8000071f1f3f3f3f, 0x0040071f1f3f3f3f, 0x0000271f1f3f3f3f, 0x0000171f1f3f3f3f, 0x00000f1f1f3f3f3f, 0x80000f1f1f3f3f3f, 0x00002f1f1f3f3f3f, 0x00000f3f1f3f3f3f, 0x00000f1f3f3f3f3f,
  0x80000f1f3f3f3f3f, 0x00400f1f3f3f3f3f, 0x00002f1f3f3f3f3f, 0x00001f1f3f3f3f3f, 0x80001f1f3f3f3f3f, 0x00401f1f3f3f3f3f, 0x00003f1f3f3f3f3f, 0x00001f3f3f3f3f3f, 0x80001f3f3f3f3f3f, 0x00401f3f3f3f3f3f, 0x00003f3f3f3f3f3f, 0x80003f3f3f3f3f3f, 0x00403f3f3f3f3f3f, 0x00103f3f3f3f3f3f,
  0x00083f3f3f3f3f3f, 0x00043f3f3f3f3f3f, 0x00023f3f3f3f3f3f, 0x00013f3f3f3f3f3f, 0x80013f3f3f3f3f3f, 0x00413f3f3f3f3f3f, 0x00017f3f3f3f3f3f, 0x00013f7f3f3f3f3f, 0x00013f3f7f3f3f3f, 0x00013f3f3f7f3f3f, 0x00013f3f3f3f7f3f, 0x00013f3f3f3f3f7f, 0x80013f3f3f3f3f7f, 0x00413f3f3f3f3f7f,
  0x00213f3f3f3f3f7f, 0x00113f3f3f3f3f7f, 0x00093f3f3f3f3f7f, 0x00053f3f3f3f3f7f, 0x00033f3f3f3f3f7f, 0x80033f3f3f3f3f7f, 0x00433f3f3f3f3f7f, 0x00037f3f3f3f3f7f, 0x00033f7f3f3f3f7f, 0x00033f3f7f3f3f7f, 0x00033f3f3f7f3f7f, 0x00033f3f3f3f7f7f, 0x80033f3f3f3f7f7f, 0x00433f3f3f3f7f7f,
  0x00233f3f3f3f7f7f, 0x00133f3f3f3f7f7f, 0x000b3f3f3f3f7f7f, 0x00073f3f3f3f7f7f, 0x80073f3f3f3f7f7f, 0x00077f3f3f3f7f7f, 0x00073f7f3f3f7f7f, 0x00073f3f7f3f7f7f, 0x00073f3f3f7f7f7f, 0x80073f3f3f7f7f7f, 0x00473f3f3f7f7f7f, 0x00273f3f3f7f7f7f, 0x00173f3f3f7f7f7f, 0x000f3f3f3f7f7f7f,
  0x800f3f3f3f7f7f7f, 0x004f3f3f3f7f7f7f, 0x000f7f3f3f7f7f7f, 0x000f3f7f3f7f7f7f, 0x000f3f3f7f7f7f7f, 0x800f3f3f7f7f7f7f, 0x004f3f3f7f7f7f7f, 0x002f3f3f7f7f7f7f, 0x001f3f3f7f7f7f7f, 0x801f3f3f7f7f7f7f, 0x005f3f3f7f7f7f7f, 0x001f7f3f7f7f7f7f, 0x001f3f7f7f7f7f7f, 0x801f3f7f7f7f7f7f,
  0x005f3f7f7f7f7f7f, 0x003f3f7f7f7f7f7f, 0x803f3f7f7f7f7f7f, 0x007f3f7f7f7f7f7f, 0x003f7f7f7f7f7f7f, 0x803f7f7f7f7f7f7f, 0x007f7f7f7f7f7f7f, 0x807f7f7f7f7f7f7f, 0x407f7f7f7f7f7f7f, 0x40ff7f7f7f7f7f7f, 0x60ff7f7f7f7f7f7f, 0x60ffff7f7f7f7f7f, 0x70ffff7f7f7f7f7f, 0x70ffffff7f7f7f7f,
  0x78ffffff7f7f7f7f, 0x78ffffffff7f7f7f, 0x7cffffffff7f7f7f, 0x7cffffffffff7f7f, 0x7effffffffff7f7f, 0x7effffffffffff7f ,0x7fffffffffffff7f, 0x7fffffffffffffff
};
const int IMAGES_LEN1 = sizeof(IMAGES1) / 8;
uint8_t data[] = {0, 0, 0, 0};

void connect_to_MQTT() {
  client.setServer(mqtt_server, MQTT_PORT HIER EINSETZEN);//Set the MQTT server details
  client.setCallback(Callback);

  if (client.connect("AlexaTimer" , mqttUser, mqttPassword)) {
    Serial.println("Verbinde zum MQTT Server");
  } else {
    Serial.println("zu MQTT Server nicht verbunden ");
  }
  client.subscribe("timer/set/zeit");
  long rssi = WiFi.RSSI();
  itoa(rssi, tmp, 10);
  client.publish("timer/set/rssi", tmp);
}

void setup() {
  connect_to_MQTT();
  Serial.begin(115200);
  display.setBrightness(0x0f);
  // All segments on
  display.setSegments(data);
  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  int devices = lc.getDeviceCount();
  //we have to init all devices in a loop
  for (int address = 0; address < devices; address++) {
    /*The MAX72XX is in power-saving mode on startup*/
    lc.shutdown(address, false);
    /* Set the brightness to a medium values */
    lc.setIntensity(address, 2);
    /* and clear the display */
    lc.clearDisplay(address);
  }
  display.setSegments(wait);
}

void loop() {
  client.loop();
  if (!client.connected()) {
    Serial.println("Not connected to MQTT....");
    connect_to_MQTT();
  }
//Übertraägt die Restzeit in Sekunden an den Broker! Nützlich für die Anzeige in der VIS 
  if ( (millis() - tellstate) > 3000 and gotor > 0) {
    gettime();
    tellstate = millis();
  }

  // Counter
  unsigned long currentMillisTM = millis();
  if (gotor >= 300) {
    if (currentMillisTM - previousMillisTM >= intervalTM) {
      previousMillisTM = currentMillisTM;

      data[3] = display.encodeDigit(gotor / 1 / 60 % 10);
      data[2] = display.encodeDigit(gotor / 10 / 60 % 10);
      data[1] = display.encodeDigit(gotor / 100 / 60 % 10);
      data[0] = display.encodeDigit(gotor / 1000 / 60 % 10);
      display.setSegments(data);
      if (gotor <= 0) {
        display.setSegments(DONE);
        fertig = true;
      } else {
        gotor--;
        fertig = false;
      }

    }
  } else {
    if (currentMillisTM - previousMillisTM >= intervalTM) {
      previousMillisTM = currentMillisTM;

      data[3] = display.encodeDigit(gotor / 1 % 10);
      data[2] = display.encodeDigit(gotor / 10 % 10);
      data[1] = display.encodeDigit(gotor / 100 % 10);
      data[0] = display.encodeDigit(gotor / 1000 % 10);

      if (gotor <= 0) {
        display.setSegments(DONE);
        fertig = true;
      } else {
        display.setSegments(data);
        gotor--;
        fertig = false;
      }

    }

  }
  // Counter Ende

if (fertig == false) {
  //Sanduhr 7219 Display oben
  unsigned long currentMillis72191 = millis();
  if (currentMillis72191 - previousMillis72191 >= animation1) {
    previousMillis72191 = currentMillis72191;


    displayImage(IMAGES[i]);
    if (++i >= IMAGES_LEN ) {
      i = 0;
    }
   }
  unsigned long currentMillis72192 = millis();
  if (currentMillis72192 - previousMillis72192 >= animation2) {
    previousMillis72192 = currentMillis72192;


    displayImage1(IMAGES1[i1]);
    if (++i1 >= IMAGES_LEN1 ) {
      i1 = 0;
    }
   }

} else {
     lc.clearDisplay(0);
     lc.clearDisplay(1);
}

}

void displayImage(uint64_t image) {
  for (int i = 0; i < 8; i++) {
    byte row = (image >> i * 8) & 0xFF;
    for (int j = 0; j < 8; j++) {
      lc.setLed(0, i, j, bitRead(row, j));
    }
  }
}
void displayImage1(uint64_t image) {
  for (int i = 0; i < 8; i++) {
    byte row = (image >> i * 8) & 0xFF;
    for (int j = 0; j < 8; j++) {
      lc.setLed(1, i, j, bitRead(row, j));
    }
  }
}



void Callback(char* topic, byte* payload, unsigned int length) {
  // Zähler
  int i = 0;
  // Hilfsvariablen für die Convertierung der Nachricht in ein String
  char message_buff[100];

  Serial.println("Message arrived: topic: " + String(topic));
  Serial.println("Length: " + String(length, DEC));

  // Kopieren der Nachricht und erstellen eines Bytes mit abschließender \0
  for (i = 0; i < length; i++) {
    message_buff[i] = payload[i];
  }
  message_buff[i] = '\0';

  // Konvertierung der Nachricht in ein String
  String msgString = String(message_buff);
  Serial.println("Payload: " + msgString);

  if (strcmp(topic, "timer/set/zeit/set") == 0) {
    Serial.println("rein geschneit");
    int count = atoi((char *)payload);
    Serial.println(count);
    gotor = count;
    int dyncount1;
    //Animation2
    dyncount1 = count * 1000;
    animation2 = dyncount1 / 302;
    //Animation1
    animation1 = dyncount1 / 64;
    //Leer Bildschirm 
    lc.clearDisplay(0);
    lc.clearDisplay(1);
    i1 = 0;
    i = 0;
    //Testausgabe
    Serial.println(dyncount);
    //Setze Display auf Zeit: gotor
    data[3] = display.encodeDigit(gotor / 1 % 10);
    data[2] = display.encodeDigit(gotor / 10 % 10);
    data[1] = display.encodeDigit(gotor / 100 % 10);
    data[0] = display.encodeDigit(gotor / 1000 % 10);
    display.setSegments(data);
    
    displayImage(inlin[i]);
    if (++i >= IMAGES_inl ) {
      i = 0;
    }
   }
    
  }




//Überträgt die Restzeit in den Broker per MQTT
void gettime() {
  //count as string
  int t = gotor;
  itoa(t, tmp, 10);
  client.publish("timer/set/verbleibend", tmp);
  Serial.println(tmp);
}

 

Uff.
Ok, weiter geht es zum Zusammenbau 🙂 

-Wo gehört was hin?-

Wie baue ich das nun zusammen? 

Die Max7219 und das TM1673 kommen gelötet an, da brauchen wir erstmal nichts weiter zu machen, der Wemos D1 Mini kommt ohne angelötete PINS.

Als erstes die Pinbelegung:

MAX7219 ->

VCC = 5V Wemos D1 Mini ( hier eine Y Litze für das Netzteil anfertigen )
GND = GND ( Masse )
D7 = DIN
D5 = CLK
D6 = CS

Display 2 wird eins zu eins wie auf dem MAX7219 Beschriftet weiter verbunden!

TM1637 ->

VCC = 5V Wemos D1 Mini ( Siehe oben )
GNG = GND 8 Masse )
D1 = CLK
D2 = DIO

Nachdem alles angeschlossen ist, starten wir einen Versuch und Ordnen die Displays zu.

Jetzt läuft soweit alles und wir können das ganze in das Gehäuse verstauen:

Ich habe bewusst ein wenig Spiel gelassen, da nicht jeder auf dem mm Maßhaltig Drucken kann oder will.

Das heißt aber auch, wir müssen die Displays mit Heißkleber fixieren:

-3D Druck Dateien-

Welche Dateien werden benötigt?

Einmal Body und einmal Backcover .

Download Base
Download Backcover

Joar, das soll es auch schon wieder gewesen sein 🙂

Bis bald und danke für Deinen Besuch 🙂

Schreibe einen Kommentar

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

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.