Zeiterfassung und LCD-Anzeige bis 98Tage / 23Stunden / 59Minuten / 59Sekunden.

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Zeiterfassung und LCD-Anzeige bis 98Tage / 23Stunden / 59Minuten / 59Sekunden.

      Die vorgestellte Schaltung und das zugehörige BASCOM-Programm auf einem Attiny4313
      dienen der Erfassung von Zeitsituationen in unserem Haus. Hier wird erstmal ein kleiner mechanischer Stundenzähler zur Messung der Brenndauer der Außenbeleuchtung abgelöst, weil der dem Synchronmotor vorgeschaltete Kondensator wieder mal defekt war.
      Die Messung wird durch schließen eines Reedkontaktes am Objekt gestartet und beim öffnen gestoppt. Auf einem zweizeiligen LCD wird der aktuelle Wert dargestellt.
      Das LCD ist über eine RJ45-Buchse und 1m Flachbandleitung angeschaltet.
      Erhöhte Sicherheit garantiert die Verwendung eines Optokopplers im Signalpfad.
      Durch Verwendung eines 12MHz-Quarzes und schlanker Interupt-Routine wird eine hohe Genauigkeit erreicht.
      Die Betriebszustände Loop-on und Sekundentakt werden auch über 2 LED's angezeigt.
      Die Ausgabe auf einem seriellen Port mit 19200Bps ist möglich.
      Für weitere Aufgaben stehen noch 5 Ports zur freien Verfügung.

      Gruß Rudi
      Files
      Immer Glück haben ist fast wie können..

      The post was edited 1 time, last by Rudi Einstein ().

    • Rudi Einstein wrote:

      Durch Verwendung eines 12MHz-Quarzes und schlanker Interupt-Routine wird eine hohe Genauigkeit erreicht.
      Richtig genau wird es, wenn du Timer 1 als CTC-Timer verwendest.

      Mir ist aufgefallen, dass dein Hardware-Stack überläuft.
      Das sollten für deine Anwendung 32 Byte sein (minimum). Speicher haste ja übrig.

      Leuchtet bei dir eigentlich die ganze Zeit die Display-Beleuchtung?
    • Danke Pluto25; djmsc und Mitch64 für eure Einschätzungen und Anregungen.

      Pluto25 wrote:

      D0-4 auf Gnd? Meins ließ sich nicht mehr Initialiesieren bis sie wieder floating waren ;(
      V0 über Festwiderstande - mutig, gerade die blauen sind da pingelig.
      In meinem Schaltbild ist diese Anschlußfolge nicht so dargestellt D0-D4, funktioniert deshalb wohl auch bei dir nicht. Richtig siehe oben ist D0-D3.
      Die Kontrastbeschaltung ist ein Standard und alle meine Beiträge welche dieses LCD verwenden, laufen noch ohne Einschränkung.

      Mitch64 wrote:

      Rudi Einstein wrote:

      Durch Verwendung eines 12MHz-Quarzes und schlanker Interupt-Routine wird eine hohe Genauigkeit erreicht.
      Richtig genau wird es, wenn du Timer 1 als CTC-Timer verwendest.Mir ist aufgefallen, dass dein Hardware-Stack überläuft
      Leuchtet bei dir eigentlich die ganze Zeit die Display-Beleuchtung?
      Die Verwendung des Timers 1 als CTC-Timer werde ich demnächst mal testen, um den Grad der Verbesserung einschätzen zu können,
      ebenso die sinnvolle Vergrößerung des HW-Stack, da ja genug Platz dafür da ist.
      Die Abschaltung der LCD-LED ist ein sinnvoller Vorschlag wenn Stromersparnis ein Aspekt ist.

      Gruß Rudi
      Immer Glück haben ist fast wie können..
    • Rudi Einstein wrote:

      nicht so dargestellt D0-D4
      die 4 war ein Tippfehler, hier dürfen die unteren 4 Eingänge (d0-3)nicht auf Gnd. Auch eine feste Vo wäre hier nicht brauchbar da sie bei Modulwechsel teilweise nachgestellt werden muß.

      Mitch64 wrote:

      Man könnte auch mit PWM dimmen
      Das geht recht gut, nützlich bei unterschiedlichen Lichtverhältnissen . Dann blenden sie im Dunkeln nicht und sind im Hellen besser zu erkennen.

      The post was edited 1 time, last by Pluto25 ().

    • Rudi Einstein wrote:

      Die Verwendung des Timers 1 als CTC-Timer werde ich demnächst mal testen, um den Grad der Verbesserung einschätzen zu können,
      In deinem obigen Programm wirst du da überhaupt keine Verbesserung sehen.
      Die Verzögerungen kommen durch andere Interrupts, die die Ausführung der ISR etwas verspäten. Das summiert sich auf und kann nicht mehr aufgeholt werden.
      Oder wenn du einen Prescale < 64 hast, weil dann der Timer durch das Sichern der Register schon wieder hochgezählt hat, bevor du den Wert setzt. Bei prescale =64 kann es auch passieren, wenn du nicht sofort den Timer setzt.
      Aber grundsätzlich hat Mitch recht. Ich würde auch immer den CTC verwenden, wenn er denn verfügbar ist, weil du dir dann keine Gedanken um solche Effekte machen musst.
    • Ja es macht tatsächlich nicht viel aus.
      Ich habe es mal hochgerechnet auf 99 Tage, da sind es ca. 44 Sekunden.

      Ich denke, da ist der Fehler, der auftritt viel größer, wenn das Licht oft angeht.
      Da der Timer ja weiter läuft ist bei "Licht aus" ja das Flag "Sekflag" gesetzt, wenn es länger als eine Sekunde aus ist.

      Wenn dann die Sekunde schon zu 90% verstrichen ist (Sekflag würde gesetzt in 0.1s, wenn nicht schon gesetzt) und das Licht geht an, wird eine Sekunde gezählt und das Flag zurück gesetzt, aber dann nach 0,1s schon wieder gesetzt und wieder ne Sekunde gezählt.

      Eigentlich müsste man dann den Zähler anhalten, wenn das Licht aus ist und wieder starten, wenn es an geht.
      Dann würden die Bruchteilsekunden auch richtig berücksichtigt.

      Auf der anderen Seite wird aber immer eine volle Sekunde gezählt, auch wenn das Licht nur 10% von der Sekunde an war.

      Ob man das ausrechnen kann, wie groß da der Messfehler ist? Ich kanns nicht.
      Von daher wäre den Timer anhalten, wenns licht aus ist am besten.
    • Rudi Einstein wrote:

      Die vorgestellte Schaltung und das zugehörige BASCOM-Programm auf einem Attiny4313
      dienen der Erfassung von Zeitsituationen in unserem Haus. Hier wird erstmal ein kleiner mechanischer Stundenzähler zur Messung der Brenndauer der Außenbeleuchtung abgelöst, weil der dem Synchronmotor vorgeschaltete Kondensator wieder mal defekt war.
      Da hier nur ein mechanischer Stundenzähler abgelöst werden soll, ist eine allzu akademische Betrachtung der Genauigkeit wohl nicht zielführend.
      Betrachtet man eine Umrechnungstabelle für Echtminuten in Dezimalstunden wie es in der Industrie an vielen Projekten gemacht wird,
      Industriestunde = Std +(min/60)+(sec/3600) so ist das vorliegende Ergebnis zufriedenstellend.
      Dennoch werde ich die Anregung von Mitch64 mal weiter verfolgen, denn es ist schon interessant, ob zwischenzeitlich auch mal loop off war und das wäre für das Ergebnis und dessen Interpretation ziemlich wichtig. Ports und Memory ist ja noch ziemlich vorhanden.
      Auch das steuern der Displayhelligkeit werde ich mir vornehmen, der Vorschlag PWM zu nehmen ist gut.
      Bei der Belegung des DS1602A gibt es im Netz tatsächlich unterschiedliche Angaben über die Pinbelegung der 4Bit-Dateneingänge.
      Mein Aufbau ist nach der im beigefügten Bild Methode ausgeführt. Das höherwertige Nibble braucht nicht die Belegung nach GND.

      Gruß RudiLCD Belegung.JPG
      Immer Glück haben ist fast wie können..
    • Ja kann ich.

      Vom Auftreten des Interrupts, bis in der Interrupt-Routine der Timer neu gestellt wird, vergehen einige Takte.
      Ich glaube es waren 56 System-Takte nach Simulator.

      Der Systemtakt ist 12MHz. also ein Takt = 1/12MHz = 83ns, das mal die 56 Takte, dann hat man 56x 83ns = 4,66µs, die der Timer pro Sekunde nachläuft.

      Das musst du miltiplizieren mit der Anzahl Sekunden für 99 Tage, dann kommst du auf die 44s.

      Beim CTC-Timer wird der Zähler direkt bei Compare-Match zurückgesetzt. Daher ist da die Ungenauigkeit nur soi groß wie die des Quarzes.

      Aber wie gesagt, das fällt bei 99 Tagen nicht ins Gewicht.

      Ich würde es trotzdem mit CTC-Timer machen, da erja vorhanden ist. Der Code wird deswegen ja nicht schlechter :)
    • Wenn der Prescale wie hier auf 256 ist, dann hat der Timer noch nicht weitergezählt. Und der prescale Wert des Timers hat keinen Einfluss auf die Rechnung, da er nicht zurückgesetzt wird, wenn du einen neuen Preload setzt. Also sehe ich nicht, wie das hier einen Einfluss haben sollte.
      Bei 64 kommt es darauf an, ob der Preload schnell genug gesetzt wird, bevor der Timer hochgezält hat. Bei noch kleineren Prescalern, hat es definitiv einen Einfluss.
      Bzgl CTC generell sind wir einer Meinung.
    • Du vergisst aber, dass der Prescaler genau genommen schon ein Zähler ist.
      Der Fehler ist dann vielleicvht nicht bei der 1. Sekunde oder der 2. Sekunde im Timer. Aber der Prescaler summiert den Fehler und so trifft es dann auch den eigentlichen Sekunden-Takt.

      Rechne mal 56 Takte. Wieviel mal passt das in 256?

      Du kannst ja mal eine Messung machen.

      Falls dich die Begründung nicht überzeugt, schau mal in das Tutoriel rein Timer-Berechnung.
      Dort habe ich unter Punkt 2 die Timer-Ergebnisse mit Preload und CTC gegenübergestellt, mit Oszillogrammen.

      Ein Timer mit Preload ist immer Ungenauer als einer mit CTC.
      Man muss für die Anwendung eben entscheigen wie genau "Genau genug" ist.

      The post was edited 1 time, last by Mitch64 ().

    • Hallo Mitch,
      um dich zu überzeugen hier mal ein kleines Testprogramm.

      BASCOM Source Code

      1. $regfile = "m1284pdef.dat"
      2. $hwstack = 100
      3. $swstack = 100
      4. $framesize = 100
      5. Config Portd.5 = Output
      6. Config Portb.6 = Output
      7. Config Timer1 = Timer , Prescale = 256
      8. On Ovf1 Ovf1_isr
      9. Enable Ovf1
      10. Config Timer3 = Timer , Prescale = 256 , Clear_timer = 1 , Compare_a = Toggle
      11. Ocr3a = 127
      12. Enable Interrupts
      13. Do
      14. Loop
      15. End
      16. Ovf1_isr:
      17. Load Timer1 , 128
      18. Toggle Portd.5
      19. Return
      Display All
      Timer1 läuft mit Preload, nach 128 Timertakten wird der Ausgang getoggelt.
      Timer3 läuft mit CTC und sein Ausgang wird auch nach 128 Timertakten getoggelt.
      Deiner Theorie nach würden die Ausgänge zeitlich auseinanderlaufen.
      Wenn du dir das ansiehst wirst du feststellen, dass das nicht der Fall ist. Der Anfangsversatz bleibt genau erhalten.

      Das ganze ändert sich, wenn du auf Prescale 8 gehst, dann toggelt der Timer 1 langsamer, der Versatz wird immer größer.

      Es kommt also auf die Werte an und was sonst noch so im Programm passiert, ob CTC genauer ist. Auch ein Timer, der kein CTC hat, kann für ein sehr genaues Timing (so genau, wie der Systemtakt ist) genommen werden.
    • @Franz

      Hast du den Code nur so hingeschrieben?
      Oder hast du das ausprobiert?

      Ich sehe da kein $Crystal und auch keine ISR für den Timer 3.

      Schließlich sollten für einen Vergleich die Bedingungen gleich sein.

      Nur bei Timer 3 ein "Compare = Toggle" zu verwenden gilt nicht. - Das ist ja Hardware!

      Es müssen dann schon beide Varianten ober eine ISR den Pin toggeln.
      Am besten nicht gleichzeitig beide ISR aktiv, sondern die Timer einzeln beobachten.

      Und ich bin nach wie vor überzeugt, dass ein CTC-Timer immer die bessere Variante ist, sofern verfügbar.



      @Michael

      Michael wrote:

      Deine 56 Takte sind ja Systemtakte, der Timer wird bei Prescaler 256 nur alle 256 Systemtakte weitergezählt.
      Das ist schon richtig. Aber der Prescaler bekommt ja genau nur den Systemtakt. Der Fehler teilt sich dann runter, aber es bleibt immer ein Restfehler.
      Je größer der Prescaler, umso geringer der Fehler. Aber eine Abweichung bleibt.

      Probiert es doch einfach mal mit Oszi aus!
    • So, ich muss etwas revidieren.

      @Franz
      @Michael

      Beim Preload wird ja der Timer definitiv verzögert gesetzt. Nämlich um die Anzahl Systemtakte, bis in der ISR eben der Timer mit dem Preload-Wert gesetzt ist.
      Da sind wir uns ja alle einig.

      Mit Oszi und Testsoftware habe ich überprüft, ob da ein Versatz statt findet, wenn der Prescaler groß genug ist.
      Und ich konnte folgendes feststellen:

      Wenn der Timer gesetzt ist, bevor die Takte der Prescaler durchgelaufen sind, läuft der Timer synchron, also ohne driftende Zeit (Versatz).
      Wenn jedoch der Prescaler durchläuft und danach der Timer gesetzt wird, dann hat man Fehler in der zeitlichen Abfolge der Pulse.
      Dann ist nichts mehr synchron. Siehe Testsoftware - 2

      Heißt, wenn der Prescaler groß genug ist, damit rechtzeitig der Timer gesetzt ist, ist alles gut.
      Man hat eben nur eine Phasenverschiebung zwischen dem Ausgabepuls und dem Auftreten des Interrupts.
      Das ist aber beim CTC-Timer auch so, wegen der Laufzeit, bis in der ISR der Pin gesetzt wird.

      Ich habe wieder mal was gelernt,
      trotzdem bleibe ich nach Möglichkeit beim CTC-Timer. Es ist einfach unkomplizierter und man muss nicht so genau hinschauen,
      wenns mal genau sein soll.

      Preload mache ich eigentlich nur bei Dingen, wo es relativ egal ist, bei LED-PWM oder Tastenabfragen etc.
      Bei Timer, die möglichst stimmen sollten, pflege ich immer einen CTC-Timer zu verwenden.
      Und bis Dato bin ich damit immer sehr gut gefahren.

      Hier meine Testsoftware-1, Timer einzeln betrachtet.

      BASCOM Source Code: Testsoftware-1 (Ausgabefrequenz)

      1. ' Testsoftware 1 (Ausgabefrequenz)
      2. ' Vergleich Timer CTC vs. Preload
      3. $Regfile = "m328pdef.dat"
      4. $HWStack = 40
      5. $SWStack = 32
      6. $Framesize = 32
      7. $Crystal = 16000000 ' Schwingt mit ca. 16,0016 Mhz, gemessen an Pin CLKO (PortB.0)
      8. Const True = 1
      9. Const False = 0
      10. ' ----------------------------------------------
      11. ' verwendete IO-Pins
      12. ' ----------------------------------------------
      13. pinFrequenz Alias PortB.1 ' Ausgabe-Pin der Frequenz (Puls 0,4µs)
      14. ' ----------------------------------------------
      15. ' Konfiguration
      16. ' Umschaltung der Betriebsart des Timers und
      17. ' Setzen des Prescalers.
      18. ' ----------------------------------------------
      19. Const MODE_PRELOAD = False ' True = Normal-Mode mit Preload / False = CTC-Mode
      20. Const VORTEILER = 1 ' Prescaler Timer 2
      21. ' ----------------------------------------------
      22. ' Initialisierung
      23. ' ----------------------------------------------
      24. Config pinFrequenz = Output
      25. #IF MODE_PRELOAD = True ' Normal-Mode mit Preload
      26. ' Timer im Normal-Mode mit Preload
      27. ' Prescale: 1 8 64 256
      28. ' Rechnerisch: 125000Hz 15625Hz 1953,1Hz 488,3Hz
      29. ' Gemessen: 83341Hz 14816Hz 1953,3Hz 488,3Hz
      30. Config Timer2 = Timer , Prescale = VORTEILER
      31. On Timer2 ISR_Timer2
      32. Enable Timer2
      33. #ELSEIF MODE_PRELOAD = False ' CTC-Mode
      34. ' Timer im CTC-Mode
      35. ' Prescale: 1 8 64 256
      36. ' Rechnerisch: 125000Hz 15625Hz 1953,1Hz 488,3Hz
      37. ' Gemessen: 125012Hz 15626Hz 1953,3Hz 489,3Hz
      38. Config Timer2 = Timer , Prescale = VORTEILER , Clear_Timer = 1
      39. Compare2a = 128 - 1
      40. On OC2A ISR_Timer2
      41. Enable OC2A
      42. #ENDIF
      43. Enable Interrupts
      44. ' ----------------------------------------------
      45. ' Hauptschleife
      46. ' ----------------------------------------------
      47. Do
      48. NOP
      49. Loop
      50. ' --------------------------
      51. ' ISR-Routine
      52. ' --------------------------
      53. ISR_Timer2:
      54. #IF MODE_PRELOAD = 1
      55. Load Timer2 , 128
      56. #ENDIF
      57. Set pinFrequenz ' Pulsausgabe ca. 0,4µs
      58. NOP
      59. NOP
      60. NOP
      61. NOP
      62. NOP
      63. Reset pinFrequenz
      64. Return
      Display All
      Im Code sind die berechneten Frequenzen bei unterschiedlichen Prescalern und die real gemessene für Timer mit Preload und Timer im CTC-Mode angegeben.
      Ab Prescaler 64 läuft das im obigen Beispiel auch synchron.

      Und hier die Testsoftware 2 (Drift-Messung ala Franz)

      BASCOM Source Code: Testsoftware-2 (Driftmessung)

      1. ' Testsoftware 2
      2. ' Vergleich Timer CTC vs. Preload
      3. $Regfile = "m328pdef.dat"
      4. $HWStack = 40
      5. $SWStack = 32
      6. $Framesize = 32
      7. $Crystal = 16000000 ' Schwingt mit ca. 16,0016 Mhz, gemessen an Pin CLKO (PortB.0)
      8. Const True = 1
      9. Const False = 0
      10. ' ----------------------------------------------
      11. ' verwendete IO-Pins
      12. ' ----------------------------------------------
      13. pinFrqPreload Alias PortB.0
      14. pinFrqCTC Alias PortB.1 ' Ausgabe-Pin der Frequenz (Puls 0,4µs)
      15. ' ----------------------------------------------
      16. ' Konfiguration
      17. ' Setzen des Prescalers.
      18. ' ----------------------------------------------
      19. Const VORTEILER = 64 ' Prescaler Timer 0 + 2
      20. ' ----------------------------------------------
      21. ' Initialisierung
      22. ' ----------------------------------------------
      23. Config pinFrqPreload = Output
      24. Config pinFrqCTC = Output
      25. Config Timer0 = Timer , Prescale = VORTEILER ' Normal-Timer
      26. Config Timer2 = Timer , Prescale = VORTEILER , Clear_Timer = 1 ' CTC-Timer
      27. Compare2a = 128 - 1
      28. On Timer0 ISR_Timer0
      29. Enable Timer0
      30. On OC2A ISR_Timer2
      31. Enable OC2A
      32. Enable Interrupts
      33. ' ----------------------------------------------
      34. ' Hauptschleife
      35. ' ----------------------------------------------
      36. Do
      37. NOP
      38. Loop
      39. ' --------------------------
      40. ' ISR-Routine Timer0 mit Preload
      41. ' --------------------------
      42. ISR_Timer0:
      43. 'NOP
      44. 'NOP
      45. Load Timer0 , 128 ' Preload
      46. Set pinFrqPreload ' Pulsausgabe ca. 0,4µs
      47. NOP
      48. NOP
      49. NOP
      50. NOP
      51. NOP
      52. Reset pinFrqPreload
      53. Return
      54. ' --------------------------
      55. ' ISR-Routine Timer2 CTC-Mode
      56. ' --------------------------
      57. ISR_Timer2:
      58. Set pinFrqCTC ' Pulsausgabe ca. 0,4µs
      59. NOP
      60. NOP
      61. NOP
      62. NOP
      63. NOP
      64. Reset pinFrqCTC
      65. Return
      Display All
      Im Drift-Beispiel läuft der abgebildete Code ebenfalls synchron und genau ab Prescaler 64 (Beide Nops am begin der ISR_Timer_0 auskommentiert).
      Werden die beiden NOPs ausgeführt (nicht auskommentiert),
      dann bricht das Chaos los. Keine Synchronisation der beiden Timer mehr.
      Das liegt an den besagten Takten, die verstreichen, bis der Timer in der ISR gesetzt wird.
      Mit NOPs müsste man jetzt den nächst größeren Prescaler nehmen.

      Ich denke CTC-Mode ist einfacher zu händeln, wenns genau sein soll.
    • Morning!
      wenn es ziemlich genau werden soll, solltest Du einfach einen Quarz von 4194304 Hz nehmen und ihn dementsprechend teilen.
      So läuft meine Digitaluhr problemlos auf die Sekunde genau schon über 2 Jahre. Allerdings muss ich alle 72 Stunden eine Sekunde
      abziehen, da der Quarz diese Abweichung hat. Am Anfang waren es alle 20 Stunden. Der Quarz ist dann etwas gealtert und wurde
      etwas genauer. Auch die Temperatur hat einen Einfluss.
      Die Pins von LCD's (D0-D3) liegen bei mir immer auf GND und da hatte ich noch nie Probleme auch nicht mit LCD's aus Asien. Habe
      anfangs auch mal die Eingänge von LCD's von Reichelt offen gelassen und auch nicht negatives erlebt. Die wurden intern sogar auf
      VCC gehalten. Und die Beleuchtung solltest Du auch abschalten wenn sie nicht gebraucht wird.
      Viel Spass noch
      Jürgen