Timer0 Interrupt für Modellbau Servo ansteuerung

Begonnen von ^Cobra, 05.02.2024, 20:23:44 CET

Vorheriges Thema - Nächstes Thema

^Cobra

So meine Freunde,
ich bin nochmal inmich gegangen, habe (mal wieder) hin und her gerechnet und kam zu dem Ergebnis:
Fehler sitzt vor dem PC.
Kurz gesagt den ersten Servo (von ges. 10) konnte ich nun Positionieren und bis auf eine für mich derzeitige unerklärliche Abweichung von 50 von Sollwert zu Istweit funktioniert dieser.

Ab hier nur wer die Kraft hat :D

Bei den ganzen gerechne bin ich wohl die ersten (bestimmt 100) male durcheinander gekommen und daher passte es hinten und vorne nicht.
Nun ist die Rechnung:
Genutzt wird der 16mhz intere takt der nochmal *4 genommen wird.
Dabei würde der Timer0 im 8 Bit Betrieb 16mhz / 255 => 62,74 Khz erzeugen was wiederum 0,0000159s wären. Da mein Servo Sollbereich ein Byte groß ist ergibt sich 0,0000159 *255 => 0,00406s => 4,06ms doppelt so viel wie benötigt. Um die Auflösung zu verbessern wurde also der Istwert von dem Timer0 manipuliert und auf 128 geschrieben. Somit 16mhz / 128=> 128 Khz => 0,000008s .
0,000008s *255 Servostellwert => 2,04ms max
So ein Servo arbeitet bei 1ms (Links am anschlag) bis 2ms (Rechts Anschlag).
Bei mir habe ich nun bei Stellwert 50 Links Anschlag, 128 mitte, 210 Rechtsanschlag. Dabei sollte es 125 (Links), 187 (mitte), 250 (rechts) sein. Ob dies nun Abweichungen von dem Takt,berechnung,Zykluszeit,Servo sind kann ich derzeit nicht sagen. Bin erstmal froh das da überhaupt was sich bewegt.
Werde nun die anderen Kanäle prüfen und eventuell dann weiter schauen woher die Abweichungen kommen.



pic18

#1
Spontan rechne ich da anders:
Du hat 16Mhz interner Takt, mit PLL *4 = 64 Mhz =Fosc

Der Timer0 bekommt am Eingang Fosc/4 =16 Mhz
als precaler hast du 256 eingestellt = 16Mhz /256 =62,5 Khz

es würde also alle 62,5Khz/256 bzw alle 16us*256  ein Timerüberlauf entstehen womit Du einen Interrupt auslösen kannst. (256 ist der Wert vom precaler)

Was ich nicht ganz verstehe, benötigst Du nicht ein PWM-Signal? Dieses wird normaler Weise mit TMR2 gemacht. Den kannst Du über das PR2- Register programmieren.



















^Cobra

Da hast du mich falsch verstanden.
Ich nutze nicht den Vorteiler somit liegen 16Mhz an dem Timer0. Den Timer0 stelle ich dann auf 128 somit braucht der Timer also nur noch die Hläfte der Zeit
bis ein Interrupt erzeugt wird und es ergibt sich eine Frequenz von 16Mhz/128 =>125kHz bzw.  0,000008s => 8 us

Ja es wird ein PWM benötigt von 50Hz mit 1-2ms Highteil. Dieses erzeuge ich ja durch den Timer0. Jeden Interrupt wird ein Counter Hoch gezählt, wenn Counter den Sollwert erreicht hat wird der Ausgang ausgeschaltet und der nächste Servo angewählt und eingeschaltet bis dieser auch den Wert erreicht hat.
Wie gesagt klappt eig. ganz gut muss nur noch die anderen 9 Ausgänge testen.

Gruß
Cobra

Ottmar

@Cobra
Sind die Servos über die Ausgänge eines Schieberegisters angeschlossen?

^Cobra

Nein. Direkt an ein io pin des Controllers. 
Habe noch nie mit schiebe register gearbeitet. Steht aber auf meine doto :D

Ottmar

Wie verteilst Du dann die unterschiedlichen Impulszeiten für die Position/Bewegungsrichtung der Servos?

pic18

ich habe mir mal ein Datenblatt vom Servo angeschaut,
1ms entsp. -90°
1,5ms entsp. 0°
2ms entspr. +90°

kannst Du auch über -90° bzw. +90° fahren, oder ist dieser Bereich begrenzt?

was passiert eigentlich wenn kein PWM Signal am Servo anliegt, aber Betriebsspannung?

Um nicht unnötig viele Interrups auszulösen ist zu überlegen, ob man den Startwert (1ms) und den Endwert (20ms) anders festlegt. Z.B die Timereinstellung verstellt, oder einen anderen Timer nimmt. Dann hat man mehr Zeit für andere Aufgaben. Die Interruptroutine sollte so kurz wie möglich gehalten werden, am Besten in Assembler schreiben.
Like Like x 1 View List

vloki

#7
Zitat von: pic18 in 06.02.2024, 15:50:21 CETwas passiert eigentlich wenn kein PWM Signal am Servo anliegt, aber Betriebsspannung?
Dann bleibt der Servo einfach so wie er ist. (sofern er nicht durch eine äußere Kraft verstellt wird)

Eigentlich bräuchte man nicht wirklich ein PWM Signal, wenn der Servo die Position auch halten kann.
Es reicht dann ein einzelner Puls als Kommando.

Die Pseudo/Software-PWM von z.B. einem Arduino kann sogar richtig störend werden,
wenn der Servo wegen dem Jitter dann die ganze Zeit rumzittert.
MPLABX  XC8  KiCAD

Ottmar

Ich denke an die 10 Servos die ^Cobra verwendet. Geht das so einfach mit PWM, wenn jedes Servo für sich angesteuert werden soll?
Mir fällt da so sporadisch eine Lösung ein, unter Verwendung eines Schieberegisters, diverser Takte, eines Zählers, (Anzahl Servos x Vergleichsregister + Zustandbits).

^Cobra

Wow hier ist ja richtig was passiert :P

also mal der Reihe nach:
Zitat von: Ottmar in 06.02.2024, 11:14:03 CETWie verteilst Du dann die unterschiedlichen Impulszeiten für die Position/Bewegungsrichtung der Servos?
Ich verwende ein Select Byte um den ausgewählten Servo zu bestimmen, Ein Sollwert Byte um von den ausgewählten die Soll Position zu erhalten, ein Counter Byte der von dem Timer Hoch gezählt wird.
Derzeit ist der Ablauf: Slect Byte 1, Vergleiche Sollpos1 mit Counter wenn <=0 Ausgang für Servo1 aus, Select Byte +1 und Ausgang für Servo2 an.
Mir gefällt das aber noch nicht alles so richtig. Werde da noch etwas ändern und wenn es "final" ist kann ich es gern mal rein setzen.
Zitat von: pic18 in 06.02.2024, 15:50:21 CETich habe mir mal ein Datenblatt vom Servo angeschaut,
1ms entsp. -90°
1,5ms entsp. 0°
2ms entspr. +90°

kannst Du auch über -90° bzw. +90° fahren, oder ist dieser Bereich begrenzt?

was passiert eigentlich wenn kein PWM Signal am Servo anliegt, aber Betriebsspannung?

Um nicht unnötig viele Interrups auszulösen ist zu überlegen, ob man den Startwert (1ms) und den Endwert (20ms) anders festlegt. Z.B die Timereinstellung verstellt, oder einen anderen Timer nimmt. Dann hat man mehr Zeit für andere Aufgaben. Die Interruptroutine sollte so kurz wie möglich gehalten werden, am Besten in Assembler schreiben.

Also i.d.R. ist es so das man etwas über die 90° gehen kannst und somit der Bereich von ca. 0,8-2,2ms "angefahren" werden kann. Wie gesagt habe ich noch nicht bei mir geschaut welche Impulse genau der PIC ausgibt. Auch gibt es wohl billig Servos (und ich habe ein billigen) die sehr von der "norm" abweichen können.
Wenn man nur Spannung anlegt passiert eig. erstmal nichts. Wenn aber die Signalleitung Flakert (Wackelkontakt) macht der Servo ein tollen Tanz :D
Ich bin bereits im Assembler unterwegs. - C ist mir derzeit zu sperrig für meine kleinen PICs die ich hier habe. wie gesagt gefällt mir der ganze Ablauf noch nicht und wird nochmal überarbeitet. Dann werde ich einige Messungen machen um zu beurteilen wie "ausgelasstet" der PIC damit ist. min. 1 Aufgabe muss ich dem PIC noch zu muten können für mein vorhaben :P :D
Zitat von: vloki in 06.02.2024, 16:38:16 CET
Zitat von: pic18 in 06.02.2024, 15:50:21 CETwas passiert eigentlich wenn kein PWM Signal am Servo anliegt, aber Betriebsspannung?
Dann bleibt der Servo einfach so wie er ist. (sofern er nicht durch eine äußere Kraft verstellt wird)

Eigentlich bräuchte man nicht wirklich ein PWM Signal, wenn der Servo die Position auch halten kann.
Es reicht dann ein einzelner Puls als Kommando.

Die Pseudo/Software-PWM von z.B. einem Arduino kann sogar richtig störend werden,
wenn der Servo wegen dem Jitter dann die ganze Zeit rumzittert.
Mir ist es nicht bekannt das Servos die Position auch halten wenn es nur ein "Puls als Kommando" kommt. Wie lange ist der Puls? Wannkommt die wiederholung uzsw.? Ich weiß das der Servo i.d.R. schneller einlesen kann als 50Hz und man somit die Pause verkürzen kann. Dies nutze ich indirket wenn ich weniger als 10 Servos nutze bzw. wenn nicht alle Rechtsausschlag haben: alle Servos links 1+1+1+1+1+1+1+1+1+1 => nach 10 ms kriegt Servo1 neuen impuls.
Zitat von: Ottmar in 06.02.2024, 17:49:10 CETIch denke an die 10 Servos die ^Cobra verwendet. Geht das so einfach mit PWM, wenn jedes Servo für sich angesteuert werden soll?
Mir fällt da so sporadisch eine Lösung ein, unter Verwendung eines Schieberegisters, diverser Takte, eines Zählers, (Anzahl Servos x Vergleichsregister + Zustandbits).
Wie bereits oben erwähnt Vergleiche  ich immer den Counter mit dem Sollwert von dem ausgewählten Servo. muss noch erprobiert werden ob es so geht. Bin aber keiner der was "fertiges" aus dem internet holt sondern selbst ein Weg finden. - meistens mit Steinen und Hinfallen :D


schönen Abend
Cobra

 

pic18

Zitat von: Ottmar in 06.02.2024, 17:49:10 CETMir fällt da so sporadisch eine Lösung ein, unter Verwendung eines Schieberegisters, diverser Takte, eines Zählers, (Anzahl Servos x Vergleichsregister + Zustandbits)
@Ottmar, was verstehst Du unter Schiebregister? Ich denke da mehr an einen Ringpuffer, wo man die einzelnen Daten einliest und der Reihe nach abarbeitet.

^Cobra

Habe nun mein Programm überarbeitet. Laut der simulation sieht es gut aus. Alle 10 Ausgänge schalten. Etwas Versatz ist drin (ca 0,002s). Dies liegt vermutlich daran wie das ganze abgearbeitet wird. Sollte sich das mit Oszi bestätigen werde ich aber einfach ein korrekturwert einrechnen lassen und wäre zufrieden.
Ob ich dazu heute schon komme weiß ich aber nicht.

Gruß
Cobra

Ottmar

@pic18
Ich dachte da an ein Schieberegister z.B. 74HC595 dessen Ausgänge direkt die Servos ansteuern.

Ansonsten hatte ich die Gewinnung der Servo-Pulszeiten wie von Cobra beschrieben angedacht.

Mit Ringpuffer habe ich mich bisher nicht befasst.

pic18


Ottmar

Ja, das bietet sich einfach an. Würde das gerne mal praktisch austesten, bin aber noch bis Ende April fern der Heimat und meiner Bastelecke.

pic18


Ottmar


^Cobra

Ich habe nun alle 0 Servo ausgänge getestet. Alle funktionieren soweit. :)
Desweiteren habe ich mal mein Oszi dran gehalten. Bei einer vorgabe von 1,5ms werden 1,55ms ausgegeben. Bei 1,25ms eingestellt kommen 1,29ms raus.
Witzig dabei: Mein Servo ist in mittelstellung bei 1,29ms.

Nun gehts darum das ganze mit ein I2C Master zu steuern. Der Pic mit den Servo ausgangen soll dann ein Slave sein.
Mal sehn ob ich das hinkriege.

Gruß
Cobra

Schnellantwort

Name:
Verifizierung:
Bitte lassen Sie dieses Feld leer:
Geben Sie die Buchstaben aus dem Bild ein
Buchstaben anhören / Neues Bild laden

Geben Sie die Buchstaben aus dem Bild ein:

Tastenkürzel: Alt+S Beitrag schreiben oder Alt+P für Vorschau

Similar topics (5)