Arduino Nixie Uhr

Hallo Leute.

Also ich Fange mal, und zwar habe ich mir vorgenommen eine Nixie Uhr zu Bauen mit folgenden teilen :
die Röhre 6 mal
http://www.ebay.de/itm/like/332364251132?chn=ps&dispItem=1

Der Chip
http://www.ebay.de/itm/Nixie-Chip-K155ID1-SN-MH-74141-decoder-driver-IC-tube-clock-Uhr-NOS-DE-DHL/332018109498?_trkparms=aid%3D222007%26algo%3DSIM.MBE%26ao%3D1%26asc%3D20150313114020%26meid%3D02bebf4a598146cb9b5c7ae66fd4861b%26pid%3D100338%26rk%3D3%26rkt%3D28%26sd%3D332364251132&_trksid=p2141725.c100338.m3726

ich habe mir das so vorgestellt das ich alle 6 Röhren über einen chip steuere und zwar durch Multiplexing

ich habe hier bereits meinen Code schonmal vorbereitet wo auch drin steht wie der chip das GND der röhre schaltet

#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <Wire.h>

//---D---C---B---A 
//0=0---0---0---0
//1=0---0---0---1
//2=0---0---1---0
//3=0---0---1---1
//4=0---1---0---0
//5=0---1---0---1
//6=0---1---1---0
//7=0---1---1---1
//8=1---0---0---0
//9=1---0---0---1


  //D2 => A
  //D3 => B
  //D4 => C
  //D5 => D

  //SDA => A4
  //SCL => A5
  
#define A 2
#define B 3
#define C 4
#define D 5

int t = 500; 




void setup() {
Serial.begin(9600);//serielle Verbindung

setSyncProvider(RTC.get);

pinMode(A,OUTPUT);//pin2
pinMode(B,OUTPUT);//pin3
pinMode(C,OUTPUT);//pin4
pinMode(D,OUTPUT);//pin5

}

void loop() {
        //Uhrzeit Im Monitor
          Serial.print(hour()); //Serial.print ist der Befehl etwas im seriellen Monitor anzuzeigen (Stunde, Minute, Sekunde, Leerzeichen, Tag, Leerzeichen, usw.)
          printDigits(minute()); //bei den Minuten und Sekunden wird der Befehl
          printDigits(second()); //printDigits angegeben welcher am Ende des Codes noch festgelegt wird.
          Serial.print(" ");
          Serial.print(day());
          Serial.print(" ");
          Serial.print(month());
          Serial.print(" ");
          Serial.print(year());
          Serial.println();

        delay(1000);

}



  void Null(){      //Nixie zeigt 0 an
      digitalWrite(A, LOW);
      digitalWrite(B, LOW);
      digitalWrite(C, LOW);
      digitalWrite(D, LOW);
        // Anweisungsblock Ende
        }

      void Eins(){      //Nixie zeigt 1 an
      digitalWrite(A, HIGH);
      digitalWrite(B, LOW);
      digitalWrite(C, LOW);
      digitalWrite(D, LOW);
        // Anweisungsblock Ende
        }

      void Zwei(){      //Nixie zeigt 2 an
        digitalWrite(A, LOW);
        digitalWrite(B, HIGH);
        digitalWrite(C, LOW);
        digitalWrite(D, LOW);
          // Anweisungsblock Ende
          }

      void Drei(){      //Nixie zeigt 3 an
        digitalWrite(A, HIGH);
        digitalWrite(B, HIGH);
        digitalWrite(C, LOW);
        digitalWrite(D, LOW);
          // Anweisungsblock Ende
          }

      void Vier(){      //Nixie zeigt 4 an
        digitalWrite(A, LOW);
        digitalWrite(B, LOW);
        digitalWrite(C, HIGH);
        digitalWrite(D, LOW);
          // Anweisungsblock Ende
          }

      void Fuenf(){     //Nixie zeigt 5 an
        digitalWrite(A, HIGH);
        digitalWrite(B, LOW);
        digitalWrite(C, HIGH);
        digitalWrite(D, LOW);
          // Anweisungsblock Ende
          }

      void Sechs(){     //Nixie zeigt 6 an
        digitalWrite(A, LOW);
        digitalWrite(B, HIGH);
        digitalWrite(C, HIGH);
        digitalWrite(D, LOW);
          // Anweisungsblock Ende
          }

      void Sieben(){    //Nixie zeigt 7 an
        digitalWrite(A, HIGH);
        digitalWrite(B, HIGH);
        digitalWrite(C, HIGH);
        digitalWrite(D, LOW);
          // Anweisungsblock Ende
          }

      void Acht(){      //Nixie zeigt 8 an
        digitalWrite(A, LOW);
        digitalWrite(B, LOW);
        digitalWrite(C, LOW);
        digitalWrite(D, HIGH);
          // Anweisungsblock Ende
          }

      void Neun(){      //Nixie zeigt 9 an
        digitalWrite(A, HIGH);
        digitalWrite(B, LOW);
        digitalWrite(C, LOW);
        digitalWrite(D, HIGH);
        // Anweisungsblock Ende
        }

      void Nichts(){    //Nixie zeigt nichts an
        digitalWrite(A, HIGH);
        digitalWrite(B, HIGH);
        digitalWrite(C, HIGH);
        digitalWrite(D, HIGH);
        // Anweisungsblock Ende
        }

      void printDigits(int digits){   //<10 eine 0 davor
        Serial.print(":"); 
        if(digits < 10) 
        Serial.print('0'); 
        Serial.print(digits); 
        // Anweisungsblock Ende
        }

jetzt meine Frage wie kann ich die zahlen am sinnvollsten ausgeben auf den röhren???
bis jetzt hatte ich das alles schon alleine hin bekommen aber an der stelle hapert es nun doch da ich nicht genau weiß wie ich das mache ohne das es endlos und unübersichtlich wird.

ich hoffe sehr das ihr mir helfen könnt

phillert: ... da ich nicht genau weiß wie ich das mache ohne das es endlos und unübersichtlich wird. ...

Ich finde, dass Du arg weit „vorgreifst“, wenn Du die Software schon fertig haben möchtest, bevor Du die Hardware vor Dir liegen hast.

Zur eigentlichen Frage: Pack' die Ausgabe auf den Nixies in eine separate Funktion, die Du der Übersichtlichkeit wegen in einen eigenen Tab „auslagerst“. Dann kannst Du die Ausgabe auf den Nixies in verhältnismäßig übersichtlichen Code packen.

HTH

Gregor

Kuck mal hier:
Alles Fertig >HIER< Der K155ID ist der Russische Bruder zum 74er
Gruß
DerDani

hey danke für die Antworten

also die teile habe ich schon und die röhren leuchten auch......

von dir @Volvodani habe ich schon 3 foren beiträge gesehen wo es um den bau deiner schreibtischuhr ging leider kann ich deinen link nicht öffnen.....

ja das in eine funktion zu packen habe ich mir auch schon gedacht da werde ich mich mal mit befassen müssen wie ich das genau mache da dies für mich eine premiere ist

Der K155ID ist ein BCD zu 10 Decoder und Treiber. Damit kannst Du die 10 Kathodenaschlüsse der NIXIE auf Masse schalten. Welche Zahl leuchten soll bestimmst Du mit 4 Datenleitungen.

Multiplexing finde ich zu schwierig für einen Anfänger weil ca +200V geschaltet werden müssen. Ich rate Dir einenn K155ID pro NIXIE-Röhre und notfalls falls Du zuwenig Ausgänge hast die K155ID mittels Schieberegister zB 74HC595 ansteuern.

Die Kathoden auf Masse schalten ist einfacher da die Kathoden, wenn sie nicht leuchten kein allzuhohes Potetial haben bzw kein Strom fließt und ein 60 bis 80V open Kollektorausgang des K155ID bzw 74141 ausreichend spannungsfest sind.

Zur Ansteuerung der K155ID lerne Bitmanipulation, for-Schleifen und Arrays. Du brauchst nicht 10 Funktionen um 10 BCD Werte auf 4 Ausgänge auszugeben. https://www.arduino.cc/en/Reference/HomePage

Grüße Uwe

phillert: leider kann ich deinen link nicht öffnen.....

Der Link verweist auf Deine Treiberchips aus Deinem ersten Beitrag.

Noch zum Multiplexing. Dies wird eine Immense Auswirkung auf die Helligkeit deiner Uhr haben, da jede Röhre nur 1/6 der Zeit "an" ist. Ich denke spendiere 6*den k155ID + 74HC595. Verbessunger zur meiner Uhr würde ich dieses Nezteil von TaylorEdge nehmen und mit einem AnlagOut(PWM) die Spannung des Netzteil über den Eingang am Netzteil ändern. Auch wenn mit von diesem Absputtern an den Zahlen gewarnt worden ist kann ich nach ca 4 Jahren noch nix feststellen. Aber um diesem doch vorzubeugen würde ich die Helligkeitregelung über das Netzteil machen. Wenn man schon bastelt warum multiplexing machen der Aufpreis ist nicht so hoch und die Uhr dankt es dir. Gruß DerDani

Sorry.... Hatte mich vorhin im Quelltext der Seite verhauen... :confused: Jetzt funktioniert der Link von volvodani aber ;)

Das Problem mit den nicht mehr leuchtenden Ziffern ist akut wenn Ziffern sehr wenig gegenüber anderen eingeschaltet sind. Kathodenmaterial verdampft und schlägt sich als nichtleitender Oxydüberzug an den anderen Kathoden ab. Da diese dann ganz oder teilweise isoliert sind, leuchtet dieser Bereich nicht mehr.
Bei einer Uhr die dauernd läuft wechseln sich die Zahlen dauernd ab. Die Zeichen 3-9 bei den Zehnern Stunden und 7-9 bei den Zehnern Minuten und Sekunden werden dieses Problem aufweisen, da Du aber diese Ziffern nie brauchst bemerkst Du diese vergifteten Ziffern nicht.

Grüße Uwe

PS ab den link von volvodani korrigiert.

uwefed: Das Problem mit den nicht mehr leuchtenden Ziffern ist akut wenn Ziffern sehr wenig gegenüber anderen eingeschaltet sind. Kathodenmaterial verdampft und schlägt sich als nichtleitender Oxydüberzug an den anderen Kathoden ab. Da diese dann ganz oder teilweise isoliert sind, leuchtet dieser Bereich nicht mehr.

Wo soll in einer Anzeigeröhre Sauerstoff herkommen? Röhren werden evakuiert und unter geringem Druck kommt ein wenig Edelgas da rein. Sauerstoff wird sogar rausgegettert (mit hochraktiven Metallen aus der Alkali- und Erdalkaligruppe eingefangen) Es ist eher so, das der Glaskolben und die Anode bei zu hohen Strömen und beim Muxen besputtert werden. Zum einen wird das Glas dunkler durch die Bedampfung (wie eine Sonnenbrille) und zum anderen wird die Oberflächenmetallisierung irgendwann hochohmig leitfähig und sorgt so für eine Feldstärkeverzerrung zwischen Anode und Katoden. Wenn nicht mehr alle Ecken eine homogene Feldstärke sehen, dann gibt es dunkle Stellen. Das wäre eine mögliche Erklärung nach meinem Verständnis.

danke für eure ratschläge....

ich sehe ein das ich mir mit den multiplexen sehr viel vorgenommen habe was ich aber eigentlich nur mache weil ich kein register davor setzen wollte und nur der mega genügend i/o s hat.

könnte mir denn jemand im groben erklären wie ich dem arduino sagen kann "hey es ist 14 uhr 22 und 43sek. röhre 1 geh an röhre zwei zeig 4 nr 3 zeig 2 nur 4 zeig 2 nr 5 zeig 4 und nr mach mal die 3 an"

Uwefed ich danfe dir für deine ratschläge ich werde sie befolgen und mich schrittweise vorarbeiten.

Zerlege die Uhrzeit in einzelne Ziffern. 14 = 1 und 4. 43 = 4 und 3. Wenn du dann machst was Uwe vorgeschlagen hast und direkt die I/O-Ports statt die einzelnen Pins ansprichst kannst du die fast direkt ausgeben, da man so 8 Pins auf einmal setzen kann. So werden Mikroncontroller-Pins normal angesprochen. Die IDE macht das zwar in vielen Fällen mit digitalWrite() einfacher, aber hier wird das dadurch nur komplizierter.

Stichwort auch "BCD". Binary Coded Decimal. Da sind 4 Bits eine Ziffer. z.B. 10011001 = 99 (dezimal). Es gibt da auch einfache Wege Dezimal nach BCD zu konvertieren ohne viel zu rechnen.

gäbe es dafür ein beispiel? versuche das gerade nachzuvollziehen.

ich muss gerade wahrscheinlich erstmal überlegen wie ich dem programm sage das immer wenn eine 1 irgendwo ist erscheint der arduino automatisch sagt ah ich habe ja den "void Eins"

Es gibt keine voids. Void ist ein Datentyp. Die Dinger heißen Funktionen. Du denkst immer noch falsch. Vergiss es eigene Funktionen für jede Zahl zu haben. Das ist Irrsinn.

Schau dir den UNO an:
http://www.pighixxx.com/test/wp-content/uploads/2017/05/uno.png

Da siehst dass Port D direkt hintereinander auf den Pins 0-7 liegt. Also kann man einfach das tun:

byte stunden = 12;
byte einer = stunden % 10;    //% = Modulo, der Rest einer Division
byte zehner = stunden / 10;

PORTD = (zehner << 4) | einer;   //Zehner um 4 Bit nach links schieben und mit Einer verordern

Das ist alles was man braucht um zwei Ziffern anzuzeigen

Praktisch ist es etwas problematischer, da es z.B. keine gute Idee ist Pins 0 und 1 zu belegen. Und Ports B und C nicht komplett zur Verfügung stehen. Da kann man das aber auf verschiedene Ports verteilen. z.B.:

byte tmp = PORTB;  //Port Register einlesen
tmp &= 0xF0;       //Bits 0-3 löschen
tmp |= einer;      //Einer-Stelle auf Bits 0-3 schreiben (Pins 8-11)
PORTB = tmp;   //Register schreiben

tmp = PORTD;
tmp &= 0x0F;         //Bits 4-7 löschen
tmp |= zehner << 4;  // Zehner-Stellen auf Bits 4-7 schreiben (Pins 4-7)
PORTD = tmp;

EDIT: so geändert dass man das Register erst mal einliest, die Änderungen macht und zurückschreibt.

Ansonsten kann es sich wie auch schon gesagt anbieten das mit Schieberegistern zu machen. Da du auf dem UNO halt nicht 3 * 8 Pins hast! Dann muss man nur Stunden, Minuten und Sekunden jeweils nach BCD konvertieren und 3 mal schieben

das ist eine super erklärung wirklich ich danke dir dafür und auch die aussage das es irrsinn ist gebe ich dir recht.

ich werde mich mal probieren und ersteinmal versuchen das ansteuern der zahlen so zu gestallten und das dann hier nochmal posten in der hoffnung das ich dann darauf weiter aufbauen kann.

dümmer kann ich ja nicht werden.

danke

Als Test für ein paar Ziffern geht das erst mal. Aber wie gesagt ohne Multiplexing hast du halt nicht genug Pins für 6 Ziffern. Da ist schon verständlich wie du darauf gekommen bist

Aber du kannst für jede Ziffer einen BCD-Dekoder nehmen. Und diese mit 3 Schiebregister ansteuern. Die brauchen nur 3 Pins:

Ist da mit LEDs, aber da können genauso anderen ICs an den Ausgängen hängen. Das ist auch nicht unüblich für 7-Segment-Anzeigen

Ein Byte schreibt man bequem mit shiftOut():
https://www.arduino.cc/en/Reference/ShiftOut
Und wie in dem Beispiel vorher den Latch-Pin auf Low and danach wieder auf High

nix_mehr_frei:
Wo soll in einer Anzeigeröhre Sauerstoff herkommen? Röhren werden evakuiert und unter geringem Druck kommt ein wenig Edelgas da rein. Sauerstoff wird sogar rausgegettert (mit hochraktiven Metallen aus der Alkali- und Erdalkaligruppe eingefangen)
Es ist eher so, das der Glaskolben und die Anode bei zu hohen Strömen und beim Muxen besputtert werden. Zum einen wird das Glas dunkler durch die Bedampfung (wie eine Sonnenbrille) und zum anderen wird die Oberflächenmetallisierung irgendwann hochohmig leitfähig und sorgt so für eine Feldstärkeverzerrung zwischen Anode und Katoden. Wenn nicht mehr alle Ecken eine homogene Feldstärke sehen, dann gibt es dunkle Stellen.
Das wäre eine mögliche Erklärung nach meinem Verständnis.

Ich weiß jetzt nicht woher die stöhrende Schicht auf den Kathoden herkommt, aber wenig benutzte Ziffern funktionieren nach längerer Zeit nicht mehr richtig. Es ist nicht eine Beschlag auf der Innenseite des Glaskolbens sondern auf der Oberfläche der Ziffer sodaß die Ziffer nicht mehr überall gleichmäßig hell leuchtet sondern dunkler leuchtende Bereiche hat.
Diskussion über dieses Thema:
https://www.mikrocontroller.net/topic/310739
Beispiel einer Vergifteten NIXIE und Reparatur:
http://www.tube-tester.com/sites/nixie/different/cathode%20poisoning/cathode-poisoning.htm

Grüße Uwe

Schaltplän zu Schiftregister ansteuerung der 74141: Projektbeschreibung http://elektronik-kompendium.de/public/arnerossius/schaltungen/avr/nixieclk.htm mit Schaltplan: http://elektronik-kompendium.de/public/arnerossius/schaltungen/avr/nixieclk.png Die 74164 entsprechend den 74595, immer Schieberegister.

oder http://www.jb-electronics.de/html/elektronik/nixies/n_uhr3.htm mit 'nem großen Schaltplan: http://www.jb-electronics.de/images/elektronik/nixies/n_uhr3/nixieuhr_schaltplan_gross.png In diesem Fall werden die Schiberegister nicht Hintereinandergeschaltet sondern immer nur 1 aktiviert und daten übertragen. Geht auch so, braucht halt mehr Ausgänge.

Grüße Uwe

so leute da bin ich wieder dieses mal mit einer überarbeiteten version meines codes.

int t = 500;

void setup() {

  //D2 => A
  //D3 => B
  //D4 => C
  //D5 => D
    DDRD = DDRD | B00111100;
}

void loop() {
  int i;
  //je sekunde eins weiter
  while(true){
    ausgabe(i);
    delay(t);
    i++;
    if (i >= 10){
      i = 0;
    }
  }
}

void ausgabe(int eingabe){
  switch (eingabe){
    case 0: PORTD = 0x0;
            break;
    case 1: PORTD =  0x4;
            break;
    case 2: PORTD =  0x8;
            break;
    case 3: PORTD =  0xC;
            break;
    case 4: PORTD =  0x10;
            break;
    case 5: PORTD =  0x14;
            break;
    case 6: PORTD =  0x18;
            break;
    case 7: PORTD =  0x1C;
            break;
    case 8: PORTD =  0x20;
            break;
    case 9: PORTD =  0x24;
            break;
    
    default: break;
  }  
}

habe diesen mit hilfe eines freundes heute zusammen erstellt

void loop() {
  int i;
  //je sekunde eins weiter
  while(true){
    ausgabe(i);
    delay(t);
    i++;
    if (i >= 10){
      i = 0;
    }
  }
}

Zu was brauchst Du die While-Schleife?