OLED TapeCounter

Digitales Zählwerk für Bandmaschinen oder Tapedecks mit Arduino Nano oder Arduino Nano Every und OLED-Display. Primär für ReVox A700 entwickelt, aber allgemein verwendbar.

Überblick

Projektziel

Ersatz des mechanischen Zählwerks der ReVox A700 Bandmaschine durch ein OLED-Display. Der Counter an sich ist universell einsetzbar.

Zählen

In diesem Modus arbeitet der Zähler wie der originale, mechanische Zähler und kann in fast jede Bandmaschine und fast jedes Tapedeck eingebaut werden.

Längenmessung

Die Länge des Bandes wird angezeigt. Das funktioniert am besten in der ReVox A700 oder jeder Maschine mit Impulsgewinnung an einer Umlenkrolle.

Zeitmessung

Anzeige der Spieldauer in Minuten und Sekunden. Auch hier braucht es eine Impulsgewinnung an einer Umlenkrolle, am besten wie bei der ReVox A700.

Hans-Volker hat mir freundlicherweise einige Bilder und ein Video seiner ReVox A700 Bandmaschine überlassen, die ich hier zeigen möchte. Herzlichen Dank dafür! Oben links der originale Zähler, rechts die OLED-Version im Modus Zeitmessung.

Das OLED-Display leuchtet weiß und kann gut mit Farbfolien teilweise oder ganz eingefärbt werden. Die Taste mit der Beschriftung COUNTER hatte beim originalen Zähler die Funktion zum Zurücksetzen der Anzeige und ist beim OLED Counter mit einem elektromechanischen Taster verbunden. Der Taster hat mehrere Funktionen (Ebenen), die sich durch unterschiedliche Betätigungsweisen realisieren ließen.

Die Komponenten für dieses Projekt sind leicht und preiswert zu beschaffen. Das Herz des Ganzen bildet ein Arduino Nano oder der modernere und mit USB-C ausgestattete Arduino Nano Every. beim Compilieren der Firmware erkennt der Compiler automatisch, für welchen Arduino kompiliert werden soll und erzeugt die nötige Version zum Flashen des Controllers.

0.91″ OLED Display

Weiterhin wird ein OLED-Display benötigt. Zum Ausschnitt der ReVox A700 passt sehr gut die 0.91″ Version mit einer Auflösung von 128x32 Pixeln.

Dieses Display gibt es bei vielen Händlern preiswert zu kaufen. Bitte darauf achten, dass es weiß leuchtet, denn es gibt auch eine blau leuchtende Version. Wobei das natürlich Geschmacksache ist, das blaue Display eignet sich genauso gut für dieses Projekt.

Schaltplan

Dieser vereinfachte Schaltplan sollte ausreichen, um ein Verständnis für das Projekt zu bekommen.

Zu sehen ist der Anschluss des Displays, des Tasters, die Impuls- und Geschwindigkeitseingänge und der Nullpunkt-Impuls-Ausgang.

Die benötigten 5V zur Spannungsversorgung des Arduino Nano müssen auf geeignete Weise bereitgestellt werden. Es gibt viele Lösungen, die in den auf der Seite unten verlinkten Original-Threads im Old-Fidelity-Forum zu entdecken sind. Möglich ist prinzipiell auch die Versorgung über die 5V eines USB-Anschlusses, wenn das Projekt dementsprechend eingesetzt wird. Weiterhin sind lineare Spannungsregler und DC/DC-Wandler möglich. Persönlich finde ich galvanisch getrennte DC/DC-Wandler sehr gut. Ob sich das nun unbedingt positiv auf die Funktionsweise auswirkt, sei dahingestellt.

Die drei Eingänge für die Geschwindigkeit sind optional zu betrachten und machen eigentlich nur bei der ReVox A700 Sinn. Die Signale an diesen Eingängen müssen TTL-Pegel haben. Das ist bei der ReVox A700 kein Problem, da die Signale direkt an einer Platine zur Verfügung stehen.

Der Anschluss des Tasters ist selbsterklärend. Er schaltet zwischen dem Eingang des Arduinos und GND.

Am Arduino-Ausgang, der mit NULLPULS beschriftet ist, kommt ein Impuls bei „0“ in der Anzeige. Das funktioniert sowohl beim reinen Zählermodus, als auch bei der Längen- und Zeitanzeige. Bitte auf keinen Fall ein Relais direkt anschließen, den benötigten Strom kann der Arduino nicht liefern! Denkbar ist eine Auskopplung über einen Transistor oder einen Optokoppler.

Die beiden Eingänge, die im Plan mit LS bezeichnet sind, sind die eigentlichen Eingänge zur Impulsverarbeitung. Viele User benutzten dafür Reflex-Lichtschranken (siehe Orignal-Threads). Bei der ReVox A700 lassen sich die Lichtschranken hinter der Segmentscheibe anbringen. Möglich sind auch Gabel-Lichtschranken oder Hall-Sensoren. Deiner Kreativität sind keine Grenzen gesetzt.

Für dieses Projekt gibt es kein eigenständiges Konfigurationsprogramm. Alle Parameter werden vor dem Kompilieren direkt im Programm gesetzt und nur in dem Bereich, der mit USER CONFIG SECTION beschriftet ist:

 //////////////////////////////////////////////////////////////////////////////////////////////////
 // USER CONFIG SECTION (please only edit here!)                                                 //
 //////////////////////////////////////////////////////////////////////////////////////////////////

 // Software configuration:
#define	HELLO_LOGO          true    // Show logo picture.
#define	HELLO_TEXT          true    // Show welcoming text (search for 'welcome helloText').
#define HELLO_TIMEOUT       3000    // The display duration of the greeting in ms. 
#define BRIGHTNESS          128     // Display brightness (0 to 255).
#define FLIPDISPLAY         false   // Set the display to normal (false) oder 180 degree mode (true).
#define INVERTDISPLAY       false   // Set inverted display (true) or normal dispalay (false).
#define SWAPCLICK           false   // Swap click with double click.
#define FONTSIZE            1       // Set the fontsize (1 to 2).
#define	UNSIGN              false   // Minus sign (true: sign not shown, false: sign shown).
#define DIGITS_MINUTES      2       // Digits for the minute display in realtime mode (2 or 3). 
#define DIGITS_COUNTER      5       // Number of digits for normal counter (FontSize1: 4, 5 or 6 - FontSize2: 4 or 5). 
#define PULSES_COUNTER      1       // Number of pulses for one count in counter mode (1 to 255).
#define OPHOURSOFFSET       0       // Offset for operating hours counter in seconds. Example: 1261440000 = 40 YEARS ;o)

// ~~~ meter and realtime preferences ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define MACHINE             700     // Machine type (700 = A700, 77 = A77/B77 and other, no machine specified = NONE).
#define	SHOWSPEED           true   // Should the speed be displayed?
#define SPEEDHIGH           381.0   // Highest belt speed A700 15" in mm.
#define SPEEDMIDDLE         190.5   // Middle  belt speed A700 7,5" in mm.
#define SPEEDLOW            95.25   // Lowest  belt speed A700 3,75" in mm.
#define CAPSTANOFF          -1      // Capstan is OFF.
#define NUMSEGS             5       // Segments of the tape reel A700.
#define SCOPE               118.6   // Circumference of the tape roll in mm.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Further adjustments (only change if you know what you are doing!).
#define SENSOR_A            2       // INPUT PIN (Sensor-A) 'INT0'.
#define SENSOR_B            3       // INPUT PIN (Sensor-B)	'INT1'.
#define SPEED95             15      // INPUT PIN (TTL, Speed 9,5 cm/s) 'A1'.
#define SPEED19             16      // INPUT PIN (TTL, Speed  19 cm/s) 'A2'.
#define SPEED38             17      // INPUT PIN (TTL, Speed  38 cm/s) 'A3'.   
#define BUTTON              5       // INPUT PIN (RESET-Button).
#define ZEROPOINT           7       // OUTPUT PIN ('000000' pulse).
#define LEFT                0       // Left rotation.
#define RIGHT               1       // Right rotation.
#define EEPROM_MODE         10      // EEPROM address for mode.
#define EEPROM_BRIGHTNESS   20      // EEPROM address for brightness.
#define EEPROM_COUNTER      100     // EEPROM address for counter data.
#define EEPROM_METER        200     // EEPROM address for meter data.
#define EEPROM_REALTIME     300     // EEPROM address for realtime data.
#define EEPROM_OPHOURS      400     // EEPROM address for operating hour counter data.
#define I2C_ADDRESS         0x3C    // I2C display address (0x3C/0x3D, depending on display type).
#define RST_PIN             -1      // Define proper RST_PIN if required.
//////////////////////////////////////////////////////////////////////////////////////////////////

HELLO_LOGO

true: Beim Einschalten wird das Logo angezeigt.
false: Beim Einschalten wird kein Logo angezeigt.

HELLO_TEXT

true: Beim Einschalten wird der Begrüßungstext angezeigt.
false: Beim Einschalten wird kein Begrüßungstext angezeigt.

HELLO_TIMEOUT

3000 Die Anzeigedauer der Begrüßung in Millisekunden. 3000 steht also für 3 Sekunden.

BRIGHTNESS

128 Die Helligkeit des Displays im Bereich von 0 bis 255 als initialer Startwert. Beim Betrieb kann die Helligkeit mittels Taster eingestellt werden und wird dann im EEPROM des Mikrocontrollers abgelegt. Konstruktionsbedingt liegen die sichtbaren Helligkeitsänderungen mehr im unteren Bereich, weiter oben sieht man keinen Unterschied mehr.

FLIPDISPLAY

false: Der Inhalt des Displays wird so ausgegeben, wie es der Hersteller vorsieht.
true: Der Inhalt des Displays wird um 180 Grad gedreht ausgegeben. Das ist praktisch, wenn man das Display verkehrt herum eingebaut hat oder einbauen musste.

INVERTDISPLAY

false: Die Anzeige auf dem Display ist hell auf dunklem Hintergrund.
true: Die Anzeige auf dem Display ist dunkel auf hellem Hintergrund (nur praktisch, wenn man selbst Schriften oder Bilder entwickelt und die Position pixelgenau sehen möchte. Außerdem kann man durch diese Einstellung das komplette Displayfeld sehen, um es mechanisch auszurichten.

SWAPCLICK

Die Funktion des einfachen Klicks kann mit der Funktion des Doppelklicks vertauscht werden.

FONTSIZE

1 Mittlere Schrift- und Anzeigengröße. In dieser Einstellung passen in der Breite mehr Informationen auf das Display und die Höhe passt auch in kleine mechanische Ausschnitte von vorhandenen Displays in den Maschinen.
2 Die größte mögliche Darstellung. In der Höhe werden die maximalen 32 Pixel des Displays ausgenutzt. Daher weniger Informationen in der Breite.

UNSIGN

false: Counterwerte werden mit negativem Vorzeichen angezeigt, wenn sie negativ sind (z.B. nach einem 0-Reset mitten im Band und zurückspulen).
true: Es werden keine negativen Vorzeichen im normalen Counter angezeigt (nur im Zählmodus, nicht bei der Meter- oder Echtzeitanzeige). Der Counter verhält sich wie ein mechanisches Modell.

DIGITS_MINUTES

Anzahl der Minutenstellen bei der Echtzeitanzeige. Möglich ist 2 oder 3. Bei drei Stellen entfallen die Stunden.

DIGITS_COUNTER

6 Je nach eingestellter Anzeigengröße können hier die Anzahl der Stellen für den normalen Zähler eingetragen werden.
Bei FONTSIZE=1 passen maximal 6 Stellen auf das Display, gültige Werte bei FONTSIZE=1 sind 4, 5 oder 6 Stellen.
Bei FONTSIZE=2 passen maximal 5 Stellen auf das Display, gültige Werte bei FONTSIZE=2 sind 4 oder 5 Stellen.

PULSES_COUNTER

1 Die Anzahl der erforderlichen Impulse, um eine Stelle bei dem normalen Zähler weiter zu zählen.
Angenommen es gibt eine Segmentscheibe mit 4 Segmenten und man möchte pro Umdrehung eine Stelle weiterzählen, nimmt man die Einstellung 4.
Dann wären 4 Impulse nötig pro Zählung. Das muss jeder für sich einstellen!

OPHOURSOFFSET

Der Offset für den Betriebsstundenzähler in Sekunden. Hier kann eine feste Zeit eingetragen werden, zu der der aktuelle Zähler dazu addiert wird.
Es gibt diverse Onlinetools zum Umrechnen einer Zeitangabe in Sekunden.

MACHINE

Bandmaschinenbezeichnung. Momentan stehen nur zwei Möglichkeiten zur Verfügung: 700 für die ReVox A700 und NONE, wenn keine unterstützte Maschine vorhanden ist.

SHOWSPEED

Legt fest, ob die Geschwindigkeitsangaben kurz auf dem Display ausgegeben werden sollen oder nicht.

SPEEDHIGH

Korrekturwert für 38cm/s bei der eingestellten Maschine.

SPEEDMIDDLE

Korrekturwert für 19cm/s bei der eingestellten Maschine.

SPEEDLOW

Korrekturwert für 9,5cm/s bei der eingestellten Maschine.

CAPSTANOFF

Interner Arbeitswert des Zustands, wenn der Capstan nicht dreht (momentan gibt es keine Veranlassung, diesen Wert zu ändern).

NUMSEGS

Anzahl der Segmente der Bandrolle.

SCOPE

Umfang der Bandrolle in mm.

SENSOR_A

Arduino-Eingang für Sensor A. (durch Vertauschen der Pins für SENSOR_A und SENSOR_B kann die Zählrichtung umgekehrt werden!).

SENSOR_B

Arduino-Eingang für Sensor B. (durch Vertauschen der Pins für SENSOR_A und SENSOR_B kann die Zählrichtung umgekehrt werden!).

SPEED95

Arduino-Eingang für die Bandgeschwindigkeit 9,5cm/s (active LOW).

SPEED19

Arduino-Eingang für die Bandgeschwindigkeit 19cm/s (active LOW).

SPEED38

Arduino-Eingang für die Bandgeschwindigkeit 38cm/s (active LOW).

BUTTON

Arduino-Eingang für den Anschluss des Tasters.

ZEROPOINT

Arduino-Ausgang für den Null-Impuls.

LED

Arduino-Ausgang für die Onboard-LED zum Anzeigen des Speichervorgangs.

LEFT

Logischer Zustand der Drehrichtung ‚links‘.

RIGHT

Logischer Zustand der Drehrichtung ‚rechts‘.

Diverse EEPROM-Adressen

*nur ändern, wenn die Speicherzellen des EEPROMs nach ca. 100.000 Schreibvorgängen verbraucht sind!

I2C_ADDRESS

Adresse des Displays. In den meisten Fällen vom Hersteller auf 0x3C festgelegt. In Ausnahmefällen auch 0x3D möglich.

Begrüßungstext

Der Begrüßungstext kann sehr einfach geändert werden. Bitte im Programm nach welcome helloText suchen. Dort findest du dann diesen Abschnitt:

/**************************************************************************/
/*!
    Here you define the welcome text. A maximum of 2 lines is possible.
    Syntax: Message, column (0 to 128), row (1 or 2).
    If a line is not used, it is commented out.
*/
/**************************************************************************/
welcome helloText[2] = {
    /*Line1*/ { "DIYLAB", 52, 1 },
    /*Line2*/ { "COUNTER 1.10", 52, 2 }
};

Mit dem benutzten Font utf8font10x16 sind auf dem Display 2 Zeilen möglich. Die Syntax des oben zu sehenden Codeabschnitts ist Text, Spalte, Zeile. Der Text muss auf die Displaybreite passen, Scrollen ist nicht implementiert. Mit Spalte ist ein Punkt zwischen 0 und 128 gemeint, auf den der Cursor gesetzt wird. Mit Zeile ist entweder Zeile 1 oder Zeile 2 gemeint. Wenn nur eine Zeile benutzt werden soll, kann die andere Zeile mit zwei // auskommentiert werden. Wenn du andere Schriftarten und Größen verwenden willst, solltest du dich unbedingt mit der Dokumentation der verwendeten OLED-Bibliothek auseinandersetzen.

Vorsicht: Änderungen der Schriftart und Größe wirken sich direkt auf den Menüpunkt Brightness aus und könnten zu einer falschen Darstellung führen!

Startlogo

Das verwendete OLED-Display hat eine Auflösung von 128x32 Pixeln. Jedes Pixel kann per Direktbeschreibung des Puffers gesetzt werden. Daher ist es recht einfach, beim Start ein Bild in dieser Größe anzuzeigen. Das Bild kann mit jedem Zeichenprogramm erstellt werden, welches Bitmapformate abspeichern kann. Für das Startlogo habe ich z.B. solch ein Bild benutzt:

Das Hintergrundgitter ist nur im Zeichenprogramm zu sehen und zeigt die einzelnen Pixel. Du kannst z.B. auch mit dem Zeichenprogramm deiner Wahl Text an beliebigen Stellen und in jeder Sprache zeichnen. Ist das Bild dann fertig, muss es in ein Format gewandelt werden, welches der Arduino verarbeiten kann. Dazu gibt es eine Website, die das für dich automatisch erledigt: https://javl.github.io/image2cpp/

Dort lädst du dein Bild hoch und stellst Folgendes ein:

Wenn du dann auf Generate code klickt, hast du im Kästchen darunter den kompletten Code für das Projekt. Du öffnest im Projektverzeichnis die Datei logo.h und kopierst den generierten Code dort hinein (den kompletten vorhandenen Code bitte ersetzen!).

Dann noch die Zeile

const unsigned char NaN [] PROGMEM = {

durch

const unsigned char logo [] PROGMEM = {

ersetzen, das Projekt kompilieren und in den Arduino laden und schon hast du ein neues Logo.

Schriftarten

Im Forum Original-Thread kam öfter die Frage: „wie kann ich die Schriftgröße verändern?“. Dazu musst du verstehen, dass ein Mikrocontroller natürlich kein PC oder Tablet ist und die verwendete Schriften auf Displays beliebiger Art nicht als Vektoren, sondern als Bild dargestellt werden.

Jedes Pixel eines Zeichens ist ein Bit und ein Zeichen kann nicht frei skaliert werden. Die verwendete Bibliothek stellt bereits eine stattliche Auswahl an Schriftarten zur Verfügung. Vielleicht guckst du mal ins Font-Verzeichnis der Bibliothek? Alle Arduino-Bibliotheken werden hier abgelegt: c:\Users\<dein Username>\Documents\Arduino\libraries\. Dort findest du auch die Bibliothek SSD1306Ascii, sie wird für das Projekt verwendet!

*Anmerkung: SSD1306 bezieht sich auf den Chip, der sich auf dem OLED-Display befindet und das Display steuert. Ascii bedeutet, dass diese Bibliothek ausschließlich dafür entwickelt wurde, ASCII-Schriftzeichen darzustellen und keine Grafikroutinen beinhaltet.

Es gibt verschiedene Bibliotheken anderer Entwickler die viel mehr Komfort, Grafikroutinen und Effekte haben, allerdings sind diese Bibliotheken meist wesentlich langsamer und brauchen deutlich mehr Speicherplatz im Controller.

Benutzt werden insgesamt 3 Schriftarten:

  • utf8font10x16.h für den Begrüßungstext und die Änderung der Displayhelligkeit, sie ist bei der Bibliothek dabei;
  • tapecounter_16x24.h für die Darstellung bei FONTSIZE 1, selbst erstellt;
  • tapecounter_23x32.h für die Darstellung bei FONTSIZE 2, selbst erstellt;

Die Zahlen im Dateinamen stehen für die maximale Größe der Zeichen. Einige Zeichen können weniger Breite haben, es sind Proportionalschriften.

Wenn du möchtest, kannst du dir einen eigenen Zeichensatz erstellen. Wobei dies eine sehr zeitaufwändige Angelegenheit ist und die Anpassung auf optimale Darstellung bei diesem Projekt schwierig ist, ganz besonders bei FONTSIZE 2. Dort wird mit einigen Tricks gearbeitet, die z.B. gewährleisten, dass bei der Längenanzeige trotz des begrenzten Platzes auch mehr als 1000 Meter angezeigt werden können. Da die Veränderung der Schriften in diesem Projekt ein komplexes Thema ist, möchte ich dies nicht supporten, sorry. Der Counter wird mit passenden und funktionierenden Schriften geliefert.

Wenn du es trotzdem versuchen möchtest

Ganz unten auf dieser Seite findest du zwei Downloads. Einmal ein kleines Programm zum Zeichnen von Schriften und die beiden selbst erstellten Schriften in 24px und 32px Größe. Das Programm ist im Internet schwer zu finden, daher biete ich es hier zum Download an. Es ist eine Java-Applikation und setzt eine installierte Java-JRE voraus. Du kannst nun meine Schriftdateien damit öffnen, sie haben die Endung .fnt und Zeichen für Zeichen ansehen. Dieses Programm ist in der Lage, die nötigen C-Header Dateien zu erzeugen, die das Projekt benötigt. Diese Dateien haben die Endung .h.

Die exportierte Schrift als Header-Datei lässt sich mit jedem Texteditor anschauen. Wenn du die Schrift anschaut, wirst du merken, dass das Java-Programm fehlerhaft arbeitet! In der Datei steht bei der Font-Größe ein negativer Wert. Alles Negative muss ins Positive geändert werden und bei der Größe musst du dann auch die reale, positive Größe der Zeichen als Zahl im hexadezimalen Format eintragen. Außerdem ist eine Zeile zu ändern.

Beim Export wird im Header folgendes erzeugt:

static uint8_t <name eurer schrift>[] PROGMEM = {

Das muss in

GLCDFONTDECL(<name deiner schrift>) = {

geändert werden. Am besten ist es, du vergleichst deine erzeugten Headerdateien mit den mitgelieferten Dateien.

Bedienung über den Taster

1x kurz

Reset für alle Anzeigemodi.

2x kurz hintereinander

Umschalten auf Zähler, Längenanzeige oder Zeitanzeige.

Langer Druck

Die Helligkeit kann in 16 Schritten eingestellt werden. Der Wert wird nach dem Loslassen der Taste persistiert.

Taste festhalten beim Einschalten der Maschine

Betriebsstundenzähler wird angezeigt.