Gezählte ereignisse zur Anzeige bringen

Ich plane mein erstes Projekt mit Arduino, ich habe Vorstellung, wie ich es verwirkliche, nur in einem Punkt suche ich, vergeblich. Eigentlich einfach, oder gar Standard:

Eine Integer Zahl möchte ich als zweistellige Integer Zahl (maximal 50) zur Anzeige bringen. Wie kann ich dies im Sketch eingeben? Anzeige hat 4 bit, gemultiplext.

Ich denke, das ist eine triviale Aufgabe, aber ich finde die Lösung nicht.

Ja!

Wenn Zahl < 10 dann '0' & Zahl.

Hilft vielleicht doch mehr als combies Ansatz.

Ja!?

Hallo @h-gnagflow ,

willkommen im Arduino-Forum

Diese Aussage ist ungenau. Man kann aus dieser Aussage nicht schlussfolgern was das genau für ein Display ist. 4bit könnte ein LCD mit 4 bit parallel sein.
gemultiplext könnte eine Siebensegmentanzeige sein.
Deshalb links zu den Datenblättern der verwendeten Bauteile und einen handgezeichneten Schaltplan posten.
Wenn du noch kein Display hast dann würde ich so eines empfehlen

Das ist zwar gleich 4-stellig aber supergünstig und es gibt vorgefertigte Programme dafür
TM1637-library

vgs

Hallo,
sorry ich kanns mir nicht verkneifen, Ja Du hast Recht ist einfach , Eingabe mit der Tastatur :wink: dazu wurde die erfunden.

Im Ernst
Du wirst eine Lib benötigen , dazu gibt es in aller Regel Beispiele.

Wozu interger da reicht ein byte es sei denn Du hast negative Ereignisse, aber die nennt man Misserfolg

Heinz

Das Display ist ein DL2416T (steinalt). Davon habe ich etliche, will die einfach nicht so rumliegen lassen.
Das Display hat 4 Digits, alphanumerisch, jedes Digit wird parallel angesteuert. Das Datum jedes Digits wird parallel eingegeben, mittels Speicherbefehl gespeichert. Pro Digit hat man 7 Bit, wenn ich drei Bit fest vorgebe, kann ich es als numerische Anzeige mit 4 Bit verwenden.
Rein hardwaremäßig würde ich nicht um Hilfe nachfragen. Nur, wie kann ich die Zahl aus dem Programmcode hardwaremäßig mittels 4-Bit-Wert an die Ports ausgeben? Ich denke, ich brauche eine Library dafür, aber welche?
Intern zählt der Prozessor ja binär, aber im Programmcode ist eine Zahl ein abstrakter Wert, der mit den Ports am Prozessor, oder dessen internen Registern, nichts zu tun hat. Da fehlt mir dieses "Missing Link" für die Umsetzung.
Auch für Hinweise, wo ich eine Lösung finde, bin ich dankbar.

ich verstehe nicht was das eigentliche Problem ist.

https://www.google.com/search?client=firefox-b-d&q=+DL2416T++arduino
das erste Suchergebnis

was funktioniert daran nicht?

in der Lib gibt es zwei Signaturen für ein "Print"

void Display::Print(String word)

und

void Display::setLetter(char letter, int position)

wenn man eine library zu irgendeiner hardware finden will
Suchstichworte

  • Github
  • Arduino
  • "Typenbezeichnung der Hardware"

also in diesem Fall

  • Github
  • Arduino
  • DL2416T

und voila

gar nicht direkt die ports ansteuern,
sondern so wie in der library gezeigt die function digitalWrite benutzen.

Wenn das zu viele IO-pins verbraucht eine library nehmen die I2C-portexpander ansteuert
und die entsprechenden Befehle in der Libary

anpassen

vgs

Vielen Dank für die Antwort, leider wurde hier am Ziel vorbei geschossen. Das Google-Suchergebnis kenne ich, nur ist das nicht, was ich möchte. Wie ich bereits andeutete, hier im Klartext: Ich will die Daten-Bit des Display D4,D5,D6 mit H,H,L belegen, und habe somit ein Zahlen-Disply mit 4 Bit Eingang. Es ist, als hätte ich zwei Anzeigen mit Binär-Eingang und vorgeschaltetem Register. Den Wert 0 bis 50 möchte ich in diesen zwei Displays zur Anzeige bringen. Ich möchte Low- und High- Nibble des Wertes wechselweise an 4 Ports legen, und zwar BCD codiert. Das ist alles.

Ich weiß zwar immer noch nicht ob ich die Frage richtig verstanden habe,
aber vielleicht hilft ja folgendes weiter:


uint8_t decToBcd(uint8_t dec) { return (dec + 6 * (dec / 10)); }

void setup() {
  Serial.begin(115200);

  for (byte i = 0; i <= 50; ++i) {
    byte varBCD = decToBcd(i);
    byte varBCDLowByte = varBCD & 0x0F;
    byte varBCDHighByte = (varBCD >> 4);
    Serial.print("Dezimal: "); Serial.print(i); Serial.print(" BCD HB: ");
      Serial.print(bitRead(varBCDHighByte,3) ? 1:0);
      Serial.print(bitRead(varBCDHighByte,2) ? 1:0);
      Serial.print(bitRead(varBCDHighByte,1) ? 1:0);
      Serial.print(bitRead(varBCDHighByte,0) ? 1:0);
    Serial.print(" LB: ");
      Serial.print(bitRead(varBCDLowByte,3) ? 1:0);
      Serial.print(bitRead(varBCDLowByte,2) ? 1:0);
      Serial.print(bitRead(varBCDLowByte,1) ? 1:0);
      Serial.print(bitRead(varBCDLowByte,0) ? 1:0);
    Serial.println("");
  } 
}

void loop() {
}

Die einzelnen Bits werden mit Serial.println ausgegeben. Dementsprechend könnte man auch DigitalWrite() verwenden um vier Pins entsprechend zu schalten....

das verstehe ich kein bisschen

Ja und wenn du das mal ausführlicher beschreibst wird es vermutlich auch verständlicher.

welcher "Wert"???
meinst du mit 4 Ports vier einzelne Ausgänge = IO-pins??
oder
meinst du mit Port einen 8bit-Port??

Eine Möglichkeit wäre du zeichnest mal einen Schaltplan auf dem die einzelnen Leitungen zu sehen sind

Oder andere Möglichkeit
Eine Beschreibung
Es gibt am Display folgende Anschlüsse
A
B
C
D
oder wie immer du die Nennen willst. Hauptsache sie haben leicht unterscheidbare Namen
Dann ein Beispiel
Ich habe die Zahl 49 binär ist das 0011 0001‬‬
damit soll jetzt folgendes gemacht werden ....

vgs

Du suchst eine Binär -> BCD Wandlung und Multiplexer.
Zur Vereinfachung ist der Binärwert kein uint16_t, sondern nur ein byte mit Werten bis 99. Und es wird nur 1 Multiplexer-Bit gebraucht.

Ein Beispielcode (in Unkenntnis deiner Anzeige)

const byte M = 13;  // Multiplexer-Pin
const byte D[4] = {2,3,4,5}; // DatenPins 1 2 4 8

void setup() {
  pinMode (M, OUTPUT);
  for (auto& d : D) pinMode(d, OUTPUT);
  Serial.begin(9600);
}

byte test; // 0 .. 50
const unsigned int ZYKLUS = 5000; //ms je test-Wert
const unsigned int HI_DAUER = 1000; 

void loop() {
  static unsigned long alt;
  unsigned int t = millis() - alt;
  if ( t >= ZYKLUS ) {
    alt = millis();
    if (++test > 50) test=0;
    return;
  }

  if (t < HI_DAUER) show(HIGH, test);
  else show(LOW, test);
}

void show(bool hi, byte val) {
  digitalWrite(M, hi);
  if (hi) val = val/10; else val = val%10;
  for (byte b=0, p=1; b < 4; b++, p = p<<1) {
    digitalWrite(D[b], val & p);
  }

  // Debug-Ausgabe
  static byte oldval;
  if ( val != oldval ) 
   {Serial.print(hi); Serial.print(" "); Serial.println((oldval=val), HEX); }
}

StefanL38: Ich habe Bild dazu gemalt zum besseren Verständnis. Mit dem Wert 49, binär
0011 0001 soll am Binär-Eingang zur Anzeige einmal 1001 stehen, wenn das rechte Register beschrieben wird, dann 0100 beim Beschreiben des zweiten Registers.

Nachtrag: Dank an @StefanL38 fürs Datenblatt in#16.

Das Bild mit der 7Segment-Ansteuerung ist wohl eher verwirrend.
Fraglich ist vielleicht das Timing zwichen Ansteuerung der 4 Datenbit und des Adressbits A0.

Also Displays vom Typ DL2416T
Datenbatt DL2416T

haben vier Digits

Das Display hat doch schon vier Stellen. Wozu brauchst du da noch ein zweites?

Oder willst du jetzt 14 Stück davon benutzen um mit je einem DL2416 einen großen Einzelbalken für eine zweistellige 7-Segmentanzeige zu bauen???

Warum muss denn da ein Register (was für eines ??) dazwischen um dann einen BCD-zu.7-Segment-Decoder anzusteuern der dann wiederum die Eingänge des Displays ansteuert??

Das ist entweder hochintelligenter Hardware-Brainfuck oder einfach nur wahnsinnig kompliziert.

Ich würde die Displays mit zwei I2C-IO-expander direkt ansteuern.
Wenn dazu bestimmte IO-pins dauernd auf LOW oder HIGH bleiben können um so besser
hat man weniger bitbanging zu programmieren.

vgs

Wenn man sich die Bit-Banging-Tabelle anschaut: Genau 16 bit = 1 Stück I²C-MCP2307 IO-expander

Da könnte man einen Array aus unsigned int definieren

in den an der passenden Stelle per Oder-Verknüpfung noch die Datenbits D0, D1, D2, D3 "hinein-geodert" werden auf dem IO-expander ausgeben und gut is.

Und wenn ich mir jetzt noch das Characterset anschaue dann sind für Zahlen
D4 HIGH
D5 HIGH
D6 LOW
auf D0 bis D3 kann man direkt den Zahlenwert als Binärzahl des Digits raushauen

Das bedeutet wenn man auf dem IO-Expander die IObits A0, A1, A2, A3 für D0, bis D3 nimmt
dann reduziert sich das auf
im vordefinierten Array sind die vier untersten bits immer 0 und dann werden diese Bits durch simple Addition hinzugefügt.

my16bitIO[AusgabeSchritt] = my16bitIO[AusgabeSchritt] + Zahl;
und dann die 16bit in den MCP23017-Portexpander schreiben.

vgs

Schwierig, mich verständlich zu machen. Was du schreibst, weiss ich bereits alles. Das Datenblatt habe ich auch bereits. Den Zahlenwert als Binärzahl raushauen, das ist seit Anfang meine Frage.
Wenn ich die Lösung, wie auf meinem Bildchen gezeigt, gefunden habe, ist alles klar. Ich will zwei (zunächst) Zeichen in diesem Display zur Anzeige bringen. Diese zwei Zeichen verhalten sich genau so, wie in meinem Bildchen gezeigt. Vergiß das Display, das ich verwende, mein Problem ist diese 4 Bit anzusteuern, nämlich A,B,C,D. Den Rest krieg ich hin.
Ich will einen Wert (integer), welcher im Programmablauf inkrementiert wird, mit einer 2-stelligen Anzeige zu sehen bekommen. Steht dieser Wert beispielsweise auf 5, soll auf A,B,C,D 1,0,1,0 ausgegeben werden. Steht da 25, ist das Ergebnis dasselbe. Durch Division des Wertes durch 10, erhalte ich 2, die dann ebenfalls ausgegeben werden soll, =0100.
Gibt es eine Library, die so etwas kann? Aus den Namen der Libraries kann ich nicht entnehmen, ob diese meine Arbeit erledigen können.

ja aber da bist du zu 110% selbst Schuld dran!

Keine Ahnung was du damit meinst!

An welchen Bauteil hast du die Anschlüsse A,B,C,D??

Meine Güte was ist so schwierig daran die Dinge genau zu benennen?!!

Sind "A,B,C,D" am:

  • Display?
  • am BCD-Decoder?
  • am Register ?
  • am Microcontroller?

Aus den zwei Beispielen wird nicht klar wie die Zahlen mit den einzelnen IO-Ports zusammenhängen.
Binär 1,0,1,0 wäre die Dezimal-Zahl 10

8421
1010  = 8 + 2 = 10

binär 0100 wäre die Dezimal-Zahl 4
du sagst aber es bedeutet "5" bzw. "2"
also sind es nicht einfach bits sondern ist irgendwie anders
und dann musst du das im Detail beschreiben!

A,B,C,D gibt es auch nicht auf deiner Zeichnung

Du arbeitest an einem Informatik-Projekt und was man meisten in einem Informatik-Projekt gebraucht wird ist Information. Relevante und

ausreichend

Information

Ich bin gespannt wie viele dutzend Runden Info-Schnipsel Ping-Pong noch gebraucht werden bis klar ist was du machen willst.

Mein Vorschlag mache mit Excel eine vollständige Tabelle in der alle Zeichen
(Früher waren es mal nur Ziffern 0,1,2,3,4,5,6,7,8,9) und ihre A,B,C,D-Codierung drin aufgelistet sind
In der ZIP-Datei stehen schon mal die Werte für "2" und "5" drin
h-gnagflow-Ereignisse-Zählen-anzeigen.zip (1.8 KB)

Ich versteh nicht, was Du Dich so aufregst. Er hat nach seinem Wissens- und Kenntnisstand beschrieben.
Wenn Du nicht verstehst, dann ist das Dein Problem.

Merkst Du was?

Also las es doch mal langsam angehen und versetz Dich in 4 bit.
Die kann man nämlich auch anders lesen.

Und für mich wäre das vollkommen Wurscht was er damit machen will.
Es soll eine 2stellige Zahl in 2x 4 bit dargestellt werden.
Also ist die Zahl aufzuteilen.
Und dann bitweise auszugeben.
Nicht mehr und nicht weniger.

@h-gnagflow Spiele den folgenden Sketch auf, las Dir auf dem Seriellen Monitor ausgeben was da rauskommt.
Hinweis: Achte drauf, das die Einstellung für den SerMon ggfls. angepasst werden muss.

// Forensketch Von der Schwierigkeit eine 2 stellige Zahl in 4 bit Multiplex auf dem Seriellen Monitor auszugeben
// https://forum.arduino.cc/t/gezahlte-ereignisse-zur-anzeige-bringen/1069184

constexpr byte Zahl {42};

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  Serial.print(F("Aufzuteilende Zahl: "));
  Serial.println(Zahl);
  Serial.print(F("Zehner: "));
  Serial.println(Zahl / 10);
  Serial.print(F("Einer: "));
  Serial.println(Zahl % 10);
  Serial.println(F("Bitweise Ausgabe: "));
  for (byte b = 0; b < 4; b++)
  {
    Serial.print(bitRead(Zahl / 10,b));
  }
  Serial.print('\t');
  for (byte b = 0; b < 4; b++)
  {
    Serial.print(bitRead(Zahl % 10, b));
  }
  Serial.println();
}

void  loop()

{}