Notaussteuerung die zweite

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

    • Notaussteuerung die zweite

      Hallo,
      nachdem unsere Notaussteuerung funktioniert,haben unsere Lokführer ein neues Problem.
      Wenn man jetzt im Winter die Diesellok warmlaufen lassen möchte,muss der Lokführer auf der Lok bleiben
      da ja die SiFa anspricht.Habe dann das Programm geändert das beim Start "Stop Timer" aufgerufen wird.
      Habe dann einen Kontakt installiert der beim Gang einlegen den Timer mit "Start Timer" startet.
      Funktioniert auch.Die Lokführer haben nun die Idee,den vom Tacho vorhandenen Impuls auszuwerten
      und die Schaltung erkennt wann der Zug fährt.Also : Zug fährt start Timer Zug hält stop Timer selbstständig
      Es besteht die Möglichkeit über mysetting im Timer was zu schalten aber da komm ich nicht hinter.
      Hat einer eine Idee ?
      Files
    • Hallo,bin jetzt auf den Befehl Pulsein gestossen.
      Wie wird der Eingangspin definiert ?
      Wird das über Config gemacht ?
      Wenn kein Impuls anliegt so ich das verstanden habe, läuft ein err-Flag voll den man abfragen kann.

      Also:
      Port difinieren Pulsein W , Pind ,6 , 0
      Varable Dim w as word

      in der Schleife
      If W=1 then
      stop Timer1
      else
      start Timer1
      end if

      so erst mal meine Idee

      Gruß
      Jürgen
    • Wenn man dein Programm anschaut, dann fällt auf, dass diverse Waits dafür sorgen, dass Zeiten eingehalten werden.
      Sei dir bewusst, dass in der Zeit nichts sonst passiert, außer dass der Timer dazwischenfunkt und die Waits verzögert.
      Wenn z.B. Nottastelok betätigt wird, dann wartet dein Programm 1 Minute und 15 Sekunden um den Abmagnet auszuschalten und nach weiteren 40 Sekunden das Dieselventil zu schließen.
      In der Zeit schaffe ich selber schon als Spaziergänger 100 Meter.

      Nottaste ist Nottaste, das heißt sofortiger Stop.

      Um verschiedene Verzögerungen bei deinem Programm zu erreichen kannst du es ähnlich wie bei deiner Sekunden-Variable machen.
      Ein Ereigniss füllt eine Variable.
      Tritt das Ereignis mehrfach ein, wird die Variable wieder auf den Wert gesetzt.
      Ist die Variable Null, dann gibt es eine Aktion.
      Die Variable wird im Timer heruntergezählt, wenn größer Null.

      Vorteil: du brauchst keine Wait und kannst nebenher schnellstmöglich auf einen Notaus reagieren.

      mysetting im Timer sorgt nur für andere Timereinstellungen.
      Der Befehl Pulsin wartet 65ms auf einen Puls und das Programm läuft dann einfach weiter.
      Nimmt man, um die Pulsbreite zu bekommen, z.B. bei Servobefehlen.

      Die Idee mit den Tachoimpulsen ist nicht schlecht, kommt drauf an, ob die Pulse breit genug sind, sie zu erfassen, aus Sicherheitsgründen würde ich da ein Stück Hardware vorschalten, einen monostabilen Multivibrator.
      Den kann man einmal pro Schleife abfragen und wenn er meldet, und der Totmannschalter nicht, dann - Notaus.

      P.S.: Ich bin nicht auf die GOTOs eingegangen, die sind auch unpassend für so ein Programm.
    • Hallo Michael
      das Programm entstand mal aus einem einfachen Nothalt mit Abschaltung Dieselventil.
      Dann kam immer mehr dazu,es läuft aber erstmal.
      Kann mich jetzt in Ruhe an die Änderungen machen.
      Habe auch von anderen hier tips bekommen,die eingearbeitet wurden.
      Bin auch nicht so der Programmierer ,versuche aber ans ziel zu kommen.

      Gruß an alle
      Jürgen
    • Hallo @Telefonbastler
      Ich habe mir deinen Code angeschaut und hatte so meine Mühe, den ganzen Goto und dem hin und her-gespringe zu folgen.
      Ich wollte verstehen, wie das Programm eigentlich funktioniert. Also welche Ereignisse (Taster, Sensoren) bewirken was.
      Daher habe ich ein Flussdiagramm gezeichnet, damit man erkennt, wie das Programm funktioniert.
      Das möchte ich hier mal zeigen:
      Flussdiagramm.JPG
      Mir sind dann bei der Analyse verschiedene Dinge aufgefallen.

      z.B. Wenn man die SiFa Taste nicht innerhalb 65 Sekunden drückt, dann wird zur Routine "Totmannaus" gesprungen,
      die dann durchläuft und in die Routine "NotausPult" reinläuft. Ist das so gewollt? Außerdem machen beide Routinen das gleiche. Und wenn Die letztere Routine durchgelaufen ist, kommt kein Sprunf und kein End. D.h. der Code läuft ins Leere, was nicht sein darf.

      Dann ist mir aufgefallen, dass du im Code einen Systemtakt von 100kHz angegeben hast. Kann das sein?
      Ist das Richtig so? Wenn ja, dann läuft dein Sekundentakt falsch.

      Wenn du das Flussdiagramm ansiehst, wirst du merken, dass dein Programm ziemlich verflochten ist. Jede Erweiterung
      die da eingepflegt werden soll, macht es noch komplizierter.

      Zuletzt stand ja die Idee im Raum, den Motor warmlaufen zu lassen. Und das Problem, dass während dem Warmlauf ständig die SiFa-Taste gedrückt werden muss.

      Wenn du das in deinen Code einpflegen willst, wird das Programm immer undurchsichtiger (was es nach meiner Auffassung jetzt bereits ist).

      Zum Glück kann man es auch einfacher und übersichtlicher machen.

      Du könntest das Programm als Statemachine umschreiben. Das würde künftige Änderungen deutlich vereinfachen.
      Wie das geht, erkläre ich dir im nachfolgenden Post, damit dieser nicht zu lang wird.
    • Die Statemachine ist dabei relativ einfach nachzuvollziehen.

      Du musst dir überlegen, welche Zustände deine Steuerung hat.
      2 Zustände stechen schon mal ins Auge und die sind, der Zug fährt oder er steht.
      Der Warmlauf des Motors wäre ein 3 Zustand.
      Auch die Notaus-Varianten kann man als Zustände sehen.

      Diese Zustände kannst du einfach mit einer Select Case-Anweisung unterscheiden.
      Und jetzt kommt es.

      Du hast nun die Kontrolle, auf welche Ereigbnisse du in den einzelnen Zuständen reagieren musst.

      Beim Warmlauf des Motors steht ja der Zug. Hier muss man also nicht auf Türen Achten oder auf den SiFa-Taster.

      Wenn der Zug z.B. im Zustand "Zug fahrt" ist, muss man auf den SiFa achten, und ob Impulse vom Tacho kommen (Erkennung Zug Steht). Bleiben die Pulse aus (W=0), wäre das die Bedingung, die den Zustand in "Zug steht" wechselt.
      Und in diesem Zustand musst du wieder aud andere Ereignisse achten.

      Ereignisse sind hierbei einfach Signale, Eingaben, Sensoren, auf die das Programm reagieren soll.
      Aber in jedem Zustand sind eben andere Ereignisse von Bedeutung.

      Damit du das besser nachvollziehen kannst hier ein Auszug aus deiner Steuerung, wie die als Statemachine
      aufgebaut sein könnte.

      BASCOM Source Code: Hauptprogramm

      1. ' Vorschlag als Zustandsautomat
      2. ' Zugtrennung mit SiFa und Türkontakt
      3. $regfile = "ATTINY2313.dat"
      4. $crystal = 100000
      5. $swstack = 32
      6. $hwstack = 32
      7. $framesize = 10
      8. Config SubMode = New ' Deklaration von Routinen nicht notwendig
      9. $Include "Include\Setup.inc"
      10. $Include "Include\Routinen.inc"
      11. $Include "Include\Statemachine.inc"
      12. Call Initialisierung()
      13. ' ----------------------------------------------------------------------------
      14. ' Hauptschleife
      15. ' ----------------------------------------------------------------------------
      16. Call setState(ST_ZUG_STEHT) ' Start-Zustand
      17. Enable Interrupts
      18. Do
      19. Select Case getState() ' aktueller Zustand ermitteln
      20. ' ----------------------------------------
      21. Case ST_ZUG_WARMLAUF ' Motor warmlaufen lassen
      22. ' ----------------------------------------
      23. If stateChanged() = True then ' Aktion bei Zustands-Eintritt
      24. Stop Timer1
      25. Call Reset_Totmann()
      26. End If
      27. ' Welches Ereignis beendet den Motor-Warmlauf?
      28. ' ----------------------------------------
      29. Case ST_ZUG_STEHT ' Zug steht
      30. ' ----------------------------------------
      31. If stateChanged() = True then ' Aktion bei Zustands-Eintritt
      32. Stop Timer1
      33. Call Reset_Totmann()
      34. End If
      35. If W > 5 then ' Bewegt sich der Zug?
      36. Call setState(ST_ZUG_FAHRT) ' Zustandswechsel
      37. End If
      38. ' ----------------------------------------
      39. Case ST_ZUG_FAHRT ' Zug ist in Fahrt
      40. ' ----------------------------------------
      41. If stateChanged() = True then ' Aktion bei Zustands-Eintritt
      42. Start Timer1 ' Timer starten, wenn Zug fährt
      43. End If
      44. If pin_Nottaste_Lok = 0 then
      45. Call Blinken()
      46. Call setState(ST_NOTAUSPULT) ' Zustandswechsel
      47. Redo ' Jump Do
      48. End If
      49. If TuerCount > TuerMax or NotausCount > NotausMax then
      50. Call setState(ST_NOTAUS) ' Zustandswechsel
      51. Redo ' Jump Do
      52. End If
      53. If W = 0 then ' steht der zug?
      54. Call setState(ST_ZUG_STEHT) ' Zustandswechsel
      55. Redo ' Jump Do
      56. End If
      57. If getTasteSiFa() = True then ' Totmann-Taste gedrückt?
      58. Call Reset_Totmann()
      59. End If
      60. Select Case Sekunden_Ticks ' Totmann-Status prüfen
      61. Case 50 : Set pin_lampeblau ' Blaue Lampe an
      62. Case 55 : Set pin_Summer ' Summer an
      63. Case 65 : Call setState(ST_NOTAUSPULT) ' Zustandswechsel
      64. End Select
      65. ' ----------------------------------------
      66. Case ST_NOTAUS ' Notaus wird ausgelöst durch TürCount und NotausCount
      67. ' ----------------------------------------
      68. If stateChanged() = True then ' Aktion bei Zustands-Eintritt
      69. AbMagnet = 0
      70. wait 40
      71. Diesel = 0
      72. Call HV()
      73. End If
      74. ' ----------------------------------------
      75. Case ST_NOTAUSPULT ' Notaus wird ausgelöst durch Totmann-Zeitüberschreitung
      76. ' ----------------------------------------
      77. If stateChanged() = True then ' Aktion bei Zustands-Eintritt
      78. AbMagnet = 0
      79. pin_Summer = 1
      80. wait 40
      81. Diesel = 0
      82. End If
      83. End Select
      84. Loop
      85. ' ----------------------------------------------
      86. ' Interrupt-Routine Timer1 OVF
      87. ' ----------------------------------------------
      88. Isr_Timer1:
      89. timer1 = timer1_preload
      90. incr Sekunden_Ticks
      91. toggle pin_Test 'Kontrolle Timerüberlauf
      92. if Notauscount < Notausmax then
      93. if pin_Zugschleife = 0 then
      94. Notauscount = 0
      95. else
      96. Incr Notauscount
      97. End if
      98. end if
      99. if Tuercount < tuermax then
      100. if pin_Tuerkontakt = 0 then
      101. Tuercount = 0
      102. else
      103. Incr Tuercount
      104. end if
      105. end if
      106. return
      Display All
      Das ganze Programm ist in mehrere Module aufgeteilt, damit im Hauptprogramm die Übersicht gegeben ist.
      Das komplette Programm ist im Anhang.

      Falls du mehr über Statemachine wissen möchstest, schau mal im Lexikon unter "S".

      Noch ein Tip zum Schluss.

      Bascom kann dein Programm strukturieren. Rechtsklick in das Code-Fenster und "Proper Indent" auswählen.
      Das verbessert die Lesbarkeit erheblich.
      Files
    • Hallo Mitch64,

      also,das Programm ist mir zu hoch.
      Gehe mal davon aus ,das die Ports noch configuriert werden müssen.
      Auch vom ablauf her hab ich einige Fragezeichen auf der Stirn.
      Ich habs mal abgespeichert und werde versuchen,es zu verstehn.

      Gruß
      Jürgen
    • @Telefonbastler

      Wenn du die Projekt-Datei öffnest, werden alle Module (INC-Dateien) auch geladen.
      Die Ports werden im Modul "setup.inc" konfiguriert.

      Ich habe vor einer Weile ein Tutorial "Statemachine" geschrieben. Das findest du im Lexikon unter dem Buchstabe "S".
      Da kannst du mehr zum Thema Statemachine lesen, wie das ganze funktioniert.

      Bei Fragen stehe ich aber auch zur Verfügung.

      Gruß Mitch
    • Hallo Mitch64,
      habe mich mit dem Programm beschäftigt,bekomme es aber nicht ans laufen.
      Wenn ich die Projektdatei öffne,erscheinen die inc-Dateien in der Bascomleiste.
      Wenn jetzt die main compiliere werden dann die Inc mit verarbeitet ?
      Oder welche Reihenfolge muss ich einhalten um die Sache in den Chip zu bekommen.

      Gruß
      Jürgen
    • Ja, die .inc Dateien werden automatisch mit kompiliert, da sie in der main eingebunden sind.
      Die Reihenfolge ist genau die selbe wie bei ganz normalen .bas-Dateien: Erst kompilieren, dann auf den Chip flashen.

      Bedenke aber, dass das Programm von Mitch noch nicht fertig ist.
      In der Sub readTacho() ist z.B. bisher nur ein Kommentar drin. Somit wird sich die Variable "W" auch nicht ändern und der State "ST_ZUG_STEHT" auch niemals verlassen.
    • Telefonbastler wrote:

      Wenn jetzt die main compiliere werden dann die Inc mit verarbeitet ?
      Oder welche Reihenfolge muss ich einhalten um die Sache in den Chip zu bekommen.
      Hallo @Telefonbastler

      Das ist ja das schone. Wenn man ein Programm als Projekt anlegt, welches aus mehreren Dateien bestehen kann, weis Bascom, welche Datei zu kompilieren ist.
      Das wird in der Projekt-Datei festgelegt, welche die Hauptdatei ist.
      Es spielt dann keine Rolle, welche Datei du gerade bearbeitest. Mit F7 wird alles korrekt kompiliert. Und mit F4 geplashed.

      Im Vergleich ohne Projekt-Datei geht Bascom davon aus, dass in jedem Fenster ein eigenes Programm steht. Wenn man so will, mehrere Projekte.

      Vielleicht ist bei dir der Projekt-Explorer noch nicht eingeblendet?
      Im Menü "Anzeigen" --> "Projekt Files" anhaken. Sollte dann rechts erscheinen.
      In dem Fenster siehst du dann, welches die Hautdatei ist, und welche zu dem Projekt gehören.
      Dort kann man auch das Projekt zusammen stellen. Man muss allerdings im Hinterkopf behalten, wenn man da Änderungen macht, dass man die selber mit "Datei" --> "Project" --> "Save" speichert.

      Vorteil ist vei den Project-Dateien, dass man immer alle Dateien geladen bekommt, die zum Projekt gehören. Auch wenn sie mal nicht im Reiter sind, kann man sie zum Edititeren mit Doppelklick im Projekt-Explorer öffnen.

      Auch das verteilen ist einfach. Man wählt im Menü "Datei" --> "Zip Project Files" und man hat alle Dateien in der Zip. Leider ohne Projekt-Datei. Die schiebt man das eben nach dem Packen noch in die Zip.

      Kurz zum Programm.
      Das Programm ist so noch nicht wirklich lauffähig. Da musst du noch etwas Hand anlegen.
      Weil ich eben vieles nicht nachvollziehen kann aus deiner Original-Datei.

      Aber ich habe das Programm mal so aufgebaut, das das Prinzip klar wird. Musst eigentlich und im wesentlichen nur die Main.bas anschauen.
      Die anderen Dateien enthalten dann nur noch die Routinen und Konfigurationen.

      Die Routinen.inc dürfte noch interessant sein. Z.B. die Routine Read_Tacho().
      Sie sollte eigentlich den Tachowert einlesen und in w speichert, was ja im Hauptprogramm der Auslöser ist - in manchen Zuständen.

      Falls du noch Fragen hast, immer gerne her damit!

      @R2D2 Bastler
      Danke für deine Unterstützung.