SPS-Steuerung im Schaltschrank


Google-Suche auf MEINE-SCHALTUNG.de :





Dauerkalender


Küchenuhr

mit Arduino


Die nächste Aufgabe ist Konstruktion einer einfachen Küchenuhr mit Arduino, die mit drei Bedientasten zu bedienen und mit einer 7-Segmentanzeige sowie einem akustischen Signalgeber ausgestattet ist.
Die Anzeige der Küchenuhr wird aus vier einzelnen 7-Segmentanzeigen gebildet. Zwei Digits dienen zur Anzeige der Sekunden, zwei weitere sind für die Minuten zuständig. Bei solchem Aufbau beträgt die maximale Zeitspanne, die mit der Uhr einstellbar ist, 99 Minuten und 59 Sekunden.
Die Schaltung wird von Arduino Nano gesteuert. Da der Mikrocontroller nicht ausreichend viele digitale Ausgänge zur Verfügung stellt, werden die Anzeigen mithilfe eines Decoders im Multiplexing Verfahren angesteuert.
Die gewünschte Zeit wird mit zwei Tasten eingestellt. Mit einer Taste werden die Sekunden, mit der anderer die Minuten eingegeben. Mit der dritten Taste wird unsere Küchenuhr gestartet.
Zum Schluss kommt ein Signalgeber ins Spiel. Die Aufgabe der Erzeugung eines akustischen Signals übernimmt ein aktiver Summer.

Mikrocontroller

Mikrocontroller Arduino Nano

Arduino Nano

Arduino


7-Segmentanzeige

7-Segmentanzeige

7-Segmentanzeige

7-Segmentanzeige 5101AH


7-Segment-Decoder

7-Segment-Decoder

7-Segment-Decoder

7-Segment-Decoder 74HC4511


Aktiver Summer

Aktiver Summer

Aktiver Summer


Der Schaltplan

Schaltplan

Schaltplan

Alle Elemente der 7-Segmentanzeigen sind an den Decoder 74HC5411 angeschlossen. Die Widerstände von 680 Ohm dienen der Strombegrenzung. Der Decoder wird von Arduino gesteuert. Die Ausgänge D2 bis D5 bestimmen, welche Ziffer gerade angezeigt werden soll. Die Ausgabe erfolgt im BCD-Code. Ohne weitere Maßnahmen würde die Ziffer an allen vier Anzeigen sichtbar. Um das zu verhindern, kommen die Ausgänge D6 bis D9 zum Einsatz. Sie bestimmen, auf welcher 7-Segmentanzeige die aktuelle Ziffer zu sehen sein wird. Mit jedem Ausgang wird jeweils nur eine Anzeige aktiviert. Die Umschaltung zwischen den einzelnen Anzeigen erfolgt so schnell, dass das menschliche Auge sie nicht wahrnehmen kann. Diese Art der Steuerung wird als Multiplexing bezeichnet. Der Vorteil des Verfahrens liegt darin, dass die Menge der nötigen Verbindungen sehr stark reduziert werden kann. In diesem Fall werden mit acht Ausgängen vier 7-Segmentanzeigen gesteuert, die sonst insgesamt 28 Ausgänge beansprucht hätten.

Das Programm

// ---------------------------------------------------------------------------
// Küchenuhr
// 4 x 7-Segmentanzeige, Decoder 74HC4511, Multiplexing, aktiver Summer
// Arduino Nano, IDE 1.8.13
// ---------------------------------------------------------------------------
  byte bcd_D0 = 2;                                // Ausgang Bit 0
  byte bcd_D1 = 3;                                // Ausgang Bit 1
  byte bcd_D2 = 4;                                // Ausgang Bit 2
  byte bcd_D3 = 5;                                // Ausgang Bit 3
  byte DIGIT_1 = 6;                          // 7-Segmentanzeige Sekunden Einer
  byte DIGIT_2 = 7;                          // 7-Segmentanzeige Sekunden Zehner
  byte DIGIT_3 = 8;                          // 7-Segmentanzeige Minuten Einer
  byte DIGIT_4 = 9;                          // 7-Segmentanzeige Minuten Zehner
  byte Taste_Min_Plus = 10;                       // Minuten inkrementieren
  byte Taste_Sek_Plus = 11;                       // Sekunden inkrementieren
  byte Taste_Start_Stop = 12;                     // Start / Stop
  byte Summer = 13;                               // akustisches Signal

  byte BCD_Pin [] = { 5, 4, 3, 2 };
  byte Ziffer_1;                                  // Sekunden Einer
  byte Ziffer_2;                                  // Sekunden Zehner
  byte Ziffer_3;                                  // Minuten Einer
  byte Ziffer_4;                                  // Minuten Zehner
  byte Sekunden;
  byte Minuten;
  unsigned long Millis_Aktuell;
  unsigned long Millis_Alt_Anzeige;
  unsigned long Millis_Alt_Eingabe;
  bool Takt_Flanke;                               // Sekunden takt
  bool Eingabe_Freigabe;
  bool Start;
  word Stand_Aktuell;                             // Aktueller Stand in Sekunden
  

  void setup() {
    pinMode (bcd_D0, OUTPUT);
    pinMode (bcd_D1, OUTPUT);
    pinMode (bcd_D2, OUTPUT);
    pinMode (bcd_D3, OUTPUT);
    pinMode (DIGIT_1, OUTPUT);
    pinMode (DIGIT_2, OUTPUT);
    pinMode (DIGIT_3, OUTPUT);
    pinMode (DIGIT_4, OUTPUT);
    pinMode (Taste_Min_Plus, INPUT_PULLUP);
    pinMode (Taste_Sek_Plus, INPUT_PULLUP);
    pinMode (Taste_Start_Stop, INPUT_PULLUP);
    pinMode (Summer, OUTPUT);
  }

  // -------------------------------------------- // HAUPTPROGRAMM
  void loop() {
                                                  // Sekunden-Takt erzeugen
    Takt_Flanke = false;
    Millis_Aktuell = millis();
    if (Millis_Aktuell > (Millis_Alt_Anzeige + 1000)) {
      Millis_Alt_Anzeige = Millis_Aktuell;
      Takt_Flanke = true;
    }                                             // Anzeige Freigabe
    if (Millis_Aktuell > (Millis_Alt_Eingabe + 200)) {
      Eingabe_Freigabe = true;
    }    
                                                  // Sekunden inkrementieren
                                                  // Taste S2
    if ((digitalRead(Taste_Sek_Plus) == LOW) and Eingabe_Freigabe) { 
      Sekunden = ++Sekunden; 
      if (Sekunden == 60) { Sekunden = 59; }
      Ziffer_1 = Sekunden;
      Ziffer_2 = 0; 
      if (Sekunden > 9) {
        Ziffer_2 = Sekunden / 10;
        Ziffer_1 = Sekunden - (Ziffer_2 * 10); }           
      Millis_Alt_Eingabe = Millis_Aktuell;
      Eingabe_Freigabe = false;
      Start = false;
      }
                                                  // Minuten inkrementieren
                                                  // Taste S1
    if ((digitalRead(Taste_Min_Plus) == LOW) and Eingabe_Freigabe) { 
      Minuten = ++Minuten; 
      if (Minuten == 100) { Minuten = 99; }
      Ziffer_3 = Minuten;
      Ziffer_4 = 0; 
      if (Minuten > 9) {
        Ziffer_4 = Minuten / 10;
        Ziffer_3 = Minuten - (Ziffer_4 * 10); }           
      Millis_Alt_Eingabe = Millis_Aktuell;
      Eingabe_Freigabe = false;
      Start = false;
      }      
                                                  // Sekunden + Minuten nullen
    if ((digitalRead(Taste_Sek_Plus) == LOW) & (digitalRead(Taste_Min_Plus) == LOW)) {
        Sekunden = 0;  Minuten = 0;
        Ziffer_1 = 0;  Ziffer_2 = 0;
        Ziffer_3 = 0;  Ziffer_4 = 0;
        Start = false;
      }
                                                  // Küchenuhr starten / stoppen
                                                  // Taste S3
    if ((digitalRead(Taste_Start_Stop) == LOW) and (digitalRead(Summer) == LOW)) { 
      Start = true;
      Stand_Aktuell = (Ziffer_4 * 600) + (Ziffer_3 * 60) + (Ziffer_2 * 10) + Ziffer_1;
    } 
    if ((digitalRead(Taste_Start_Stop) == LOW) and (digitalRead(Summer) == HIGH)) { 
      Start = false;
      digitalWrite(Summer, LOW);
    } 
      
    if (Start and Takt_Flanke and (Stand_Aktuell > 0)) { 
        Stand_Aktuell = --Stand_Aktuell;
        Ziffer_4 = Stand_Aktuell / 600;
        Ziffer_3 = (Stand_Aktuell - Ziffer_4 * 600) / 60;
        Ziffer_2 = (Stand_Aktuell - Ziffer_4 * 600 - Ziffer_3 * 60) / 10;
        Ziffer_1 = (Stand_Aktuell - Ziffer_4 * 600 - Ziffer_3 * 60 - Ziffer_2 * 10);
        Minuten = Ziffer_4 * 60 + Ziffer_3;
        Sekunden = Ziffer_2 * 10 + Ziffer_1;
        if (Stand_Aktuell == 0) { 
          Start = false; 
          digitalWrite(Summer, HIGH); }
    }
      
    Digits_Aus ();                                // Anzeige DIGIT 1
    digitalWrite(DIGIT_1, LOW);
    Ziffer_anzeigen (Ziffer_1);
    Digits_Aus ();                                // Anzeige DIGIT 2
    digitalWrite(DIGIT_2, LOW);
    Ziffer_anzeigen (Ziffer_2);
    Digits_Aus ();                                // Anzeige DIGIT 3
    digitalWrite(DIGIT_3, LOW);
    Ziffer_anzeigen (Ziffer_3);
    Digits_Aus ();                                // Anzeige DIGIT 4
    digitalWrite(DIGIT_4, LOW);
    Ziffer_anzeigen (Ziffer_4);   
  }

  // UNTERPROGRAMME
  // ---------------------------------------------------------------------------

  void Digits_Aus () {                       // UNTERPROGRAMM alle Anzeigen AUS
    digitalWrite(DIGIT_1, HIGH);
    digitalWrite(DIGIT_2, HIGH);
    digitalWrite(DIGIT_3, HIGH);
    digitalWrite(DIGIT_4, HIGH);
    }

  void Ziffer_anzeigen (byte Ziffer) {            // UNTERPROGRAMM Anzeigen
    digitalWrite (BCD_Pin [3], bitRead(Ziffer,0));
    digitalWrite (BCD_Pin [2], bitRead(Ziffer,1));
    digitalWrite (BCD_Pin [1], bitRead(Ziffer,2));
    digitalWrite (BCD_Pin [0], bitRead(Ziffer,3));
    delay (3);
    }    

  // ---------------------------------------------------------------------------        
  

Die Taste S1, die an den Eingang D10 des Arduino angeschlossen ist, ist für die Minuten verantwortlich. Bei jedem Betätigen der Taste wird die Variable „Minuten“ um 1 erhöht. Der maximale Einstellwert beträgt 99. Ähnlich arbeitet die Taste S2. Sie ist für die Sekunden zuständig. Der maximale Wert, der hier eingestellt werden kann, beträgt 59. Der aktuelle Wert wird in der Variable „Sekunden“ gespeichert. Aus diesen zwei Variablen werden während der Eingabe die Ziffern gebildet, die auf den einzelnen 7-Segmentanzeigen anschließend angezeigt werden sollen.
Um das Prellen der Tasten umzugehen, wird am Anfang des Programms die Variable „Eingabe_Freigabe“ gebildet. Nach jeder Eingabe wartet das Programm 200 ms bevor eine neue Eingabe erfolgen kann.
Werden die Tasten S1 und S2 gleichzeitig betätigt, werden die Werte genullt.
Mit dem Betätigen der Taste S3 wird die Uhr gestartet. Der aktuelle Zeitwert wird dann in Sekundentakt um 1 dekrementiert. Den Takt gibt die Variable „Takt_Flanke“ vor. Sie fungiert im Programm als eine Flanke und steht nur für einen Programmablauf mit dem Wert „True“ zur Verfügung. Danach wird sie auf „False“ zurückgesetzt und erst nach Ablauf 1 Sekunde geht sie für einen Programmablauf wieder auf „True“.
Erreicht der aktuelle Zeitwert den Wert 0, wird das Dekrementieren unterbrochen und der akustische Signalgeber eingeschaltet. Die Zeit ist abgelaufen.
Die Anzeige auf den 7-Segmentanzeigen erfolgt in dem Multiplexing Verfahren. Die Anzeigen werden im Takt von 3 Millisekunden abwechselnd nacheinander eingeschaltet. Das erledigen die Ausgänge D6 bis D9. Sie werden für die Zeit jeweils auf Masse gezogen. Z.B. digitalWrite(DIGIT_1, LOW);
Gleichzeitig, während eine Anzeige eingeschaltet ist, wird über die Ausgänge D2 bis D5 die für sie passende Ziffer ausgegeben. Die Ausgabe erfolgt in dem BCD-Code. Soll z.B. auf einer 7-Segmentanzeige die Ziffer 6 dargestellt werden, werden die Ausgänge wie folgt gesetzt:

D2 (Bit 0) = LOW
D3 (Bit 1) = HIGH
D4 (Bit 2) = HIGH
D5 (Bit 3) = LOW

Die zuständigen Bitwerte werden mit dem Befehl "bitRead" aus den „Ziffer“-Variablen ausgelesen. Für die zweite 7-Segmentanzeige (A2) ist die Variable „Ziffer_2“ zuständig. Hier hat das dritte Bit (bei Ziffer = Ziffer_2) den Wert bitRead(Ziffer,2).
Die Übersetzung des BCD-Codes auf sieben Signale, die die Anzeigen ansteuern, übernimmt der Decoder 74HC5411.

Die Testschaltung

Testschaltung

Testschaltung

Kurzvideo

Kurzvideo


Zeit - Experimente


Google-Suche auf MEINE-SCHALTUNG.de :


Home Impressum Datenschutz