Unerklärlicher Fehler, komme einfach nicht weiter.

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    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!

    • Unerklärlicher Fehler, komme einfach nicht weiter.

      Hallo,

      ich habe hier ein Projekt, wo zwei Servomotoren zwei Pneumatikzylinder betätigen.
      Das lief bisher auch viele Tage ohne Probleme. Da aber die Zylinder bei zB. fehlender
      Schmierung gern mal Probleme machen, habe ich eine Fehlerbehandlung programmiert.
      Bei Schwergängigkeit gibt die Steuerung ein Fehlersignal aus, ich setze sie maximal
      dreimal zurück und starte neu, dann stoppt das Programm beim nächsten Start.
      Das funktioniert auch, ABER!
      Immer wieder, in unregelmäßigen Abständen startet das Programm neu, ohne das ein Motorfehler auftritt.
      In Zeile 244 gebe ich dann eine Meldung aus und stoppe danach testweise das Programm.
      Danach würde der Watchdog normalerweise das Programm neu starten, das ist auf jeden Fall der
      Auslöser.
      Wie um alles in der Welt kommt das Programm ohne Motorfehler dorthin?
      In Zeile 241 und 243 würde ja vorher der Fehlerstand im Eprom abgespeichert werden und beim
      nächsten Start auf dem Display angezeigt werden. Das funktioniert bei simulierten Motorfehlern
      einwandfrei, hier steht aber beim nächsten Start alles auf Null.

      Ich weiß, das nicht so viel Kram in die ISR gehört, hab es aber nicht anders hinbekommen.
      Hatte ja schon in diesem Tread angefragt:
      Geschwindigkeit Schrittmotor linear verändern

      Gruß Ralf

      Ist ja Blöd, Nachricht zu lang!



      Gruß Ralf
    • BASCOM-Quellcode

      1. Config Timer1 = Timer , Prescale = 1 'Timer Servomotor
      2. Config Timer3 = Timer , Prescale = 256
      3. Config Int3 = Low Level
      4. Timer3 = 3036
      5. On Timer1 Schrittirq
      6. On Timer3 Entlueften
      7. Config Lcdpin = Pin , Db4 = Portg.5 , Db5 = Porte.3 , Db6 = Porth.3 , Db7 = Porth.4 , E = Porth.6 , Rs = Porth.5
      8. Config Lcd = 16 * 2 'configure lcd screen
      9. Cls
      10. 'Locate 1 , 1 : Lcd " M "
      11. 'Locate 2 , 1 : Lcd " Herzprojekt"
      12. Dim Schrittzaehler As Word , Preload As Word , Z As Word
      13. Dim Controllertakte_diff As Word , Controllertakte_teil As Word
      14. Dim Zeit As Long , Messung As Long , Naehe As Word
      15. Dim Sekundenzaehler As Word , Posi_entl_l As Word , Posi_entl_r As Word
      16. Dim Schlagfrequenz As Word
      17. Dim Motorfehler_links_e As Eram Byte , Motorfehler_rechts_e As Eram Byte
      18. Dim Motorfehler_links As Byte , Motorfehler_rechts As Byte
      19. Dim Entlueftungsintervall As Word
      20. Motorfehler_links = Motorfehler_links_e 'Fehlerwerte aus dem Eprom laden
      21. Motorfehler_rechts = Motorfehler_rechts_e
      22. Schrittzaehler = 0
      23. 'Controllertakte_diff = 14000
      24. 'Controllertakte_teil = Controllertakte_diff / 800
      25. 'Naehe = 0
      26. Sekundenzaehler = 0
      27. Entlueftungsintervall = 900 'Entlüftungsintervall in Sekunden
      28. Posi_entl_l = 400 'Entlüftungsposition links
      29. Posi_entl_r = 700 'Entlüftungsposition rechts
      30. Schlagfrequenz = 51500 'Timerpreload > Schlagfrequenz
      31. Controllertakte_teil = 10 'Beschleunigung
      32. Preload = Schlagfrequenz 'Grundgeschwindigkeit
      33. '---- Programm -----------------------------------------------------------------
      34. Locate 1 , 1 : Lcd " START! "
      35. Wait 30
      36. Locate 1 , 1 : Lcd "Fehler links: " ; Motorfehler_links
      37. Locate 2 , 1 : Lcd "Fehler rechts: " ; Motorfehler_rechts
      38. If Motorfehler_links > 3 Then Call Fehler_links 'maximal 3 Fehler werden toleriert
      39. If Motorfehler_rechts > 3 Then Call Fehler_rechts
      40. Reset R_l 'Richtung Motor links
      41. While Hall_l = 1 'wenn Hallsensor nicht aktiv
      42. Waitus 500
      43. Reset T_l
      44. Waitus 500
      45. Set T_l
      46. Wend
      47. Waitms 200
      48. Set R_l 'Richtung Motor links
      49. While Hall_l = 0 'den Hallsensor freifahren
      50. Waitus 500
      51. Reset T_l
      52. Waitus 500
      53. Set T_l
      54. Wend
      55. For Z = 0 To 1375
      56. Reset T_l
      57. Waitus 500
      58. Set T_l
      59. Waitus 500
      60. Next Z
      61. Set R_r 'nach Rechts
      62. While Hall_r = 1 'wenn Hallsensor rechts nicht aktiv
      63. Waitus 500
      64. Reset T_r 'nach links fahren, bis er auslöst
      65. Waitus 500
      66. Set T_r
      67. Wend
      68. Waitms 200
      69. Reset R_r 'nach Rechts
      70. While Hall_r = 0 'den Hallsensor rechts freifahren
      71. Waitus 500
      72. Reset T_r
      73. Waitus 500
      74. Set T_r
      75. Wend
      76. 'For Z = 0 To 1400
      77. For Z = 0 To 1100
      78. Reset T_r
      79. Waitus 500
      80. Set T_r
      81. Waitus 500
      82. Next Z
      83. Waitms 200
      84. On Int3 Motorfehler
      85. Enable Timer1
      86. Enable Timer3
      87. Enable Int3
      88. Do
      89. nop
      90. Loop
      91. Schrittirq:
      92. Incr Schrittzaehler 'Schrittzähler erhöhen
      93. If Schrittzaehler > 1599 Then
      94. Schrittzaehler = 0 'nach einer Umdrehung auf 0 setzen
      95. Preload = Schlagfrequenz
      96. If Sekundenzaehler > Entlueftungsintervall Then 'wenn Entlüftung ansteht
      97. Stop Timer1 'Schritt ISR stoppen
      98. Sekundenzaehler = 0 'Zähler zurücksetzen
      99. For Z = 0 To Posi_entl_r 'Position Entlüftung anfahren
      100. Reset T_r
      101. Waitus 500
      102. Set T_r
      103. Waitus 500
      104. Next Z
      105. Set Mg_r 'Magnetventil ansteuern
      106. Waitms 2000 'Wartezeit für Entlüftung
      107. Reset Mg_r 'Magnetventil freigeben
      108. Set R_r 'Richtung ändern
      109. For Z = 0 To Posi_entl_r 'auf Ausgangsstellung zurück
      110. Reset T_r
      111. Waitus 500
      112. Set T_r
      113. Waitus 500
      114. Next Z
      115. Reset R_r 'Richtung aus Standart
      116. Waitms 200 'kurz warten
      117. For Z = 0 To Posi_entl_l 'Position Entlüftung anfahren
      118. Reset T_l
      119. Waitus 500
      120. Set T_l
      121. Waitus 500
      122. Next Z
      123. Set Mg_l 'Magnetventil ansteuern
      124. Waitms 2000 'Wartezeit für Entlüftung
      125. Reset Mg_l 'Magnetventil freigeben
      126. Reset R_l 'Richtung ändern
      127. For Z = 0 To Posi_entl_l 'auf Ausgangsstellung zurück
      128. Reset T_l
      129. Waitus 500
      130. Set T_l
      131. Waitus 500
      132. Next Z
      133. Set R_l 'Richtung aus Standart
      134. Waitms 200 'kurz warten
      135. Start Timer1 'Schritt ISR freigeben
      136. End If
      137. End If
      138. If Schrittzaehler < 800 Then '0- 180 Grad
      139. Preload = Preload + Controllertakte_teil 'wird mit jedem Takt schneller
      140. Timer1 = Preload 'neuer Preload
      141. Else '180- 360 Grad
      142. Preload = Preload - Controllertakte_teil 'wird mit jedem Pakt langsamer
      143. Timer1 = Preload 'neuer Preload
      144. End If
      145. Reset T_l 'Taktpin auf Low
      146. Reset T_r
      147. Waitus 1 'kurze Verzögerung
      148. Set T_l 'Taktpin wieder auf High
      149. Set T_r
      150. Return
      151. Sub Fehler_links
      152. Motorfehler_links_e = 0 'Fehlerstand löschen
      153. Locate 1 , 1 : Lcd "links 3 Motorfel"
      154. Locate 2 , 1 : Lcd "Bitte Neustarten"
      155. Do 'Hier stoppen!
      156. Loop
      157. End Sub
      158. Sub Fehler_rechts
      159. Motorfehler_rechts_e = 0 'Fehlerstand löschen
      160. Locate 1 , 1 : Lcd "rechts 3 Motorfe"
      161. Locate 2 , 1 : Lcd "Bitte Neustarten"
      162. Do 'Hier stoppen!
      163. Loop
      164. End Sub
      165. Entlueften:
      166. Timer3 = 3036
      167. Incr Sekundenzaehler
      168. Return
      169. Motorfehler:
      170. Disable Int3 'Interrupt sperren
      171. If Fehler_l = 0 Then Incr Motorfehler_links 'Fehlerstand links erhöhen
      172. Motorfehler_links_e = Motorfehler_links 'und im Eprom speichern
      173. If Fehler_r = 0 Then Incr Motorfehler_rechts 'Fehlerstand rechts erhöhen
      174. Motorfehler_rechts_e = Motorfehler_rechts 'und im Eprom speichern
      175. Locate 1 , 1 : Lcd "ISR Motorfehler"
      176. Do
      177. Loop
      178. Start Watchdog 'Neustart
      179. Return
      180. End
      Alles anzeigen
      Die Zeilennummern stimmen jetzt leider nicht mehr.
      Also die Frage ist maximal gekürzt: Wie kommt das Programm zum Watchdog in Zeile 197, ohne in den Zeilen 191 und 193 was im Eprom zu speichern? Die Schleife davor ist nur wegen der Fehlersuche drin.
    • BASCOM-Quellcode

      1. $regfile = "m2560def.dat" ' specify the used micro
      2. $crystal = 16000000 ' used crystal frequency
      3. $baud = 9600
      4. $hwstack = 64 ' default use 32 for the hardware stack
      5. $swstack = 20 ' default use 10 for the SW stack
      6. $framesize = 80 ' default use 40 for the frame space
      7. Declare Sub Fehler_links
      8. Declare Sub Fehler_rechts
      9. Config Watchdog = 1024
      10. Config Porta.2 = Output 'Magnetventil Rechts
      11. Config Porta.3 = Output 'Magnetventil Links
      12. Config Porta.4 = Input 'Hallsensor Rechts
      13. Config Porta.5 = Input 'Hallsensor Links
      14. Config Porta.6 = Output 'Freigabe Links
      15. Config Porta.7 = Input 'Fehler Links
      16. Config Portb.7 = Output 'LED
      17. Config Portc.0 = Output 'Richtung Rechts
      18. Config Portc.1 = Output 'Takt Rechts
      19. Config Portc.2 = Output 'Reset Rechts
      20. Config Portc.3 = Input 'Fehler Rechts
      21. Config Portc.4 = Output 'Freigabe Rechts
      22. Config Portc.5 = Output 'Richtung Links
      23. Config Portc.6 = Output 'Takt Links
      24. Config Portc.7 = Output 'Reset Links
      25. Mg_r Alias Porta.3 : Mg_l Alias Porta.2
      26. Hall_l Alias Pina.5 : Hall_r Alias Pina.4
      27. R_l Alias Portc.5 : R_r Alias Portc.0
      28. T_l Alias Portc.6 : T_r Alias Portc.1
      29. Frei_l Alias Porta.6 : Frei_r Alias Portc.4
      30. Fehler_l Alias Pina.7 : Fehler_r Alias Pinc.3
      31. Set Frei_r 'Motor rechts sperren
      32. Set Frei_l 'Motor links sperren
      33. Porta.4 = 1 'Pullups einschalten
      34. Porta.5 = 1
      35. Portc.3 = 1
      36. Porta.7 = 1
      37. Reset Portc.2 'Reset rechts
      38. Reset Portc.7 'Reset links
      39. Waitms 10
      40. Set Portc.2 'Reset rechts aufheben
      41. Set Portc.7 'Reset links aufheben
      42. Waitms 100
      43. Reset Frei_r 'Motor rechts freigeben
      44. Reset Frei_l 'Motor links freigeben
      45. Config Timer1 = Timer , Prescale = 1 'Timer Servomotor
      46. Config Timer3 = Timer , Prescale = 256
      47. Config Int3 = Low Level
      48. Timer3 = 3036
      49. On Timer1 Schrittirq
      50. On Timer3 Entlueften
      51. Config Lcdpin = Pin , Db4 = Portg.5 , Db5 = Porte.3 , Db6 = Porth.3 , Db7 = Porth.4 , E = Porth.6 , Rs = Porth.5
      52. Config Lcd = 16 * 2 'configure lcd screen
      53. Cls
      54. 'Locate 1 , 1 : Lcd " M "
      55. 'Locate 2 , 1 : Lcd " Herzprojekt"
      56. Dim Schrittzaehler As Word , Preload As Word , Z As Word
      57. Dim Controllertakte_diff As Word , Controllertakte_teil As Word
      58. Dim Zeit As Long , Messung As Long , Naehe As Word
      59. Dim Sekundenzaehler As Word , Posi_entl_l As Word , Posi_entl_r As Word
      60. Dim Schlagfrequenz As Word
      61. Dim Motorfehler_links_e As Eram Byte , Motorfehler_rechts_e As Eram Byte
      62. Dim Motorfehler_links As Byte , Motorfehler_rechts As Byte
      63. Dim Entlueftungsintervall As Word
      64. Motorfehler_links = Motorfehler_links_e 'Fehlerwerte aus dem Eprom laden
      65. Motorfehler_rechts = Motorfehler_rechts_e
      66. Schrittzaehler = 0
      67. 'Controllertakte_diff = 14000
      68. 'Controllertakte_teil = Controllertakte_diff / 800
      69. 'Naehe = 0
      70. Sekundenzaehler = 0
      71. Entlueftungsintervall = 900 'Entlüftungsintervall in Sekunden
      72. Posi_entl_l = 400 'Entlüftungsposition links
      73. Posi_entl_r = 700 'Entlüftungsposition rechts
      74. Schlagfrequenz = 51500 'Timerpreload > Schlagfrequenz
      75. Controllertakte_teil = 10 'Beschleunigung
      76. Preload = Schlagfrequenz 'Grundgeschwindigkeit
      77. '---- Programm -----------------------------------------------------------------
      Alles anzeigen
    • Ralf schrieb:

      Wie kommt das Programm zum Watchdog in Zeile 197
      Ganz einfach - schlecht programmiert. Sorry, aber wenn ich ein Do - Loop sehe die nichts macht kann das Ganze nicht gut gehen.
      Dann ist das End (Zeile 200 in oben gezeigtem Quellcode) an der falschen Stelle, dass kommt direkt nach dem Loop der Hauptschleife und erst danach folgen die Unterprogramme.
      Und es wäre besser das ganze Programm zu zeigen, denn keiner weiss welchen AVR du nutzt noch sehe ich Stack-Werte.
      Eine Lösung habe ich nicht, aber mir gefällt Ihr Problem.
    • Das END ist ganz am Ende als letzte Zeile und das Do Loop testweise drin.

      Trotzdem Danke!


      djmsc schrieb:

      Und es wäre besser das ganze Programm zu zeigen, denn keiner weiss welchen AVR du nutzt noch sehe ich Stack-Werte.
      Das Programm ist zu lang, deshalb habe ich es auf den Rat von Michael als Anhang angefügt.
      Ich bin kein guter Programmierer, das weiß ich. Meine Stärken liegen eher im Bereich Feinmechanik und Elektronik.
      Trotzdem wäre es schön, wenn jemand ganz konkret auf den Fehler eingeht.

      Vielen Dank!

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Ralf ()

    • Ich beziehe mich auf das Programm aus Beitrag #7.
      Ich nehme an, die Zeilen 112 bis 165 so eine Art Referenzfahrt sind, richtig?
      In Zeile 159-161 Enablest du Interrupts aber es fehlt die globale Interruptfreigabe "Enable Interrupts" im Programm.
      Danach bleibt er in der Do-Loop gefangen.

      Betrachten wir den erstmaligen Programmstart:
      In Zeile 87/88 holt er Werte aus dem EEprom, die bei leerem EEprom den Wert 255 haben.
      Das sollte er auch nach den 30 Sekunden Wartezeit auf das Display schreiben.
      Er springt dann (weil Wert > 3) in Zeile 109 nach "Fehler_links" und überschreibt den Inhalt des Displays sofort wieder.
      Ab da bleibt er in der dortigen Do-Loop stecken.

      Der 2. Start geht genauso, nur diesmal mit der rechten Seite.

      Beim 3. Start sieht das anders aus, hier wurde ja der EEprom mit dem Wert 0 gefüllt und die Abfragen lassen das Programm nicht verzweigen.
      Jedesmal die Wartezeit von 30 Sekunden muss man mögen ;)
      Nun kommt er in Zeile 112-165, führt die Referenzfahrt (?) aus und deklariert die Interruptadressen.
      Danach geht es wieder in eine leere Do-Loop.

      Ich sehe ein Config Watchdog, aber nirgends im Programm wird der Watchdog zurückgesetzt.
      Ich meine aber auch, dass ein Start Watchdog benötigt wird, müsste man mal die Hilfe durchforsten.
      Möglicherweise schlägt er auch immer in der 30s Wartezeit zu.

      ich kann mir aber schwer vorstellen, dass das Programm so läuft, wie du im ersten Beitrag schreibst, aber vielleicht ist beim Kopieren was verloren gegangen.
    • Hallo Michael,

      danke für deine Antwort!
      Ich wollte sowieso gerade schreiben, hab das Problem inzwischen gelöst!

      Ich gehe dein Posting noch mal genau durch, bloß kurz mal eine Nachricht, weil gleich Besuch kommt.

      Michael schrieb:

      Ich sehe ein Config Watchdog, aber nirgends im Programm wird der Watchdog zurückgesetzt.
      Ich meine aber auch, dass ein Start Watchdog benötigt wird, müsste man mal die Hilfe durchforsten.
      Möglicherweise schlägt er auch immer in der 30s Wartezeit zu.
      Ich habe versucht in der ISR das Programm mit !call 0 und Goto 0 im Fehlerfall neu zu starten, was es auch gemacht hat
      nur liefen die Timer danach nicht.
      Dann habe ich es mit "Start Watchdog" erledigt, das funktioniert einwandfrei. Er wir nirgens zurüchgesetzt und
      startet das Programm sauber neu.
      Der eigentliche Fehler ist, das entweder die Servoregler am Fehlerausgang kurze Spikes ausgeben,
      oder das meine Verdrahtung nicht optimal ist.
      Wenn ich in der ISR die Fehlerpins abfrage, dann sind sie inaktiv, es ist ja auch kein richtiger Motorfehler
      aufgetreten, denn der bleibt dann auch statisch bestehen bis er zurückgesetzt wird.
      Ich frage jetzt einfach in der ISR die Pins nach ein paar Millisekunden ab und wenn sie nicht zurückgesetzt sind,
      dann wird der Interrupt ignoriert.

      Michael schrieb:

      ich kann mir aber schwer vorstellen, dass das Programm so läuft, wie du im ersten Beitrag schreibst, aber vielleicht ist beim Kopieren was verloren gegangen.
      Doch, es funktioniert. Ist vorher sauber viele Tage gelaufen, diese Fehlerbehandlung hab ich erst gestern hinzugefügt
      und das Gerät läuft jetzt gerade Probe. Wenn ich Motorfehler simuliere, dann startet er genau dreimal neu, beim vierten Fehler
      zeigt er eine Meldung und bleibt dann stehen. Beim nächsten Neustart werden die Fehler gelöscht und es geht weiter.


      Michael schrieb:

      In Zeile 159-161 Enablest du Interrupts aber es fehlt die globale Interruptfreigabe "Enable Interrupts" im Programm.
      Da hab ich mich auch schon gewundert, ist in der Tat nicht drin, funktioniert aber. Seltsam. a_27_b277ca12


      Gruß Reinhard
    • Pluto25 schrieb:

      Er kann als Neustarter benutzt werden ( ein goto 0 wäre da schneller)
      Hatte ich ja geschrieben, bei goto 0 laufen die Timer nicht an.

      Pluto25 schrieb:

      Muss es, aber er stört sich dann natürlich an den Wait 30 oder Waitms 2000 da er vor Ablauf einer Sekunde resetet werden muß.
      Er soll ja nicht resetten werden, er wird nur zum Auslösen des Resets benutzt, im normalen Programmablauf wird er
      gar nicht gestartet.