PWM-Berechnung führt zu Programmhalt

    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!

    • PWM-Berechnung führt zu Programmhalt

      Hallo,
      das Programm liest ein Signal von einer Fernsteuerung und schaltet in Abhängigkeit von der Länge des Impulses einen Ausgang (eine LED ein) bzw. gibt bei einem längerem Impuls ein PWM-Signal an einen zweiten Ausgang, mit dem die Helligkeit einer weiteren LED gesteuert wird. Später soll das Programm in einen ATTiny45, jetzt läuft es aber erst einmal auf dem evaluation board von Pollin. Grundsätzlich tut das Programm auch, was es soll, aber ab und an bleibt es einfach stehen. Das Problem liegt in dem Teil von Zeile 153 bis 165. Wenn der Impuls an der Einschaltschwelle (158) des zweiten Ausgangs liegt (minmale Impulslänge ist 137 und maximale 243), wird ein PWM1A von 2 ausgegeben und damit hängt sich das Programm reproduzierbar auf.
      Ich vermute, dass es irgendetwas mit der Berechnung von PWW1A zu tun hat. Deshalb habe ich versucht, mit der Bedingung in Zeile 176 eine gültige Impulslänge sicher zustellen; aber leider vergeblich. Natürlich ließe sich ein Neustart per watchdog erzwingen, aber das finde ich irgendwie unbefriedigend, weil es nur am Symptom arbeitet anstatt das Problem zu lösen.
      Falls jemand dazu eine Idee hat, bitte her damit - ich komme mit meinem Latein nicht weiter.

      Quellcode

      1. '----- Settings ----------------------------------------------------------------
      2. $regfile = "m16DEF.Dat"
      3. $crystal = 1000000 'Frequency 1 MHz
      4. $hwstack = 48
      5. $swstack = 20
      6. $framesize = 32
      7. '----- Settings for Pollin Evaluation Board -----
      8. ' Port selected as given by addon board to use jumpers instead of cables to ports
      9. Lcd_db4 alias Porta.4
      10. Lcd_db5 alias Porta.5
      11. Lcd_db6 alias Porta.6
      12. Lcd_db7 alias Porta.7
      13. Lcd_e alias Portb.0
      14. Lcd_rs alias Portb.2
      15. config Portb.1 = output 'R/W of LCD to be connected to GND
      16. reset Portb.1 'PortB.1 set to GND
      17. ' 76543210
      18. Ddrd = &B00110001 '0 = input
      19. ' 76543210
      20. Portd = &B11001110 '1 = PullUp active
      21. '----- Variables ---------------------------------------------------------------
      22. dim wPulse as word 'stores current reading of RC signal
      23. dim wPulseMin as word : dim wPulseMinStore as word 'minimum pulse lenght
      24. dim wPulseMax as word : dim wPulseMaxStore as word 'maximum pulse length
      25. dim wPulseWidth as word 'pulse width
      26. dim ewPulseMin as eram word 'Minimum pulse length in EEPROM
      27. dim ewPulseMax as eram word 'Maximum pulse length in EEPROM
      28. dim wFactorPWM1 as word 'Division factor
      29. dim bCount as byte 'used as loop counter
      30. dim bSigMeasErr as byte 'used to indicate error in signal measurement routine
      31. dim wcloseUpOn as word
      32. dim wFarRangeOn as word
      33. RC_In alias pind.2 'PortD.2, Pin 16 (INT0) to read RC signal
      34. SigMeas alias pind.3 'PortD.3, Pin 17 to start signal measurement
      35. FeedBack alias portd.4 'Pin 18
      36. CloseUp alias portD.0 'Pin 14
      37. const PrecisionPWM1 = 2500 'Multiplied by 10 to get better precision of PWM
      38. const PulseTolerance = 3 'range to define valid switch bias
      39. const CloseUpOn = 10 'minimum value to switch CloseUp on
      40. const FarRangeOn = 20 'minimum value to switch FarRange on
      41. const ReadRepeat = 5 'necessary pulse readings before program continues
      42. '----- Initialization ----------------------------------------------------------
      43. config lcd = 16x2
      44. config Lcdpin = Pin , Db4 = Lcd_db4 , Db5 = Lcd_db5 , Db6 = Lcd_db6 , Db7 = Lcd_db7 , E = Lcd_e , Rs = Lcd_rs
      45. config Lcdbus = 4
      46. initlcd
      47. cls 'LCD used in 4-bit-mode
      48. config timer0 = timer , Prescale = 8
      49. config int0 = change
      50. on int0 GetPulse
      51. config Timer1 = Pwm, Pwm = 8, Compare_A_Pwm = Clear_Up, Prescale = 8
      52. wPulse = 0
      53. Timer0 = 0
      54. FeedBack = 0
      55. '===== Program =================================================================
      56. enable Timer0
      57. enable int0
      58. enable interrupts
      59. '----- Part 1 - Check for reliable pulse min & max value in EEPROM -------------
      60. wPulseMinStore = ewPulseMin 'read stored values of EEPROM
      61. wPulseMaxStore = ewPulseMax
      62. gosub PulseCheck
      63. if bSigMeasErr > 0 then
      64. gosub ErrorSignal
      65. else
      66. for bCount = 1 to 6 '3 slow LED signals = o.k. to start
      67. toggle Feedback
      68. Waitms 300
      69. Next bCount
      70. cls
      71. upperline : Lcd "Min " ; wPulseMinStore
      72. locate 1,9 : Lcd "Max " ; wPulseMaxStore
      73. wait 2
      74. end if
      75. '----- Part 2 - Measures minimum & maximum pulse length -----------------------
      76. if SigMeas = 0 or bSigMeasErr > 0 then
      77. do
      78. wait 1
      79. wPulseMinStore = wPulse 'measurement of min pulse
      80. for bCount = 1 to 4 '2 slow LED signals = finished
      81. toggle Feedback
      82. Waitms 300
      83. Next bCount
      84. wait 1 'measurement of max pulse
      85. wPulseMaxStore = wPulse
      86. gosub PulseCheck
      87. select case bSigMeasErr 'error handling
      88. case is > 0
      89. gosub ErrorSignal
      90. Wait 1
      91. case is = 0
      92. for bCount = 1 to 8 '4 slow LED signals = final o.k.
      93. toggle Feedback
      94. Waitms 300
      95. Next bCount
      96. ewPulseMin = wPulseMinStore 'store values in EEPROM
      97. ewPulseMax = wPulseMaxStore
      98. end select
      99. loop until bSigMeasErr = 0
      100. else 'read stored values of EEPROM
      101. wPulseMinStore = ewPulseMin
      102. wPulseMaxStore = ewPulseMax
      103. endif
      104. wCloseUpOn = wPulseMinStore + CloseUpOn 'effective treshold to switch close up LED
      105. wFarRangeOn = wPulseminStore + FarRangeOn 'effective treshold to switch far range LED's
      106. wPulseWidth = wPulseMaxStore - wPulseMinStore
      107. wPulseWidth = wPulseWidth - FarRangeOn 'effective puls width for PWM
      108. wFactorPWM1 = PrecisionPWM1 / wPulseWidth 'calculates PWM multiplication factor
      109. upperline : Lcd "Show pulse "
      110. wait 1
      111. locate 1 , 1 :lcd "P-Length "
      112. waitms 500
      113. '----- Part 3 - Main: Pulse width calculation & output switches ----------------
      114. do
      115. bCount = 0
      116. wPulseMin = wPulse - PulseTolerance
      117. wPulseMax = wPulse + PulseTolerance
      118. do 'repeat pulse readings
      119. if wPulse > wPulseMin and wPulse < wPulseMax then
      120. incr bCount
      121. waitms 25
      122. if wPulse > PulseTolerance then
      123. wPulseMin = wPulse - PulseTolerance
      124. end if
      125. wPulseMax = wPulse + PulseTolerance
      126. end if
      127. Loop until bCount = ReadRepeat
      128. ' Shows current pulse length
      129. locate 1 , 10
      130. lcd wPulse ; spc(8)
      131. if wPulse > wCloseUpOn then 'Switch close up LED
      132. CloseUp = 1
      133. else
      134. CloseUp = 0
      135. end if
      136. if wPulse > wFarRangeOn then 'Switch far range LED's
      137. wPulse = wPulse - wFarRangeOn
      138. if wPulse > 0 and wPulse < wPulseMaxStore then
      139. wPulse = wPulse * wFactorPWM1
      140. wPulse = wPulse / 10
      141. PWM1A = wPulse
      142. else
      143. PWM1A = 0
      144. end if
      145. else
      146. PWM1A = 0
      147. end if
      148. locate 2, 10 : lcd wPulse ; spc(8)
      149. loop
      150. End 'end program
      151. '===== End of program ==========================================================
      152. '----- Sub routines ------------------------------------------------------------
      153. PulseCheck:
      154. if wPulseMinStore < wPulseMaxStore then bSigMeasErr = 0
      155. if wPulseMinStore > wPulseMaxStore then bSigMeasErr = 1
      156. if wPulseMinStore = wPulseMaxStore then bSigMeasErr = 2
      157. return
      158. ErrorSignal:
      159. for bCount = 1 to 20 '10 quick LED signals = n.o.k.
      160. toggle Feedback
      161. Waitms 100
      162. Next bCount
      163. return
      164. '----- Interrupts --------------------------------------------------------------
      165. GetPulse:
      166. if RC_In = 1 then 'start Timer1 if positive signal on input
      167. start timer0
      168. Else 'stop Timer1 if no positive signal
      169. stop timer0
      170. wPulse = timer0
      171. timer0 = 0
      172. end if
      173. return
      Alles anzeigen
      Beste Grüße
      Jürgen
    • Hi, mir fällt auf, du verwendest 'wpulse' in der main und in einem interrupt. Kann da, während deiner Berechnungen mit wpulse in der main, nicht wpulse durch den interrupt neu gesetzt werden und deine bisherigen Berechnungen sind für die Katz?
      Ich würde vor dem Losrechnen zum Rechnen eine Kopie von wpulse erstellen, dann kann wpulse durch den interrupt verändert werden, aber deine Berechnung wird nicht gestört.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

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

    • In Zeile 114 (IDE Zeile 103) ist ein endif, was aber ein end if (mit Leerzeichen) sein muss.
      Die maximale Pulslänge beträgt 2,04 ms, dann läuft der Timer über und es gibt Chaos.
      Der Oszillator des AVRs kann schon mal 5% daneben liegen, dann sind das nur noch gut 1,9ms.
      Das Risiko würde ich nicht eingehen.


      ftelektro schrieb:

      Zeile 159 bis 164 ist der Inhalt doppelt.
      das sieht vielleicht nur so aus, abhängig vom If davor soll ja nur die PWM auf 0 gesetzt werden.
    • Hallo,
      der Tipp von tschoeatch hat mich weiter gebracht, besten Dank. Nach dem Einfügen einer neuen Variablen nur für die Pulsmessung läuft das Programm jetzt stabil.
      @Michael: Bei dem besagten "endif" ist das Programm nicht ins Stolpern gekommen, ich habe es aber dennoch geändert.
      Die Impulslänge liegt zwischen 1,1 und 1,9 (und ein wenig, so gepeilt sind es 1,94) ms. Bevor ich die Erkennung mit dem 8Bit-Timer gemacht habe, habe ich die 16bit-Variante versucht. Die maximal erkannte Impulslänge ist bei 243/244. Dabei ist das Programm aber immer gelaufen, die Aussetzer kamen wie gesagt im unteren Bereich. Ich vermute mal, dass das Schreiben aufs LCD in der Hauptschleife auch noch einige Zeit dauert und dadurch die Aussetzter im unteren Grenzberich mit verurscaht wurden. Sieht du jetzt noch ein generelles Problem? Das Programm ist jetzt stabil über 30 Minuten auch im unteren Impulslängenbereich gelaufen (allerdings nur im Testaufbau); der Test im Modell kommt dann noch.

      Zum Nachlesen: Hier ist die aktuelle Variante des Programms:

      Quellcode

      1. '----- Settings ----------------------------------------------------------------
      2. $regfile = "m16DEF.Dat"
      3. $crystal = 1000000 'Frequency 1 MHz
      4. $hwstack = 48
      5. $swstack = 20
      6. $framesize = 32
      7. '----- Settings for Pollin Evaluation Board -----
      8. ' Port selected as given by addon board to use jumpers instead of cables to ports
      9. Lcd_db4 alias Porta.4
      10. Lcd_db5 alias Porta.5
      11. Lcd_db6 alias Porta.6
      12. Lcd_db7 alias Porta.7
      13. Lcd_e alias Portb.0
      14. Lcd_rs alias Portb.2
      15. config Portb.1 = output 'R/W of LCD to be connected to GND
      16. reset Portb.1 'PortB.1 set to GND
      17. ' 76543210
      18. Ddrd = &B00110001 '0 = input
      19. ' 76543210
      20. Portd = &B11001110 '1 = PullUp active
      21. '----- Variables ---------------------------------------------------------------
      22. dim wPulse as word : dim wPulseMeas as word 'stores current reading of RC signal
      23. dim wPulseMin as word : dim wPulseMinStore as word 'minimum pulse lenght
      24. dim wPulseMax as word : dim wPulseMaxStore as word 'maximum pulse length
      25. dim wPulseWidth as word 'pulse width
      26. dim ewPulseMin as eram word 'Minimum pulse length in EEPROM
      27. dim ewPulseMax as eram word 'Maximum pulse length in EEPROM
      28. dim wFactorPWM1 as word 'Division factor
      29. dim bCount as byte 'used as loop counter
      30. dim bSigMeasErr as byte 'used to indicate error in signal measurement routine
      31. dim wcloseUpOn as word
      32. dim wFarRangeOn as word
      33. RC_In alias pind.2 'PortD.2, Pin 16 (INT0) to read RC signal
      34. SigMeas alias pind.3 'PortD.3, Pin 17 to start signal measurement
      35. FeedBack alias portd.4 'Pin 18
      36. CloseUp alias portD.0 'Pin 14
      37. const PrecisionPWM1 = 2500 'Multiplied by 10 to get better precision of PWM
      38. const PulseTolerance = 3 'range to define valid switch bias
      39. const CloseUpOn = 10 'minimum value to switch CloseUp on
      40. const FarRangeOn = 20 'minimum value to switch FarRange on
      41. const ReadRepeat = 5 'necessary pulse readings before program continues
      42. '----- Initialization ----------------------------------------------------------
      43. config lcd = 16x2
      44. config Lcdpin = Pin , Db4 = Lcd_db4 , Db5 = Lcd_db5 , Db6 = Lcd_db6 , Db7 = Lcd_db7 , E = Lcd_e , Rs = Lcd_rs
      45. config Lcdbus = 4
      46. initlcd
      47. cls 'LCD used in 4-bit-mode
      48. config timer0 = timer , Prescale = 8
      49. config int0 = change
      50. on int0 GetPulse
      51. config Timer1 = Pwm, Pwm = 8, Compare_A_Pwm = Clear_Up, Prescale = 8
      52. wPulse = 0 : wPulseMeas = 0
      53. Timer0 = 0
      54. FeedBack = 0
      55. '===== Program =================================================================
      56. enable Timer0
      57. enable int0
      58. enable interrupts
      59. '----- Part 1 - Check for reliable pulse min & max value in EEPROM -------------
      60. wPulseMinStore = ewPulseMin 'read stored values of EEPROM
      61. wPulseMaxStore = ewPulseMax
      62. gosub PulseCheck
      63. if bSigMeasErr > 0 then
      64. gosub ErrorSignal
      65. else
      66. for bCount = 1 to 6 '3 slow LED signals = o.k. to start
      67. toggle Feedback
      68. Waitms 300
      69. Next bCount
      70. cls
      71. upperline : Lcd "Min " ; wPulseMinStore
      72. locate 1,9 : Lcd "Max " ; wPulseMaxStore
      73. wait 2
      74. end if
      75. '----- Part 2 - Measures minimum & maximum pulse length -----------------------
      76. if SigMeas = 0 or bSigMeasErr > 0 then
      77. do
      78. wait 1
      79. wPulseMinStore = wPulseMeas 'measurement of min pulse
      80. for bCount = 1 to 4 '2 slow LED signals = finished
      81. toggle Feedback
      82. Waitms 300
      83. Next bCount
      84. wait 1 'measurement of max pulse
      85. wPulseMaxStore = wPulseMeas
      86. gosub PulseCheck
      87. select case bSigMeasErr 'error handling
      88. case is > 0
      89. gosub ErrorSignal
      90. Wait 1
      91. case is = 0
      92. for bCount = 1 to 8 '4 slow LED signals = final o.k.
      93. toggle Feedback
      94. Waitms 300
      95. Next bCount
      96. ewPulseMin = wPulseMinStore 'store values in EEPROM
      97. ewPulseMax = wPulseMaxStore
      98. end select
      99. loop until bSigMeasErr = 0
      100. else 'read stored values of EEPROM
      101. wPulseMinStore = ewPulseMin
      102. wPulseMaxStore = ewPulseMax
      103. end if
      104. wCloseUpOn = wPulseMinStore + CloseUpOn 'effective treshold to switch close up LED
      105. wFarRangeOn = wPulseminStore + FarRangeOn 'effective treshold to switch far range LED's
      106. wPulseWidth = wPulseMaxStore - wPulseMinStore
      107. wPulseWidth = wPulseWidth - FarRangeOn 'effective puls width for PWM
      108. wFactorPWM1 = PrecisionPWM1 / wPulseWidth 'calculates PWM multiplication factor
      109. upperline : Lcd "Show pulse "
      110. wait 1
      111. locate 1 , 1 :lcd "P-Length "
      112. waitms 500
      113. '----- Part 3 - Main: Pulse width calculation & output switches ----------------
      114. do
      115. bCount = 0
      116. wPulse = wPulseMeas
      117. wPulseMin = wPulse - PulseTolerance
      118. wPulseMax = wPulse + PulseTolerance
      119. do 'repeat pulse readings
      120. if wPulse > wPulseMin and wPulse < wPulseMax then
      121. incr bCount
      122. waitms 25
      123. if wPulse > PulseTolerance then
      124. wPulseMin = wPulse - PulseTolerance
      125. end if
      126. wPulseMax = wPulse + PulseTolerance
      127. end if
      128. Loop until bCount = ReadRepeat
      129. ' Shows current pulse length
      130. locate 1 , 10
      131. lcd wPulse ; spc(8)
      132. if wPulse > wCloseUpOn then 'Switch close up LED
      133. CloseUp = 1
      134. else
      135. CloseUp = 0
      136. end if
      137. if wPulse > wFarRangeOn then 'Switch far range LED's
      138. wPulse = wPulse - wFarRangeOn
      139. if wPulse > 0 and wPulse < wPulseMaxStore then
      140. wPulse = wPulse * wFactorPWM1
      141. wPulse = wPulse / 10
      142. PWM1A = wPulse
      143. else
      144. PWM1A = 0
      145. end if
      146. else
      147. PWM1A = 0
      148. end if
      149. locate 2, 10 : lcd wPulse ; spc(8)
      150. loop
      151. End 'end program
      152. '===== End of program ==========================================================
      153. '----- Sub routines ------------------------------------------------------------
      154. PulseCheck:
      155. if wPulseMinStore < wPulseMaxStore then bSigMeasErr = 0
      156. if wPulseMinStore > wPulseMaxStore then bSigMeasErr = 1
      157. if wPulseMinStore = wPulseMaxStore then bSigMeasErr = 2
      158. return
      159. ErrorSignal:
      160. for bCount = 1 to 20 '10 quick LED signals = n.o.k.
      161. toggle Feedback
      162. Waitms 100
      163. Next bCount
      164. return
      165. '----- Interrupts --------------------------------------------------------------
      166. GetPulse:
      167. if RC_In = 1 then 'start Timer1 if positive signal on input
      168. start timer0
      169. Else 'stop Timer1 if no positive signal
      170. stop timer0
      171. wPulseMeas = timer0
      172. timer0 = 0
      173. end if
      174. return
      Alles anzeigen
      Beste Grüße
      Jürgen
    • JuWi schrieb:

      Die Impulslänge liegt zwischen 1,1 und 1,9 (und ein wenig, so gepeilt sind es 1,94) ms.
      das ist nicht weit weg von 2,04 ms, hart auf Kante, oder wie man sagt.

      JuWi schrieb:

      Sieht du jetzt noch ein generelles Problem?
      Da ist z.B. config Lcdbus = 4
      das ist beim Mega16 nicht möglich, er hat keinen externen Speicherbus, das hast du falsch abgeschrieben.
      Was war denn die Quelle? Ich hätte gerne diesen Anfängerfehler abgestellt, aber er taucht immer wieder auf, irgendwer muss das ja in Umlauf gebracht haben.

      Da ist z.B. $crystal = 1000000

      Warum tust du dir ohne Not 1MHz an? mit 8MHz hast du 8 mal mehr Takte und manche zeitkritischen Probleme sind keine mehr.

      Strom sparst du damit nicht.


      Zeile 123

      If Wpulse > Pulsetolerance Then

      Pulsetolerance ist eine Konstante mit dem Wert 3, da ist eigentlich zu erwarten, dass wPulse größer ist, sonst wäre ja auch die drüber stehende If-Bedingung nicht erfüllt worden.

      Eigentlich nicht sinnvoll, da der Wert ja bereits festgelegt wurde und auch der Max-Wert 2 Zeilen tiefer ohne If neu gesetzt wird (auch sinnlos)


      Zeile 122 Waitms 25 ist auch nicht glücklich, da so ein Puls schon mal früher kommen kann, also in der Zeit 2 Pulse.

      Ein Flag im Interrupt der Pulserfassung und eine Abfrage mit Rücksetzen wäre hier besser., dann wird jeder Puls benutzt.


      In Zeile 107 und 108 sehe ich ausserdem die Gefahr von Überläufen.


      JuWi schrieb:

      Wenn der Impuls an der Einschaltschwelle (158) des zweiten Ausgangs liegt (minmale Impulslänge ist 137 und maximale 243), wird ein PWM1A von 2 ausgegeben und damit hängt sich das Programm reproduzierbar auf.


      Wenn PWM = 2 und wPulse = 158 war, dann muss in Zeile 140 bis 142 der Wert von wFarRangeOn ausserhalb des gewünschten Bereichs liegen, was wieder zu der fraglichen Zeile 108 und Zeile 107 führt ;)
    • Hallo Michael,
      erst einmal Danke für die Anregungen...

      Michael schrieb:

      Da ist z.B. config Lcdbus = 4
      Das Statement stammt aus dem mit dem Evaluation-Board von Pollin mitgeliefertem Testprogramm. Ich habe für meine weiteren Testprogramme die Teile aus dem ursprünglichen Programm gelöscht, die Hardwarekomponenten betrafen, die ich nicht nutze. So ist das einfach stehen gebleiben und hat auch nicht wieter gestört.
      Bei der Taktfrequenz habe ich mich von der Überlegung leiten lassen, dass der µC ohnehin mit der Überwachung eines RC-Kanals und dem bisschen Rechnerei schon bei 1MHz die meiste Zeit nichts zu tun hat.
      Zu deinen anderen Kommentaren habe ich leider das Problem, dass irgendwie die von dir zitierten Zeilennummern weder zu dem ersten noch dem zweiten eingestellten Programm wirklich passen. Wie muss ich das Programm denn einstellen, dass diese Verwirrung nicht auftritt?
      Beste Grüße
      Jürgen
    • Michael schrieb:

      Die Zeilennummern habe ich direkt aus der Bascom-IDE
      Jetzt hab ich's: bei dem HIneinkopieren bleiben die Leerzeilen auf der Strecke...

      Die Idee hinter der Schleife bei Zeile 119 bis 128 ist, über mehrere Impulse abzuwarten, ob die Impulslänge gleich bleibt. Das soll das Springen ziwschen Schaltzuständen verhindern, der Nachteil ist natürlich, dass es etwas dauert, bis eine Reaktion erfolgt. Die 25 ms Wartezeit sollen sicherstellen, dass in der Zwischenzeit auch ein neuer Impuls am Kanal angekommen ist. Wenn ich dich richtig verstanden habe, schlägst du so etwas in der Interrupt-Routine vor:

      Quellcode

      1. GetPulse:
      2. if RC_In = 1 then
      3. start timer0
      4. Else
      5. stop timer0
      6. wPulseMeas = timer0
      7. timer0 = 0
      8. incr bPulseCount
      9. end if
      10. return
      Und in der Schleife sollte es dann heißen:

      Quellcode

      1. do
      2. if wPulse > wPulseMin and wPulse < wPulseMax then
      3. wPulseMin = wPulse - PulseTolerance
      4. wPulseMax = wPulse + PulseTolerance
      5. end if
      6. Loop until bPulseCount = ReadRepeat
      7. bPulseCount = 0

      In 107, 108 habe ich bisher kein Problem feststellen können. Die Wartezeiten braucht es auch, um den zu messenden Kanal an der Fernsteuerung in die beiden Endstellungen zu bringen. Wenn die Wartezeiten kürzer sind, brauchte es mehrere Durchläufe, bis ein stimmiges Ergebnis erzielt wird.
      Beste Grüße
      Jürgen
    • JuWi schrieb:

      In 107, 108 habe ich bisher kein Problem feststellen können.
      Wpulsewidth = Wpulsewidth - Farrangeon
      Das Problem, das ich in Zeile 107 sehe, ist, wenn
      Wpulsewith kleiner als Farrangeon ist.
      Wie würdest du denn sonst nach der Berechnung einen PWM-Wert von 2 erklären?

      Du hast ein LC-Display und gibst in den Zeilen 131 und 149 den Wert von wpulse aus.
      Damit kannst du ja die Rechnung nachvollziehen.
      Zum Debuggen lassen sich sicher auch noch die anderen beteiligten Werte ausgeben, Farrangeon z.B.
      Da Zeile 108 von Zeile 107 abhängt, muss das Ergebnis dort auch nicht unbedingt richtig sein.


      JuWi schrieb:

      Die Idee hinter der Schleife bei Zeile 119 bis 128 ist, über mehrere Impulse abzuwarten, ob die Impulslänge gleich bleibt.
      Dann kannst du dir die Abfrage in Zeile 120 sparen, weil die Bedingung immer erfüllt ist durch die Berechnungen in Zeile 117+118
      Wenn ich mir die Zeile 119 bis 128 genauer anschaue, stelle ich fest, dass die Schleife 5 mal durchlaufen werden soll.
      Der Wert für den Fernsteuerimpuls wird aber nicht aktualisiert, das wurde in Zeile 116 vorher einmalig gemacht.
      Da anzunehmen ist, dass wpulse erstmal größer ist als wpulsetolerance, ist die Bedingung erfüllt und wpulsemin jedesmal um 3 verringert (5x)
      Das gleiche mit wpulsemax in die andere Richtung.
      Da sich wpulse nicht ändert, ist das erstmal nicht ganz so schlimm.
      Die Schleife hat also nichts gebracht, außer 125ms zu warten und die Toleranz um +/- 3 zu erweitern.

      Die anderen Bestandteile deines Programms habe ich noch nicht näher beleuchtet, da fehlt mir momentan die Zeit.
      Ich würde an deiner Stelle hier einen Schnitt machen und das ganze von vorn anfangen.
      Ohne abschreiben.
      Also mit einem Timer den Puls gescheit erfassen und die LED sauber schalten lassen.
      Dann die PWM dazu nehmen und erst am Schluss die Sache mit den Toleranzen einfügen.
      Die ganze Kopiererei bringt dir keinen Lerneffekt und deine Helfer haben Mühe, sich da reinzudenken und den ganzen Ballast zu erkennen.

      Hilfreich sind auch Tools wie Programmablaufplaner z.B. PAPDesigner von Friedrich Folkmann