i2c

7-Segment Anzeige

Funktionsweise

Die 7-Segment Anzeige auf dem CrowPi besteht aus 4 verschiedenen Ziffern, welche jeweils die Werte 0-9 sowie A-F darstellen können. Der Name ist dabei auch Programm, da jede Ziffer grundsätzlich aus 7 verschiedenen Segmenten besteht, welche je nach Zustand (an/aus) dann die verschiedenen Werte darstellen können. Dies bedeutet jedoch auch, dass bei der Anzeige auf dem CrowPi insgesamt 33 verschiedene Segmente existieren (4x 7-Segment, 4x Dezimalpunkt, 1x Doppelpunkt), welche alle einzeln angeschlossen und gesteuert werden müssten.

Um dies zu vermeiden, verwendet die 7-Segment Anzeige den HT16K33, einen elektronischen Baustein zur Ansteuerung von mehreren LEDs über eine einzelne Schnittstelle. Hierfür wird der Bus I2C eingesetzt, über welchen verschiedene Steuerungsbefehle an die 7-Segment Anzeige gesendet werden können.

Da das Übertragen jeder einzelnen Änderung an die Komponente sehr ineffizient ist, wird üblicherweise ein Buffer in der Software implementiert. Alle gewünschten Anpassungen verändern somit nur den Buffer, welcher anschliessend mit nur einem einzigen Befehl übertragen werden kann. Dieses Prinzip wird auch von der Komponenten-Klasse SevenSegmentComponent verwendet.

Voraussetzungen

DIP Switches

Für diese Komponente werden keine spezifischen DIP-Switches benötigt, sodass diese in der Standardkonfiguration belassen werden können:

ON(links)12345678ON(rechts)12345678

Verwendung

Nachfolgend wird die Verwendung der Klasse com.pi4j.crowpi.components.SevenSegmentComponent Javadoc beschrieben. Es ist hierbei wichtig zu beachten, dass alle Methoden mit dem Wort “Buffer:” am Anfang der Beschreibung nicht eine direkte Auswirkung haben, sondern erst mit einem Aufruf von void refresh() auf der Anzeige sichtbar werden. Es ist somit zu empfehlen, alle gewünschten Einstellungen zu tätigen und dann mit einem einzigen Aufruf die Änderungen auf dem Gerät darzustellen.

Konstruktoren

Konstruktor Bemerkung
SevenSegmentComponent(com.pi4j.context.Context pi4j) Initialisiert eine 7-Segment Anzeige mit der Standard Bus- und Geräteadresse für den CrowPi.
SevenSegmentComponent(com.pi4j.context.Context pi4j, int bus, int device) Initialisiert eine 7-Segment Anzeige mit einer benutzerdefinierten Bus- und Geräteadresse.

Methoden

Methode Bemerkung
void print(int i) Gibt eine Ganzzahl mit bis zu 4 Ziffern auf der Anzeige aus. Zu lange Zahlen werden nach hinten abgeschnitten.
void print(double d) Gibt eine Kommazahl mit bis zu 4 Ziffern auf der Anzeige aus. Zu lange Zahlen werden nach hinten abgeschnitten.
void print(java.time.LocalTime time) Gibt die übergebene Uhrzeit in Stunden und Minuten auf der Anzeige aus. Der Doppelpunkt auf der Anzeige wird bei ungerader Sekundenzahl aktiviert und ansonsten deaktiviert.
void print(String s) Gibt die ersten 4 übergebenen Zeichen auf der Anzeige aus. Hierbei ist zu beachten dass die Anzeige nur wenige Zeichen unterstützt und ansonsten eine IllegalArgumentException wirft.
void clear() Löscht den internen Buffer ohne die Anzeige zu aktualisieren.
void refresh() Aktualisiert die Anzeige mit dem aktuellen Inhalt des Buffers.
void setEnabled(boolean enabled) Schaltet die Anzeige ein oder aus gemäss Boolean-Wert.
void setBlinkRate(int rate) Setzt die gewünschte Blink-Geschwindigkeit der ganzen Anzeige zwischen 0 (aus) und 3 (am schnellsten).
void setBrightness(int brightness) Setzt die gewünschte Helligkeit der ganzen Anzeige zwischen 0 (am dunkelsten) und 15 (am hellsten).
void setColon(boolean enabled) Buffer: Aktiviert/deaktiviert den Doppelpunkt auf der Anzeige.
void setDecimalPoint(int position, boolean enabled) Buffer: Aktiviert/deaktiviert den entsprechenden Dezimalpunkt auf der Anzeige. Diese Einstellung wird durch Setzen einer Ziffer automatisch wieder deaktiviert.
void setDigit(int position, int i) Buffer: Setzt die entsprechende Ziffer auf die übergebene Zahl zwischen 0 und 9.
void setDigit(int position, char c) Buffer: Setzt die entsprechende Ziffer auf das übergebene Zeichen.
void setDigit(int position, Segment... segments) Buffer: Setzt bei der entsprechenden Ziffer die übergebenen Segmente.

Beispielapplikation

Die nachfolgende Beispielapplikation besteht aus 3 verschiedenen Sektionen, welche die Vielfältigkeit der 7-Segment Anzeige veranschaulichen sollen. Zuerst werden die 4 Ziffern auf der Anzeige auf verschiedene Werte gesetzt, wobei es sich bei der letzten Ziffer sogar um ein komplett eigenes Symbol handelt.

Nach einer Wartezeit von 3 Sekunden wird eine kleine Ladeanimation auf der Anzeige dargestellt. Hierfür wird ein Array states definiert, in welchem die Ladeposition mithilfe von Zeichenketten dargestellt wird. Es handelt sich hierbei um einen Strich, welcher sich jeweils von links nach rechts bewegt. Hierfür wird eine verschachtelte for-Schleife eingesetzt, wobei mit i die ganze Animation insgesamt fünfmal wiederholt wird, während die innere Schleife über alle möglichen Animationszustände iteriert und diese nacheinander mit einer Verzögerung von 50 Millisekunden ausgibt.

Nachdem diese Ladeanimation abgespielt wurde, geht die Applikation in eine Schleife für 15 Sekunden und stellt jeweils die aktuelle Uhrzeit dar. Die API-Methode print(LocalTime time) übernimmt hierbei den Grossteil der Arbeit und blinkt sogar automatisch wenn die Sekundenzahl zurzeit ungerade ist. Nach 15 Sekunden schaltet sich die Anzeige aus und die Applikation endet.

Pfad zum Codebeispiel: src/main/java/com/pi4j/crowpi/applications/SevenSegmentApp.java
Auf GitHub ansehen
package com.pi4j.crowpi.applications;

import com.pi4j.context.Context;
import com.pi4j.crowpi.Application;
import com.pi4j.crowpi.components.SevenSegmentComponent;
import com.pi4j.crowpi.components.SevenSegmentComponent.Segment;

import java.time.LocalTime;

/**
 * Shows some basic digits and a fake loading indicator before acting as a clock which displays the time on the CrowPi for 15 seconds.
 * The colon on the seven-segment display will blink for every odd second.
 */
public class SevenSegmentApp implements Application {
    @Override
    public void execute(Context pi4j) {
        // Initialize and enable seven-segment display component
        final var segment = new SevenSegmentComponent(pi4j);
        segment.setEnabled(true);

        // Activate full brightness and disable blinking
        // These are the defaults and just here for demonstration purposes
        segment.setBlinkRate(0);
        segment.setBrightness(15);

        // Manually set some digits and symbols to demonstrate the advanced API
        segment.setDigit(0, '1'); // Place the character "1" into the first digit
        segment.setDecimalPoint(0, true); // Activate the decimal point after the first digit
        segment.setDigit(1, 'a'); // Place the character "a" into the second digit
        segment.setDigit(2, 4); // Place the number 4 into the third digit
        segment.setDigit(3, Segment.TOP, Segment.BOTTOM); // Activate top and bottom segment for fourth digit
        segment.refresh(); // Send updated buffer to display

        // Sleep for three seconds before moving on...
        sleep(3000);

        // Show fake loading indicator by moving a single dash from left to right several times
        // We do so by initializing an array with all possible states (forward & reverse) and printing it in order
        final var states = new String[]{"-   ", " -  ", "  - ", "   -", "  - ", " -  ", "-   "};
        for (int i = 0; i < 5; i++) {
            for (String state : states) {
                // Print current state and sleep for 50 milliseconds
                segment.print(state);
                sleep(50);
            }
        }

        // Loop for 15 seconds and print the current time every second
        for (int i = 0; i < 15; i++) {
            // Print current local time
            segment.print(LocalTime.now());

            // Sleep for one second before continuing
            sleep(1000);
        }

        // Disable the seven-segment display
        segment.setEnabled(false);
    }
}

Weitere Möglichkeiten

  • Das Beispiel könnte so umgeschrieben werden, dass von einer vordefinierten Zeit heruntergezählt wird und die Anzeige nach Erreichen von 0 entsprechend blinkt. In Kombination mit dem Buzzer wäre so sogar eine Eieruhr möglich.

  • Statt jeweils nur die aktuelle Zeit mit LocalTime.now() anzuzeigen, könnte auch die aktuelle Uhrzeit in verschiedenen Zeitzonen hintereinander dargestellt werden.

  • In Kombination mit den vorhandenen Buttons lassen sich Eingaben für Zahlen realisieren, sodass beispielsweise eine Stoppuhr implementiert werden könnte.