Servo Drehgeschwindigkeit verlangsamen "Slow Down Tiny"

    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!

    • Ich hatte vor langer Zeit auch mit dem speicherarmen Attiny13 experimentiert. Aus einem alten Projekt hab ich den folgenden Code zusammenkopiert. Die 4,8Mhz zusammen mit nur einem 8-Bit Timer lassen nur begrenzte Auflösung zu, aber vielleicht probierst Du ihn einfach mal (kann den Code nicht testen, da kein Attiny13 vorhanden). Der Vorteil von diesem Code wäre, dass die Werte (Eingangs- und Ausgabewerte) nicht umgerechnet werden müssten. Wichtig: Das RC-Eingangssignal muss an PortB2/INT0 eingespeist werden! Den Servo Pin kannst Du dagegen im Code selbst festlegen.

      Nette Grüße
      Robert

      BASCOM-Quellcode

      1. ' Projekt: Verzögerte RC-Ausgabe mit Poti
      2. ' Autor: R. Link 2020
      3. ' BascomAVR: 2.0.8.2
      4. ' Version: 0.0.1
      5. $regfile "attiny13.dat"
      6. $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
      7. $hwstack = 16
      8. $swstack = 8
      9. $framesize = 24
      10. ' -----------------------------------------
      11. ' Timer konfigurieren
      12. ' -----------------------------------------
      13. Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
      14. On Timer0 RC_ISR
      15. ' -----------------------------------------
      16. ' ISR für Einlesen des RC-Signals konfigurieren
      17. ' -----------------------------------------
      18. Config Int0 = Change ' Beim Flankenwechsel an PB2/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
      19. Enable Int0 ' Int0 freigeben
      20. On Int0 RC_ISR
      21. ' -----------------------------------------
      22. ' Servo-Pin festlegen
      23. ' -----------------------------------------
      24. Servo_Pin Alias PortB.1 ' Hier den Ausgangspin des Servosignals festlegen
      25. Config Servo_Pin = Output
      26. ' -----------------------------------------
      27. ' Variablen
      28. ' -----------------------------------------
      29. 'Variablen fürs RC Einlesen
      30. Dim Flag_Eingabe_Ausgabe As Bit
      31. Dim RC_Eingangswert As Byte
      32. 'Variablen für Servoausgabe
      33. Dim Servoausgabe_Wert As Byte
      34. ' -----------------------------------------
      35. ' Startwerte setzen
      36. ' -----------------------------------------
      37. Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
      38. Waitms 500
      39. Enable Interrupts
      40. ' -----------------------------------------
      41. ' Hauptprogramm
      42. ' -----------------------------------------
      43. Do
      44. Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
      45. Loop
      46. End
      47. ' ======================================================
      48. ' RC_ISR
      49. ' ======================================================
      50. RC_ISR:
      51. If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
      52. If Pinb.2 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
      53. Timer0 = 0 ' ...den Timer auf 0 setzen
      54. Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
      55. RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
      56. Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
      57. Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
      58. Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
      59. Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
      60. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      61. End If
      62. Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
      63. Servo_Pin = 0 ' Servo_Pin abschalten
      64. Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
      65. Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
      66. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      67. End If
      68. Return
      Alles anzeigen
    • Hallo zusammen,

      erstmal vielen Dank für Eure Hilfe.

      Michael, der Eingang ist da. Wenn ich das Servo direkt an PB0 anschließe, funktioniert es einwandfrei.

      Pluto, ich habe es auch mit den " *25 " versucht. Auch hier leider ohne Erfolg.

      Robert, vielen Dank für das komplett Programm. Habe die Hardware entsprechend umgeändert. Also Servosignal kommend an PB2 und Servoausgang an PB1. Auch hier leider ohne jegliche Funktion.
    • Hallo Sven

      Vielleicht ist irgend was vom Servo-Ausgang nicht ok.

      Schreib doch mal deine Hauptschleife wie folgt. (Dein Code remmen)

      BASCOM-Quellcode

      1. ' Hauptschleife
      2. Do
      3. PortB.1 = PinB.0 ' Eingang direkt auf Ausgang übergeben
      4. Loop

      Der Rest in deinem Programm bleibt unverändert.

      So müsste der Eingangs-Pegel direkt auf den Ausgangspegel gelegt werden.
      Ein Servo an PortB.1 sollte also dem Signal vom Eingang PinB.0 direkt folgen.

      Wenn das so wie oben gezeigt funktioniert, ist die Hardware schon mal in Ordnung und du musst den Fehler im Programm suchen.

      Funktioniert dein Servo mit obiger Änderung nicht, dann stimmt was an der Hardware nicht.
    • Im nächsten Schritt würde ich in der Hauptschleife nur mal
      einen 1,5ms Puls mit PulseOut ausgeben lassen, gefolgt von einem Waitms 20.

      Der Servo sollte dann in Mittelstellung gehen.

      Do
      PulseOut ...
      Waitms 20
      Loop

      Wirst erst mal ausrechnen müssen, welchen Wert du da ausgeben musst für 1,5ms.

      Wenn es dann soweit funktioniert, kann man mal mit dem Poti den Servo steuern und schließlich
      wieder zu deinem Programm übergehen und den Servo-Wingang an den Ausgang geben (ohne Poti).

      Dann haste schon mal ne Basis.
    • Hab noch nen Fehler gefunden, versuch's mal mit dem Code.
      RC Einganssignale an PB1 (Pin 6)
      Servo an PB0 (Pin 5)

      BASCOM-Quellcode

      1. ' Projekt: Verzögerte RC-Ausgabe mit Poti
      2. ' Autor: R. Link 2020
      3. ' BascomAVR: 2.0.8.2
      4. ' Version: 0.0.2
      5. $regfile "attiny13.dat"
      6. $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
      7. $hwstack = 16
      8. $swstack = 8
      9. $framesize = 24
      10. ' -----------------------------------------
      11. ' Timer konfigurieren
      12. ' -----------------------------------------
      13. Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
      14. On Timer0 RC_ISR
      15. ' -----------------------------------------
      16. ' ISR für Einlesen des RC-Signals konfigurieren
      17. ' -----------------------------------------
      18. Config Int0 = Change ' Beim Flankenwechsel an PB1/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
      19. Enable Int0 ' Int0 freigeben
      20. On Int0 RC_ISR
      21. ' -----------------------------------------
      22. ' Servo-Pin festlegen
      23. ' -----------------------------------------
      24. Servo_Pin Alias PortB.0 ' Hier den Ausgangspin des Servosignals festlegen
      25. Config Servo_Pin = Output
      26. ' -----------------------------------------
      27. ' Variablen
      28. ' -----------------------------------------
      29. 'Variablen fürs RC Einlesen
      30. Dim Flag_Eingabe_Ausgabe As Bit
      31. Dim RC_Eingangswert As Byte
      32. 'Variablen für Servoausgabe
      33. Dim Servoausgabe_Wert As Byte
      34. ' -----------------------------------------
      35. ' Startwerte setzen
      36. ' -----------------------------------------
      37. Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
      38. Waitms 500
      39. Enable Interrupts
      40. ' -----------------------------------------
      41. ' Hauptprogramm
      42. ' -----------------------------------------
      43. Do
      44. Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
      45. Loop
      46. End
      47. ' ======================================================
      48. ' RC_ISR
      49. ' ======================================================
      50. RC_ISR:
      51. If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
      52. If Pinb.1 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
      53. Timer0 = 0 ' ...den Timer auf 0 setzen
      54. Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
      55. RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
      56. Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
      57. Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
      58. Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
      59. Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
      60. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      61. End If
      62. Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
      63. Servo_Pin = 0 ' Servo_Pin abschalten
      64. Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
      65. Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
      66. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      67. End If
      68. Return
      Alles anzeigen
    • Ich hab zwischenzeitlich versucht, dass Programm für einen Nano umzuschreiben. Hier zeigen sich immer wieder "Aussreißer" beim Einlesen des RC-Signals, die ich mir noch nicht so recht erklären kann, irgendwas funkt mir da hin und wieder dazwischen (liegt vielleicht an den benutzten "Print" Anweisungen?).
      Einen Code hab ich noch zum Testen für Dich. Das Poti kommt an PB4 (Pin3 des Attinys). Wie immer ungetestet :whistling:

      BASCOM-Quellcode

      1. ' Projekt: Verzögerte RC-Ausgabe mit Poti
      2. ' Autor: R. Link 2020
      3. ' BascomAVR: 2.0.8.2
      4. ' Version: 0.0.3
      5. $regfile "attiny13.dat"
      6. $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
      7. $hwstack = 16
      8. $swstack = 8
      9. $framesize = 24
      10. ' -----------------------------------------
      11. ' Timer konfigurieren
      12. ' -----------------------------------------
      13. Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
      14. On Timer0 RC_ISR
      15. ' -----------------------------------------
      16. ' ISR für Einlesen des RC-Signals konfigurieren
      17. ' -----------------------------------------
      18. Config Int0 = Change ' Beim Flankenwechsel an PB1/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
      19. Enable Int0 ' Int0 freigeben
      20. On Int0 RC_ISR
      21. ' -----------------------------------------
      22. ' ADC für Poti konfigurieren
      23. ' -----------------------------------------
      24. Config Adc = Single , Prescaler = Auto
      25. Start Adc
      26. ' -----------------------------------------
      27. ' Servo-Pin festlegen
      28. ' -----------------------------------------
      29. Servo_Pin Alias PortB.2 ' Hier den Ausgangspin des Servosignals festlegen
      30. Config Servo_Pin = Output
      31. ' -----------------------------------------
      32. ' Variablen
      33. ' -----------------------------------------
      34. 'Variablen fürs RC Einlesen
      35. Dim Flag_Eingabe_Ausgabe As Bit
      36. Dim RC_Eingangswert As Byte
      37. 'Variablen für Servoausgabe
      38. Dim Servoausgabe_Wert As Byte
      39. 'Variablen für Poti
      40. Dim Poti_Wert as Word
      41. Poti_Eingang Alias Getadc(2) ' Hier den Poti-Pin festlegen
      42. ' -----------------------------------------
      43. ' Startwerte setzen
      44. ' -----------------------------------------
      45. Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
      46. Waitms 500
      47. Enable Interrupts
      48. ' -----------------------------------------
      49. ' Hauptprogramm
      50. ' -----------------------------------------
      51. Do
      52. If Servoausgabe_Wert < RC_Eingangswert then
      53. Incr Servoausgabe_Wert
      54. End If
      55. If Servoausgabe_Wert > RC_Eingangswert then
      56. Decr Servoausgabe_Wert
      57. End If
      58. Poti_Wert = Poti_Eingang ' Getadc(2)
      59. Poti_Wert = Poti_Wert / 20 ' Wert auf brauchbare Größe bringen
      60. Waitms Poti_Wert
      61. 'Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
      62. Loop
      63. End
      64. ' ======================================================
      65. ' RC_ISR
      66. ' ======================================================
      67. RC_ISR:
      68. If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
      69. If Pinb.1 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
      70. Timer0 = 0 ' ...den Timer auf 0 setzen
      71. Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
      72. RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
      73. Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
      74. Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
      75. Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
      76. Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
      77. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      78. End If
      79. Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
      80. Servo_Pin = 0 ' Servo_Pin abschalten
      81. Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
      82. Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
      83. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      84. End If
      85. Return
      Alles anzeigen
    • "Waitms Poti_Wert" dürfte kaum ein Servo gut vertragen. Versuch mal die main loop mit dem

      Quellcode

      1. do
      2. Poti_Wert = Poti_Eingang
      3. Poti_Wert = Poti_Wert / 128
      4. If Servoausgabe_Wert < RC_Eingangswert then
      5. Servoausgabe_Wert = Servoausgabe_Wert + Poti_Wert
      6. If Servoausgabe_Wert > RC_Eingangswert then Servoausgabe_Wert = RC_Eingangswert
      7. End If
      8. If Servoausgabe_Wert > RC_Eingangswert then
      9. Servoausgabe_Wert = Servoausgabe_Wert + Poti_Wert
      10. If Servoausgabe_Wert < RC_Eingangswert then Servoausgabe_Wert = RC_Eingangswert
      11. End If
      12. Loop
      Alles anzeigen


      zu ersetzen.
    • Das Poti in meinem Code ist (sollte) für die Bewegungsgeschwindigkeit verantwortlich (sein), nicht für die Bewegung selbst.
      Ein reines Drehen am Poti zeigt bei stehendem Servo keine Wirkung.
      Wenn Du das RC-Eingangssignal umschaltest (von einem Anschlag zum anderen), sollte das Servo je nach Potistellung schneller oder langsamer fahren.

      Falls das nicht klappt, einfach Bescheid geben :)


      Nachtrag, versuch mal diesen Code ( "Reference = Avcc" wurde hinzugefügt)

      BASCOM-Quellcode

      1. ' Projekt: Verzögerte RC-Ausgabe mit Poti
      2. ' Autor: R. Link 2020
      3. ' BascomAVR: 2.0.8.2
      4. ' Version: 0.0.4
      5. $regfile "attiny13.dat"
      6. $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
      7. $hwstack = 16
      8. $swstack = 8
      9. $framesize = 24
      10. ' -----------------------------------------
      11. ' Timer konfigurieren
      12. ' -----------------------------------------
      13. Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
      14. On Timer0 RC_ISR
      15. ' -----------------------------------------
      16. ' ISR für Einlesen des RC-Signals konfigurieren
      17. ' -----------------------------------------
      18. Config Int0 = Change ' Beim Flankenwechsel an PB1/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
      19. Enable Int0 ' Int0 freigeben
      20. On Int0 RC_ISR
      21. ' -----------------------------------------
      22. ' ADC für Poti konfigurieren
      23. ' -----------------------------------------
      24. Config Adc = Single , Prescaler = Auto , Reference = Avcc
      25. Start Adc
      26. ' -----------------------------------------
      27. ' Servo-Pin festlegen
      28. ' -----------------------------------------
      29. Servo_Pin Alias PortB.2 ' Hier den Ausgangspin des Servosignals festlegen
      30. Config Servo_Pin = Output
      31. ' -----------------------------------------
      32. ' Variablen
      33. ' -----------------------------------------
      34. 'Variablen fürs RC Einlesen
      35. Dim Flag_Eingabe_Ausgabe As Bit
      36. Dim RC_Eingangswert As Byte
      37. 'Variablen für Servoausgabe
      38. Dim Servoausgabe_Wert As Byte
      39. 'Variablen für Poti
      40. Dim Poti_Wert as Word
      41. Poti_Eingang Alias Getadc(2) ' Hier den Poti-Pin festlegen
      42. ' -----------------------------------------
      43. ' Startwerte setzen
      44. ' -----------------------------------------
      45. Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
      46. Waitms 500
      47. Enable Interrupts
      48. ' -----------------------------------------
      49. ' Hauptprogramm
      50. ' -----------------------------------------
      51. Do
      52. If Servoausgabe_Wert < RC_Eingangswert then
      53. Incr Servoausgabe_Wert
      54. End If
      55. If Servoausgabe_Wert > RC_Eingangswert then
      56. Decr Servoausgabe_Wert
      57. End If
      58. Poti_Wert = Poti_Eingang ' Getadc(2)
      59. Poti_Wert = Poti_Wert / 20 ' Wert auf brauchbare Größe bringen
      60. Waitms Poti_Wert
      61. 'Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
      62. Loop
      63. End
      64. ' ======================================================
      65. ' RC_ISR
      66. ' ======================================================
      67. RC_ISR:
      68. If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
      69. If Pinb.1 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
      70. Timer0 = 0 ' ...den Timer auf 0 setzen
      71. Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
      72. RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
      73. Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
      74. Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
      75. Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
      76. Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
      77. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      78. End If
      79. Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
      80. Servo_Pin = 0 ' Servo_Pin abschalten
      81. Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
      82. Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
      83. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      84. End If
      85. Return
      Alles anzeigen

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von R2D2 Bastler ()

    • Freut mich :)

      Es kann allerdings passieren, dass Dein Servo hin und wieder zuckt. Dass passiert immer dann, wenn Dein RC-Eingangssignal genau auf einer Schaltschwelle zwischen 2 Werten liegt. Mal angenommen, Dein RC-Eingangssignal pendelt immer zwischen den Werten 100 und 101 hin und her. Dann regelt der Code immer nach und das Servo zuckt. Da würde ich persönlich noch ein Todband einbauen, also einen Toleranzbereich, den der Code dann ignoriert.

      Auf die Schnelle würde ich das in etwa so lösen (ungetestet):

      BASCOM-Quellcode

      1. ' Projekt: Verzögerte RC-Ausgabe mit Poti
      2. ' Autor: R. Link 2020
      3. ' BascomAVR: 2.0.8.2
      4. ' Version: 0.0.5
      5. $regfile "attiny13.dat"
      6. $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
      7. $hwstack = 16
      8. $swstack = 8
      9. $framesize = 24
      10. ' -----------------------------------------
      11. ' Timer konfigurieren
      12. ' -----------------------------------------
      13. Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
      14. On Timer0 RC_ISR
      15. ' -----------------------------------------
      16. ' ISR für Einlesen des RC-Signals konfigurieren
      17. ' -----------------------------------------
      18. Config Int0 = Change ' Beim Flankenwechsel an PB1/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
      19. Enable Int0 ' Int0 freigeben
      20. On Int0 RC_ISR
      21. ' -----------------------------------------
      22. ' ADC für Poti konfigurieren
      23. ' -----------------------------------------
      24. Config Adc = Single , Prescaler = Auto , Reference = Avcc
      25. Start Adc
      26. ' -----------------------------------------
      27. ' Servo-Pin festlegen
      28. ' -----------------------------------------
      29. Servo_Pin Alias PortB.2 ' Hier den Ausgangspin des Servosignals festlegen
      30. Config Servo_Pin = Output
      31. ' -----------------------------------------
      32. ' Variablen
      33. ' -----------------------------------------
      34. 'Variablen fürs RC Einlesen
      35. Dim Flag_Eingabe_Ausgabe As Bit
      36. Dim RC_Eingangswert As Byte
      37. 'Variablen für Servoausgabe
      38. Dim Servoausgabe_Wert As Byte
      39. 'Variablen für Poti
      40. Dim Poti_Wert as Word
      41. Poti_Eingang Alias Getadc(2) ' Hier den Poti-Pin festlegen
      42. 'Variablen für Berechnungen
      43. Dim Tod_Bereich as Byte
      44. ' -----------------------------------------
      45. ' Startwerte setzen
      46. ' -----------------------------------------
      47. Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
      48. Waitms 500
      49. Enable Interrupts
      50. ' -----------------------------------------
      51. ' Hauptprogramm
      52. ' -----------------------------------------
      53. Do
      54. If Servoausgabe_Wert < RC_Eingangswert Then
      55. Tod_Bereich = RC_Eingangswert - 1
      56. If Tod_Bereich < Servoausgabe_Wert Then
      57. Incr Servoausgabe_Wert
      58. End If
      59. End If
      60. If Servoausgabe_Wert > RC_Eingangswert Then
      61. Tod_Bereich = RC_Eingangswert + 1
      62. If Tod_Bereich > Servoausgabe_Wert Then
      63. Decr Servoausgabe_Wert
      64. End If
      65. End If
      66. Poti_Wert = Poti_Eingang ' Getadc(2)
      67. Poti_Wert = Poti_Wert / 20 ' Wert auf brauchbare Größe bringen
      68. Waitms Poti_Wert
      69. 'Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
      70. Loop
      71. End
      72. ' ======================================================
      73. ' RC_ISR
      74. ' ======================================================
      75. RC_ISR:
      76. If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
      77. If Pinb.1 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
      78. Timer0 = 0 ' ...den Timer auf 0 setzen
      79. Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
      80. RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
      81. Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
      82. Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
      83. Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
      84. Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
      85. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      86. End If
      87. Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
      88. Servo_Pin = 0 ' Servo_Pin abschalten
      89. Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
      90. Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
      91. Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
      92. End If
      93. Return
      Alles anzeigen
      Hier dürfte der Eingangswert +-1 schwanken, ohne dass es Auswirkungen auf den Ausgabewert hätte :)


      Man könnte es sogar noch weiter treiben: Du hättest ja noch 2 weitere Pins am Attiny frei. Als "Luxusvariante" könntest Du dort 2 weitere Potis anschließen, und somit sogar noch die Endstellungen des Servos einstellbar machen a_38_b45e201d

      Nette Grüße
      Robert