PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino Frage



tortelini66
25.11.2010, 19:11
Hey Leute,
ich bin drauf und dran mir ein Arduino Board von typ uno zu kaufen.
Ich hab schon ein wenig erfahrung mit programmieren und Elektronik durch den Asuro.
Ich möchte halt mal etwas eigenes zusammenbauen.
Einen Roboter der fahren soll \:D/
Nun habe ich herausgefunden das man servos über das pwm signal gar nicht in der geschwindigkeit regeln kann, sondern nur in der gradzahl, wieviel sie sich drehen.
Das wäre ja auf gut deutsch gesagt S C H E I ß E, wenn ich die geschwindigkeit variieren möchte.
Vielleicht kann mich ja jemand aufklären.

MfG tortelini66

wisda.noobie
25.11.2010, 20:19
google mal nach servo hacking, dann findest du eine Anleitung, wie man Servos dazu bringt, sich im Kreis zu drehen. Man kann die auch so modifizieren, dass die sich mit der internen Elektronik drehen, aber da müsste ich erstmal nachschauen, wie das geht...

mfg wisda.noobie

radbruch
25.11.2010, 21:07
Hallo

Beim Servohacking wird der mechanische Anschlag (sofern vorhanden) entfernt. Das Servo kann dann endlos in jede Richtung drehen. Wenn man dann noch zusätzlich die komplette Elektronik entfernt, hat man einen normalen Getriebemotor.

Man kann die Ansteuerelektronik aber auch weiterverwenden, wenn man z.B. keine eigenen Motortreiber bauen will oder nur einen Pin zur Ansteuerung zur Verfügung hat. Das funktioniert dann so:

Plan A: Das Poti wird ersetzt durch zwei Widerstände.
Plan B: Die mechanische Verbindung des Potis wird getrennt und das Poti in Mittelstellung fixiert.
Plan C: Das Poti wird mechanisch getrennt und nach außen geführt.

Bei allen Möglichkeiten ist die Funktion aber gleich:

Der µC erzeugt ein Signal für die Servomitte. Da der Spannungsteiler des Potis in der Mittelstellung steht, bewegt sich das Servo nicht.

Der µC sendet Impulslängen die nicht der Mittelstellung entsprechen. Das Servo dreht je nach Abweichung in die eine oder anderere Richtung. Da sich aber der Spannungsteiler nicht mehr ändert, dreht das Servo endlos. Je näher dabei der gesendete Impuls an der Mittelstellung ist, umso langsamer dreht das Servo, weil es "denkt" es muss kurz vor dem Ziel bremsen. Das funktioniert aber extrem ungenau...

Plan A, B oder C? Bei A kann sich die Mittelstellung nie mehr ändern, B ist billig, aber das Poti kann sich verstellen. C ist mein Favorit, denn dann kann man die Mittelstellung auch am Roboter noch nachjustieren.

http://www.youtube.com/watch?v=Z7VJT-kw9VQ
http://www.youtube.com/watch?v=XTYzLqgKMLM
http://www.youtube.com/watch?v=a3gR2IzL18Y
http://www.youtube.com/watch?v=wIwsT-f-TYU
http://www.youtube.com/watch?v=Q2tggwy7uhU

Gruß

mic

Hessibaby
26.11.2010, 09:45
@tortelini66 , Richtig, über das PWM-Signal regelst Du nur den Stellwinkel. Wenn Du die Stellgeschwindigkeit verändern möchtest kannst Du entweder die Servospannung im Bereich von 4-6V variieren, oder den Antriebsmotor im Servo an eine externe Spannungsquelle ( die dann auch über PWM geregelt wird ) anschließen.

Carlos31
26.11.2010, 11:43
Hi
Die Geschwindigkeit kann man verändern mit eine for next schleife
Du must nur der Pwm wert Anfang zu Pwm ende in der schleife laufen lasen
Mit ein wait.
Zb
For servoposist to servopossoll
Incr servoposist
Waitms 5
Next servoposist

radbruch
26.11.2010, 12:39
Hallo

Irgendwie habe ich den Eindruck, wir reden aneinander vorbei. Anhand eines Democodes möchte ich versuchen zu zeigen, wie die Geschwindigkeitssteuerung eines gehackten Servos mit Verwendung der orginalen Servoelektronik (Plan C) umgesetzt werden kann. Das Demo ist für die drei Omniwheels geschrieben, deshalb werden gleichzeitig drei identische Impulse an PB1, PB2 und PB4 erzeugt:


#include "asuro-probot.h"
#include "asuro-probot.c"

int main(void)
{
int i, j;
Init();
PORTC |= 3; // Odo-PullUps simulieren für PollSwitch()
PORTB &= ~(1<<PB5 | 1<<PB4 | 1<<PB2 | 1<<PB1);
while(!PollSwitch());
while(PollSwitch());
StatusLED(RED);

while(!PollSwitch()) // kalibrieren
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(36);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
while(PollSwitch()); //fertig
StatusLED(YELLOW);
Msleep(2000);

while(1) // Demo
{
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(31);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(41);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}

for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(26);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(46);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}

}
}

Die Impulslängen werden im Demo recht einfach über interrupterzeugte Sleep()-Funktionen erzeugt. Zeitbasis ist eine 36kHz-ISR, deshalb dauert eine Pause von Sleep(36) ziemlich genau 1ms. Im folgenden Programmabschnitt werden nun bis zu einem Tastendruck 1ms-Impulse gesendet. Dies dient der Kalibierung der Potis (Plan C):

while(!PollSwitch()) // kalibrieren
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(36);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}


Nach Abschluss der Kalibrierung steht das Servo, wenn ein 1ms-Impuls gesendet wird!

Im folgenden Abschnitt werden Impulse mit Sleep(31) bzw. Sleep(41) erzeugt. Dies entspricht Impulslängen von 0,86ms (1/36*31) bzw. 1,14ms (1/36*41), also ca. 0,14ms von der Mittelstellung von 1ms entfernt.

for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(31);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(41);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}


Im dritten Abschnitt sind die Impulslängen dann Sleep(26) bzw. Sleep(46) (oder 0,72ms bzw. 1,28ms):

for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(26);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(46);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}


Die Servoelektronik errechnet nun jedesmal die erforderliche/mögliche Drehgeschwindigkeit aus dem Unterschied zwischen dem 1ms-Impuls, auf dem es ja durch den (nach dem Kalibrieren) fixen Spannungsteiler des Potis zu stehen glaubt, und der Sollposition des gesendeten Impulses. Dadurch ergibt sich im zweiten Abschnitt (31/41) eine geringere Drehgeschwindigkeit des Servos als bei (26/46). Die Maximaldrehzahl und die einzelnen Drehzahlstufen sind natürlich vom verwendeten Servo abhängig und können deshalb als "extrem ungenau" bezeichnet werden. Entscheidend für die Brauchbarkeit dieser Technik ist aber letztlich die geplante Anwendung.

Erwähnen möcht ich hier noch, dass die 1ms für die Mittelstellung in der Literatur und auch in der Praxis auch 1,5ms sein können ;) Und es gibt natürlich noch viele andere Möglichkeiten die Servoimpulse zu erzeugen. Das Prinzip der hier beschriebenen Drehzahlsteuerung ändert sich dadurch aber nicht.

Beachten muss man zusätzlich noch, dass die Servos einen "Totpunkt" haben. Das bedeutet, erst wenn der Sollimpuls einen bestimmten Abstand zur Istposition hat, regelt das Servo seine Position nach. Das begrenzt die minimale Drehzahl.

https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=8139
http://www.electronicsplanet.ch (http://www.electronicsplanet.ch/Roboter/Servo/Servo.htm)

Gruß

mic

tortelini66
26.11.2010, 16:06
Ah, vielen dank für die Info.
Ich denke ich entscheide mich für Methode a.
Dann kann ich ja per pwm die pulslänge steuern und damit dann die Geschwindigkeit, oder sehe ih das falsch?

wisda.noobie
26.11.2010, 16:15
ja, aber wie radburch schon schrieb, ist version c eigentlich viel besser, da man da noch justieren kann. Und da man das Poti so oder so ausbauen muss, wäre das eigentlich auch nicht viel aufwendiger...

mfg wisda.noobie

Sigi123
26.11.2010, 17:30
Wenn man nun variante C nimmt. Kann man dann auch die geschwindigkeit regeln oder?

ohne währendessen das potentiometer zu drehen..

radbruch
26.11.2010, 17:35
Dann kann ich ja per pwm die pulslänge steuern und damit dann die Geschwindigkeit, oder sehe ich das falsch?Ja, über die Impulslänge kannst du Drehzahl und Drehrichtung vorgeben.


Bei allen Möglichkeiten ist die Funktion aber gleich: A, B oder C ist egal für die Ansteuerung. Da ich bisher immer C gemacht habe, kann ich nicht sagen, ob die anderen Varianten auch gut funktionieren. Zum einen ändern sich bei meinen 5€-Servos die Eigenschaften etwas, wenn sie warmgefahren sind, außerdem ist das Verhältniss Impulslänge zu Drehwinkel nicht linear. Bei festen Widerständen sollte man die Kalibrierung der Mittelstellung softwaremässig vorsehen.


ohne währendessen das potentiometer zu drehen..Wenn das Poti auf die Mitte eingestellt ist, wird alles weitere über die Impulslänge gemacht.

Netter Nebeneffekt: Auch ohne Impulsänderung kann man für schnelle Tests auch einfach mal am Poti drehen um zu sehen, wie sich der Antrieb dreht ;)

Gruß

mic