Impulslänge einer Fernsteuerung messen - Finde den Fehler nicht...

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

    • Impulslänge einer Fernsteuerung messen - Finde den Fehler nicht...

      Hallo,
      sorry für den etwas nichtssagenden Titel, aber etwas Zielführenderes ist mir leider nicht eingefallen.
      Zu meinem Problem: Das folgende Programm soll die Impulslänge einer Fernsteuerung messen, das tut es auch. Falls kein Impuls kommt, soll eine Fehlermeldung ausgegeben werden; und da liegt der Fehler: Die LED an Port D.1 zeigt durch Blinken auch brav das fehlende Signal an, aber die Ausgabe aufs LC-Display (Zeile 134-142) klappt nicht. Dieser Zweig des Programms wird nicht aufgerufen, obwohl ich wie gesagt dafür keine Ursache finden kann. Erhöhen des Zählers bPulseError per incr sollte nach einiger Zeit doch die per Konstante eingestellte Schwelle ErrorTolerance erreichen.

      Source Code

      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 = &B00000010 'PinD0, 2-7 input, D1 output
      19. ' 76543210
      20. Portd = &B11111101 'PullUp PinD0, 2-7 active
      21. '----- Constants ---------------------------------------------------------------
      22. const ReadRepeat = 5 'necessary pulse readings before program continues
      23. const ErrorTolerance = 10 'number of errors before showing error condition
      24. '----- Variables ---------------------------------------------------------------
      25. dim wPulse as word 'stores current reading of RC signal
      26. dim wPulseMin as word : dim wPulseMax as word
      27. dim wPulseMeas as word : dim wPulseWidth as word
      28. dim bCount as byte 'loop counter
      29. dim bPulseError as byte 'error counter
      30. dim bPulseRead as byte 'indicate pulse readings
      31. FeedBack alias PortD.1 'feedback about signal errors
      32. SignalRead alias bPulseRead.0 'handles signal readings
      33. RC_In alias pind.2 'INT0 to read RC signal
      34. '----- Initialization ----------------------------------------------------------
      35. config lcd = 16x2 'LCD used in 4-bit-mode
      36. config Lcdpin = Pin , Db4 = Lcd_db4 , Db5 = Lcd_db5 , Db6 = Lcd_db6 , Db7 = Lcd_db7 , E = Lcd_e , Rs = Lcd_rs
      37. initlcd
      38. cls
      39. config timer0 = timer , prescale = 8
      40. config int0 = change
      41. on int0 GetPulse
      42. config timer1 = timer, prescale = 8 'timer overflow each 0,5 s
      43. on timer1 MisPulse
      44. wPulse = 0 : wPulseMeas = 0
      45. wPulseMax = 0 : wPulseMin = 65535 : wPulseWidth = 0
      46. Timer0 = 0 : timer1 = 0
      47. bPulseError = 0
      48. '===== Program =================================================================
      49. enable Timer0
      50. enable int0
      51. enable interrupts
      52. '----- Part 1 - Measures minimum pulse length ----------------------------------
      53. upperline : lcd "RC SigMeas 8bit"
      54. lowerline : lcd "Mes. Low "
      55. for bCount = 9 to 0 step -1
      56. locate 2 , 10 : lcd bCount
      57. waitms 300
      58. next bCount
      59. wPulseMin = wPulseMeas
      60. lowerline : lcd "MinPulse " ; wPulseMin ; spc(5)
      61. wait 2
      62. '----- Part 2 - Measures maximum pulse length ----------------------------------
      63. lowerline : locate 2 , 1 : lcd "Mes.High " ; spc(5)
      64. for bCount = 9 to 0 Step -1
      65. locate 2 , 10 : lcd bCount
      66. Waitms 300
      67. Next bCount
      68. wPulseMax = wPulseMeas
      69. lowerline : Lcd "MaxPulse " ; wPulseMax ; spc(5)
      70. Wait 2
      71. '----- Part 3 - Calculates pulse width and shows result at LCD -----------------
      72. if wPulseMin > wPulseMax then
      73. wPulseWidth = wPulseMin - wPulseMax
      74. else
      75. wPulseWidth = wPulseMax - wPulseMin
      76. end if
      77. lowerline : lcd "Pulse width " ; wPulseWidth
      78. wait 3
      79. '----- Part 4 - Summarizes results ---------------------------------------------
      80. upperline : home
      81. lcd "L" : lcd wPulseMin ; " H" ; wPulseMax
      82. lcd " W" ; wPulseWidth ; spc(8)
      83. '----- Part 5 - Main: Measures current pulse length and shows results at LCD ---
      84. lowerline : locate 2 , 1 : lcd "P-Length" ; spc(8)
      85. enable timer1 : start timer1
      86. Do
      87. SignalRead = 0 : wPulse = 0 : bCount = 0 'reset variables & counter
      88. do
      89. if SignalRead = 1 then
      90. wPulse = wPulse + wPulseMeas 'sum of pulse readings
      91. SignalRead = 0
      92. incr bCount
      93. end if
      94. Loop until bCount = ReadRepeat
      95. wPulse = wPulse / ReadRepeat 'average of pulse readings
      96. locate 2 , 10 'shows current pulse length
      97. lcd wPulse ; spc(8)
      98. If bPulseError > ErrorTolerance Then
      99. Stop Timer1
      100. locate 2, 10 : lcd "Error"
      101. waitms 500
      102. timer1 = 0
      103. start timer1
      104. bPulseError = 0 'reset counter
      105. Feedback = 0
      106. end if
      107. Loop
      108. End 'end program
      109. '===== End of program ==========================================================
      110. '----- Interrupts --------------------------------------------------------------
      111. GetPulse:
      112. if RC_In = 1 then 'start Timer0 if positive signal on input
      113. start Timer0
      114. Else 'stop Timer0 if no positive signal
      115. stop Timer0
      116. wPulseMeas = timer0
      117. Timer0 = 0
      118. SignalRead = 1
      119. Timer1 = 0
      120. end if
      121. return
      122. MisPulse:
      123. incr bPulseError
      124. toggle Feedback
      125. timer1 = 0
      126. return
      Display All
      Beste Grüße
      Jürgen
    • JuWi wrote:

      If bPulseError > ErrorTolerance Then
      Stop Timer1
      locate 2, 10 : lcd "Error"
      waitms 500
      timer1 = 0
      start timer1
      bPulseError = 0 'reset counter
      Feedback = 0
      end if
      Hier würde ich die Abfrage etwas anders machen

      BASCOM Source Code

      1. If bPulseError >= ErrorTolerance Then
      2. Disable Timer1
      3. locate 2, 10 : lcd "Error"
      4. waitms 500
      5. timer1 = 0
      6. Enable timer1
      7. bPulseError = 0 'reset counter
      8. Feedback = 0
      9. end if
      Und soweit ich weiss funktioniert Start und Stop Timer1 nicht richtig. Also mit Disable und Enable arbeiten.
      Eine Lösung habe ich nicht, aber mir gefällt Ihr Problem.
    • @djmsc: Gilt das auch für den Timer0?
      @Michael: in GetPulse wird doch bPulseError nicht verändert, wie wird dann der Wert gelöscht? Wenn ich den Wert in der Anzeigeschleife zurücksetze, dann geht das Spiel halt von vorne los (das war auch das Ziel), soll heißen, bei einem nach wie vor fehlenden Signal kommt die Anzeige noch mal (solange, bis ein Signal anliegt)
      Beste Grüße
      Jürgen
    • @Michael: O.k. jetzt hab' ich's. Meine Überlegung war, den Zähler laufen zu lassen, um z.B. eine Situation erkennen zu können, bei der neben gültigen Impulsen ab und an welche nicht erkannt werden. Aber das dürfte wohl mit einem zweiten "Langzeit-Zähler" besser zu erkennen sein.
      Beste Grüße
      Jürgen
    • Hallo,
      o.k., hier noch einmal die aktuelle Version meines Programms:

      Source Code

      1. $regfile = "m16DEF.Dat"
      2. $crystal = 1000000 'Frequency 1 MHz
      3. $hwstack = 48
      4. $swstack = 20
      5. $framesize = 32
      6. '----- Settings for Pollin Evaluation Board -----
      7. ' Port selected as given by addon board to use jumpers instead of cables to ports
      8. Lcd_db4 alias Porta.4
      9. Lcd_db5 alias Porta.5
      10. Lcd_db6 alias Porta.6
      11. Lcd_db7 alias Porta.7
      12. Lcd_e alias Portb.0
      13. Lcd_rs alias Portb.2
      14. config Portb.1 = output 'R/W of LCD to be connected to GND
      15. reset Portb.1 'PortB.1 set to GND
      16. ' 76543210
      17. Ddrd = &B00000010 'PinD0, 2-7 input, D1 output
      18. ' 76543210
      19. Portd = &B11111101 'PullUp PinD0, 2-7 active
      20. '----- Constants ---------------------------------------------------------------
      21. const ReadRepeat = 5 'necessary pulse readings before program continues
      22. const ErrorTolerance = 10 'number of errors before showing error condition
      23. '----- Variables ---------------------------------------------------------------
      24. dim wPulse as word 'stores current reading of RC signal
      25. dim wPulseMin as word : dim wPulseMax as word
      26. dim wPulseMeas as word : dim wPulseWidth as word
      27. dim bCount as byte 'loop counter
      28. dim bPulseError as byte 'error counter
      29. dim bPulseRead as byte 'indicate pulse readings
      30. FeedBack alias PortD.1 'feedback about signal errors
      31. SignalRead alias bPulseRead.0 'handles signal readings
      32. RC_In alias pind.2 'INT0 to read RC signal
      33. '----- Initialization ----------------------------------------------------------
      34. config lcd = 16x2 'LCD used in 4-bit-mode
      35. config Lcdpin = Pin , Db4 = Lcd_db4 , Db5 = Lcd_db5 , Db6 = Lcd_db6 , Db7 = Lcd_db7 , E = Lcd_e , Rs = Lcd_rs
      36. initlcd
      37. cls
      38. config timer0 = timer , prescale = 8
      39. config int0 = change
      40. on int0 GetPulse
      41. config timer1 = timer, prescale = 8 'timer overflow each 0,5 s
      42. on timer1 MisPulse
      43. wPulse = 0 : wPulseMeas = 0
      44. wPulseMax = 0 : wPulseMin = 65535 : wPulseWidth = 0
      45. Timer0 = 0 : timer1 = 0
      46. bPulseError = 0
      47. '===== Program =================================================================
      48. enable Timer0
      49. enable int0
      50. enable interrupts
      51. '----- Part 1 - Measures minimum pulse length ----------------------------------
      52. upperline : lcd "RC SigMeas 8bit"
      53. lowerline : lcd "Mes. Low "
      54. for bCount = 9 to 0 step -1
      55. locate 2 , 10 : lcd bCount
      56. waitms 300
      57. next bCount
      58. wPulseMin = wPulseMeas
      59. lowerline : lcd "MinPulse " ; wPulseMin ; spc(5)
      60. wait 2
      61. '----- Part 2 - Measures maximum pulse length ----------------------------------
      62. lowerline : locate 2 , 1 : lcd "Mes.High " ; spc(5)
      63. for bCount = 9 to 0 Step -1
      64. locate 2 , 10 : lcd bCount
      65. Waitms 300
      66. Next bCount
      67. wPulseMax = wPulseMeas
      68. lowerline : Lcd "MaxPulse " ; wPulseMax ; spc(5)
      69. Wait 2
      70. '----- Part 3 - Calculates pulse width and shows result at LCD -----------------
      71. if wPulseMin > wPulseMax then
      72. wPulseWidth = wPulseMin - wPulseMax
      73. else
      74. wPulseWidth = wPulseMax - wPulseMin
      75. end if
      76. lowerline : lcd "Pulse width " ; wPulseWidth
      77. wait 3
      78. '----- Part 4 - Summarizes results ---------------------------------------------
      79. upperline : home
      80. lcd "L" : lcd wPulseMin ; " H" ; wPulseMax
      81. lcd " W" ; wPulseWidth ; spc(8)
      82. '----- Part 5 - Main: Measures current pulse length and shows results at LCD ---
      83. lowerline : locate 2 , 1 : lcd "P-Length" ; spc(8)
      84. enable timer1 : start timer1
      85. Do
      86. SignalRead = 0 : wPulse = 0 : bCount = 0 'reset variables & counter
      87. do
      88. if SignalRead = 1 then
      89. wPulse = wPulse + wPulseMeas 'sum of pulse readings
      90. SignalRead = 0
      91. incr bCount
      92. end if
      93. Loop until bCount = ReadRepeat
      94. wPulse = wPulse / ReadRepeat 'average of pulse readings
      95. locate 2 , 10 'shows current pulse length
      96. lcd wPulse ; spc(8)
      97. If bPulseError >= ErrorTolerance Then
      98. 'Stop Timer1
      99. disable timer1
      100. locate 2, 10 : lcd "Error"
      101. waitms 500
      102. timer1 = 0
      103. 'start timer1
      104. enable timer1
      105. bPulseError = 0 'reset error counter
      106. Feedback = 0
      107. end if
      108. Loop
      109. End 'end program
      110. '===== End of program ==========================================================
      111. '----- Interrupts --------------------------------------------------------------
      112. GetPulse:
      113. if RC_In = 1 then 'start Timer0 if positive signal on input
      114. start Timer0
      115. Else 'stop Timer0 if no positive signal
      116. stop Timer0
      117. wPulseMeas = timer0
      118. Timer0 = 0
      119. SignalRead = 1
      120. Timer1 = 0
      121. bPulseError = 0 'reset error counter
      122. Feedback = 0 'reset error LED
      123. end if
      124. return
      125. MisPulse:
      126. incr bPulseError
      127. toggle Feedback
      128. timer1 = 0
      129. return
      Display All
      Das weiter oben beschriebene Verhalten hat sich nciht verändert. Der Zweig, der auf dem LC-Display einfach nur "Err" sagen soll (Zeile 134-144), wird nicht abgearbeitet. Die LED (Feedback) signalisiert aber bei fehlendem RC-Impuls diese Situation durch Blinken. Also interpretiere ich das so, dass der Timer1-Overflow funktioniert und damit auch bPulseError hochgezählt werden sollte. Nur verstehe ich nicht, warum der Vergleich (If bPulseError >= ErrorTolerance Then) nicht funktioniert, der nach einiger Zeit so etwas ergeben sollte wie "if 11 >= 10 then).

      @Lica: Die Impulslängenmessung funktioniert grundsätzlich auch mit dem Timer0, die gemessenen Werte bewegen sich natürlich in einem kleinerem Zahlenbereich als bei Timer1.
      Beste Grüße
      Jürgen
    • Hallo,
      so der "Fehler" ist gefunden, in Anführungsstrichen, weil es kein Fehler im Programm war, sondern mehr ein Denkfehler von mir. Der Programmteil, der auf dem Display den Fehler zeigen soll, wird natürlich nicht angesteuert, wenn der Fernsteuer-Impuls wegbleibt, während das Programm das mehrmalige Lesen und die Mittelwertberechnung ausführt. Das Ganze fällt so die Kategorie a_67_e210de67 a_67_e210de67 . Des Rätsels Lösung war dann das Veschieben dieser Abfrage in die Schleife zum Impulslesen.

      Zum Schluß noch das Programm, wie es jetzt auch läuft:

      BASCOM Source Code

      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 = &B00000010 'PinD0, 2-7 input, D1 output
      19. ' 76543210
      20. Portd = &B11111101 'PullUp PinD0, 2-7 active
      21. '----- Constants ---------------------------------------------------------------
      22. const ReadRepeat = 5 'necessary pulse readings before program continues
      23. const ErrorTolerance = 10 'number of errors before showing error condition
      24. '----- Variables ---------------------------------------------------------------
      25. dim wPulse as word 'stores current reading of RC signal
      26. dim wPulseMin as word : dim wPulseMax as word
      27. dim wPulseMeas as word : dim wPulseWidth as word
      28. dim bCount as byte 'loop counter
      29. dim bPulseError as byte 'error counter
      30. dim bPulseRead as byte 'indicate pulse readings
      31. FeedBack alias PortD.1 'feedback about signal errors
      32. SignalRead alias bPulseRead.0 'handles signal readings
      33. RC_In alias pind.2 'INT0 to read RC signal
      34. '----- Initialization ----------------------------------------------------------
      35. config lcd = 16x2 'LCD used in 4-bit-mode
      36. config Lcdpin = Pin , Db4 = Lcd_db4 , Db5 = Lcd_db5 , Db6 = Lcd_db6 , Db7 = Lcd_db7 , E = Lcd_e , Rs = Lcd_rs
      37. initlcd
      38. cls
      39. config timer0 = timer , prescale = 8
      40. config int0 = change
      41. on int0 GetPulse
      42. config timer1 = timer, prescale = 1 'timer overflow each 0,06 s
      43. on timer1 MisPulse
      44. wPulse = 0 : wPulseMeas = 0
      45. wPulseMax = 0 : wPulseMin = 65535 : wPulseWidth = 0
      46. Timer0 = 0 : timer1 = 0
      47. bPulseError = 0
      48. '===== Program =================================================================
      49. enable Timer0
      50. enable int0
      51. enable interrupts
      52. '----- Part 1 - Measures minimum pulse length ----------------------------------
      53. upperline : lcd "RC SigMeas 8bit"
      54. lowerline : lcd "Mes. Low "
      55. for bCount = 9 to 0 step -1
      56. locate 2 , 10 : lcd bCount
      57. waitms 300
      58. next bCount
      59. wPulseMin = wPulseMeas
      60. lowerline : lcd "MinPulse " ; wPulseMin ; spc(5)
      61. wait 2
      62. '----- Part 2 - Measures maximum pulse length ----------------------------------
      63. lowerline : locate 2 , 1 : lcd "Mes.High " ; spc(5)
      64. for bCount = 9 to 0 Step -1
      65. locate 2 , 10 : lcd bCount
      66. Waitms 300
      67. Next bCount
      68. wPulseMax = wPulseMeas
      69. lowerline : Lcd "MaxPulse " ; wPulseMax ; spc(5)
      70. Wait 2
      71. '----- Part 3 - Calculates pulse width and shows result at LCD -----------------
      72. if wPulseMin > wPulseMax then
      73. wPulseWidth = wPulseMin - wPulseMax
      74. else
      75. wPulseWidth = wPulseMax - wPulseMin
      76. end if
      77. lowerline : lcd "Pulse width " ; wPulseWidth
      78. wait 3
      79. '----- Part 4 - Summarizes results ---------------------------------------------
      80. upperline : home
      81. lcd "L" : lcd wPulseMin ; " H" ; wPulseMax
      82. lcd " W" ; wPulseWidth ; spc(8)
      83. '----- Part 5 - Main: Measures current pulse length and shows results at LCD ---
      84. lowerline : locate 2 , 1 : lcd "P-Length" ; spc(8)
      85. enable timer1 : start timer1
      86. Do
      87. SignalRead = 0 : wPulse = 0 : bCount = 0 'reset variables & counter
      88. do
      89. if SignalRead = 1 then
      90. wPulse = wPulse + wPulseMeas 'sum of pulse readings
      91. SignalRead = 0
      92. incr bCount
      93. end if
      94. If bPulseError >= ErrorTolerance Then
      95. Stop Timer1
      96. locate 2, 10 : lcd "Error" : waitms 500
      97. timer1 = 0 : start timer1
      98. bPulseError = 0 'reset error counter
      99. Feedback = 0
      100. end if
      101. Loop until bCount = ReadRepeat
      102. wPulse = wPulse / ReadRepeat 'average of pulse readings
      103. locate 2 , 10 'shows current pulse length
      104. lcd wPulse ; spc(8)
      105. Loop
      106. End 'end program
      107. '===== End of program ==========================================================
      108. '----- Interrupts --------------------------------------------------------------
      109. GetPulse:
      110. if RC_In = 1 then 'start Timer0 if positive signal on input
      111. start Timer0
      112. Else 'stop Timer0 if no positive signal
      113. stop Timer0
      114. wPulseMeas = timer0
      115. Timer0 = 0
      116. SignalRead = 1
      117. Timer1 = 0
      118. Feedback = 0 'reset error LED
      119. end if
      120. return
      121. MisPulse:
      122. incr bPulseError
      123. toggle Feedback
      124. timer1 = 0
      125. return
      Display All
      a_67_e210de67
      Beste Grüße
      Jürgen