Nixie-Uhr mit 6x Z570M

avrkarl

Neues Mitglied
04. Mai 2011
28
0
0
Sprachen
Wollte Euch mein aktuelles Nixie-Uhren-Projekt vorstellen. Irgendwie mag ich diese Röhren und als ich 6 noch nie benutze Z570M erhalten habe, gab es dafür keine (aus meiner Sicht) bessere Verwendung. Das ist mittlerweile meine 2. Nixie-Uhr. Die erste habe ich noch auf einer Lochrasterplatine aufgebaut, was nicht unbedingt zu empfehlen ist (zu viele Kabel).

Nun gibt es im Netz diverse Bauanleitungen, die jedoch meisten die Röhren im Multiplex-Verfahren ansteuern. Das hat aus meiner Sicht nur den Vorteil, dass die Baugröße der Uhr kleiner wird. Es sind jedoch nicht alle Röhrentypen dafür geeignet. Deshalb hat in dieser Version jede Röhre ihren eigenen Treiberbaustein. Der ist notwendig, da die Röhren erst bei > 140V überhaupt anfangen etwas anzuzeigen. Als Treiberbausteine werden sechs KM155ID1 benutzt (es gehen auch K155ID1 oder 74141), die im Vergleich zu den Röhren leicht beschaffbar und preiswert sind.

Die Ansteuerung selbst ist recht einfach. Für die 10 Ziffern einer Nixie braucht man 4 Pins des Mikrocontrollers. Der ATMega16 eignet sich hervorragend als µC. Als Programmiersprache verwende ich BASCOM.

Um die Hochspannung zu erzeugen, wird ein MC34063 eingesetzt. Die Schaltung dafür war auf der Homepage www.stefankneller.de verfügbar (über das Gästebuch lässt sich sich mittlerweile wieder herunterladen). Wichtig ist vor allen Dingen die Strombegrenzung. Wie bei einer LED kann die Nixie-Röhre ihren Strom nicht selbst begrenzen. Laut Datenblatt der Z570M sind 2 mA typisch. Am besten ermittelt man den dafür passenden Widerstand mit einem Strommessgerät (so um die 10 kOhm ist ein guter Startwert). In diesem Fall waren es 27 kOhm.

Bei den Röhren handelt es sich um sechs Z570M aus DDR-Produktion. Diese sind im Original rot lackiert, um den Kontrast zu erhöhen.

Die Firmware ist vielleicht nicht optimal, aber sie funktioniert. Zum Beispiel könnten die Pull-Up-Widerstände R10 und R12 weggelassen werden, wenn die Software noch etwas optimiert werden würde.......:eek: Die Uhrzeit liefert eine DS1307 Echtzeituhr. Ein Pin des µCs ist sogar noch frei, so dass hier auch ein Funkuhrmodul angeschlossen werden könnte.

Beim Aufbau könnte man den Quarz auch weglassen. Leider stimmen auch zwei Bohrungen nicht überein, deshalb sind die Verbindungen bei zwei Röhren etwas schräg, was die Funktionalität aber nicht beeinträchtigt.

Anbei noch ein paar Fotos und ein Video der Uhr im Rohbau, die Uhrzeit und Datum anzeigt. Das schnelle Durchzählen aller Ziffern zwischen Uhrzeit- und Datumswechsel dient nicht nur als Effekt, sondern auch dazu, die "Kathodenvergiftung (Cathode Poisoning)" zu minimieren. Über längere Zeit nicht eingeschaltete Ziffern würden aufgrund dieses Effekts dann ungleichmäßiger leuchten.

Die für die Nixie-Uhren notwendige Spannung kann lebensgefährlich sein. Insbesondere die spannungsführenden Teile/Leiterbahnen am Ausgang des MC34063 Schaltreglers und an den Nixie-Röhren selbst sollten unter keinen Umständen berührt werden.



nixie1.jpgnixie2.jpgnixie4.jpgnixie.PNG



[video=youtube;lGf1MKWt8wc]http://www.youtube.com/watch?v=lGf1MKWt8wc[/video]

Code:
$regfile = "m16def.dat"
$crystal = 8000000

Dim A As Integer
Dim Astr As String * 2

Dim Ziffer12str As String * 2
Dim Ziffer3str As String * 2
Dim Ziffer4str As String * 2
Dim Ziffer56str As String * 2


Dim Timestr As String * 8
Dim Datestr As String * 8

Dim Sekundestr As String * 2
Dim Minutestr As String * 2
Dim Minute3str As String * 1
Dim Minute4str As String * 1
Dim Stundestr As String * 2
Dim Jahrstr As String * 2
Dim Monatstr As String * 2
Dim Monat3str As String * 1
Dim Monat4str As String * 1
Dim Tagstr As String * 2

Dim Tagx As Integer
Dim Monatx As Integer
Dim Jahrx As Integer
Dim Stundex As Integer
Dim Minutex As Integer
Dim Sekundex As Integer

Dim Weekday As Byte

Dim Exitbit As Bit

Config Porta = Output
Config Portb = Output
Config Portd = Output

Config Portc.7 = Output
Config Portc.6 = Output
Config Portc.5 = Output
Config Portc.4 = Output

Config Pinc.3 = Input
Config Pinc.2 = Input

Portc.3 = 1
Portc.2 = 1

Config Debounce = 50


Config Clock = User
Config Date = Dmy , Separator = .

$lib "i2c_twi.lbx"                                          '
Config Sda = Portc.1
Config Scl = Portc.0
Const Ds1307w = &HD0
Const Ds1307r = &HD1
Config Twi = 100000

Enable Interrupts

Declare Sub Setweekday
Declare Sub Showtime
Declare Sub Antipoisening
Declare Sub Setup

'Date$ = "23.12.11"
'Time$ = "22:22:00"
'Weekday = 5
'Call Setweekday

Do

'Portc.3 = 1
'Portc.2 = 1


Timestr = Time$
Datestr = Date$
Exitbit = 0

Sekundestr = Mid(timestr , 7 , 2)
Minutestr = Mid(timestr , 4 , 2)
Minute3str = Mid(minutestr , 1 , 1)
Minute4str = Mid(minutestr , 2 , 1)
Stundestr = Mid(timestr , 1 , 2)
Jahrstr = Mid(datestr , 7 , 2)
Monatstr = Mid(datestr , 4 , 2)
Monat3str = Mid(monatstr , 1 , 1)
Monat4str = Mid(monatstr , 2 , 1)
Tagstr = Mid(datestr , 1 , 2)

Tagx = Val(tagstr)
Monatx = Val(monatstr)
Jahrx = Val(jahrstr)

Stundex = Val(stundestr)
Minutex = Val(minutestr)


If _sec > 30 And _sec < 32 Then

   Call Antipoisening

Elseif _sec > 31 And _sec < 38 Then

   Ziffer12str = Tagstr
   Ziffer3str = Monat3str
   Ziffer4str = Monat4str
   Ziffer56str = Jahrstr
   Ziffer4str = Ziffer4str + "0"

Elseif _sec > 37 And _sec < 39 Then

   Call Antipoisening

Else

   Ziffer12str = Stundestr
   Ziffer3str = Minute3str
   Ziffer4str = Minute4str
   Ziffer56str = Sekundestr
   Ziffer4str = Ziffer4str + "0"

End If

Call Showtime

Debounce Pinc.2 , 0 , Setup , Sub
'Debounce Pinc.3 , 0 , Setup , Sub


Loop


'#####################################

Showtime:
   Porta = Hexval(ziffer12str)
   Portb = Hexval(ziffer3str)
   Portc = Hexval(ziffer4str)
   Portd = Hexval(ziffer56str)
Return

'#####################################

Antipoisening:

   For A = 0 To 99 Step 11

      Astr = Str(a)
      Astr = Format(astr , "00")
      Ziffer12str = Astr
      Ziffer3str = Left(astr , 1)
      Ziffer4str = Right(astr , 1)
      Ziffer4str = Ziffer4str + "0"
      Ziffer56str = Astr
      Waitms 50
      Call Showtime

   Next

Return

'#####################################

Setup:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Tagstr = Str(tagx)

      Ziffer12str = Tagstr
      Ziffer3str = Monat3str
      Ziffer4str = Monat4str
      Ziffer56str = Jahrstr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup2 , Sub
      Debounce Pinc.3 , 0 , Settag , Sub

   Wend

Return

'#####################################

Settag:

   Bitwait Pinc.3 , Reset

   Incr Tagx

   If Tagx > 31 Then Tagx = 1

Return


'#####################################

Setup2:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Tagstr = Str(tagx)
      Monatstr = Str(monatx)
      Monatstr = Format(monatstr , "00")
      Monat3str = Mid(monatstr , 1 , 1)
      Monat4str = Mid(monatstr , 2 , 1)

      Ziffer12str = Tagstr
      Ziffer3str = Monat3str
      Ziffer4str = Monat4str
      Ziffer56str = Jahrstr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup3 , Sub
      Debounce Pinc.3 , 0 , Setmon , Sub

   Wend

Return

'#####################################

Setmon:

   Bitwait Pinc.3 , Reset

   Incr Monatx

   If Monatx > 12 Then Monatx = 1

Return

'#####################################

Setup3:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Tagstr = Str(tagx)
      Monatstr = Str(monatx)
      Monatstr = Format(monatstr , "00")
      Monat3str = Mid(monatstr , 1 , 1)
      Monat4str = Mid(monatstr , 2 , 1)
      Jahrstr = Str(jahrx)

      Ziffer12str = Tagstr
      Ziffer3str = Monat3str
      Ziffer4str = Monat4str
      Ziffer56str = Jahrstr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup4 , Sub
      Debounce Pinc.3 , 0 , Setjahr , Sub

   Wend

Return

'#####################################

Setjahr:

   Bitwait Pinc.3 , Reset

   Incr Jahrx

   If Jahrx > 41 Then Jahrx = 11

Return

'#####################################

Setup4:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Stundestr = Str(stundex)

      Ziffer12str = Stundestr
      Ziffer3str = Minute3str
      Ziffer4str = Minute4str
      Ziffer56str = Sekundestr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup5 , Sub
      Debounce Pinc.3 , 0 , Setstunde , Sub

   Wend

Return

'#####################################

Setstunde:

   Bitwait Pinc.3 , Reset

   Incr Stundex

   If Stundex > 23 Then Stundex = 0

Return

'#####################################

Setup5:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Stundestr = Str(stundex)
      Minutestr = Str(minutex)
      Minutestr = Format(minutestr , "00")
      Minute3str = Mid(minutestr , 1 , 1)
      Minute4str = Mid(minutestr , 2 , 1)

      Ziffer12str = Stundestr
      Ziffer3str = Minute3str
      Ziffer4str = Minute4str
      Ziffer56str = Sekundestr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup6 , Sub
      Debounce Pinc.3 , 0 , Setminute , Sub

   Wend

Return

'#####################################

Setminute:

   Bitwait Pinc.3 , Reset

   Incr Minutex

   If Minutex > 59 Then Minutex = 0

Return

'#####################################

Setup6:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Stundestr = Str(stundex)
      Minutestr = Str(minutex)
      Minutestr = Format(minutestr , "00")
      Minute3str = Mid(minutestr , 1 , 1)
      Minute4str = Mid(minutestr , 2 , 1)
      Sekundestr = Str(sekundex)

      Ziffer12str = Stundestr
      Ziffer3str = Minute3str
      Ziffer4str = Minute4str
      Ziffer56str = Sekundestr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup7 , Sub
      Debounce Pinc.3 , 0 , Setsekunde , Sub

   Wend

Return

'#####################################

Setsekunde:

   Bitwait Pinc.3 , Reset

   Incr Sekundex

   If Sekundex > 59 Then Sekundex = 0

Return

'#####################################

Setup7:

   Bitwait Pinc.2 , Reset

   Tagstr = Format(tagstr , "00")
   Monatstr = Format(monatstr , "00")
   Jahrstr = Format(jahrstr , "00")

   Stundestr = Format(stundestr , "00")
   Minutestr = Format(minutestr , "00")
   Sekundestr = Format(sekundestr , "00")

   Date$ = Tagstr + "." + Monatstr + "." + Jahrstr
   Time$ = Stundestr + "." + Minutestr + "." + Sekundestr

   Exitbit = 1

Return


'#####################################

Gotomain:

   Exitbit = 1

Return

'#####################################

Getdatetime:
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 0
  I2cstart
  I2cwbyte Ds1307r
  I2crbyte _sec , Ack
  I2crbyte _min , Ack
  I2crbyte _hour , Ack
  I2crbyte Weekday , Ack
  I2crbyte _day , Ack
  I2crbyte _month , Ack
  I2crbyte _year , Nack
  I2cstop
  _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return

Setdate:
  _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 4
  I2cwbyte _day
  I2cwbyte _month
  I2cwbyte _year
  I2cstop
  Waitms 10
Return

Setweekday:
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 3
  I2cwbyte Weekday
  I2cstop
  Waitms 10
Return

Settime:
  _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 0
  I2cwbyte _sec
  I2cwbyte _min
  I2cwbyte _hour
  I2cstop
  Waitms 10
Return

End
 
Hallo AVRKarl !

Sehr nettes Projekt! :)

Ich mag diese Nixie-Uhren einfach, weil sie zum Einen so ein nettes Licht machen und zum Anderen immer super aussehen.
Auch wenn der Programmcode vielleicht nicht am effektivsten ist, die Funktion ist jedenfalls gegeben. :)


Wenn ich also irgendwann mal den Reiz dieser Nixie-Röhren nicht mehr wiederstehen kann, dann werde ich mir deinen Beitrag schon mal als Vorlage nehmen. :wink:


Grüße und Danke,
Cassio
 
Hallo AVRKarl,

ich finde ich Uhr richtig hübsch!

Sie erinnert mich ein Stück weit an die guten alten Röhrenzeiten die ich selbst nicht mehr mitbekommen habe da ich schon im Transistor-Zeitalter gebohren wurde.
Aber ich weiss noch meine Versuche ein altes Röhrenradio und einen Fernseher zu reparieren welcher mit Röhren vollgestopft war.

Ein bissle Nostalgie haben die Röhren schon. Überrascht war ich, als ich bei Dir im Schaltplan HV gelesen habe und dann erfahren musste, dass die Dinger ab 80V aufwärts bis teilweise 250V Rümps brauchen. Ich meine .... das kitzelt dan schon a bissle an den Fingern wenn man nicht aufpasst.

Grüße,
Markus
 
Vielen Dank für Eure Anmerkungen.

@Cassio. Das ist immer noch der Code von der ersten Uhr. Mittlerweile würde ich es sicher anders programmieren, aber da es funktioniert und da es noch so viele andere spannende Projekte gibt................

@Markus. Ich bin eigentlich auch ein Kind des Transistorzeitalters, aber als ich die Röhren zum ersten mal gesehen habe, war ich so fasziniert, dass ich unbedingt etwas damit machen wollte.

Viele Grüße,
Sebastian
 
Hallo alle Miteinander,

ich bin neu hier im Forum und durch eine Suchmaschine auf dieses Forum gestoßen, da ich nach einer Microcontroller Version einer Nixie Uhr suchte.

Ich habe den Beitrag von avrKarl diesen gefunden und war begeistert. Da ich noch nicht sehr viel Erfahrung mit Programmieren und Microcontrollern habe dachte ich mir diese hier im Thead einmal nachzubauen. Leider kann ich den Themenstarter nichts fragen da sein letztes Login irgendwann im Jahre 2012 war.

Da dieser aber Programm und Schaltplan sowie kurze Tipps schrieb dachte ich mir das nichts gegen einem Nachbau spricht.


Zu meinem Problem.
Ich habe die Uhr nun einfach mal Nachgebaut, habe mir einen Atmega16 gekauft sowie ISP Programmer.
Ich habe nun einfach mal das Programm mit Bascom Compiliert und in den Atmega gebrannt. Nun läuft diese Uhr aber nicht, sondern es stehen nur ein paar Zahlen auf der Uhr 01:03:00. Sie tut auch nichts über die Taster auch das Verändern der Daten der uhrzeit Time$ usw bringt nichts.
Da ich mich wie gesagt nicht sehr gut mit der Programierung auskenne dachte ich das mir Vielleicht jemand der erfahrenen User einen Lösungsansatz oder einen Tipp geben könnte. Ich habe meine Hardware nun 2 mal komplett überprüft sodass meine Vermutung dahin geht das es Vieleicht an dem Programm liegt.

Entschuldigung auch nochmals an dieser Stelle das ich einen Extrem alten Thead wieder hochhole aber ich dachte mir hier rein zu schreiben ist die beste Lösung.


Ich bedanke mich nun schon einmal im Voraus und wünsche noch einen schönen Abend


Mit freundlichen Grüßen
 
Hallo und Willkommen im AVR-Praxis Forum!

Wenn du die Hardware von "avrkarl" ordnungsgemäß nachgebaut hast und
sich das Programm von "avrkarl" in BASCOM fehlerfrei kompilieren
sowie in den ATMega16 spielen lässt, dann sollte es auch funktionieren!

Denn.....
wenn "avrkarl" schreibt das es so funktioniert, dass ist das auch so!
Garantiert! :wink:


Es ist jetzt natürlich schwer möglich dir irgendwie zu helfen.
Letztlich scheint aber doch fast alles zu funktionieren, denn die Röhren zeigen sogar etwas an.


Ich schieße daher jetzt mal aus dem Bauch und vermute einfach mal zwei Dinge:
Hast du per FUSES den ATMega16 auch auf den 8MHz externen Crystal eingestellt?
Hast per FUSES den JTAG abgeschaltet?


Könnte mir gut vorstellen, dass diese beiden Einstellungen an deinem ATMega16 "falsch" sind und du deswegen keine vollständige Funktion hast.


Grüße,
Cassio
 
Hallo nochmals.

Dankeschön für die Antwort. Ich habe die Fehler nun gefunden und die Uhr tut das was sie soll :D:D:D


Mit deinem Bauchgefühl lagst du zu 50% richtig =) ich habe JTAG nicht deaktiviert. Dazu kam dann noch das ich die Pullups am Ds1307 an der SCL / SDA vergessen habe. ( schande auf mich :p). Ich hoffe das es mir keiner übel nimmt das ich hier einen sehr begabten angezweifelt habe.

Ich bin hellauf begeistert. Ich habe schon diverse Nixie Uhren gebaut, aber nur mit Cmos Technik. Dieses hier entlastet meine Platine erheblich. Ich bedanke mich auch nochmal für die Hilfe und hoffe sobald ich mir mehr Wissen angeeignet habe ein kleiner Teil eines Super Forums hier zu werden =)


Mit freundlichen Grüßen

Holger
 
Hallo

ich bin es nochmal. Ich habe ein Problem, und da mir beim letzten mal bei der Aktion hier schon so gut geholfen wurde, dachte mir ich frage hier mal nach. Vielleicht hat ja jemand lust und zeit und hilft mir bei meinem Problem. Wie schon oben beschrieben habe ich diese Uhr ja nachgebaut. Nun habe ich das Problem, das nach Neujahr die Uhr in fast regelmäßigen Abständen (meist 20-40 Minuten nach Einschalten oder Reset) einfach "einfriert". Nach einem Reset des Controllers läuft diese dann einfach und mit der richtigen Uhrzeit weiter. Es wurde nichts verändert, die Uhr steht ja im Regal. Hat jemand einen Lösungsansatz für mich?


Ich muss nochmal eine neue Erkenntnis dazu schreiben:
Sobald ich die Uhr wieder ins Jahr 2014 versetzte läuft diese wieder ohne Probleme. Sobald ich aber das Jahr 2015 oder ein anderes höheres Jahr einstelle friert diese nach ca. 5-30 min ein.


Ich bedanke mich schon mal im Voraus.


MFG Holger
 
Hallo Holger!

Es ist mal wieder nur so ein Bauchgefühl von mir, aber.......

Im obigen Programm sind keine Werte für "$hwstack", "$swstack" und "$framesize" angegeben worden.
Damit werden von BASCOM einfach die Default-Werte angenommen, die aber für das Vorhaben arg knapp bemessen sind.

Sollte es der Platz noch hergeben, dann versuch es mal mit:
Code:
$hwstack = 128
$swstack = 128
$framesize = 128

Einfach oben, gleich nach "$regfile" und "$crystal", eingeben und ausprobieren. :wink:


Grüße,
Cassio
 
Hallo Cassio,

erst einmal danke für deine Antwort.

Ich habe die Daten nun in mein Programm geschrieben, aber es ergab sich leider keine Änderung.
Die Uhr ist inzwischen wieder 4 mal stehen geblieben.

Ich verstehe dies nicht, da sie mit dem Alten Datum super funktioniert?





mfg Holger
 
Hallo Holger!

Oh jee....
Schade, dass es nicht an den Stackwerten gelegen hat.

Scheint so, als müsste ich mich doch mal mit dem Programm befassen. :wink:
Allerdings stehe ich mit dem Programm etwas auf "Kriegsfuß", weil ich es ganz anders realisiert hätte.
Aus dem Grunde müsste ich mich da erst mal komplett reindenken.

Mal nebenbei....
Wie und wann werden eigentlich die Subroutinen für die DS1307 aufgerufen? :hmmmm:

Die Subroutinen stehen zwar unten am Ende des Programms, aber ich finde gerade keine Stelle wann diese überhaupt aufgerufen werden!
Irgendwann muss ja die RTC mal gestellt und auch abgefragt werden.....
oder habe ich da jetzt etwas übersehen.

Na ja, vielleicht muss ich mich da heute Abend doch mal reindenken. :wink:


Ach so....
bleibt die Uhr denn immer nach ein paar Minuten stehen, egal welche Uhrzeit es ist?
Liegt es nur an der Jahreszahl von 15?


Grüße,
Cassio
 
Hallo,

ich finde es total super das du mir hilfst, da ich das alleine wohl nicht hin bekomme.

Also ich habe die Uhr über Nacht noch mit dem Jahr 2014 laufen lassen und sie tat es ohne Probleme. Sobald ich sie aber >2014 stelle bleibt sie haken.

Ja die Uhr bleibt immer auf einer anderen Uhrzeit stehen, egal welche es gerade ist. Ab und an bleibt sie auch in der Datums Ausgabe hängen.

Mich wundert es nur da sie den ganzen Dezember ohne ein Problem funktionierte.

Ich danke dir jetzt schonmal für die Hilfe.


mfg Holger
 
Hallo!

Ich muss mir das Programm wohl mal kopieren und genauer anschauen.
Irgendwie kommt mir das seltsam vor.... :hmmmm:

Wenn ich dich berichtigen darf:
Es geht ja nicht um 2014 und 2015 sondern lediglich um die Zahlen 14 und 15.


Momentan habe ich keine Idee wo das Problem liegen sollte.
Kannst du vielleicht mal DEIN Programm hier einstellen?

Es macht ja keinen Sinn, wenn ich mir einen anderen Programmcode ansehe. :wink:
Nicht das dir ein kleiner Fehler unterlaufen ist.


Grüße,
Cassio
 
Hallo,

ja klar mach ich das, hier ist der Code den ich verwendet habe

aber ich habe eigentlich nicht viel verändert.

mfg



CodeBox BascomAVR
$regfile = "m16adef.dat"
$crystal = 8000000
$hwstack = 100
$swstack = 100
$framesize = 100


Dim A As Integer
Dim Astr As String * 2

Dim Ziffer12str As String * 2
Dim Ziffer3str As String * 2
Dim Ziffer4str As String * 2
Dim Ziffer56str As String * 2


Dim Timestr As String * 8
Dim Datestr As String * 8

Dim Sekundestr As String * 2
Dim Minutestr As String * 2
Dim Minute3str As String * 1
Dim Minute4str As String * 1
Dim Stundestr As String * 2
Dim Jahrstr As String * 2
Dim Monatstr As String * 2
Dim Monat3str As String * 1
Dim Monat4str As String * 1
Dim Tagstr As String * 2

Dim Tagx As Integer
Dim Monatx As Integer
Dim Jahrx As Integer
Dim Stundex As Integer
Dim Minutex As Integer
Dim Sekundex As Integer

Dim Weekday As Byte

Dim Exitbit As Bit

Config Porta = Output
Config Portb = Output
Config Portd = Output

Config Portc.7 = Output
Config Portc.6 = Output
Config Portc.5 = Output
Config Portc.4 = Output

Config Portc.3 = Input
Config Portc.2 = Input

Portc.3 = 1
Portc.2 = 1

Config Debounce = 50


Config Clock = User
Config Date = Dmy , Separator = .

$lib "i2c_twi.lbx"                                          '
Config Sda = Portc.1
Config Scl = Portc.0
Const Ds1307w = &HD0
Const Ds1307r = &HD1
Config Twi = 100000

Enable Interrupts

Declare Sub Setweekday
Declare Sub Showtime
Declare Sub Antipoisening
Declare Sub Setup


'zum einmaligen stellen
'Date$ = "01.01.15"
'Time$ = "14:02:00"
'Weekday = 4
'Call Setweekday

Do

'Portc.3 = 1
'Portc.2 = 1


Timestr = Time$
Datestr = Date$
Exitbit = 0

Sekundestr = Mid(timestr , 7 , 2)
Minutestr = Mid(timestr , 4 , 2)
Minute3str = Mid(minutestr , 1 , 1)
Minute4str = Mid(minutestr , 2 , 1)
Stundestr = Mid(timestr , 1 , 2)
Jahrstr = Mid(datestr , 7 , 2)
Monatstr = Mid(datestr , 4 , 2)
Monat3str = Mid(monatstr , 1 , 1)
Monat4str = Mid(monatstr , 2 , 1)
Tagstr = Mid(datestr , 1 , 2)

Tagx = Val(tagstr)
Monatx = Val(monatstr)
Jahrx = Val(jahrstr)

Stundex = Val(stundestr)
Minutex = Val(minutestr)


If _sec > 30 And _sec < 32 Then

   Call Antipoisening

Elseif _sec > 31 And _sec < 38 Then

   Ziffer12str = Tagstr
   Ziffer3str = Monat3str
   Ziffer4str = Monat4str
   Ziffer56str = Jahrstr
   Ziffer4str = Ziffer4str + "0"

Elseif _sec > 37 And _sec < 39 Then

   Call Antipoisening

Else

   Ziffer12str = Stundestr
   Ziffer3str = Minute3str
   Ziffer4str = Minute4str
   Ziffer56str = Sekundestr
   Ziffer4str = Ziffer4str + "0"

End If

Call Showtime

Debounce Pinc.2 , 0 , Setup , Sub
'Debounce Pinc.3 , 0 , Setup , Sub


Loop


'#####################################

Showtime:
   Porta = Hexval(ziffer12str)
   Portb = Hexval(ziffer3str)
   Portc = Hexval(ziffer4str)
   Portd = Hexval(ziffer56str)
Return

'#####################################

Antipoisening:

   For A = 0 To 99 Step 11

      Astr = Str(a)
      Astr = Format(astr , "00")
      Ziffer12str = Astr
      Ziffer3str = Left(astr , 1)
      Ziffer4str = Right(astr , 1)
      Ziffer4str = Ziffer4str + "0"
      Ziffer56str = Astr
      Waitms 50
      Call Showtime

   Next

Return

'#####################################

Setup:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Tagstr = Str(tagx)

      Ziffer12str = Tagstr
      Ziffer3str = Monat3str
      Ziffer4str = Monat4str
      Ziffer56str = Jahrstr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup2 , Sub
      Debounce Pinc.3 , 0 , Settag , Sub

   Wend

Return

'#####################################

Settag:

   Bitwait Pinc.3 , Reset

   Incr Tagx

   If Tagx > 31 Then Tagx = 1

Return


'#####################################

Setup2:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Tagstr = Str(tagx)
      Monatstr = Str(monatx)
      Monatstr = Format(monatstr , "00")
      Monat3str = Mid(monatstr , 1 , 1)
      Monat4str = Mid(monatstr , 2 , 1)

      Ziffer12str = Tagstr
      Ziffer3str = Monat3str
      Ziffer4str = Monat4str
      Ziffer56str = Jahrstr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup3 , Sub
      Debounce Pinc.3 , 0 , Setmon , Sub

   Wend

Return

'#####################################

Setmon:

   Bitwait Pinc.3 , Reset

   Incr Monatx

   If Monatx > 12 Then Monatx = 1

Return

'#####################################

Setup3:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Tagstr = Str(tagx)
      Monatstr = Str(monatx)
      Monatstr = Format(monatstr , "00")
      Monat3str = Mid(monatstr , 1 , 1)
      Monat4str = Mid(monatstr , 2 , 1)
      Jahrstr = Str(jahrx)

      Ziffer12str = Tagstr
      Ziffer3str = Monat3str
      Ziffer4str = Monat4str
      Ziffer56str = Jahrstr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup4 , Sub
      Debounce Pinc.3 , 0 , Setjahr , Sub

   Wend

Return

'#####################################

Setjahr:

   Bitwait Pinc.3 , Reset

   Incr Jahrx

   If Jahrx > 41 Then Jahrx = 11

Return

'#####################################

Setup4:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Stundestr = Str(stundex)

      Ziffer12str = Stundestr
      Ziffer3str = Minute3str
      Ziffer4str = Minute4str
      Ziffer56str = Sekundestr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup5 , Sub
      Debounce Pinc.3 , 0 , Setstunde , Sub

   Wend

Return

'#####################################

Setstunde:

   Bitwait Pinc.3 , Reset

   Incr Stundex

   If Stundex > 23 Then Stundex = 0

Return

'#####################################

Setup5:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Stundestr = Str(stundex)
      Minutestr = Str(minutex)
      Minutestr = Format(minutestr , "00")
      Minute3str = Mid(minutestr , 1 , 1)
      Minute4str = Mid(minutestr , 2 , 1)

      Ziffer12str = Stundestr
      Ziffer3str = Minute3str
      Ziffer4str = Minute4str
      Ziffer56str = Sekundestr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup6 , Sub
      Debounce Pinc.3 , 0 , Setminute , Sub

   Wend

Return

'#####################################

Setminute:

   Bitwait Pinc.3 , Reset

   Incr Minutex

   If Minutex > 59 Then Minutex = 0

Return

'#####################################

Setup6:

   Bitwait Pinc.2 , Reset


   While Exitbit = 0

      Stundestr = Str(stundex)
      Minutestr = Str(minutex)
      Minutestr = Format(minutestr , "00")
      Minute3str = Mid(minutestr , 1 , 1)
      Minute4str = Mid(minutestr , 2 , 1)
      Sekundestr = Str(sekundex)

      Ziffer12str = Stundestr
      Ziffer3str = Minute3str
      Ziffer4str = Minute4str
      Ziffer56str = Sekundestr
      Ziffer4str = Ziffer4str + "0"

      Call Showtime

      Debounce Pinc.2 , 0 , Setup7 , Sub
      Debounce Pinc.3 , 0 , Setsekunde , Sub

   Wend

Return

'#####################################

Setsekunde:

   Bitwait Pinc.3 , Reset

   Incr Sekundex

   If Sekundex > 59 Then Sekundex = 0

Return

'#####################################

Setup7:

   Bitwait Pinc.2 , Reset

   Tagstr = Format(tagstr , "00")
   Monatstr = Format(monatstr , "00")
   Jahrstr = Format(jahrstr , "00")

   Stundestr = Format(stundestr , "00")
   Minutestr = Format(minutestr , "00")
   Sekundestr = Format(sekundestr , "00")

   Date$ = Tagstr + "." + Monatstr + "." + Jahrstr
   Time$ = Stundestr + "." + Minutestr + "." + Sekundestr

   Exitbit = 1

Return


'#####################################

Gotomain:

   Exitbit = 1

Return

'#####################################

Getdatetime:
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 0
  I2cstart
  I2cwbyte Ds1307r
  I2crbyte _sec , Ack
  I2crbyte _min , Ack
  I2crbyte _hour , Ack
  I2crbyte Weekday , Ack
  I2crbyte _day , Ack
  I2crbyte _month , Ack
  I2crbyte _year , Nack
  I2cstop
  _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return

Setdate:
  _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 4
  I2cwbyte _day
  I2cwbyte _month
  I2cwbyte _year
  I2cstop
  Waitms 10
Return

Setweekday:
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 3
  I2cwbyte Weekday
  I2cstop
  Waitms 10
Return

Settime:
  _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 0
  I2cwbyte _sec
  I2cwbyte _min
  I2cwbyte _hour
  I2cstop
  Waitms 10
Return

End
 
Hallo Holger!

Danke, für die prompte Rückmeldung mit Programmcode.

Ich werde mich dann mal da durch wuseln und vielleicht finde ich ja einen Hinweis. :wink:


Hast du in der Zwischenzeit vielleicht schon beim Verhalten etwas entdeckt was wichtig sein könnte?
Besteht bei dir die Möglichkeit eine serielle Schnittstelle hinzuzufügen um ggf. ein paar Debugausgaben auf den PC zu bringen?


Grüße,
Cassio
 
Ich danke dir erstmal für diese super Hilfe die wie ich schon mehrmals feststellen musste nicht mehr selbstverständlich ist.

Ich habe gerade einfach mal nur zum Testen einen anderen Atmega16 sowie einen anderen DS1307 aufgesteckt und konfiguriert.

Nun läuft die Uhr seid etwas über einer Stunde ohne aussetzter (aber ich möchte den Tag nicht vor dem Abend loben :) ).

Die Möglichkeit eine serielle Schnittstelle hinzuzufügen hätte ich theoretisch schon, nur leider fehlt mir dafür und auch fürs Debuggen das nötige Know-how.

Ich beschäftige mich eigentlich erst seid kurzer Zeit mit dem Programmieren und Lese viel in meinen Büchern und probiere auch viel aus, aber soweit bin ich leider noch nicht gekommen ;)

Also ich würde dann nun nochmal einen Rückmeldung geben, sollte die Uhr nun laufen oder es auch nicht tun.

Tausend danke bis jetzt schon mal für die großartige Hilfestellung =)

mfg Holger
 
Hallo Holger!

Das du noch eine andere DS1307 liegen hast, hätte ich jetzt gar nicht vermutet.
Das war zwar einer meiner Gedanken zum Ausprobieren, aber begründen konnte ich ihn nicht.

Das mit dem Debuggen im Programm hätte ich dann schon eingepflegt, mach dir darüber keine Gedanken. :wink:

Ich schau mir den Code jetzt trotzdem noch mal ein wenig an und du lässt die Uhr inzwischen einfach weiterlaufen. :D


Hoffe dann mal auf die nächste positive Rückmeldung von dir.
Cassio :ciao:
 
Wie und wann werden eigentlich die Subroutinen für die DS1307 aufgerufen? :hmmmm:

Die Subroutinen stehen zwar unten am Ende des Programms, aber ich finde gerade keine Stelle wann diese überhaupt aufgerufen werden!
Irgendwann muss ja die RTC mal gestellt und auch abgefragt werden.....
oder habe ich da jetzt etwas übersehen.



Hallo!

Nur der Vollständigkeit halber hier noch kurz die Info, wann die Subroutinen für die RTC aufgerufen werden:

Info aus der BASCOM-Hilfe (Version 2.0.7.7)
Config Clock = User 'Use USER to write/use your own code

You also need to include the following labels with config clock = user:

Getdatetime:
'called when date or time is read
Return

Setdate:
'called when date$ is set
Return

Settime:
'scanned when time$ is set
Return


Die drei Subroutinen werden also automatisch aufgerufen, wenn man "config clock = user" verwendet. :wink:
Der Programmersteller muss also nur noch dafür sorgen, dass die drei Routinen im Programm enthalten sind und sinnvoll gefüllt werden.


Grüße,
Cassio
 
Hallo zusammen,

also wenn ich das Programm richtig verstanden hab dann hätte ich das in den Subroutinen etwas anders gemacht ...


CodeBox BascomAVR
Getdatetime:
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 0
  I2cstart
  I2cwbyte Ds1307r
  I2crbyte _sec , Ack
  I2crbyte _min , Ack
  I2crbyte _hour , Ack
  I2crbyte Weekday , Ack
  I2crbyte _day , Ack
  I2crbyte _month , Ack
  I2crbyte _year , Nack
  I2cstop
  ' === wenn man hier in eine Interruptroutine springt,hat man falsche Werte in den Sys-Variablen ===
  _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return

Ich hätte vom DS1307 in eine temporäre Variable gelesen und die dann nach der Wandlung in die Systemvariable geschrieben. Man weiß ja nie was BASCOM zwischendurch mit der Systemvariable anstellt. Auf jeden Fall hat man zwischenzeitlich etwas drin was eventuell quer kommen kann.



CodeBox BascomAVR
Getdatetime:
  I2cstart
  I2cwbyte Ds1307w
  I2cwbyte 0
  I2cstart
  I2cwbyte Ds1307r
  I2crbyte rtc_sec , Ack
  I2crbyte rtc_min , Ack
  I2crbyte rtc_hour , Ack
  I2crbyte Weekday , Ack
  I2crbyte rtc_day , Ack
  I2crbyte rtc_month , Ack
  I2crbyte rtc_year , Nack
  I2cstop
  _sec = Makedec(rtc_sec) : _min = Makedec(rtc_min) : _hour = Makedec(rtc_hour)
  _day = Makedec(rtc_day) : _month = Makedec(rtc_month) : _year = Makedec(rtc_year)
Return

... so hätte ich das gemacht. Dann ist man sicher das nur passende Werte in den Systemvariablen landen.

Weil ... wenn diese Subroutinen keine Interruptroutinen sind (wo ich von ausgehe) und BASCOM in der Zwischenzeit eine Interruptroutine (Timer?) für die Zeitberechnung ausführt, kann es zu einer RaceCondition kommen und der falsche Wert vor der Makedec-Wandlung in der Interruptroutine auftauchen. Damit würde Bascom die Zeit falsch berechnen oder anders durcheinanderkommen.

Die Zeit die für eine RaceCondition zur Verfügung steht könnte man minimieren wenn man direkt hinter jedem I2Cread den jeweiligen Wert wandelt und in die Systemvariable schreibt. Dann ist die Wahrscheinlichkeit für eine RaceCondition zwar kleiner aber immer noch nicht Null. Das wird sie erst wenn man mit temporären Variablen zwischenspeichert. Allerdings verbraucht man damit im Gegenzug auch mehr SRAM.

Gruß
DIno
 
Hallo Holger!

Ich habe mir das Programm und auch das Datenblatt der DS1307 noch ein paar mal durchgesehen, aber dein Fehler will sich mir einfach nicht erschließen.

Natürlich ist das Programm nicht optimal, was avrkarl selbst schon geschrieben hat und Dino hat ja auch schon beispielhaft etwas dazu geschrieben.

Mir missfällt nicht nur die Variablenumwandlung (BCD) sondern speziell die gesamte Setup-Struktur.
Man springt z.B. von einer Sub in die Nächste, ohne das zugehörige "Return" beim Wechsel gleich zu berücksichtigen!

Obendrein ist die Do-Loop Schleife alles andere als optimal und auch die Dimensionierung der Variablen hätte man platzsparender (nicht so viele Integer) und effektiver (Overlays) gestalten können.


Egal....
das Programm macht was es soll und niemand wird gezwungen den Porgrammcode zu verwenden, den avrkarl hier freundlicher Weise öffentlich zur Verfügung gestellt hat! :)


Bleibt mir nur zu hoffen, dass nach dem Wechsel der Hardware deine Uhr immer noch fehlerfrei arbeitet.
Hast du schon heraus gefunden ob es am ATMega lag, oder an der DS1307?
Ich persönlich hätte erst mal auf die RTC getippt..... oder dessen Verbindung.


Grüße,
Cassio
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)