NANO Timer oder DCF...Genauigkeit?

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

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • NANO Timer oder DCF...Genauigkeit?

      Wann immer ich bisher mit den Timern Impulslängen gemessen hatte, waren immer deutliche Abweichungen in den Meßwerten.

      Nun werkel ich gerade an eine eigene DCF-Decodierung welche letzendlich auf eine Hardware laufen die auf niedrige Taktrate und Energieeffizienz (Batteriebetrieb, gerne > 1 Jahr) optimiert ist.
      Dachte zuerst an 1MHz Quarz an einem Mega328PB. Alternativ, weil 1MHz Quarze selten und ungenau sind (bis zu +-100ppm!) auch 4MHz Quarz mit DIV8 für 500kHz Taktfrequenz.

      Aktuell bin ich aber noch bei der DCF-Decodierung an einem NANO (16MHz Resonantor) und aktivierter DIV8-Fuse für 2MHz Takt.

      An INT0 hängt ein DCF1 von Pollin

      BASCOM Source Code

      1. $regfile = "m328pdef.dat" 'ARUNDIO-NANO Prozessor
      2. $crystal = 2000000 'ARUNDIO-NANO Originalquarz 16MHz mit DIV8 auf 2MHz geteilt
      3. $hwstack = 400
      4. $swstack = 400
      5. $framesize = 600
      6. $baud = 9600
      7. Config Portb = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      8. Config Portc = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      9. Config Portd = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      10. Ddrb = &B11111111 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      11. Ddrc = &B11111111 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      12. Ddrd = &B11111010 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      13. Dim 1word as Word
      14. Dim 2word as Word
      15. Dim I as byte
      16. Dim Neword as Byte
      17. Dim Msek as Word
      18. wait 5
      19. Print "Config Timer und INT0"
      20. Config Timer1 = Timer,Prescale=64 ' Timer 1 mit 2MHz / 64 = 31,25kHz entsprechend 32µs laufen lassen
      21. Config INT0 = Change
      22. Print "Ready"
      23. Timer1 = 0
      24. Enable INT0
      25. Enable interrupts
      26. On INT0 leseT
      27. Do
      28. If Neword = 1 then gosub Ausgabe
      29. Loop
      30. leseT:
      31. 2word = Timer1
      32. Timer1 = 0
      33. Neword = 1
      34. I = I + 1
      35. Return
      36. Ausgabe:
      37. Msek = 2word / 32
      38. Print "Zählwert: ";2word;" = ";Msek;"ms"
      39. Neword = 0
      40. Return
      Display All

      Eine Zuordnung der Meßwerte ist problemlos möglich, aber die Abweichungen sind doch enorm...

      Timer1 läuft mit 2MHz / 64 = 31,25kHz entsprechend mit 32µs Auflösung.
      Impulslängen 100ms werden mit 2868-4726 (x32µs = 91,776 - 151,232ms) gemessen.
      Impulslängen 200ms werden mit 6196 - 7918 (x32µs = 198,272 - 253,376ms) gemessen.
      Impulspausen 800ms werden mit 23609 - 25166 (x32µs = 755,488 - 805,312ms) gemessen.
      Impulspausen 900ms werden mit 27000 - 28415 (x32µs = 864,0 - 909,28ms) gemessen.
      Impulspausen 1900ms werden mit 58574 - 59326 (x32µs = 1874,368 - 1898,432ms) gemessen.

      Wie bereits erwähnt ist die Zuordnung durchaus klar trennbar, keine Meßwerte die zwischen diesen Bereichen liegen.
      Dennoch frage ich mich wo die Ungenauigkeiten genau her kommen?
      Klar, die NANO's haben einen ungenauen 16MHz Resonator drauf, nur hätte ich gedacht das der /8 Vorteiler den Fehler weitgehend kleiner hält.

      Ebenso irritiert mich:

      Addiere ich die Impulslängen mit dem darauf folgenden Pauselängen, welche beide ziemlich ungenau erfasst werden, lande ich erstaunlicher weise bei korrekten 996 - 1010ms ?(

      Source Code

      1. Zählwert: 6980 = 225ms
      2. Zählwert: 24326 = 784ms = 1009ms
      3. Zählwert: 6860 = 221ms
      4. Zählwert: 24527 = 791ms = 1012ms
      5. Zählwert: 3573 = 115ms
      6. Zählwert: 27680 = 892ms = 1007ms
      7. Zählwert: 6914 = 223ms
      8. Zählwert: 24404 = 787ms = 1010ms
      9. Zählwert: 6639 = 214ms
      10. Zählwert: 24898 = 803ms = 1017ms
      11. Zählwert: 3163 = 102ms
      12. Zählwert: 27852 = 898ms = 1000ms
      13. Zählwert: 6656 = 214ms
      14. Zählwert: 24742 = 798ms = 1012ms
      Display All
      Sollwerte sollten eigentlich sein:
      100ms mit Zählwert 3125
      200ms mit Zählwert 6250
      800ms mit Zählwert 25000
      900ms mit Zählwert 28125

      Wo sind diese Ungenauigkeiten begründet? Der ungenaue Resonator der NANO's oder eher Ausgabeungenauigkeiten (Flankenform?) der DCF-Empfänger?
      Würde ja mein DSO mal dran hängen, wenn das nicht letzte Woche abgeraucht wäre.

      Jürgen
    • Wenn du den Timerwert in der ISR änderst, wirst du immer einen Laufzeit-Versatz und damit keinen genauen Takt haben.
      Schau dir mal zum Thema mein Timer-Tutorial an.

      Was du brauchst ist ein Timer, der im CTC-Mode läuft.

      Für deinen Takt kannst du aber auch die Uhr-Unterstützung von Bascom verwenden.
      Siehe Config Clock=User,...

      Das dürfte als Zeitbasis genauer sein als dein Interrupt.
    • DG7GJ wrote:

      wenn das nicht letzte Woche abgeraucht wäre.
      Mein Beileid. Meins hat schon länger aufgegeben ;(
      Die Signale aus dem Dcf sind dafür das sie schön rechteckig aussehen, erstaunlich unterschiedlich.
      Das ist kein Fehler im Code sondern wirklich das Ausgangssignal. Für die Auswerung ist das jedoch kein Problem (If <150ms kurz else lang)
      Läuft der Empfänger immer durch? Dann braucht der Avr keinen Quarz, der kann einfach schlafen bis zum nächsten Puls.
      Oder er bekommt einen mit 32 khz und schaltet hin und wieder den Empfänger ein.
      Was wohl weniger Strom braucht?

      PS Falls mal wirklich genaue Zeitmessungen nötig sind würde sich der Icp anbieten. Da stimmt der Wert und die Isr kann ihn später abholen ohne die 3 Takte Zufall.

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

    • Hallo!

      Inwischen nutze ich den CTC Mode mit Compare 31250.
      Der OC1A Int dient hierbei der sicheren Erkennung der 59. Sekunde.

      Läuft bisher sehr stabil und zuverlässig:

      BASCOM Source Code

      1. $regfile = "m328pdef.dat" 'ARUNDIO-NANO Prozessor
      2. $crystal = 2000000 'ARUNDIO-NANO Originalquarz 16MHz mit DIV8 auf 2MHz geteilt
      3. $hwstack = 400
      4. $swstack = 400
      5. $framesize = 600
      6. $baud = 9600
      7. Config Portb = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      8. Config Portc = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      9. Config Portd = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      10. Ddrb = &B11111111 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      11. Ddrc = &B11111111 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      12. Ddrd = &B11111010 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      13. Dim 1word as Word
      14. Dim 2word as Word
      15. Dim I as byte
      16. Dim Neword as Byte
      17. Dim Msek as Word
      18. wait 5
      19. Print "Config Timer und INT0"
      20. Config Timer1 = Timer,Prescale=64, Clear_Timer = 1 ' Timer 1 mit 2MHz / 64 = 31,25kHz entsprechend 32µs laufen lassen
      21. Config INT0 = Change
      22. Print "Ready"
      23. Timer1 = 0
      24. OCR1A = 31250
      25. Enable INT0
      26. Enable OC1A
      27. Enable interrupts
      28. On INT0 leseT
      29. On OC1A NewMin
      30. Do
      31. If Neword = 1 then gosub Ausgabe
      32. Loop
      33. leseT:
      34. '2word = Timer1 - 1word
      35. '1word = 2word
      36. 2word = Timer1
      37. Timer1 = 0
      38. Neword = 1
      39. Return
      40. Ausgabe:
      41. Select Case 2word
      42. Case is <= 2799 : Return
      43. Case 2800 to 4800 : gosub Bit0
      44. Case 4801 to 6189 : Return
      45. Case 6190 to 8000 : Gosub Bit1
      46. Case is >= 8001 : Return
      47. End Select
      48. 'Msek = 2word / 32
      49. 'Print "Zählwert: ";2word;" = ";Msek;"ms"
      50. 'Neword = 0
      51. Return
      52. NewMin:
      53. I = 59
      54. Print i;"sek."
      55. I = 0
      56. Neword = 0
      57. Return
      58. Bit0:
      59. Print i;"sek. Wert= 0"
      60. Neword = 0
      61. I = I + 1
      62. Return
      63. Bit1:
      64. Print i;"sek. Wert= 1"
      65. Neword = 0
      66. I = I + 1
      67. Return
      Display All
      Das die Timer-Manipulation (Timer1 = 0) gewisse Laufzeitverzögerungen mit sich bringt ist klar.
      Aber vorhergehende Versuche mit der Methode außerhalb des Interrupts "Neuwert = Neuwert - Altwert" haben bei mir zu zyklischen Müllwerten geführt die kaum besser waren.

      Daher die Frage ob hier schon mal jemand Erfahrungswerte gesammelt hat was vom Timing her die größten Fehler baut: NANO-Nachbauten aus Fernost oder die Flanken der Pollin DCF1.

      Zumal ich zum NANO anmerken muss:
      Wenn ich bisher versucht habe mittels Timer Frequenzen zwischen 450-2800Hz sicher zu vermessen hatten die NANO's kaum eine brauchbare Genauigkeit.
      Im eigenen Projekt dann mit korrekt abgeglichenen Quarz waren die Messwerte dagegen um Dimensionen besser.
    • DG7GJ wrote:

      Das die Timer-Manipulation (Timer1 = 0) gewisse Laufzeitverzögerungen mit sich bringt ist klar.
      Ja, und die addieren sich weiter auf. Dieser Fehler dürfte größer sein als der Quarzfehler mit 100ppm, der dich im 1. Post gestört hat.

      DG7GJ wrote:

      Aber vorhergehende Versuche mit der Methode außerhalb des Interrupts "Neuwert = Neuwert - Altwert" haben bei mir zu zyklischen Müllwerten geführt die kaum besser waren.
      Da hast du wohl eine ungeeignete Methode angewendet. Wenn man die Differenz berechnet, muss der timer ohne dass er geändert wird durchlaufen können. Weiterhin sollten im Hintergrund keine Interrupts laufen, wenn man sowas in der Hauptschleife macht.
      Geeignete Methode ist hier ein Timer, der einfach durchläuft in verbindung mit dem ICP und seinem Interrupt, der dann den Wert aus dem ICP-Register holt und die Differenz zum alten ICP-Wert bildet.

      DG7GJ wrote:

      Daher die Frage ob hier schon mal jemand Erfahrungswerte gesammelt hat was vom Timing her die größten Fehler baut: NANO-Nachbauten aus Fernost oder die Flanken der Pollin DCF1.
      Fährt ein grüner Golf schneller als ein blauer?
      Ich denke, der Controller tut das, was seine Befehle ihm mitteilen. Beim Nano laufen im Hintergrund Timer, um die Millis fürtzuzählen. D.H. da laufen Interrupts im Hintergrund. Je nach Art, wie du das programmiert hast, muss man sowas beachten. Hast du den Nano mit Bascom programmiert oder mit der Arduino-IDE?
      Ich denke, es liegt am geschriebenen Code.

      DG7GJ wrote:

      Wenn ich bisher versucht habe mittels Timer Frequenzen zwischen 450-2800Hz sicher zu vermessen hatten die NANO's kaum eine brauchbare Genauigkeit.
      Im eigenen Projekt dann mit korrekt abgeglichenen Quarz waren die Messwerte dagegen um Dimensionen besser.
      Dann hast du wohl etwas falsch gemacht?
    • Hallo!

      Mitch64 wrote:

      Ja, und die addieren sich weiter auf. Dieser Fehler dürfte größer sein als der Quarzfehler mit 100ppm, der dich im 1. Post gestört hat.
      Mal abgesehen vom manuelle Rücksetzen des Timers:

      Bei den chinesischen NANO's ist keine Spezifikation zum Resonator enthalten.
      Wenn ich aber nach Datenblättern entsprechender 16MHz SMD-Resonatoren finde ich Daten die eher von einer Anfangsabweichung von +-0,5% und eine Stabilität von zusätzlich +-0,3% sprechen.
      +-0,5% bei 16MHz wären dann irgendwas zwischen 15,920000 - 16,080000MHz entsprechend einer Abweichung von +-80kHz!
      Rechnet man dann noch die +-0,3% dazu kommt man zu irgendwas zwischen 15,872240 - 16,128240MHz entsprechend stolzen +-128kHz.

      Dagegen die üblichen +-20ppm von Standardquarzen wären dann bei 16MHz irgendwas zwischen 15,999680 - 16,000320MHz entsprechend +-320Hz.
      Es liegen also Dimensionen dazwischen weswegen mich nicht wundert warum eigene Projekte mit anständigem Quarz manche zeitkritische Aufgaben besser können als diese NANO's.

      Mitch64 wrote:

      Geeignete Methode ist hier ein Timer, der einfach durchläuft in verbindung mit dem ICP und seinem Interrupt, der dann den Wert aus dem ICP-Register holt und die Differenz zum alten ICP-Wert bildet.

      Hmm, kann ich mal versuchen. ICP habe ich vor einiger Zeit mal genutzt für ASK-Decodierung. Aufgrund der Lahmheit von DCF77 mit seinen 100/200ms hab ich gestern erst mal mit dem INT0 angefangen.


      Mitch64 wrote:

      Hast du den Nano mit Bascom programmiert oder mit der Arduino-IDE?
      Ne, bin kein Freund von Ardunio.
      Die handvoll NANO's von denen ich seit Jahren zehre nutze ich mit einem USB-ISP Programmer direkt aus Bascom heraus.

      Aber davon ab:
      DCF_Minuten und DCF_Stunden habe ich in Byte-Variablen und das Datumsfeld in einem Dword, jeweils alle mit dem Paritätsbit an LSB-Stelle.
      Hab jetzt mehrfach das aktuelle Manual PDF von Bascom durchsucht. Gibt es tatsächlich keinen Befehl um die Parität einer Variable zu prüfen?

      Jürgen
    • DG7GJ wrote:

      Bei den chinesischen NANO's ist keine Spezifikation zum Resonator enthalten.
      Wenn ich aber nach Datenblättern entsprechender 16MHz SMD-Resonatoren finde ich Daten die eher von einer Anfangsabweichung von +-0,5% und eine Stabilität von zusätzlich +-0,3% sprechen.
      Du kannst jetzt aber nicht von Äpfel auf Birnen schließen.
      Das ist erst mal nur ne Vermutung. Vielleicht ist der Quarz besser als du denkst.
      Zumal du ja einen DCF-Empfänger bauen willst. Und dafür wird es ja wohl langen.

      DG7GJ wrote:

      Hmm, kann ich mal versuchen. ICP habe ich vor einiger Zeit mal genutzt für ASK-Decodierung. Aufgrund der Lahmheit von DCF77 mit seinen 100/200ms hab ich gestern erst mal mit dem INT0 angefangen.
      Beim ICP-Interrupt kann man aber nicht auf beide Flanken triggern. - Also kein Change.
      Das solltest du dabei berücksichtigen.

      DG7GJ wrote:

      Wo sind diese Ungenauigkeiten begründet? Der ungenaue Resonator der NANO's oder eher Ausgabeungenauigkeiten (Flankenform?) der DCF-Empfänger?
      Hier noch ein Update zu deinem 1. Post. Woher die Ungenauigkeit kommt.

      Du hast den INT0 Change-Interrupt verwendet.
      Die DCF-Flanken liegen nominell (pei den neg. Pulsen) um 0,1s und 0,2s auseinander.

      In der ISR_INT0 setzt du bei jeder Flanke ein Flag "Neword", welches du dann in der Hauptschleife abfragst und eine Ausgabe anspringst.
      Wenn du jetzt mal die Laufzeiten zusammen zählst ab der neg. Flanke bei einem angenommenen Puls mit 0,1s, wird's eng.

      Die Abarbeitung des Interrupts + die Abarbeitung der Ausgabe kosten mehr Zeit, als du Pulsbreite hast.
      Ein Problem dabei ist mitunter der geringe Takt und die serielle Ausgabe.

      Wenn du später z.B. mit einem Uhrenquarz ala 32768Hz arbeiten willst, muss die ISR flutschen (Assembler). Da ist keine Zeit zu verplempern.
      Den internen RC-Oszillator würde ich jetzt nicht nehmen, da der Temperatur und Spannungs-Abhängig ist.
      Ob die Toleranzen ausreichen?

      Soviel mal dazu.
      Im 2. Code hast du zumindest die serielle Ausgabe weggelassen.
      Wenn du da mal die Zeiten misst, wirst du feststellen, dass die jetzt genauer sind.

      Noch ein Tip. Weil alles Zeitkritisch ist. Verwende die Taktquelle, die du später auch im fertigen Projekt verwenden willst. Und entwickle mit diesem Takt dein Projekt. Sonst könnte es Überraschungen geben und der Decoder funktioniert nicht wie erwartet.

      DG7GJ wrote:

      DCF_Minuten und DCF_Stunden habe ich in Byte-Variablen und das Datumsfeld in einem Dword, jeweils alle mit dem Paritätsbit an LSB-Stelle.
      Hab jetzt mehrfach das aktuelle Manual PDF von Bascom durchsucht. Gibt es tatsächlich keinen Befehl um die Parität einer Variable zu prüfen?
      Mir ist eine solche Routine auch nicht bekannt, sollte aber nicht so schwer sein, das mit wenigen ASM-Zeilen zu proggen.
      Geht auch in Basic, aber langsamer.
    • Eine solche Parity-Routine könnte etwa so aussehen:

      BASCOM Source Code: Parity

      1. ' Liefert 1 bei ungerader Anzahl 1-en, sonst 0.
      2. Function GetParity(Byval value as Byte) as Byte
      3. Local tmpByte as Byte
      4. tmpByte = 0
      5. For i = 0 to 7 ' die Bits durchgehen
      6. If value.i = 1 then Incr tmpByte ' 1-Bits zählen
      7. Next
      8. GetParity = tmpByte.0 ' letzte Stelle ist Gerade/ungerade
      9. End Function
    • Hallo!

      Mitch64 wrote:

      Beim ICP-Interrupt kann man aber nicht auf beide Flanken triggern. - Also kein Change.
      Das solltest du dabei berücksichtigen.
      Ja, das ist blöd, denn wenn ich nur die steigenden Flanken messe bekomme ich nur 1000ms.
      Auf fallenden Flaken müsste ich 800 oder 900ms bekommen...müsste notfalls auch gehen.

      Mitch64 wrote:

      In der ISR_INT0 setzt du bei jeder Flanke ein Flag "Neword", welches du dann in der Hauptschleife abfragst und eine Ausgabe anspringst.
      Wenn du jetzt mal die Laufzeiten zusammen zählst ab der neg. Flanke bei einem angenommenen Puls mit 0,1s, wird's eng.
      Naja, in der Timer-ISR will ich möglichs schnell fertig werden, weswegen ich da nur ein Flag setze das ein neuer Wert vorliegt.
      Keine Ahnung ob da Timing etwas eng wird. In der Endanwendung bei nochmals einem Viertel der jetzigen Taktfrequenz (dann 500kHz) fällt die komplette UART-Protokollierung raus.
      Und die Bits die ich noch einzeln sammel und bei der 59. Sekunde entsprechend sortiere und decodiere werde ich zum Schluss auch nochmal optimieren mit Hilfe von Overlay-Variablen.

      Zur Zeit läuft es aber nach viel detailierter Hasselei ziemlich stabil, trotz monströser UART-Ausgaben:

      Source Code

      1. DCF_WX h1889 DCF_STS b00000101 DCF_Min b11000011 DCF_Std b01000010 DCF_Date b00000000001000000110001110001001 21:43:00 am 04 dem 02.11.2023 Check b00000010 Stunde b00100001
      2. DCF_WX h3FE6 DCF_STS b00000101 DCF_Min b00100010 DCF_Std b01000010 DCF_Date b00000000001000000110001110001001 21:44:00 am 04 dem 02.11.2023 Check b00000011 Stunde b00100001
      3. DCF_WX h0272 DCF_STS b00000101 DCF_Min b10100011 DCF_Std b01000010 DCF_Date b00000000001000000110001110001001 21:45:00 am 04 dem 02.11.2023 Check b00000010 Stunde b00100001
      Was die Paritätsprüfung angeht behelfe ich mich gerade mit:

      BASCOM Source Code

      1. Parity_Min = DCF_Min MOD 2
      2. Parity_Std = DCF_Std MOD 2
      3. Parity_Date = DCF_Date MOD 2
      4. If Parity_Min = 0 then Check.0 = 1
      5. If Parity_Std = 0 then Check.1 = 1
      6. If Parity_Date = 0 then Check.2 = 1

      Hat für einige Stunden herforragend geklappt.
      Bei den diversen Detailkorrekturen hat ich da aber etwas zerissen, muss ich morgen nochmal drüber schauen.

      Jürgen
    • Mitch64 wrote:

      Beim ICP-Interrupt kann man aber nicht auf beide Flanken triggern. - Also kein Change.
      Na ja, nicht direkt.
      Aber in der ISR kannst du ja die zu erkennende Flanke umschalten.

      DG7GJ wrote:

      Auf fallenden Flaken müsste ich 800 oder 900ms bekommen...müsste notfalls auch gehen.
      Eher 1000ms, wenn der gleiche Wert wie vorher erkannt wird und 900ms bzw 1100ms wenn der Wert wechselt.

      DG7GJ wrote:

      Parity_Min = DCF_Min MOD 2
      Das sagt dir ja nur, ob das letzte Bit 1 oder 0 ist. Du musst aber alle 1sen zählen.
      Einfach geht das, wenn du Parity als Bit dimensionierst und dann bei der Erkennung einer 1 das Parity togglest.
    • DG7GJ wrote:

      in der Timer-ISR will ich möglichs schnell fertig werden
      das ist lobenswert aber in dieser Anwendung unnötig. Dort ist rein gar nichts zeitkritisch.
      Der Timer nicht und ein Quarz ist völlig unnötig. Der Takt sollte weniger als 3% abweichen damit der Uart deutlich spricht, Für das Dcf Signal dürfen das auch 20% sein.
      Ob der Timer hochpräziese 3456 zählt oder irgendwas zwischen 3 und 4 Tausend macht keinen Unterschied.
      Bedenke das die Int >110 Takte braucht ohne das sie was macht. Da kommt es auf die 7 Takte für ein "If PinD.2 =1" nicht an.

      Eine ganz andere Sache ist es eine Frequenz zu messen. Da muß der Icp eingesetzt werden um die 5 Takte Differenz in der Isr Aufrufzeit zu elieminieren. Und damit keine anderen Ints das Ergebniss stören.

      DG7GJ wrote:

      dann mit korrekt abgeglichenen Quarz
      Der Vergleich ist unfair. Wie genau wird es denn wenn der Nano abgeglichen wird ? Vielleicht dazu noch einen mit internem Takt. :D

      PS Dort ist superguter Empfang. Im Normalfall fehlt hin und wieder ein erkennbarer Puls. Das sollte die Software auffangen. (z.B. über die Oc1a im 1,5S Takt)
    • Pluto25 wrote:

      Eine ganz andere Sache ist es eine Frequenz zu messen. Da muß der Icp eingesetzt werden um die 5 Takte Differenz in der Isr Aufrufzeit zu elieminieren. Und damit keine anderen Ints das Ergebniss stören.
      Im Grunde muss man den ICP für überhaupt nix unbedingt einsetzen.
      Auch nicht beim Frequenz messen. Man kann alles auch anders lösen.

      Aber wenn man genau messen möchte oder muss, dass ist der ICP das Mittel der Wahl, und zwar für Frequenz-Messung als auch für Puls-Messung.
      Und Franz hat es auch schon erwähnt, dass man im Interrupt auch die Triggerflanke umschalten kann.
      Und genau Messung erreicht man eben nur mit einer Taktquelle die stabil ist, vor allem bei Batteriebetrieb und wenn man die Spannung direkt an Controller anklemmt. Und da ist der Quarz eben besser als der interne RC-Oszillator. Das sind so einfach mal Fakten.

      Das DCF-Signal hat nominelle Toleranzen, hinzu kommen noch Abweichungen durch den Übertragungsweg (Funk), wie Interverenzen. Dann darf man nicht vergessen die Flankensteilheit von dem Empfänger, der das DFC-Signal ausgibt. Und dann nimmt man (sarkastisch gemeint) weil es eine gute Idee ist, ein RC-Oszillator, der auch von Batterie-Spannungsabhängig und Temperatur-Abhängig ist. Und obendrein nimmt man dann kein ICP. - Kann man machen, ich kann sowas aber nicht empfehlen.

      Wenn man alle Toleranzen zusammen nimmt, muss man sich fragen, ob das dann noch funktionieren kann.

      Meine Intension ist immer, wenn man eine Recource wie den ICP und Timer1 hat und sie nicht anderweitig braucht, warum dann nicht nutzen.
      Der Quarz kostet auch nicht viel. Alternativ wäre vielleicht ein Resonator mit 460kHz. Wenn man das noch bekommt.
      Und ein externer RC-Oszillator könnte noch genauer sein als der interne.

      Man sollte bei der Auslegung der Hardware auch das Gesampt-Projekt betrachten und nicht nur ein Aspekt, wie die DCF-Dekodierung.
      Es ist ja auch fraglich, ob der UART im fertigen Projekt überhaupt genutzt werden soll oder hier nur zwecks debuging drin ist. Hier sollte man dann vielleicht einen Baudquarz nehmen.

      Weiterhin kostet der Takt vom Oszillator mit steigender Frequenz mehr Strom.
      Man sollte daher auf einen möglichst geringen Takt akten, der aber noch hoch genug ist, damit man die Aufgaben noch erfüllen kann.

      Die Rede war auch mal noch von MCU "zur Ruhe legen"? Zumindest sollte man mal darüber nachdenken, wie man das elegant in den Programmablauf einbindet.
      Das hilft ungemein Strom zu sparen.
      Und eine Messung der Stromaufnahme am Anfang lässt schon eine Abschätzung zu, ob der lange Betrieb über ein Jahr dann überhaupt möglich ist.

      Zugegeben ist ein interner RC-Oszillator stromsparender als ein Quarz. Schon alleine wegen dem Taktunterschied. Aber wenns denn der interne RC-Dinger sein soll, dann sollte man das vorher mal testen, ob die Dekodierung noch klappt bei Voller und leerer Batterie, und entsprechenden Umgebungstemperaturen.
    • Mitch64 wrote:

      Meine Intension ist immer, wenn man eine Recource wie den ICP und Timer1 hat und sie nicht anderweitig braucht, warum dann nicht nutzen.
      Sehe ich genauso. Du bekommst eh kein Geld zurück, wenn du den nicht nutzt.
      Außerdem hat der ICP einen ganz entscheidenden Vorteil: Du musst im Falle eines Events - hier Flankenwechsels - nicht sofort reagieren.
      Bei DCF hast du zwischen 100ms und 1900ms Zeit, dir den Wert abzuholen, der genau beim Flankenwechsel gespeichert wurde. Selbst bei sehr niedriger Taktrate geht das eigentlich immer.
      Bei allen anderen Timersachen muss man immer ziemlich schnell reagieren, um den richtigen Wert zu bekommen, was je nach Programm aber nicht unbedingt geht.
      Wenn also andere zeitkritische Dinge gemacht werden müssen, dann kann man auf den ICP Interrupt verzichten und nur zur passenden Zeit das entsprechende Flag abfragen.
      Wenn das gesetzt ist, holt man sich den Wert aus dem Register.
    • Stöhn...
      Habe mich nun fast nen halben Tag mit dem ICP1 auseinander gesetzt.

      Config Timer1 = TIMER, Prescale=64, Noise_Cancel = X, Capture_EDGE=Falling

      Bei ICP1 Int:
      Toggle TCCR1B.6
      Neuwert = Capture1
      Neuwert = Neuwert - Altwert
      Altwert = Neuwert

      Was mir da aber an Werten rausgeballert wird ist Wahnsinn.
      Ohne Flankenumschaltung (Toggle auskommentiert):

      Bei Capture_EDGE Falling wirft mir das Teil statische Werte von abwechselnd 31113 und 34423 entsprechend 972ms und 1075ms raus.
      Bei Capture_EDGE Rising sind es eben so statisch 31545 und 33991 entsprechend 985ms und 1062ms

      Mit Flankenumschaltung in der ISR nur noch Müllwerte.

      Vermute das es am NANO liegt. Werde mir wohl die endgültige Hardware erst zusammenstellen müssen zum Feinschliff.

      Worum es geht: Eine alte Geschichte von mir die zwei mal im Jahr meinen Leidensdruck erhöht.
      IMG_1.jpg

      Zwei dieser Uhren stehen hier rum. Angenehmes, dezentes Display mit ca. 27mm Ziffernhöhe.
      Neben der Temperatur bekommen die auch Uhrzeit und Datum von einem Funksensor der es langsam mehr als hinter sich hat.
      Der DCF-Empfänger da drin ist extrem Taub - nach Batteriewechsel braucht er mindestens 30-40Minuten bis er endlich seine Zeit hat.
      Hinzu kommt das er seinen DCF77-Empfang sogar durch seinen 433MHz ASK-Sender stört.
      Zu Deutsch: Nach jeder Zeitumstellung bin ich die letzten Jahre eher beschäftigt damit den Sensor von der Aussenfassade zu nehmen um ihn zu überreden das er die Zeit aktualisieren soll.

      Nach jedem dieser Aktionen kam ich mehr und mehr hinter dieses probitäre ASK-Protokoll.
      Das kenne ich inzwischen hinreichend gut um es nachbauen zu können.

      Also Neubau eines kompatiblen Aussensensors.
      Kleiner 328PB oder 324PA mit LM75 als Temperatursensor und einem DCF77-Empfänger an einem ASK-Sender.

      Um Strom zu sparen rechne ich zunächst mit möglichst niedriger Taktfrequenz.
      An einen 32,768kHz Uhrenquarz dachte ich auch schon, werde aber wohl irgendwo zwischen 500kHz und 2MHz raus kommen.
      Denn für den ASK-Sender braucht ich eine Bitlänge von 488 / 976µs, womit die endgültige Entscheidung über die Taktfrequenz erst dann fällt wenn der ASK-Sender dran ist.

      Neubau der DCF-Routine daher weil die Bascom-interne DCF77 Funktion einerseits bei sehr niedrigen Systemtakten schnell in die Knie geht.
      An Projekten mit M324PA hat mich zudem genervt das die DCF-Routine nicht mit einer 32,768kHz RTC am Timer2 kompatibel ist.

      Was weitere Stromspartechniken angeht:
      An einem M324PA könnte ich massiv alle verfügbaren Sleepmodes anwenden, da Timer2 als RTC weiter läuft.
      Würde ich einen M324PB nehmen bleibt nur niedrige Frequenz und Idle statt Sleep.
      Denn hier müsste einer der verfügbaren Timer eine Uhrfunktion (Sekundenzähler) übernehmen.

      In so fern bin ich erst mal dabei eine DCF-Routine hin zu bekommen die auch für Systemtakte <1MHz läuft und zudem endlich mal kompatibel zu Timer2 RTC wird.

      Mit dem internen RC-Oszillator fange ich gar nicht erst an. Nicht nur was die DCF77-Routine angeht würde das fraglich werden.

      Jürgen
    • Du könntest ja mal dein Programm zeigen, dann kann man das besser nachvollziehen.
      Der Start der Flanke ist bei DCF immer nach einer Sekunde, danach bleibt der Pegel 100ms oder 200ms bevor er wieder wechselt.
      Wenn der Pegel in der langen Pause Low ist, dann solltest du bei Rising mehr oder weniger genau 1000ms bekommen.
      Bei Falling sind es 900ms, 1000ms oder 1100ms, je nachdem ob vorher eine 1 oder eine 0 war und ob jetzt eine 0 oder 1 kommt.
      Wenn du innerhalb der ISR wechselst, dann sollten 100ms, 200ms, 800ms oder 900ms kommen, also recht viel durcheinander.

      Falls der Pegel in der langen Pause High ist, dann eben genau anders herum, also 1000ms bei Falling und verschiedene Wert bei Rising.
    • Hallo!

      Mitch64 wrote:

      Aber wenn man genau messen möchte oder muss, dass ist der ICP das Mittel der Wahl, und zwar für Frequenz-Messung als auch für Puls-Messung.
      Und Franz hat es auch schon erwähnt, dass man im Interrupt auch die Triggerflanke umschalten kann.
      Habe ich bei anderen Projekten bereits häufiger gemacht. Beispielsweise FFSK im Funkbereich 1200/1800Hz erkennen, oder auch für ASK-Auswertung für 433MHz-Zeugs.
      Bislang dabei die Triggerflanke mit Toogle TCCR1B.6 umgeschaltet.
      Bei diesem NANO-Exemplar hier aber zieht sich der ICP1 nur Müll rein.
      Mag an der Spannungsversorgung (USB) liegen, am Steckbrett, oder eben am NANO selber.
      Egal ob Noice Canceller an oder aus.

      Über einen externen INT mit dem DCF-Signal bin ich anfangs aus zwei Gründen gegangen:
      Zum einen weil DCF ja in einem Schneckentempo arbeitet wo es keinesfalls auf µs ankommt, anders als so manche andere Anwendungen.
      Ebenso weil ich den CHANGE-Trigger der externen Int's bestechend fand. So wäre diese Routine universell weiter nutzbar ohne das man sich Gedanken machen müsste über die Polarität des jeweiligen DCF-Empfängermoduls.

      Mitch64 wrote:

      Das DCF-Signal hat nominelle Toleranzen, hinzu kommen noch Abweichungen durch den Übertragungsweg (Funk), wie Interverenzen. Dann darf man nicht vergessen die Flankensteilheit von dem Empfänger, der das DFC-Signal ausgibt. Und dann nimmt man (sarkastisch gemeint) weil es eine gute Idee ist, ein RC-Oszillator, der auch von Batterie-Spannungsabhängig und Temperatur-Abhängig ist. Und obendrein nimmt man dann kein ICP. - Kann man machen, ich kann sowas aber nicht empfehlen.
      Ja, es gibt Toleranzen bei DCF77 über den Funkweg. Aber diese sind im Funksignal eher im Bereich unterhalb von 10ms. Also 100ms immer grob 95-105ms und 200ms dann 19x-20xms.
      Deutlich größere Abweichungen liegen häufig am DCF-Modul und seiner Flankensteilheit.
      Im Internet hat jemand einen DCF-Empfänger online gestellt wo schön zu sehen ist welche Toleranzen er da misst: dcf77logs.de/live
      So grob entsprechen die dort gezeigten Toleranzen grob dem was mein erster Ansatz mit DCF an INT0 und rücksetzen des Timers in der isr so ausgegeben hat.

      Mitch64 wrote:

      Man sollte bei der Auslegung der Hardware auch das Gesampt-Projekt betrachten und nicht nur ein Aspekt, wie die DCF-Dekodierung.
      Es ist ja auch fraglich, ob der UART im fertigen Projekt überhaupt genutzt werden soll oder hier nur zwecks debuging drin ist. Hier sollte man dann vielleicht einen Baudquarz nehmen.
      Abseits von NANO-Experimenten nehme ich immer Quarze, wenn UART mit hohen Baudraten Essenziell für ein Projekt ist auch Baudquarze.
      Ein einziges mal, vor Jahren als ich mit Bascom anfing, dachte ich mir an einem M1284p den Quarz einsparen zu können. Mit dem Ergebnis das ich dann hinterher ein Quarz auf den TFQP-44 kleben und kunstvoll an die Pads löten musste. Seit dem pfeife ich auf den internen RC-Oszillator.

      Mitch64 wrote:

      Weiterhin kostet der Takt vom Oszillator mit steigender Frequenz mehr Strom.
      Man sollte daher auf einen möglichst geringen Takt akten, der aber noch hoch genug ist, damit man die Aufgaben noch erfüllen kann.
      Ja, bei dem Projekt jetzt aufgrund ASK-Sender sehrwohl.
      Die DCF-Routine soll dagegen möglichst universell einsetzbar sein.

      Nur mal so als Extrembeispiel:
      Der originale Außensensor mit NTC als Temperatursensor und tauben DCF77-Empfänger werkelt nur mit einem 32,768kHz-Quarz.
      Also einem Takt von knapp 30,5µs.
      Der hat also für die ASK-Bitzeit von 488µs gerade mal 16 Systemtakte zeit.
      So extrem sportlich will ich gar nicht werden.

      Mitch64 wrote:

      Die Rede war auch mal noch von MCU "zur Ruhe legen"? Zumindest sollte man mal darüber nachdenken, wie man das elegant in den Programmablauf einbindet.
      Ja, das ist mit Abstand die beste Sparmaßname. Geht aber eben nur wenn man eine 32,768kHz RTC am Timer2 hat, oder anderweitig ein Triggersignal welches den µC wieder aufweckt.
      Vor etwa 4~5Jahren habe ich mich von den Mega 324/644/1284 weg zu den 328PB umorientiert.
      Für zahlreiche Kleinprojekte reicht er, und kommt mit überraschender Ausstattung daher. Drei 16Bit-Timer, 2x UART, 2xI²C.
      Das einzig blöde ist das die TOSC aber mit den XTAL-Pads kombiniert sind.
      Will man den stromsparend im Sleepmode setzen, braucht es ein 32,768kHz-Quarz und als Systemtakt bleibt dann nur der interne RC.
      Eben aufgrund dieser Misere tendiere ich bei dem Ersatzsensor eher mit einem 324P.

      Immerhin bräuchte dieses Teil nur alle 43sek. die Temperatur messen und als ASK-Paket versenden. Nach 6 Temperaturpaketen dann ein Zeitpaket mit der RTC-Zeit. Obendrauf vielleicht 1-2 mal am Tag DCF-Decodierung für 3-5 Minuten. Dazwischen könnte der massenhaft schlafen.

      Jürgen
    • Im wesentlichen sind ja nur die 100ms und 200ms wichtig und ob der Puls ausbleibt (Timeout).

      Ich würde in der ISR abprüfen, ob der Pegel nun High oder Low ist.
      Ich gehe jetzt von einem Low-Puls aus.

      Wird die ISR aufgerufen, wird der Pegel abgefragt.

      • Ist der Low, ist mit einem Puls zu rechnen. Also Capture-wert merken und den Trigger-Pegel auf steigende Flanke umschalten. Das wars.

      • Ist der Pegel High, so holt man sich den Capture-wert und schaltet wieder die Flanke um auf Fallend. Zusätzlich muss jetzt die Differenz berechnet werden und dann eine Wertung durchgeführt werden, ob es sich bei der Zählerdifferenz um eine logische 0 oder eine 1 handelt. Das wars.
      So kann man sich die empfangenen Bits wieder zugänglich machen.
      Bleibt noch das Problem mit dem fehlenden Puls.
      2. Timer nehmen? Wäre eine Möglichkeit.

      Ist aber nicht notwendig.

      Da die Messung der Pulse ja nicht Timertakt genau sein muss, würde es auch reichen, anstatt den Capture-Wert den Timerwert direkt auszulesen.

      Das Vorgehen könnte dann so aussehen.
      • Bei Fallender Flanke wird die ISR aufgerufen. Der Timer wird auf 0 gesetzt. Flanke auf steigend umgeschaltet.
      • Bei steigender Flanke wird der Timer-Wert als Messwert genommen. Flanke wieder auf fallend umschalten.
      Der Timeout für die fehlende Sekunde kann man nun mit einem OCR erledigt werden. Der Timer wird nicht abgenullt nach der pos. Flanke und läuft werter.
      Kommt keine Negative Flanke innerhalb 1000ms, löst der OC-Interrupt aus. Damit weiß man den Minuten-Sprung.

      Diese Methode lässt sich auch mit dem INT0/1 als Eingang erledigen und man kann auch den Timer 0 oder 2 dafür verwenden. ICP wäre dann unbenutzt.
      Das schafft Freiraum, damit du eine 1s Zeitbasis für ASK mit dem Timer1 im CTC-Mode erledigen kannst.

      Hierbei kannst du dann auch den INT0 wieder auf Change einstellen.
      Solltest aber in der INT0/1 Routine abprüfen, ob der Pegel nun 0 oder 1 ist, um zu entscheiden, ob der Timer genullt werden soll und ob du rechnen musst und auswerten.
    • Hallo Franz!

      Franz wrote:

      Du könntest ja mal dein Programm zeigen, dann kann man das besser nachvollziehen.
      Der Start der Flanke ist bei DCF immer nach einer Sekunde, danach bleibt der Pegel 100ms oder 200ms bevor er wieder wechselt.
      Wenn der Pegel in der langen Pause Low ist, dann solltest du bei Rising mehr oder weniger genau 1000ms bekommen.
      Bei Falling sind es 900ms, 1000ms oder 1100ms, je nachdem ob vorher eine 1 oder eine 0 war und ob jetzt eine 0 oder 1 kommt.
      Wenn du innerhalb der ISR wechselst, dann sollten 100ms, 200ms, 800ms oder 900ms kommen, also recht viel durcheinander.

      Falls der Pegel in der langen Pause High ist, dann eben genau anders herum, also 1000ms bei Falling und verschiedene Wert bei Rising.
      Ja, so hatte ich es erwartet. Aber irgendwie scheint mein ICP1 schlecht gelaunt zu sein:

      BASCOM Source Code

      1. $regfile = "m328pdef.dat" 'ARUNDIO-NANO Prozessor
      2. $crystal = 2000000 'ARUNDIO-NANO Originalquarz 16MHz mit DIV8 auf 2MHz geteilt
      3. $hwstack = 400
      4. $swstack = 400
      5. $framesize = 600
      6. $baud = 9600
      7. Config Portb = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      8. Config Portc = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      9. Config Portd = &B00000000 'Pull Up Deaktiviert (0) oder aktiviert (1)
      10. Ddrb = &B11111110 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      11. Ddrc = &B11111111 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      12. Ddrd = &B11111010 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      13. Dim Alt as Word
      14. Dim Neu as Word
      15. Dim I as byte
      16. Dim Newword as Byte
      17. Dim Msek as Word
      18. wait 5
      19. Print "Config Timer und INT0"
      20. Config Timer1 = Timer, Prescale=64, Noise_Cancel = 0, Capture_EDGE = falling ' Timer 1 mit 2MHz / 64 = 31,25kHz entsprechend 32µs laufen lassen
      21. Print "Ready DCF77 V0b.bas"
      22. Enable ICP1
      23. Enable interrupts
      24. On ICP1 leseT
      25. Do
      26. If Newword = 1 then gosub Ausgabe
      27. Loop
      28. leseT:
      29. Toggle TCCR1B.6
      30. Neu = Capture1
      31. Neu = Neu - Alt
      32. Alt = Neu
      33. Newword = 1
      34. i = i + 1
      35. Return
      36. Ausgabe:
      37. Msek = Neu / 32
      38. Print i;"Sek Zählwert: ";Neu;" = ";Msek;"ms"
      39. Newword = 0
      40. Return
      Display All
      DCF77 Signal liegt hierbei am ICP1


      Und als Log kommt das hier aus der UART:


      Source Code

      1. Config Timer und INT0
      2. Ready DCF77 V0b.bas
      3. 1Sek Zählwert: 0 = 0ms
      4. 2Sek Zählwert: 6603 = 206ms
      5. 3Sek Zählwert: 3610 = 112ms
      6. 4Sek Zählwert: 34399 = 1074ms
      7. 5Sek Zählwert: 10141 = 316ms
      8. 6Sek Zählwert: 59051 = 1845ms
      9. 7Sek Zählwert: 13840 = 432ms
      10. 8Sek Zählwert: 21073 = 658ms
      11. 9Sek Zählwert: 17378 = 543ms
      12. 10Sek Zählwert: 48868 = 1527ms
      13. 11Sek Zählwert: 24040 = 751ms
      14. 12Sek Zählwert: 39323 = 1228ms
      15. 13Sek Zählwert: 27526 = 860ms
      16. 14Sek Zählwert: 1569 = 49ms
      17. 15Sek Zählwert: 31072 = 971ms
      18. 16Sek Zählwert: 29286 = 915ms
      19. 17Sek Zählwert: 37700 = 1178ms
      20. 18Sek Zählwert: 53771 = 1680ms
      21. 19Sek Zählwert: 41479 = 1296ms
      22. 20Sek Zählwert: 15878 = 496ms
      23. 21Sek Zählwert: 45009 = 1406ms
      24. 22Sek Zählwert: 43689 = 1365ms
      25. 23Sek Zählwert: 48494 = 1515ms
      26. 24Sek Zählwert: 5918 = 184ms
      27. 25Sek Zählwert: 55291 = 1727ms
      28. 26Sek Zählwert: 30369 = 949ms
      29. 27Sek Zählwert: 59046 = 1845ms
      30. 28Sek Zählwert: 58095 = 1815ms
      31. 29Sek Zählwert: 62514 = 1953ms
      32. 30Sek Zählwert: 20318 = 634ms
      33. 31Sek Zählwert: 3575 = 111ms
      34. 32Sek Zählwert: 45085 = 1408ms
      35. 33Sek Zählwert: 10147 = 317ms
      36. 34Sek Zählwert: 4104 = 128ms
      37. 35Sek Zählwert: 16856 = 526ms
      38. 36Sek Zählwert: 28671 = 895ms
      39. 37Sek Zählwert: 20442 = 638ms
      40. 38Sek Zählwert: 56505 = 1765ms
      41. 39Sek Zählwert: 27128 = 847ms
      42. 40Sek Zählwert: 15561 = 486ms
      43. 41Sek Zählwert: 33673 = 1052ms
      44. 42Sek Zählwert: 40313 = 1259ms
      45. 43Sek Zählwert: 37175 = 1161ms
      46. 44Sek Zählwert: 2534 = 79ms
      47. 45Sek Zählwert: 40761 = 1273ms
      48. 46Sek Zählwert: 30364 = 948ms
      49. 47Sek Zählwert: 44244 = 1382ms
      50. 48Sek Zählwert: 58060 = 1814ms
      51. 49Sek Zählwert: 50990 = 1593ms
      52. 50Sek Zählwert: 17053 = 532ms
      53. 51Sek Zählwert: 54548 = 1704ms
      54. 52Sek Zählwert: 44770 = 1399ms
      55. 53Sek Zählwert: 61254 = 1914ms
      56. 54Sek Zählwert: 3941 = 123ms
      57. 55Sek Zählwert: 64701 = 2021ms
      58. 56Sek Zählwert: 31746 = 992ms
      59. 57Sek Zählwert: 2443 = 76ms
      60. 58Sek Zählwert: 59714 = 1866ms
      61. 59Sek Zählwert: 9189 = 287ms
      Display All


      Jürgen
    • @DG7GJ

      Du hast Crystal = 2MHz eingestellt. Ist das Fuse "Clock / 8" bei dir gesetzt oder nicht? Und welches Quarz hast du jetzt dran?

      Ich vermute Arduino mit 16MHz quarz und /8 aktiviert ergibt 2MHz Systemtakt?
      Dann wäre das schon mal richtig.

      Der Timer1 bekommt dann 2MHz / Prescaler = 64, also 31250 Hz. (32µs)

      Bei 0,1s Puls müsste als Timer-Differenz = 3125 und bei 0,2s Puls ein Differenzwert = 6250 raus kommen.
      Timerüberlauf wäre dann nach 2,09s (65536*32µs).

      Wie sieht denn dein Eingangssignal aus? Achso, das Oszi ist abgeraucht.

      Vielleicht ein Frequenzgererator zur hand, der mal 0,1s Pulse im Abstand von 1s machen kann?
      So konnte man zumindest den Empfang prüfen.

      Mal davon abgesehen habe ich mal etwas weiter gedacht.

      Wie wäre es damit? Bezogen auf meinen vorherigen Post!

      BASCOM Source Code: Pseudocode

      1. $Crystal = 500000 ' Systemtakt 500kHz
      2. Config Timer0 = Timer , Prescale = 1024 ' 488,28 Hz Takt
      3. Compare0A = 244 - 1 ' alle 0,5s OC0A-Interrupt auslösen
      4. Config INT0 = Change
      5. On INT0 ISR_INT0_DCF
      6. On OC0A ISR_OC0A_OVF
      7. Enable INT0
      8. Enable OC0A
      9. Enable Interrupts
      10. Sub ISR_INT0_DCF()
      11. ' INT0-Pin Pegel abfragen
      12. If PinD.2 = 0 then ' Pin Low (Puls-Anfang)
      13. Timer0 = 0
      14. FlagHalfSecond = 0
      15. Else ' Pin High (Pulsende)
      16. tmrValue = Timer0 ' Zeitwert holen
      17. Select Case tmpValue
      18. Case 44 to 54 ' schmaler Puls (nominell 48.8 Takte), Logisch 0
      19. ' 0-Bit speichern oder in Byte schieben
      20. Case 88 to 107 ' breiter Puls (nominell 97.6 Takte), Logisch 1
      21. ' 1-Bit speichern bzw. in ein Byte schieben
      22. End Select
      23. End If
      24. Return
      25. Sub ISR_OC0A_OVF()
      26. If Flag = 0 then ' 1. Interrupt nach 0,5s abfangen
      27. FlagHalfSecond = 1
      28. Else ' auf 2. Interrupt nach 1s ohne Puls reagieren
      29. ' Hier ist jetzt der Fehlende Impuls erkannt.
      30. End If
      31. End Sub
      Display All
    • Mich wundert, dass bei dir überhaupt irgendetwas ausgegeben wird.
      Hiermit
      Ddrd = &B11111010 'definieren der verwendeten Ports ( 1 = ausgang; 0= eingang)
      setzt du den ICP Eingang auf Ausgang, sodass es dein DCF Empfänger wohl nicht schafft, den auf High zu bringen.
      Und Config PORTD = ... und DDRD= ... ist genau das gleiche.
      Um den PullUp einzuschalten müsstest du PORTD= ... schreiben.