PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 10Servo zu viel für den Mega 8?



sulu
17.06.2009, 16:30
Hi
hab da ein Problem. Wenn ich an meinen Bulldog den 9 und 10.Servo an den Mega 8 anschließe, dann stimmen die Positionen für die anderen Servos nicht mehr.
Der Reload ist schon auf 2ms damit die Servos nicht zittern.
Hat da jemand ne Idee, oder mach ich was falsch?

Vielen Dank
sulu

Rofo88
17.06.2009, 17:55
Was hast Du für ne Programmiersprache? Taktfrequenz? Programm?

hosti
17.06.2009, 18:13
klingt nach software PWM, eine wirklich tückische Sache.

Wie sieht den dein programm aus?

sulu
17.06.2009, 18:29
Hi

die Kiste läuft ja auf 16mhz.

Hier mal der Code(nicht elegant, aber funktioniert(mit 8servos :mrgreen: ):



$regfile = "m8def.dat"

Config Servos = 10 , Servo1 = Portc.0 , Servo2 = Portb.1 , Servo3 = Portb.2 , Servo4 = Portb.3 , Servo5 = Portb.4 , Servo6 = Portb.5 , Servo7 = Portc.3 , Servo8 = Portc.1 , Servo9 = Portd.7 , Servo10 = Portd.6 , Reload = 2

Config Pinc.0 = Output
Config Pinb.1 = Output
Config Pinb.2 = Output
Config Pinb.3 = Output
Config Pinb.4 = Output
Config Pinb.5 = Output
Config Pinc.3 = Output
Config Pinc.1 = Output
Config Pind.7 = Output
Config Pind.6 = Output
Enable Interrupts
Dim A As Byte
Dim B As Byte
Dim C As Byte
A = 1
B = 1
C = 1
Servo(1) = 100
Servo(2) = 100
Servo(3) = 100
Servo(4) = 100
Servo(5) = 100
Servo(6) = 100
Servo(7) = 100
Servo(8) = 100
Servo(9) = 100
Servo(10) = 100
Waitms 500
Gerade:
If A = 10 Then A = 1


Servo(1) = 100
Servo(2) = 115
......................


Mfg sulu

Besserwessi
17.06.2009, 19:59
Wenn man das Servosignal selber erzeugt, dann kann man die Servos nacheinander Abarbeiten (bis etwa 10). Dazu braucht man nur jeweils eine Verzögerung zur Zeit. Hardwaremäßig geht das ggf. auch 2 mal parallel mit timer 1. Es ist also höchstens eine Frage der Software, wie das umgesetzt ist.

Es könnte sein, das duch den 9./10 ,ten servo gerade die Grenze erreicht wird, das die Summe der einzelpulse (1-2 ms) die 20 ms Grenze für die ganze Periode erreicht.

Thomas$
17.06.2009, 20:12
so mal eine frage werden in einer situation alle servos genutzt?sonst dürfte man ja welch(recht un elegant) zwischendurch deaktivieren

ikarus_177
17.06.2009, 20:14
ist halt dann die Frage, ob das mit der Bascom-Routine so einfach ist...

Viele Grüße

yaro
17.06.2009, 21:26
Ich weiß nicht, wie das mit Bascom ist, aber mit C sollten 10 Servos kein allzugroßes Problem darstellen. Kommt natürlich auf die programmierung an.
Man muss die Servos nicht mal nacheinander abarbeiten, mit 16MHz geht das auch parallel. Eine Auflösung von 180 einstellungen (180°) ist so, mit geschickter Programmierungen locker erreichbar.

Gruß, Yaro

Willa
18.06.2009, 17:04
Guck mal im Wiki unter Servoansteuerung. Da wird genau beschrieben wie man mehrere Servos ansteuern kann. Ohne die sehr eigenartige Servo Routine von BASCOM.

hosti
18.06.2009, 20:04
Ich habe mit C maximal 12 Servos zum laufen gekriegt.
Dann ist der Controller ab so ausgelastet, das er sonst nichts mehr machen kann.

wkrug
18.06.2009, 21:57
Ich meine, wenn man die Servoimpulsgenerierung in die Hardware des ATMEGA verlegt ( Timer 1 mit Comparematch Interrupts ) dann sollten bis zu 16 Servos möglich sein.
Das ist nur mal eine theoretische Überlegung - ausprobiert hab ich das noch nicht.
Mit 8 Servos lief sowas bei mir aber schon mal sehr gut.

Die ersten 8 Kanäle werden vom Comparematch A gesteuert.
Die zweiten 8 vom Comparematch B.

Beispiel für Comparematch A.
Der erste Servoausgang wird aktiv geschaltet und die gewünschte Servoimpulslänge zum TCNT1 Register dazugezählt und im Comparematch A Register abgespeichert.
Beim nächsten Comparematch A wird Ausgang 1 abgeschaltet und 2 aktiviert, zum TCNT1 der Wert für Kanal 2 dazugezählt und im Comparematch A Register abgelegt.
Das Spielchen geht so lange weiter, bis alle 8 Kanäle verarbeitet wurden.
Dann werden alle 8 Ausgänge inaktiv geschaltet und die gewünschte Pausenzeit zum TCNT1 dazugezählt und im Comparematch A abgespeichert.
Ist auch die abgelaufen beginnt das Spielchen mit Kanal 1 von vorne.

Mit dem Comparematch B macht man genau das Gleiche für die nächsten 8 Kanäle.

Da es in der Interruptroutine nur Portoperationen, Vergleiche und Additionen gibt, könnte man das auch in Assembler schreiben und so den Interrupt Codeanteil ziemlich kürzen.

Man kommt also mit 2 Arrays für die gewünschten Servoimpulslängen und 2 Zählern für den aktuell bearbeiteten Kanal aus.

Da fast die komplette Impulsgenerierung von der Hardware gemacht wird, dürfte der Controller genügend Zeit für die anderen Aufgaben haben.
Bei einem 8MHz Quarz und Prescaler 8 laufen bei minimalen Servoimpulsen ( 1ms ) im Schnitt 4000 Taktzyklen, bevor wieder ein Interrupt auftritt.
( 8000000*(1ms/2)=4000 )
Bei 16MHz ist es dann das doppelte.

Beachten sollte man auch, das man vor dem Schreiben in die Arrays die Interruptabarbeitung verhindert ( CLI ), sonst könnte der H Wert der neuen Impulslänge mit dem L Wert der vorherigen verarbeitet werden, was zu Servozuckern führt.
Gleich nach der Werteübernahme muß man natürlich die Interrupts wieder freigeben ( SEI ).

Wie gesagt - Theoretische Überlegung !

yaro
18.06.2009, 23:43
Es kommt auf zwei Sachen an: Die Auflösung, mit der die Servos angesteuert werden, und die Geschicklichkeit des Programmierers. Man kann deutlich mehr Servos mit einem ATmega ansteuern, als hier allgemein behauptet.

Einmal ein Beispiel:
16MHz, Auflösung von 200 Einstellungen pro Servo. Software-PWM: Servopin wird auf High gestellt, und nach einer bestimmten Zeit (die von einem Timer, der im 20ms-Rhythmus durchläuft abgelesen wird) auf Low geschaltet.
20ms ist ein PWM-durchlauf, davon ist nur 1ms pro Servo tatsächlich auch relevant (also das, wo der Controller aufpassen muss).
1ms sind 16000Takte. wir brauchen eine auflösung von 200, d.h. jede 1/200ms könnte es sein, dass man das zuvor auf High gesetzte Signal auf Low schalten muss. Mal schnell gerechnet macht das 80Takte, um zu gucken ob der Servo den nötigen Wert erreicht hat. Wenn man schlau programmiert (am besten mit Assembler) kann man in diesen 80Takten nach mindestens 6Servos parallel schauen. Wenn mann dann noch so Programmiert, dass immer maximal nur3 oder 4 Servos zur gleichen Zeit auf Low gesetzt werden müssen, kann man mit einem vorher sortierten Array viel viel mehr Servos ansteuern.
Und das alles in nur 1ms (wenn man das auf High stellen eine ms zuvor, was nur einige wenige Takte dauert, vernachlässigt)

Das heißt also, man könnte in 3ms 18Servos perfekt ansteuern, bleiben noch 17ms Rechenzeit. Das ist mehr als die meißten brauchen.
Wenn man dann noch schaut, dass von den Servos, die in derselben ms auf Low gezogen werden, nicht mehr als 3 gleichzeitig auf Low gezogen werden müssen, übersteigt die Zahl der Servos locker die Zahl der Pins eines ATmega8.

Gruß, Yaro