Ok, vielen Dank. Habe es mal so versucht. Leider ohne Ergebnis. Das Servo bewegt sich garnicht.
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!
-
-
Nimm doch mal das Programm Servotester und brenne es auf einen Attiny.Die Werte für 9,6Mhz werden
sich verschieben.
Funktion:
von links nach rechts Schrittzahl x
Werte in einer For-Nextschleife einfügen.
Schrittgeschwindigkeit = Step positv oder negativ. -
Sven Loeffler schrieb:
Ok, vielen Dank. Habe es mal so versucht. Leider ohne Ergebnis. Das Servo bewegt sich garnicht.
Massen verbunden? -
Das "Ppm = Ppm * 25" fehlt?
-
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
- ' Projekt: Verzögerte RC-Ausgabe mit Poti
- ' Autor: R. Link 2020
- ' BascomAVR: 2.0.8.2
- ' Version: 0.0.1
- $regfile "attiny13.dat"
- $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
- $hwstack = 16
- $swstack = 8
- $framesize = 24
- ' -----------------------------------------
- ' Timer konfigurieren
- ' -----------------------------------------
- Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
- On Timer0 RC_ISR
- ' -----------------------------------------
- ' ISR für Einlesen des RC-Signals konfigurieren
- ' -----------------------------------------
- Config Int0 = Change ' Beim Flankenwechsel an PB2/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
- Enable Int0 ' Int0 freigeben
- On Int0 RC_ISR
- ' -----------------------------------------
- ' Servo-Pin festlegen
- ' -----------------------------------------
- Servo_Pin Alias PortB.1 ' Hier den Ausgangspin des Servosignals festlegen
- Config Servo_Pin = Output
- ' -----------------------------------------
- ' Variablen
- ' -----------------------------------------
- 'Variablen fürs RC Einlesen
- Dim Flag_Eingabe_Ausgabe As Bit
- Dim RC_Eingangswert As Byte
- 'Variablen für Servoausgabe
- Dim Servoausgabe_Wert As Byte
- ' -----------------------------------------
- ' Startwerte setzen
- ' -----------------------------------------
- Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
- Waitms 500
- Enable Interrupts
- ' -----------------------------------------
- ' Hauptprogramm
- ' -----------------------------------------
- Do
- Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
- Loop
- End
- ' ======================================================
- ' RC_ISR
- ' ======================================================
- RC_ISR:
- If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
- If Pinb.2 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
- Timer0 = 0 ' ...den Timer auf 0 setzen
- Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
- RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
- Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
- Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
- Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
- Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
- Servo_Pin = 0 ' Servo_Pin abschalten
- Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
- Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Return
-
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)
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. -
Oh Mist, ich seh gerade, das INT0 der PB1 ist.
Also das RC Eingangssignal an PB1 (Pin6)
und für das Ausgangssignal einen anderen Pin im Code festlegen und nochmal brennen. Vielleicht klappts dann. -
Mitch, ich habe es mal so versucht. Servo funktioniert dann einwandfrei. 1:1 als wäre es am der Steuerung angeschlossen. Also Fehler im Programm.
Robert, ich habe es nochmal geändert, den PB0 als Ausgang gesetzt und das Signal an PB1 angeschlossen. Das Servo bewegt sich zwar, aber relativ undefiniert. -
Kann es, wie gesagt, leider nicht testen. Vielleicht find ich noch einen Fehler.
-
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
- ' Projekt: Verzögerte RC-Ausgabe mit Poti
- ' Autor: R. Link 2020
- ' BascomAVR: 2.0.8.2
- ' Version: 0.0.2
- $regfile "attiny13.dat"
- $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
- $hwstack = 16
- $swstack = 8
- $framesize = 24
- ' -----------------------------------------
- ' Timer konfigurieren
- ' -----------------------------------------
- Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
- On Timer0 RC_ISR
- ' -----------------------------------------
- ' ISR für Einlesen des RC-Signals konfigurieren
- ' -----------------------------------------
- Config Int0 = Change ' Beim Flankenwechsel an PB1/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
- Enable Int0 ' Int0 freigeben
- On Int0 RC_ISR
- ' -----------------------------------------
- ' Servo-Pin festlegen
- ' -----------------------------------------
- Servo_Pin Alias PortB.0 ' Hier den Ausgangspin des Servosignals festlegen
- Config Servo_Pin = Output
- ' -----------------------------------------
- ' Variablen
- ' -----------------------------------------
- 'Variablen fürs RC Einlesen
- Dim Flag_Eingabe_Ausgabe As Bit
- Dim RC_Eingangswert As Byte
- 'Variablen für Servoausgabe
- Dim Servoausgabe_Wert As Byte
- ' -----------------------------------------
- ' Startwerte setzen
- ' -----------------------------------------
- Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
- Waitms 500
- Enable Interrupts
- ' -----------------------------------------
- ' Hauptprogramm
- ' -----------------------------------------
- Do
- Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
- Loop
- End
- ' ======================================================
- ' RC_ISR
- ' ======================================================
- RC_ISR:
- If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
- If Pinb.1 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
- Timer0 = 0 ' ...den Timer auf 0 setzen
- Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
- RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
- Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
- Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
- Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
- Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
- Servo_Pin = 0 ' Servo_Pin abschalten
- Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
- Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Return
-
Robert, ich habe es nochmal mit deinem Programm versucht. Was soll ich sagen, es funktioniert. Der Servo bewegt sich einwandfrei.
-
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
BASCOM-Quellcode
- ' Projekt: Verzögerte RC-Ausgabe mit Poti
- ' Autor: R. Link 2020
- ' BascomAVR: 2.0.8.2
- ' Version: 0.0.3
- $regfile "attiny13.dat"
- $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
- $hwstack = 16
- $swstack = 8
- $framesize = 24
- ' -----------------------------------------
- ' Timer konfigurieren
- ' -----------------------------------------
- Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
- On Timer0 RC_ISR
- ' -----------------------------------------
- ' ISR für Einlesen des RC-Signals konfigurieren
- ' -----------------------------------------
- Config Int0 = Change ' Beim Flankenwechsel an PB1/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
- Enable Int0 ' Int0 freigeben
- On Int0 RC_ISR
- ' -----------------------------------------
- ' ADC für Poti konfigurieren
- ' -----------------------------------------
- Config Adc = Single , Prescaler = Auto
- Start Adc
- ' -----------------------------------------
- ' Servo-Pin festlegen
- ' -----------------------------------------
- Servo_Pin Alias PortB.2 ' Hier den Ausgangspin des Servosignals festlegen
- Config Servo_Pin = Output
- ' -----------------------------------------
- ' Variablen
- ' -----------------------------------------
- 'Variablen fürs RC Einlesen
- Dim Flag_Eingabe_Ausgabe As Bit
- Dim RC_Eingangswert As Byte
- 'Variablen für Servoausgabe
- Dim Servoausgabe_Wert As Byte
- 'Variablen für Poti
- Dim Poti_Wert as Word
- Poti_Eingang Alias Getadc(2) ' Hier den Poti-Pin festlegen
- ' -----------------------------------------
- ' Startwerte setzen
- ' -----------------------------------------
- Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
- Waitms 500
- Enable Interrupts
- ' -----------------------------------------
- ' Hauptprogramm
- ' -----------------------------------------
- Do
- If Servoausgabe_Wert < RC_Eingangswert then
- Incr Servoausgabe_Wert
- End If
- If Servoausgabe_Wert > RC_Eingangswert then
- Decr Servoausgabe_Wert
- End If
- Poti_Wert = Poti_Eingang ' Getadc(2)
- Poti_Wert = Poti_Wert / 20 ' Wert auf brauchbare Größe bringen
- Waitms Poti_Wert
- 'Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
- Loop
- End
- ' ======================================================
- ' RC_ISR
- ' ======================================================
- RC_ISR:
- If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
- If Pinb.1 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
- Timer0 = 0 ' ...den Timer auf 0 setzen
- Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
- RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
- Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
- Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
- Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
- Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
- Servo_Pin = 0 ' Servo_Pin abschalten
- Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
- Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Return
-
Habe es versucht. Poti Schleifer an PB4. Der Rest an VCC bzw. GND. Das Servo bewegt sich jedoch nicht. Egal in welcher Stellung das Poti steht.
-
"Waitms Poti_Wert" dürfte kaum ein Servo gut vertragen. Versuch mal die main loop mit dem
Quellcode
- do
- Poti_Wert = Poti_Eingang
- Poti_Wert = Poti_Wert / 128
- If Servoausgabe_Wert < RC_Eingangswert then
- Servoausgabe_Wert = Servoausgabe_Wert + Poti_Wert
- If Servoausgabe_Wert > RC_Eingangswert then Servoausgabe_Wert = RC_Eingangswert
- End If
- If Servoausgabe_Wert > RC_Eingangswert then
- Servoausgabe_Wert = Servoausgabe_Wert + Poti_Wert
- If Servoausgabe_Wert < RC_Eingangswert then Servoausgabe_Wert = RC_Eingangswert
- End If
- Loop
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
- ' Projekt: Verzögerte RC-Ausgabe mit Poti
- ' Autor: R. Link 2020
- ' BascomAVR: 2.0.8.2
- ' Version: 0.0.4
- $regfile "attiny13.dat"
- $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
- $hwstack = 16
- $swstack = 8
- $framesize = 24
- ' -----------------------------------------
- ' Timer konfigurieren
- ' -----------------------------------------
- Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
- On Timer0 RC_ISR
- ' -----------------------------------------
- ' ISR für Einlesen des RC-Signals konfigurieren
- ' -----------------------------------------
- Config Int0 = Change ' Beim Flankenwechsel an PB1/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
- Enable Int0 ' Int0 freigeben
- On Int0 RC_ISR
- ' -----------------------------------------
- ' ADC für Poti konfigurieren
- ' -----------------------------------------
- Config Adc = Single , Prescaler = Auto , Reference = Avcc
- Start Adc
- ' -----------------------------------------
- ' Servo-Pin festlegen
- ' -----------------------------------------
- Servo_Pin Alias PortB.2 ' Hier den Ausgangspin des Servosignals festlegen
- Config Servo_Pin = Output
- ' -----------------------------------------
- ' Variablen
- ' -----------------------------------------
- 'Variablen fürs RC Einlesen
- Dim Flag_Eingabe_Ausgabe As Bit
- Dim RC_Eingangswert As Byte
- 'Variablen für Servoausgabe
- Dim Servoausgabe_Wert As Byte
- 'Variablen für Poti
- Dim Poti_Wert as Word
- Poti_Eingang Alias Getadc(2) ' Hier den Poti-Pin festlegen
- ' -----------------------------------------
- ' Startwerte setzen
- ' -----------------------------------------
- Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
- Waitms 500
- Enable Interrupts
- ' -----------------------------------------
- ' Hauptprogramm
- ' -----------------------------------------
- Do
- If Servoausgabe_Wert < RC_Eingangswert then
- Incr Servoausgabe_Wert
- End If
- If Servoausgabe_Wert > RC_Eingangswert then
- Decr Servoausgabe_Wert
- End If
- Poti_Wert = Poti_Eingang ' Getadc(2)
- Poti_Wert = Poti_Wert / 20 ' Wert auf brauchbare Größe bringen
- Waitms Poti_Wert
- 'Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
- Loop
- End
- ' ======================================================
- ' RC_ISR
- ' ======================================================
- RC_ISR:
- If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
- If Pinb.1 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
- Timer0 = 0 ' ...den Timer auf 0 setzen
- Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
- RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
- Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
- Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
- Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
- Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
- Servo_Pin = 0 ' Servo_Pin abschalten
- Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
- Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Return
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von R2D2 Bastler ()
-
Robert, es funktioniert mit deinem Programm. Super, vielen lieben Dank für eure Hilfe !
-
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
- ' Projekt: Verzögerte RC-Ausgabe mit Poti
- ' Autor: R. Link 2020
- ' BascomAVR: 2.0.8.2
- ' Version: 0.0.5
- $regfile "attiny13.dat"
- $crystal = 4800000 ' Taktfrequenz (4,8Mhz)
- $hwstack = 16
- $swstack = 8
- $framesize = 24
- ' -----------------------------------------
- ' Timer konfigurieren
- ' -----------------------------------------
- Config Timer0 = Timer , Prescale = 64 ' Timer für Servoausgabe, Wert 75 entspricht 1ms, Wert 150 entspricht 2ms
- On Timer0 RC_ISR
- ' -----------------------------------------
- ' ISR für Einlesen des RC-Signals konfigurieren
- ' -----------------------------------------
- Config Int0 = Change ' Beim Flankenwechsel an PB1/INT0 (RC Eingang) Int0 auslösen und in die ISR springen
- Enable Int0 ' Int0 freigeben
- On Int0 RC_ISR
- ' -----------------------------------------
- ' ADC für Poti konfigurieren
- ' -----------------------------------------
- Config Adc = Single , Prescaler = Auto , Reference = Avcc
- Start Adc
- ' -----------------------------------------
- ' Servo-Pin festlegen
- ' -----------------------------------------
- Servo_Pin Alias PortB.2 ' Hier den Ausgangspin des Servosignals festlegen
- Config Servo_Pin = Output
- ' -----------------------------------------
- ' Variablen
- ' -----------------------------------------
- 'Variablen fürs RC Einlesen
- Dim Flag_Eingabe_Ausgabe As Bit
- Dim RC_Eingangswert As Byte
- 'Variablen für Servoausgabe
- Dim Servoausgabe_Wert As Byte
- 'Variablen für Poti
- Dim Poti_Wert as Word
- Poti_Eingang Alias Getadc(2) ' Hier den Poti-Pin festlegen
- 'Variablen für Berechnungen
- Dim Tod_Bereich as Byte
- ' -----------------------------------------
- ' Startwerte setzen
- ' -----------------------------------------
- Flag_Eingabe_Ausgabe = 0 ' Zunächst mit dem Einlesen des RC-Signals beginnen
- Waitms 500
- Enable Interrupts
- ' -----------------------------------------
- ' Hauptprogramm
- ' -----------------------------------------
- Do
- If Servoausgabe_Wert < RC_Eingangswert Then
- Tod_Bereich = RC_Eingangswert - 1
- If Tod_Bereich < Servoausgabe_Wert Then
- Incr Servoausgabe_Wert
- End If
- End If
- If Servoausgabe_Wert > RC_Eingangswert Then
- Tod_Bereich = RC_Eingangswert + 1
- If Tod_Bereich > Servoausgabe_Wert Then
- Decr Servoausgabe_Wert
- End If
- End If
- Poti_Wert = Poti_Eingang ' Getadc(2)
- Poti_Wert = Poti_Wert / 20 ' Wert auf brauchbare Größe bringen
- Waitms Poti_Wert
- 'Servoausgabe_Wert = RC_Eingangswert ' zu Testzwecken erst mal nur RC-Signal durchschleifen
- Loop
- End
- ' ======================================================
- ' RC_ISR
- ' ======================================================
- RC_ISR:
- If Flag_Eingabe_Ausgabe = 0 Then ' 0 = Einlesevorgang
- If Pinb.1 = 1 Then ' Wenn die positive RC-Flanke zum Einsprung in die ISR geführt hat, dann...
- Timer0 = 0 ' ...den Timer auf 0 setzen
- Else ' Führte dagegen die negative Flange zum Einsprung, dann ...
- RC_Eingangswert = Timer0 ' ... den aktuellen Timerwert speichern, der Einlesevesevorgang für das RC Signal ist abgeschlossen nun wird mit der Ausgabe des Servosignals begonnen
- Load Timer0 , Servoausgabe_Wert ' nun wird mit der Ausgabe des Servosignals begonnen, hierzu wird zunächst Timer0 mit dem Servoausgabe_Wert vorgeladen
- Servo_Pin = 1 ' Servo_Pin einschalten (= Start des Ausgabesignals)
- Flag_Eingabe_Ausgabe = 1 ' Flag setzen, damit beim nächsten Einsprung in die ISR der Ausgabevorgang abgeschlossen wird
- Enable Timer0 ' Solange die Signalausgabe läuft, darf Timer0 die ISR auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Else ' Hier landen wir, wenn ein Timer0-Überlauf zu einem Einsprung in die ISR geführt hat (es ist Zeit, das Servosignal abzuschalten)
- Servo_Pin = 0 ' Servo_Pin abschalten
- Flag_Eingabe_Ausgabe = 0 ' Flag zurücksetzen, damit beim nächsten Einsprung in die ISR wieder RC Signal eingelesen wird
- Disable Timer0 ' Timer0 darf ab jetzt keine ISR mehr auslösen
- Tifr = &B00000010 ' Timer/Counter Interrupt Flag Register auf 1 setzen, damit ein zwischenzeitliches Timer0-Interrupt-Flag gelöscht wird
- End If
- Return
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
Nette Grüße
Robert -
Ok, werde es mal versuchen. Bei der Steuerplatine ist es jedoch so, dass sie nach ca. 3 - 5 Sekunden kein Servo Signal mehr rausgibt. Also bleibt das Servo an der Position, wo es ist. Dadadurch sollte das Problem garnicht erst besteh. Ich werde es aber nochmal ausgiebig testen.