CMOS-Dezimal-Counter- bzw. -Teiler-Kaskade in Bascom umsetzen

    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!

    • Zu wenig Code. Um die Fehler nachvollziehen zu können wäre der komplette Code nötig. So kann man nur raten. z.B.
      Wenn kein $regfile angegeben ist nimmt er den aus den Voreinstellungen (bei mir einen Tiny13) und wenn dieser keinen Port C hat gibt es auch kein Register DdrC und keine Portc Pins
      Ich hab Deinen Code mal in der alten Version gefriemelt. Dort machte es keine Fehler (außer das zwei waitms alleine ohne Zahl dort stehen)
      Portc = 0 schaltet alle Pins ab DDRC = 0 schaltet sie alle auf Eingang, so daß die in der Sectic gesetzten keine Auswirkung haben. Es muß vor der Pulsausgabe wieder auf Ausgang gesetzt werden 'DDRC = 31(255)'
      Dann sollte das 'End if nach den For.. Next stehen damit sie nur einmal gepulst werden.
      Wichtig ist das die Main mit eine Loop endet. Der jetzige Code würde nach den For Next mit der Tastanaus weitermachen bis er dann mit dem Return abgeschossen wird.
      Da das ganz weniger als eine halbe Sekunde braucht könnte das Pulsen auch in die Halbsec ausgelagert werden. Dann kann die Sectic nicht dazwischen funken. Es wäre ja blöd wenn ein Stundenwechsel genau dann passiert wenn gerade gepulst wird =O
      Damit nichts vielfach ausgeführt wird bietet sich die Aufwarm an z.B. für die Anodenspannung

      Source Code

      1. If warmzeit = 239 Then
      2. If aufwarm = 1 then ' Heizung ist an
      3. reset Portb.3 ' Anodenspannung ein
      4. aufwarm = 2 ' Röhren bereit
      5. end if
      6. End if
      ähnlich nach dem Pulsen Aufwarm = 3 ' Röhren fertig. So das nur gepulst wird wenn Aufwarm = 2 ist.
    • delatube wrote:

      Was schlägst Du zum jetzigen Zeitpunkt vor, was ich tun kann, um es sofort übersichtlicher zu machen? Ich überlege mir mal bzw. zeichne mir mal auf, was wie und wann im Ablauf geschehen soll. Gern bemühe ich mich um mehr Übersichtlichkeit, wenn ich dabei Hilfe bekomme.

      Zum Thema alias, da hatte ich gelesen, dass es in Subs Probleme geben kann, da die dort nicht erkannt werden? Bei PortC funktioniert das mit alias nicht oder ich müsste jeden Port einzeln mit einem alias verknüpfen, oder?
      Zuerst mal würde ich den Pins, die du als Eingang oder Ausgang benutzt einen zutreffenden Namen geben. Ein Prefix "pin" für den Namen macht klar, dass es sich bei der Bezeichnung um einen Pin handelt.

      Z.B.
      pinAnodenspannung Alias PortB.0

      Dann kannst du den Pin konfigurieren mit
      Config pinAnodenspannung=Output

      Setzen und Löschen des Ausgangs mit

      Set pinAnodenspannung ' bzw.
      Reset pinAnodenspannung

      Für den PortC könnte man auch ein Alias verwenden. Mann kann aber dann nur dem ganzen Port einen Wert zuweisen. Das Setzen/löschen einzelner Pins ist dann wieder unübersichtlich.

      Besser hier den einzelnen Pins auch ein Alias geben. Als Namen würden sich ja pinSec01, pinSec10, pinMin01, pinMin10, pinHour01 und pinHour10 anbieten.
      Dann weist du welcher Pin was macht.

      Mir ist unbekannt, dass ein Alias in Subs oder Unterprogrammen Probleme bereiten sollte. Bisher war das bei mir nie der Fall.

      Wichtig ist bei den Alias, dass die definiert sein müssen, bevor man die Bezeichnungen im Code verwendet.
      Und dann sollte man auch konsequent nur diese Bezeichnungen im Code verwenden und nicht wieder die Port.x und Pin.x Bezeichnungen.
      Nur so kannst du die Pins ohne große mühe später ändern oder bei anderen Controllern anpassen.

      In deinem Code verwendest du ja öfters (an mehreren Stellen) die Anweisung
      PortC = 0

      Hier würde ich eine Sub mit aussagefähigem Namen anlegen, in der dann die einzelnen Pins via Alias zurück gesetzt werden.
      Eine solche Routine könnte z.B. heißen "Sub ResetTube()"
      Anstelle der Anweisung

      PortC=0

      schreibst du dann ein Call ResetTube()

      In der Sub steht dann die Liste der zu löschenden Pins.

      BASCOM Source Code: Beispiel Sub

      1. ' Löscht alle Puls-Pins der Röhre
      2. Sub ResetTube()
      3. Reset pinSec01
      4. Reset pinSec10
      5. Reset pinMin01
      6. Reset pinMin10
      7. Reset pinHour01
      8. Reset pinHour10
      9. End Sub
    • Dann wird dem Avr nicht langweilig. :D Neben dem Haufen (unnötiger) Schreibarbeit hat er damit mehr als 8 mal mehr Arbeit als ein deutliches PortC = 0.
      Auch die Bezeichnung sorgt wirklich für Verwirrung: PortB.0 schaltet einen (Teil)Reset. Port C nur die Zählimpulse.
      @delatube gibt es auch einen Pin der alle Röhren zurücksetzen würde? Anodenspannung aus/an scheint mir da etwas grob/langsam ?
    • Es ging um die Programm-Übersichtlichkeit und nicht um Geschwindigkeits-Rekorde aufzustellen.

      Bei diesem Projekt ist es wurscht, ob die 6 Puls-Pins nun in 1µs oder in 8µs zurückgesetzt sind.
      Das bezieht sich nur auf den Fall, wenn man die Pins einzeln auf 0 setzt und nicht Port.x = 0 schreibt.

      Zudem kann man auch dem Port ein Name geben. Das hatte ich ja auch geschrieben (Post #62).

      Ob man nun den Pin (Set Portb.0) direkt setzt oder per Alias macht keinen Unterschied.
      Mit Alias ist es aber übersichtlicher. Gründe, die für den Alias sprechen, habe ich ja auch schon gegeben (Siehe Post #62).

      Aber es muss auch die Fraktion der Spaghetti-Code-Verfechter geben :P
    • Jetzt bin ich verwirrt und weiß nicht so recht, welchen Hinweisen hinsichtlich der Übersichtlichkeit ich nachgehen soll. Aber ja, mir fällt es schon zunehmend schwer, alles zu finden und zuzuordnen. Bei Euren Ideen zur Umsetzung werde ich sicherlich auch noch fragen haben.

      Ich werde mich mal dransetzen und den kompletten Code nach Euren Hinweisen durch zu arbeiten und die Erweiterungen einzubauen und dabei auch versuchen alles besser zu struturieren und zumindest aus meiner Sicht irgendwie übersichtlicher zu gestalten. Z.B. nach Funktionsgruppen oder Ablaufreihenfolge oder so. Die Alias-Namen würde ich versuchen dort einzusetzen, wo es für mich Sinn macht. Beim PortC bin ich dahingehend aber tatsächlich unsicher, ob ichs lasse oder so ändere. Dabei die Frage, wenn ich den gesamten PortC anspreche, ob das eigentlich Einfluss auf den Resetpin PortC6 hat?

      Pluto25 wrote:

      @delatube gibt es auch einen Pin der alle Röhren zurücksetzen würde? Anodenspannung aus/an scheint mir da etwas grob/langsam ?
      Nein, einen einzigen Pin als Reset für alle Röhren gibt es nicht. Das müsste ich auf der Platine Anpussungen vornehmen und Zähl- und Reseteingänge durch z.B. Dioden trennen und unabhängig von den Zählimpulsen machen.
    • Lasse dich bitte nicht konfus machen, bleibe realistisch. Realistisch bedeutet, Alles hat gleichzeitig und ohne Ausnahmen Vorteile und Nachteile.
      Es kommt immer nur auf die Betrachtung an, ob man dies als Vorteil oder Nachteil empfindet.
      Spargetticode kann es auch mit der Verwendung von Aliase sein, werden.
      Jedoch haben Aliase durchaus Vorteile wenn gute Namen gewählt werden. Dann ist das Programm zwar verständlicher, will man mal zwischendurch messen,
      muss man nachschauen an welchem Portpin die namentliche Bezeichnung liegt. Wird seltener vorkommen.

      Ich verwende gerne Aliasnamen, denn ich entwickle einiges auf einem gekauften Bord, was später auf einem anderen Bord funktionieren soll.
      Da definiere ich zb const entwicklungsbord = 1 und setze die zugehörigen Portpins etc mit Aliasnamen passend zu diesem Bord.
      Wird das später umgearbeitet auf das originale Bord, muss ich nur die Bordbezeichnung gültig machen, dann wird das Programm sachgerecht compliert.

      Wie Mitch es bereits angedeutet hat, soll man beim verwenden von Aliasen mit berücksichtigen, daran denken, ob es zum Zeitpunkt der Bearbeitung ein Port
      oder ein Pin sein soll, etc. Hat man sich an Aliase gewöhnt, wird das quasi zum Standart. Hilfreich sein kann auch das handschriftliche Zeichnen und eintragen
      von gewollter Programmbearbeitung in Kästchen mit Strichverbindungen zu den betroffenen Kästchen. Dann ist leichter erkennbar, was zu programieren ist, wohin
      Verzweigungen hinführen usw.
      Übernimmt man das ähnlich im Programmcode, wird das Programm übersichtlicher.
      Ist nur ein Vorschlag meinerseits. Darfst du egal wie realistisch betrachten, umsetzen.
    • Puhh und Hmpf. Ich stehe auf dem Schlauch. Habe mich dran gesetzt und versucht, den Ursprungscode mit den neuen Teilen zusammenzubringen und etwas mehr Nachvollziehbarkeit reinzubringen. Leider bekomme ich es nicht richtig hin. Den Uhr-Code habe ich ja irgendwie noch nachvollziehen und mir erklären können und halbwegs verstanden warum was wohin muss, damit es funzt. Aber bei den neuen zusätzlichen Teilen gelingt mir das irgendwie nicht, d.h. was machen die einzelnen Teile - die Main und die Taster-Sub An/Aus Heiz- und Anodenspannung und die Sub Refreshz - für sich und im Zusammenspiel und was muss wo genau hin? Ich verliere hier den Überblick gar nicht mal so sehr wegen des Codes, sondern eher weil mir das Wissen fehlt, es nachzuvollziehen und dann korrekt u.a. auch die Code-Ideen und vielen kleinen Hinweise von Pluto25 einzubauen.

      Ich poste hier einfach mal den leider unvollständigen und sicherlich fehlerhaften Code nach aktuellem Stand mit Bitte um Korrektur um das Ding zum Laufen zu bekommen.

      P.S.: Naheliegend wäre auch, wenn nach der Inbetriebnahme sowohl die Anodenspannung und die Pulse auch erst nach 3-4 Minuten eingeschaltet werden ähnlich wie nach dem "Aufwecken" der Röhren/der Schaltung nach einem Unterbrechen der Heiz- und Anodenspannung per Tastendruck.

      Danke und guten Abend erstmal. Code folgt nach.
    • Der Code.

      Source Code

      1. $regfile = "m8def.dat"
      2. $crystal = 1000000
      3. $swstack = 64
      4. $hwstack = 64
      5. $framesize = 64
      6. Config Clock = Soft , Gosub = Sectic 'Clock-Modus, externer Quarz 32Khz wird genutzt
      7. On Oc2 Halbsec '500ms-Pulse an Outputs
      8. Enable Oc2
      9. Ocr2 = 128 'bestimmt das Tastverhältnis
      10. Config Timer2 = Timer , Prescale = 128 'Initialisierung Timer2
      11. Dim S , Sz , Me , Mz , He, Hz As Byte 'Variablen Sekunden, Minuten, Stunden (0 bis 24)
      12. Dim warte as byte 'Für Delay Start Timer2 nach Tastendruck Stellen/Reset
      13. Dim A as byte 'Zählvariable bestimmen
      14. Dim Aufwaerm as Byte 'Flag zum Röhrenstaus
      15. Dim Warmzeit as byte 'Zeiten der Aufwärmphasen
      16. Enable Interrupts
      17. '*** Ein/Ausgänge deklarieren **************************************************
      18. 'Pulse Set/Reset für Röhren
      19. Pinresethour10 Alias Portb.0 'Resetpuls für Stunden10er Schaltung
      20. Config Pinresethour10 = Output
      21. Config Portc = Output 'C.0 = Sek. ... C.5 = Stundenzehner
      22. 'Taster Stellen und Reset der Uhr
      23. Config Portd.0 = Input 'Sekundentaster
      24. Pind.0 = 1 'Pullup einschalten
      25. Config Portd.1 = Input 'Minutentaster
      26. Pind.1 = 1 'Pullup einschalten
      27. Config Portd.2 = Input 'Stundentaster
      28. Pind.2 = 1 'Pullup einschalten
      29. Config Portd.3 = Input 'Resettaster (alle Röhren auf 0)
      30. Pind.3 = 1 'Pullup einschalten
      31. 'An/Aus Heiz- und Anodenspannung (Röhrensafer)
      32. Pintastonoff Alias Pinb.1
      33. Config Pintastonoff = Input 'Taster An/Aus Röhren
      34. Pintastonoff = 1 'Pullup einschalten
      35. pinAnodenspannung alias Portb.2
      36. Config Pinanodenspannung = Output 'Anodenspannung An/Aus
      37. pinHeizung alias Portb.3
      38. Config Pinheizung = Output 'Heizung An/Aus
      39. '*** Hauptschleife *************************************************************
      40. Do
      41. Debounce Pind.0 , 0 , Tastsec1 , Sub 'Debounce Taster, Sprung Sub Einstellen Sekunden
      42. Debounce Pind.1 , 0 , Tastsec2 , Sub 'Debounce Taster, Sprung Sub Einstellen Minuten
      43. Debounce Pind.2 , 0 , Tastsec3 , Sub 'Debounce Taster, Sprung Sub Einstellen Stunden
      44. Debounce Pind.3 , 0 , Tastsec4 , Sub 'Debounce Taster, Sprung Sub Resetpuls alle Ausgänge
      45. Debounce Pintastonoff , 0 , Tastanaus , Sub 'Debounce Taster, Sprung Sub Delay Heiz- und Anodenspannung
      46. 'An/Aus Heiz- und Anodenspannung (Röhrensafer)
      47. If Warmzeit = 240 Then '4 Minuten nach dem Wiedereinschalten
      48. Reset Pinanodenspannung 'Anodenspannung an
      49. If Warmzeit = 220 Then '3,5 Minuten nach dem Wiedereinschalten
      50. Reset Pinheizung 'Heizung an
      51. End If
      52. 'Erzeugung einer Pause (3s) nach Betätigen eines Tasters
      53. If Warte >= 1 Then 'Start Timer2 3 Sek. nach letztem Tastendruck
      54. Decr Warte '30 in Tastsec wird runtergezählt
      55. If Warte = 0 Then Start Timer2 'wenn O dann Start Timer2
      56. End If
      57. Waitms 100 '30x100ms ergibt dann die 3 Sekunden
      58. Loop
      59. End
      60. '*** Subs **********************************************************************
      61. 'Sub für Erzeugung und Ausgabe Zähl- und Resetpulse für die Röhren
      62. Sectic:
      63. Incr Warmzeit 'Timer für Aufwärmzeit
      64. Set Portc.0 'jede Sec. (Takt S1)
      65. Incr S
      66. If S >= 10 Then
      67. S = 0
      68. Set Portc.1 'alle 10s (Takt S10, Reset S1)
      69. Incr Sz
      70. If Sz >= 6 Then
      71. Sz = 0
      72. Set Portc.2 'alle 60s (jede Min) (Takt M1, Reset S10)
      73. Incr Me
      74. If Me >= 10 Then
      75. Me = 0
      76. Set Portc.3 'alle 10m (Takt M10, Reset M1)
      77. Incr Mz
      78. If Mz >= 6 Then
      79. Mz = 0
      80. Set Portc.4 'alle 60m (jede Stunde) (Takt H1, Reset M10)
      81. Incr He
      82. If He = 10 Then Portc.5 = 1 '10h
      83. Incr Hz
      84. If He = 20 Then Portc.5 = 1 '20h
      85. Incr Hz
      86. If He >= 24 Then
      87. He = 0
      88. Hz = 0
      89. Set Pinresethour10 'Reset H10 (23.59)
      90. Set Portc.5 'Reset H1
      91. End If
      92. End If
      93. End If
      94. End If
      95. End If
      96. Return
      97. 'Sub Refresh der Anzeige nach Aufwachen
      98. For A = 0 To S 'für die 1er-Sekundenröhre
      99. Set Portc.0
      100. Waitms 1
      101. reset portc.0
      102. waitms 1
      103. next
      104. For A = 0 To Sz 'für die 10er-Sekundenröhre
      105. Set Portc.1
      106. Waitms 1
      107. Reset Portc.1
      108. Waitms 1
      109. Next
      110. For A = 0 To Me 'für die 1er-Minutenröhre
      111. Set Portc.2
      112. waitms 1
      113. reset portc.2
      114. waitms 1
      115. next
      116. For A = 0 To Mz 'für die 10er-Miuntenröhre
      117. Set Portc.3
      118. Waitms 1
      119. Reset Portc.3
      120. Waitms 1
      121. Next
      122. For A = 0 To He 'für die 1er-Stundenröhre
      123. Set Portc.4
      124. Waitms 1
      125. Reset Portc.4
      126. Waitms 1
      127. Next
      128. For A = 0 To Hz 'für die 10er-Stundenröhre
      129. Set Portc.5
      130. Waitms 1
      131. Reset Portc.5
      132. Waitms 1
      133. Next
      134. 'Sub für Dauer der einzelnen Pulse (High-Low 500ms)
      135. Halbsec: 'Puls 1 Hz (500ms)
      136. Reset Pinresethour10
      137. Portc = 0
      138. Return
      139. 'Sub für Einstelltaster Stellen der Uhr und Reset alle Röhren
      140. Tastsec1: 'Bei Tastendruck
      141. Stop Timer2 'Das stoppt die Uhr.
      142. Set Portc.0 'Stellt die Sekunden
      143. Incr S
      144. If S >= 10 Then
      145. S = 0
      146. Set Portc.1
      147. Incr Sz
      148. If Sz >= 6 Then Sz = 0
      149. End If
      150. Waitms 200
      151. Portc = 0
      152. Warte = 30 '3 Sekunden warten bis Restart Timer2
      153. Return
      154. Tastsec2: 'Bei Tastendruck
      155. Stop Timer2 'Das stoppt die Uhr.
      156. Set Portc.2 'Stellt die Minuten
      157. Incr Me
      158. If Me >= 10 Then
      159. Me = 0
      160. Set Portc.3
      161. Incr Mz
      162. If Mz >= 6 Then Mz = 0
      163. End If
      164. Waitms 200
      165. Portc = 0
      166. Warte = 30 '3 Sekunden warten bis Restart Timer2
      167. Return
      168. Tastsec3: 'Das stoppt die Uhr.
      169. Stop Timer2 'Stellt die Stunden
      170. Set Portc.4
      171. Incr He
      172. If He = 10 Then Portc.5 = 1
      173. If He = 20 Then Portc.5 = 1
      174. If He >= 24 Then
      175. He = 0
      176. Set Pinresethour10
      177. Set Portc.5
      178. End If
      179. Waitms 200
      180. Portc = 0
      181. Pinresethour10 = 0
      182. Warte = 30 '3 Sekunden warten bis Restart Timer2
      183. Return
      184. Tastsec4: 'Bei Tastendruck
      185. Stop Timer2 'Das stoppt die Uhr.
      186. Set Pinresethour10
      187. Portc = &B00111111
      188. Waitms 200 'Highpuls an allen Outputs als Resetpuls für Zählschaltung
      189. Portc = 0
      190. Pinresethour10 = 0
      191. Warte = 30 '3 Sekunden warten bis Restart Timer2
      192. Return
      193. 'Sub Taster für An/Aus Heiz- und Anodenspannung (Röhrensafer, High=Aus)
      194. Tastanaus:
      195. If Pintastonoff = 0 Then 'Röhren sind an
      196. Ddrc = 0 'Ausgangspulse abschalten
      197. 'Pinresethour10 = 'Resetpuls abschalten -> was ist damit?
      198. Set Pinanodenspannung 'Anodenspannung aus (High=Aus)
      199. Set Pinheizung 'Heizung aus (High=Aus)
      200. Aufwaerm = 0 'Röhren abgeschaltet
      201. Else
      202. Reset Pinheizung 'Heizung an
      203. Aufwaerm = 1 'Vorheizen
      204. 'Ddrc = 1? 'Ausgangspulse anschalten
      205. 'Pinresthour10 = 'Resetpuls anschalten -> was ist damit?
      206. End If
      207. Return
      Display All
    • Sieht doch soweit recht gut aus. :)
      Nur eine Fehlermeldung :thumbup: in den if Warmzeit...
      ich habs mal so geändert

      Source Code

      1. If Warmzeit = 220 Then '3,5 Minuten nach dem Wiedereinschalten
      2. Reset Pinanodenspannung 'Anodenspannung an
      3. End If
      4. If Warmzeit = 240 Then
      5. DDRC = 31 'Ausgänge aktivieren
      6. Gosub Refresh 'Richtige Zeit pulsen
      7. End If
      Unklar ob die Anodenspannung wirklich 20 Sekunden anliegen muß bevor gepulst wird?

      Unter Übersichtlichkeit versteht hier jeder etwas anderes. Wichtig ist das es für Dich verständlich ist.
      Der Simulator eignet sich gut nach zu vollziehen was der Code macht.

      Die Main ist der Hauptbestandteil des Codes. In ihr werden alle Entscheidungen getroffen; sie 'mainagt' das Ganze ;)

      PS die Sub Refreshz muß auch als solche benannt werden 'Refreshz: ... Return' .
      Außerhalb der Main sollten keine Befehle alleine stehen, die würden nie ausgeführt.

      Beim Start (vor der Main könnte) die Tastanaus aufgerufen werden. Sie startet dann die Heizung und das Warten . Allerdings ist dann 00:04:00 , solange die Zeit nicht von woanders eingegangen ist (Rtc)

      delatube wrote:

      'Ddrc = 1? 'Ausgangspulse anschalten
      'Pinresthour10 = 'Resetpuls anschalten -> was ist damit?
      DdrC = 1 würde nur ein Portc.0 als Ausgang freigeben,
      Pinresthour10 braucht da nicht beachtet werden, er wurde nicht abgeschaltet und die Zehner Röhre ist sowieso 0

      Müsste der abgeschaltet werden? Schadet es der Schaltung wenn dort ein Puls auftritt solange sie keine Spannung hat? (Reset DdrB.0)

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

    • Okay, dankeschön fürs Durchsehen und ja, denke auch, die Übersichtlichkeit ist erstmal die, mit der ich selbst gut zurecht komme und die mir hilft. Ich habe da für das Projekt einen Zwischenweg genommen.

      Ich schau mir alles mal an und ändere es entsprechend. Dazu habe ich aber Fragen:

      Woher weißt Du, dass 'ddrc=31' den Port wieder einschaltet, also woher kommt die 31? Habe im Datenblatt und der Hilfe geschaut, konnte aber nichts finden.

      Warum sollten die Ausgänge auf Eingang (und nicht einfach ab-) geschaltet werden? Der Schaltung schadet es zumindest nicht, wenn Pulse auftreten obwohl die Röhren keine Anoden- und/oder Heizspannung haben. Die gehen einfach verloren. Wie könnten sich denn die Pulse aus Sectic und Refreh gegenseitig stören?

      Was hat es mit der Variablen Aufwaerm auf sich? Die kommt ja nur in der Sub Tastanaus vor und sonst nirgends. Was kann man mit der machen? In Deinem Beitrag #61 ist dazu ein Codeschnipsel, den ich aber offensichtlich gar nicht beachtet habe. Fehlt der noch? Das verwirrt mich...

      Könntest Du das bitte nochmal erklären zusammen auch mit den Hinweisen in Deinem Beitrag #61? Da bringst Du ein 'Aufwaerm =3' ins Spiel.
    • delatube wrote:

      Woher weißt Du, dass 'ddrc=31' den Port wieder einschaltet, also woher kommt die 31? Habe im Datenblatt und der Hilfe geschaut, konnte aber nichts finden.
      Da sind wir wieder bei der Übersichtlichkeit des Programms

      Anstatt DDRC = 31 ' (dezimal)
      wäre Hex oder binäre Schreibweise deutlicher gewesen.

      DDRC = &h1F ' (hex)
      DDRC = &b0001_1111 ' (binär), da sieht man die einzelnen Bits

      Gemeint damit sind die Bits am Port C, die als Ausgang (1) geschaltet werden sollen.

      Dabei fällt mir auf, dass der Wert offensichtlich falsch ist. Am Port C sind 6 Puls-Pins, die gesetzt oder gelöscht werden müssen.

      Genaus so schleichen sich Fehler ein, die man dann mühsam sucht, weil für den Compiler ist das ok.

      Richtig müsste es wohl eher
      DDRC = &b0011_1111 ' bzw.
      DDRC = &b0000_0000
      heißen.

      Aber es ist Vorsicht geboten.
      Wenn nämlich der Controller oder der Port gewechselt wird. Wenn dann dort alle 8 Pins verwendet werden. Dann könnte das so Probleme machen.
      Besser nur die Pins schalten, die auch tatsächlich geschaltet werden sollen, und nicht der ganze Port. Die anderen Pins sollte man unverändert lassen.

      Über eine Routine, wie ich es in Post #62 vorgeschlagen habe, wäre das auch bei Port oder Controller-Wechsel kein Problem.
      Zwar mehr schreibarbeit, dafür sicherer. Was für einen Anfänger sicherlich ein Vorteil ist.

      Fehlersuchen geht länger als etwas mehr schreiben.

      Soviel zur Übersicht und Lesbarkeit des Programms.

      Alternativ gibt es auch noch die Befehle Bits() und NBits().
      Damit können die Pins auch geschaltet werden.

      z.B.
      PortC = Bits(pinSec01, pinSec10, pinMin01, pinMin10, pinStd01, pinStd10) ' hier werden die benötigten an, die anderen ausgeschaltet.

      Besser:
      PortC = PortC Or Bits(pinSec01, pinSec10, pinMin01, pinMin10, pinStd01, pinStd10) ' hier werden wirklich nur die benötigten Pins eingeschaltet.

      Beim Abschalten muss man mit NBits und And verfahren.
    • delatube wrote:

      Warum sollten die Ausgänge auf Eingang (und nicht einfach ab-) geschaltet werden?
      Das auf Eingang schalten ist einfacher. Andernfalls müsste die Sectic prüfen ob er in der Aufwärmphase ist
      und solange die Ausgänge nicht schalten. Würden sie einfach weiterpulsen wird es beim wachwerden der Röhren zu Unklarheiten kommen: Ab wann zählt sie wirklich ? 0,1 Sekunden nachdem die Anodenspannung geschaltet wurde oder erst 2 Sekunden später? Wenn die Pins erst vor dem Refreshz auf Ausgang gesetzt werden kann da keine vorher Zählen.

      Das Aufwarm ist dazu gedacht das die Main weis in welcher Phase der Aufwärmvorgang sich befindet. Damit sie nichts doppelt ausführt. Bei der Anodenspannung ist das noch egal: 'anner' als an wird die nicht. :D Aber das Pulsen darf nicht mehrfach passieren. =O
      Es könnte in der Main z.B. als Select Case verwendet werden:

      Source Code

      1. Vor der Main:
      2. Pinanodenspannung Alias Portb.2
      3. Set Pinanodenspannung 'Wichtig Anodenspannung Aus
      4. Config Pinanodenspannung = Output 'Anodenspannung An/Aus
      5. Pinheizung Alias Portb.3
      6. Config Pinheizung = Output 'Heizung An
      7. Aufwarm = 1 'Vorheizen
      8. Warmzeit = 0
      9. ...
      10. 'In der Main:
      11. Case Select Aufwarm
      12. 'Case Is = 0 'Röhren sind aus
      13. Case Is = 1 'Heizung ist an, warte bis
      14. If Warmzeit = 220 Then '3,5 Minuten nach dem Wiedereinschalten
      15. Reset Pinanodenspannung 'Anodenspannung an
      16. Aufwarm = 2
      17. End If
      18. Case Is = 2 'Heizung und Spannung sind an, warte bis
      19. If Warmzeit = 240 Then '4 Minuten nach dem Wiedereinschalten
      20. Do 'Warte auf Halbsec
      21. If Tccr2 = 0 Then Exit Do 'Nicht falls der Timer steht
      22. Loop Until Timer2 > Ocr2
      23. Ddrc = $3f 'Ausgänge aktivieren
      24. Gosub Refresh 'Richtige Zeit pulsen
      25. Aufwarm = 3 'Röhren in Betrieb
      26. End If
      27. End Select
      Display All

      Das Tccr2 besagt in welchen Zustand der Timer2 ist. Ein 'If Timer2 = gestoppt' kennt Bascom nicht. :D
      Diese Abfrage ist wichtig, denn bei ungünstigen Tastendruck könnte der Timer stehen und dann würde die Loop nie aufhören. (ohne Watchdog)

      Mitch64 wrote:

      dass der Wert offensichtlich falsch ist. Am Port C sind 6 Puls-Pins
      Klar, die Uhrzeit hat auch 6 Röhren nicht 5 a_45_132ca9f5 daher 63 nicht 31.
      Der Port ist glücklich gewählt Bit 6 und 7 sind nicht vorhanden. Daher ist es einfach den gesamten Port zu schalten DDRC=0 oder 255 ohne Komplikationen zu erwachten. In dem Fall würde das auch mit PortB gehen da seine 6 und 7 vom Quarz belegt sind. (sollten die Röhren daran hängen)

      @ Delatube, ist die Platine schon fertig? Anderenfalls wäre es wirklich eine Überlegung wert die Röhren mit dem Port B zu Pulsen. Dann würden C4 und C5 frei um eine I2C-RTC dran zu hängen.

      Der Probelauf zeigte ein Problem in der Tastanaus (der Pin ist dann immer 0) Vielleicht so:


      Source Code

      1. Tastanaus:
      2. If Aufwarm = 0 Then 'Röhren sind aus
      3. Reset Pinheizung 'Heizung an
      4. Aufwarm = 1 'Vorheizen
      5. Warmzeit = 0 'ohne dem ist der Warmzeit irgendwas
      6. Else
      7. Ddrc = 0 'Ausgangspulse abschalten
      8. Set Pinanodenspannung 'Anodenspannung aus (High=Aus)
      9. Set Pinheizung 'Heizung aus (High=Aus)
      10. Aufwarm = 0 'Röhren abgeschaltet
      11. End If
      12. Return
      Display All
      So kann zwar der Aufheizvorgang abgebrochen werden jedoch hat man keine Kontrolle über dem Zustand falls er mehrfach gedrückt wird (in den ersten 4 Minuten) Vielleicht eine Led? Schalter? Zweiter Taster?

      The post was edited 2 times, last by Pluto25 ().

    • Pluto25 wrote:

      Ab wann zählt sie wirklich ? 0,1 Sekunden nachdem die Anodenspannung geschaltet wurde oder erst 2 Sekunden später?
      Soweit ich es beurteilen kann, zählt die Röhre wenn sie gut aufgewärmt ist, nahezu sofort.

      Pluto25 wrote:

      Es könnte in der Main z.B. als Select Case verwendet werden:
      Dann baue ich das im Code entsprechend um und ein.

      Pluto25 wrote:

      @ Delatube, ist die Platine schon fertig? Anderenfalls wäre es wirklich eine Überlegung wert die Röhren mit dem Port B zu Pulsen. Dann würden C4 und C5 frei um eine I2C-RTC dran zu hängen.
      Die Platine ist soweit eigentlich fertig, da als Projekt aktuell auf Lochraster, sind kleine Änderungen zwar möglich, aber der Platz zum Verschieben usw. ist dennoch begrenzt. Was konkret hätte die I2C-RTC für einen Vorteil für die Schaltung/Anwendung?

      Pluto25 wrote:

      So kann zwar der Aufheizvorgang abgebrochen werden jedoch hat man keine Kontrolle über dem Zustand falls er mehrfach gedrückt wird (in den ersten 4 Minuten) Vielleicht eine Led? Schalter? Zweiter Taster?
      Ohh, okay. D.h. heißt also, der Taster schaltet ab und bei nochmaligem Drücken wieder an (Aufheizen -> Anodenspannung -> Refresh) aber es ist unklar, was passiert wenn ich ihn genau in der Aufwärmzeit nochmals drücke? Einen weiteren Taster würde ich mir gern sparen. Es sind ja jetzt schon 5 (Stellen S, M, H, Reset, Tastanaus). Wir würde das ganze mit Schalter aussehen müssen? Der Code könnte dann so bleiben, oder?
      Mir lieber wäre es mit Taster. Wäre es hier als Kompromiss möglich (und wenn wie? Vielleicht den entsprechenden Pin auf Ausgang schalten solange Warmzeit läuft?) den Taster solange zu sperren wie der Aufheizvorgang läuft bzw. der Refresh gelaufen ist und erst wenn das alles abgeschlossen ist wieder frei zu geben? Klar, es ist nicht super nutzerfreundlich und man müsste dann immer warten, aber ich finde das klarer und sicherer als das irgendwas unvorhergesehenes passiert. Oder?
    • delatube wrote:

      zählt die Röhre wenn sie gut aufgewärmt ist, nahezu sofort.
      sind 100ms? Dann könnte die Anodenspannung (nach einem Halbsec) 100ms vor dem Refresh eingeschaltet werden. Vom Timing kann das klappen: Das Refresh braucht <100ms maximal. Nach dem Halbsec dauert es eine knappe halbe Sekunde (oder länger wenn OCR2 kleiner würde) bis der nächste Puls kommt. Dann könnten die Ausgänge aktiv bleiben. Dennoch ein mulmiges Gefühl eine spanungslosen Schaltung mit der vollen Kraft eines/mehrere Ausgang an zu steuern <X

      delatube wrote:

      was passiert wenn ich ihn genau in der Aufwärmzeit nochmals drücke?
      wenns nur einmal ist schaltet er wieder ab, beim nächsten mal beginnt der Aufheizvorgang von vorn, schlecht nur wenn die Anzahl unbekannt ist (Vertippt, Katze ...)

      delatube wrote:

      Pin auf Ausgang schalten solange Warmzeit läuft?)
      Das geht nicht: der Taster würde den Ausgang kurzschliessen X( aber die Tastanaus würde trotzdem ausgeführt. Blockieren bzw eine Reaktion verhindern geht: einfach das else durch elseif Auwarm=3 then ersetzen. Dann prüft er vor dem Ausschalten ob sie wirklich durchgestartet sind.
      Ein Schalter hätte eine erkennbare Stellung.
      Eine weiteren Pin schalten würde auch gehen. Die Röhrenheizung wird ja schon geschaltet, die könnte z.B. zwei Glimmlämpchen zwischen Stunden/Minuten und Minuten/Sekunden schalten?
      Eine Rtc könnte die Zeit behalten, solange er abgeschaltet ist. Nützlich bei Stromausfall.
    • ...hauptsächlich aber nicht nur @Pluto25: Weitere Fragen heute mit Bitte um Hilfe sowie Antworten. Das Zusammenbauen des Codes mit den vielen neuen Schnipseln fällt mir schwer...

      Pluto25 wrote:

      sind 100ms? Dann könnte die Anodenspannung (nach einem Halbsec) 100ms vor dem Refresh eingeschaltet werden.
      Denke ja, das sollte passen. Wie sähe das Einschalten dann aus?

      Pluto25 wrote:

      Der Probelauf zeigte ein Problem in der Tastanaus (der Pin ist dann immer 0) Vielleicht so:
      Ein Verständnisfrage zum Taster 'PinTastonoff' und zur Sub 'Tastanaus'. Ich kann nicht nachvollziehen, das der Pin in Deinem neuen Code (siehe nachfolgend) nicht mehr direkt abgefragt wird a la "If pinTastonoff ...then". Der Taster taucht ja gar nicht mehr als Alias oder als Portpin in der Tastanaus-Sub oder irgendwo anders auf außer oben in der Deklaration. Was sehe ich hier oder verstehe ich da nicht?

      Source Code

      1. Tastanaus:
      2. If Aufwarm = 0 Then 'Röhren sind aus
      3. Reset Pinheizung 'Heizung an
      4. Aufwarm = 1 'Vorheizen
      5. Warmzeit = 0 'ohne dem ist der Warmzeit irgendwas
      6. Else
      7. Ddrc = 0 'Ausgangspulse abschalten
      8. Set Pinanodenspannung 'Anodenspannung aus (High=Aus)
      9. Set Pinheizung 'Heizung aus (High=Aus)
      10. Aufwarm = 0 'Röhren abgeschaltet
      11. End If
      12. Return
      Display All

      Pluto25 wrote:

      Dennoch ein mulmiges Gefühl eine spanungslosen Schaltung mit der vollen Kraft eines/mehrere Ausgang an zu steuern
      Vielleicht sehe ich die Gründe für Deine Bedenken nicht, aber die Schaltung und auch die Röhren sind robust. Warum spannungslos? Die Anodenspannung wird doch jetzt immer vor irgendeinem Pulsen, egalt ob aus der Sub Sectic oder Refresh eingeschaltet (und wenn die Röhren aufgeheizt sind), oder?

      Pluto25 wrote:

      wenns nur einmal ist schaltet er wieder ab, beim nächsten mal beginnt der Aufheizvorgang von vorn, schlecht nur wenn die Anzahl unbekannt ist (Vertippt, Katze ...)
      Ob die Röhren heizen oder nicht ist nach einigen Sekunden erkennbar am Glimmen der Kathodenheizung innerhalb der Röhre. Das ist eigentich ein guter Marker. Ggf. wäre aber auch eine LED interessant, die solange rot ist bis der Aufheizvorgang abgeschlossen ist.

      Pluto25 wrote:

      Eine Rtc könnte die Zeit behalten, solange er abgeschaltet ist. Nützlich bei Stromausfall
      Diese Option ist interessant, möchte ich aber gern erstmal zurückstellen bis alles andere funktioniert.

      The post was edited 2 times, last by delatube ().

    • delatube wrote:

      Was sehe ich hier .... nicht?
      Das er zum Debonce genutzt wird: Zeile 50: Debounce Pintastonoff , 0 , Tastanaus , Sub
      Und die ruft immer die Tastanaus auf sobald der 0 wird. Innerhalb der Tastanaus muß klar sein ob sie an oder ausschalten soll nicht ob der Taster noch gedrückt gehalten ist. Man müsste auch superschnell wieder loslassen damit er zu dem Zeitpunkt wieder 1 wäre a_38_b45e201d
      Wenn die Schaltung und der AVR überleben ist es egal ob mir mulmig ist :D Wichtig, das Du beim arbeiten an der Röhrenschaltung bedenkst das da noch ein AVR lebt der keinen Kurzschluss oder Fremdspannung bekommen sollte.
      Eine Led in einer Röhrenschaltung ?( Dat jeht ga nich :D


      delatube wrote:

      gern erstmal zurückstellen
      Erscheint mir auch sinnvoll. Jedoch ist noch viel Flash frei und irgendwas fällt einem immer ein. Dann ist es einfacher wenn die Pins, die man brauchen würde, noch gut erreichbar sind. z.B auch D0 und D1. Die gehören zum Usart, falls er sich die Zeit aus dem Internet holen soll oder Bluetooth braucht. :D
      Oder sich die GPS Zeit holt: Insanity hat eben im Nachbarthreat eine Möglichkeit vorgestellt :thumbup:

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

    • Pluto25 wrote:

      Das er zum Debonce genutzt wird: Zeile 50:
      Danke, das leuchtet ein und habe ich einfach übersehen die Beziehung und Funktion von Debounce und der Sub.

      Pluto25 wrote:

      Wenn die Schaltung und der AVR überleben ist es egal ob mir mulmig ist Wichtig, das Du beim arbeiten an der Röhrenschaltung bedenkst das da noch ein AVR lebt der keinen Kurzschluss oder Fremdspannung bekommen sollte.
      Eine Überlegung wäre es, die Ausgänge nach dem Atmega bevor es in die Schaltung geht mit Dioden abzublocken, so dass keine (positive) Fremdspannung zum mC kommen könnte, im Fall der Fälle.

      Pluto25 wrote:

      Eine Led in einer Röhrenschaltung Dat jeht ga nich
      Ja, sichtbares Silizium einzubauen, dazu müsste ich mich wirklich selbst überreden, aber wenn das hinten bei der entsprechenden Taste wäre als zeitweises Signal, könnte ich damit leben.

      Dann baue ich den Code und die Hardware der Platine mal zurecht und werde berichten.

      By the way. Gibt es eine gute Anleitung zum Benutzen des Simulators in Bascom AVR? Ich komme mit den Funktionen und Möglichkeiten nicht klar.
    • Da gibt die Hilfe nicht viel her. Ich hab wild drauflos getippt und irgendwann ergab sich der Sinn/die Funktion.
      Ich nutze den vierten Button (neben Start, Pause und Stop) Einzelschritt sehr oft. Eigentlich immer den (missverständliche) 'LED'. Der öffnet eine weiteres Fenster in dem alle Port-pins dargestellt werden.
      Eine real Hardware habe ich nicht, Die Register sind in dem Fall kaum interessant, die I/O schon eher.
      (In TCCR2 könnte die 5 gegen eine 2 getauscht werden dann läuft der timer2 schneller) Der Memory ist hier auch weniger interessant. Wichtig ist der refresh Button (das 'Papier' mit der Hand) sonst ändern sich die angezeigten Pins nicht. Auch nicht die Variablen (die man in den gelben Feldern eingeben kann)
      Das Terminal ist nützlich wenn der Simmulator einen Externen Usard ansprechen soll; wird gerade nicht gebraucht. Das Sim Timers wiederum muß angeklickt sein damit der die Timer beachtet. Leider fehlt ihm die Unterstützung des OC2 ;( Heißt dass das Halbsec per Hand (über Interrupts / OC2) aufgerufen werden muß.
      Locals gibts hier keine, die uP Reg sind zur Zeit auch nicht von Bedeutung. Das Watch auch eher nicht. Es ist nützlich wenn eine Variable "plötzlich" einen falschen Wert annimmt. Damit kann die Stelle im Code gefunden werden die sie vermasselt. Bei dem kurzen übersichtlichen Code auch eher nicht nötig.

      Auch sehr nützlich sind Breakpoints. Die können gesetzt werden in dem man auf den gelben Punkt vor einer Zeile klickt und dann F9. Damit läuft das Programm solange durch bis es diese Zeile erreicht.

      Der Simulator kann den Code nicht beschädigen. Von daher ruhig austoben. Das meiste erklärt sich von allein.
      Falls er scheinbar nichts macht: Unten steht ob er läuft oder Pause macht. z.B. Waits brauchen viele tausende Operationen die er alle ausführt, was echt lange brauchen kann. (Während der Simulation habe ich das Waitms 100 auskommentiert)