PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Modelcraft Servos gehen nicht an M32



copcom-weber
24.12.2012, 19:40
Hallo,

Ich habe mir 2 neue Servos (Modelcraft vsd 5e hs) geholt und sie angebaut.
hatte vorher auch 2 dran die aber kaputt gegangen sind. nun reagieren sie nicht einmal obwohl die alten so funktioniert haben. woran kann es liegen?

Danke schonmal

Dirk
24.12.2012, 19:48
Das sind DIGITALE Servos. Wahrscheinlich hattest du vorher "normale" analoge Servos.

copcom-weber
24.12.2012, 20:05
das voher waren auch digitale Servos wie diese. sie müssen doch digital sein um sie per I/O (zb. PC6) anzusteuern?

also eingebaut sind sie richtig wenn ich mit dem finger auf den kontakten rumstreiche reagieren diese auch. weis einfach nicht woran es liegen kann.

Dirk
24.12.2012, 21:16
Die normalen Servos werden alle 20ms mit einem Impuls von 1..2ms angesteuert.
Die "digitalen" Servos müßten eigentlich so auch funktionieren, arbeiten aber auch mit Impulsen alle 3..4ms (bis sogar 0,4ms).

Meist verbrauchen die digitalen Servos mehr Strom als die normalen.
Bist du sicher, dass du die Signalleitung richtig an den µC-Pin gelegt hast (mögliche andere Steckerbelegung als bei deinen alten Servos)?

copcom-weber
24.12.2012, 21:33
Ja das wusste ich soweit muss mal einen anderen Ausgang probieren. Also du meinst denn ich sie mit einer höheren Frequenz ansteuer dann müsste es gehen? Mal seh'n aber die servos sind doch richtig oder?

Dirk
24.12.2012, 22:09
Mit welchem Programm steuerst du denn die Servos an?
Eigentlich müßten die Digitalservos auch mit konventioneller Ansteuerung funktionieren.
Die Servos sind schon ok.

copcom-weber
25.12.2012, 10:44
Ich steuere sie halt über das m32 modul und programmers notepad:

void servo1(int pos)//rechter Servo
{
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(200-pos);
}

void servo2(int pos)//linker Servo
{
PORTC |= IO_PC6;
sleep(pos);
PORTC &= ~IO_PC6;
sleep(200-pos);
}

und aufrufen in main:

for(x=3;x<25;x++)
{
servo1(x);
servo2(x);
setCursorPosLCD(1,5);
writeIntegerLCD(x, DEC);
mSleep(350);
clearLCD();
}

so hat es vorher ja auch immer funktioniert.

Dirk
25.12.2012, 12:12
Für die normalen Servos war ja sleep(200-pos) für die ~20ms Pause (18..19ms) zwischen den Impulsen gedacht.
Deine digitalen Servos schaffen auch (100-pos), (50-pos) und (10-pos) und sollten keine längeren Pausen haben.

Das ist also vielleicht das erste Hauptproblem (wenn der elektrische Anschluss stimmt!):
Deine Pause zwischen den Servo-Impulse wird durch ...
setCursorPosLCD(1,5);
writeIntegerLCD(x, DEC);
mSleep(350);
clearLCD();
... extrem verlängert,- möglicherweise kommen die digitalen Servos damit nicht klar.

Vorschläge:
1. Ich würde mal den ganzen Anzeigekram probeweise rausnehmen.
2. Auch dann werden noch die 2 Servofunktionen nacheinander abgearbeitet, so dass sich der Impuls + Pause des einen Servos zu der Pause des jeweils anderen Servos dazu addiert (2. Hauptproblem). Also haben deine Servos jetzt (ohne Anzeigezeugs) noch eine Pause nach jedem Impuls von [18-19ms eigene Pause + Impuls des anderen Servos + dessen Pause (18-19ms)]. Das müßtest du so umschreiben, dass JEDES Servo MINDESTENS alle 20ms (besser alle 5-10ms) einen eigenen Impuls bekommt.
3. In der x-Schleife gibt es viel zu wenig Zeit für die Positionsänderung: Gib den Servos pro Position mindestens 5-10 Impulse in der jeweiligen Stellung.

copcom-weber
25.12.2012, 16:22
So habe deine aussagen umgesetzt.
habe die zeiten ausprobiert mit niedrigeren sleep zeiten aber eine frage wenn ich 10-pos mache soll ich dann trotzdem pos mit zb. 20 anfahren?
zu 1: kein unterschied.
zu 2 und 3: wenn ich in der schleife servo1(x); aufrufe habe ich die funktion so abgeändert:
void servo1(int pos)//rechter Servo
{
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
}

so werden mehrere signale ausgeführt und ohne unterbrechung hintereinander abgerufen.

wenn ich mit dem finger auf der unterseite an den kontakten herstreiche (an den I/O ports) erreiche ich ab und zu ein drehn der servos. also muss die verbindung bis auf die m32 platine gut sein.

- - - Aktualisiert - - -

ist es vllt möglich ob die I/O ports kaputt gegangen sind? muss mal einen anderen probieren. ist das denn möglich?

Dirk
25.12.2012, 18:24
copcom-weber:
... muss mal einen anderen probieren. ist das denn möglich?
Ja, es gibt auf der M32 die freien Portpins PC2..PC7. Sie heissen IO_PC2..IO_PC7. Da kannst du einen nehmen für den IO_PC4.
Alle Pins findest du ja am IO-Stecker.

copcom-weber
25.12.2012, 19:40
Ist das denn möglich war auf kaputt gehen gemeint. Werde es morgen ausprobieren.

Dirk
25.12.2012, 19:59
Klar können Portpins kaputt gehen, wenn sie falsch angeschlossen werden.

copcom-weber
25.12.2012, 20:22
Melde mich morgen wenn ich es ausprobiert habe.
Danke schmal für deine Hilfe!

Filou89
26.12.2012, 00:58
Eventuell ist aber dein Problem auch ganz banal: Hast du eine gute Stromversorgung? Bei schwachem Akku hat mir der Servo immer gleich alles Resettet. Mit externem Akku - Kein Problem mehr! Viel Erfolg.
Gruss Filou

oberallgeier
26.12.2012, 09:05
... 2 neue Servos (Modelcraft vsd 5e hs) geholt und sie angebaut ... nun reagieren sie nicht ...Hast Du mal im RNWissen nachgesehen (klick mal hier)? (http://www.rn-wissen.de/index.php/Servo#Ansteuerung:_Signalform_und_Schaltung) Da gibts etliche Ratschläge, die unbedingt befolgt werden müssen, damit Servos sauber laufen.

copcom-weber
27.12.2012, 19:31
mit der spannung habe ich kein problem denn es bricht nichts zusammen und das programm läuft rauf und runter ohne eine reaktion. habe einen 10000µF Elko direkt vor den servos ausserdem habe ich auch einige elkos auf dem m32 und der hauptplatine nachgerüstet. das sollte wirklich nicht das problem sein.
zu oberallgeier: ich habe schon mehrere servos vorher dran gehabt aber nur diese neuen machen probleme..

leider habe ich dank der feiertage es nicht geschafft einen anderen I/O port auszuprobieren. fällt euch sonst noch etwas ein?

gruß

HeXPloreR
27.12.2012, 19:45
Hast Du möglicherweise einen 2k Ohm Widerstand in der PWM Leitung verbaut? - ich hörte mal das man das zum Schutz (vor was auch immer ) machen könne, aber der kann ich den Puls für einen digitalen Servo anscheinend so tief halten das der nichts wahrnimmt. Bei analogen scheint das Problemnicht so gravierend zu sein.
Wenn ja reduzieren diesen Widerstand vielleicht auf 1k Ohm...hat bei mir geklappt.

Ich denke mal, da du sagtest vorher liefen die Analaogen, muss es vielleicht nicht erwähnt werden aber ich hatte damals zusaätzlich auch meine Ausgang nicht richtig eingestellt ( Ausgang) - da ich vermutete die Funktion ( allerdings in Bascom) macht das selbstständig...kenne die Funktionen nicht die Du da benutzt. Sind die Ausgänge korrekt eingestellt?

Was meinst Du mit "die zucken wenn Du die Pins berührst"? -Hast du die Masse richtig
verbunden? Wackelkontakt?

Woher weißt Du denn das der µC nicht resetet? - ich habe immer einen kleinen Code vor die main gesetzt ... der wartet 200ms und schaltet dann eine Led ein. Wird der µC (unbemerkt/unerwartet) ständig resetet beginnt diese dann unregelmässig zu blinken.

Dirk
27.12.2012, 19:49
copcom-weber:
ich habe schon mehrere servos vorher dran gehabt aber nur diese neuen machen probleme..
Ich hatte es doch schon erklärt: Die sog. "digitalen" Servos brauchen einen sehr viel genaueren Servoimpuls. Die meisten "analogen" Servos funktionieren auch weit außerhalb der Spezifikationen: Du könntest 1x pro Jahr zu Weihnachten einen Impuls abgeben und das Standard-Servo würde versuchen, die Position anzusteuern. Bei deinem 1. geposteten Programm haben deine Servos etwa alle 350 bis 400 ms einen Impuls bekommen. Das liegt weit (20-fach) außerhalb der Spezifikation von mind. 20ms.


fällt euch sonst noch etwas ein?
Welche Vorschläge hier aus dem Thread hast du denn schon konkret umgesetzt? Insbesondere: Hast du jetzt ein Programm geschrieben, was die Servos richtig ansteuert?

HeXPloreR
27.12.2012, 20:14
Ich denke dem digitalen Servo macht es nichts wenn er sein Signal alle 400ms bekommt...der hält die Position nähmlich trotzdem Stundenlang - solange bis er was anderes "hört" oder der Strom ausfällt. Deshalb verbrauchen sie ja mehr Strom.

copcom-weber
27.12.2012, 20:22
habe das programm ja schon so geändert das wenn ich eine position angebe mit pos das die dann ca. 10mal aufgerufen wird wie:
{
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
}
habe unterschiedliche zeiten eingegeben aber nichts passiert.
in main rufe ich es einfach als funktion auf mit der übergabe der stellposition.


am pwm kabel habe ich kein widerstand dran muss ich das denn?

HeXPloreR
27.12.2012, 21:10
Das Problem was Dirk meint wird sein das Dein PWM vielleicht gar keines ist? - Weil die Periode zu lang ist, eben 350 - 400ms. Sie darf aber anfänglich nicht länger als 2ms sein um im Stellbereich des Servos zu bleiben - und auch wenn man die Grenze des Stellbereichs etwas ausweiten möchte bewegt man sich um einen Wert etwa +- 0,6ms um 1,5ms (neutral Stellung). Der digital Servo kann mit einer zu langen Periode (bzw nicht PWM) keine Stellposition berechnen.

Ich habe an eine BabyOranutan (20MHz) einen analogen Servo hängen, ich steuere den mit Bascombefehl Pulsout an. Dort sind die Werte die man eingibt von der Geschwindigkeit des µC abhängig. Bei 20MHz ist ein Wert von ca 8000 eher normal. Sollte hier doch auch so sein?


Nein, man benötigt den Widerstand nicht zwingend.

- - - Aktualisiert - - -

Ich denke wenn Du Dein Programm jetzt so schreiben würdest wie Dirk vorgeschlagen hat, dann wird es wohl eher helfen. Mehr jedenfalls als in der Funktion selbst solche sachen zu machen.

Ändere doch einfach in deinem Ersten Programmpost die Zeiten der Servos bei sleep in 50 oder auch 20 statt 200. Und in der main den mSleep höher wählen. Was ist das für eine Variable (byte; word?) - wie hoch kann man wählen? Nimm mal 500, wenn nichts geht nimm 550 usw usw... oder kleiner werden, in 50er Schritten.

Die LCD Befehlszeilen ALLE (3) auskommentieren.

copcom-weber
27.12.2012, 21:43
habe es jetzt so:


void servo1(int pos)//rechter Servo
{
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);

}

void servo2(int pos)//linker Servo
{
PORTC |= IO_PC6;
sleep(pos);
PORTC &= ~IO_PC6;
sleep(50-pos);
}

int main(void)
{
initRP6Control();
initLCD();
I2CTWI_initMaster(100);
I2CTWI_setRequestedDataReadyHandler(I2C_requestedD ataReady);
I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);
mSleep(500);
I2CTWI_transmit3Bytes(Base, 0, CMD_SET_ACS_POWER, ACS_PWR_OFF);
I2CTWI_transmit3Bytes(Base, 0, CMD_SET_WDT, true);
I2CTWI_transmit3Bytes(Base, 0, CMD_SET_WDT_RQ, true);
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, 6, BWD);
showScreenLCD("Servo Test","",""," Test");
mSleep(500);
clearLCD();
while(true)
{
for(x=4;x<25;x++)
{
servo1(x);
servo2(x);
//batpower();
//setCursorPosLCD(1,1);
//writeIntegerLCD(x,DEC);
mSleep(500);
}
//clearLCD();
}

}

ok?

aber funktioniert nichts keine bewegung!

- - - Aktualisiert - - -

eins ist aber auch komisch und zwar habt ihr ja gesagt, dass die digitalservos ihre stellung halten in der sie sind. solange diese strom haben. ich kann meine aber drehen wenn ich sie von hand bewege. sie sind aber richtig angeschlossen. habe mir extra die steckerbelegung angeguckt und alles auf richtigkeit geprüft(spannung und durchgang)

Dirk
27.12.2012, 21:52
Bei dieser Version bekommt jedes Servo alle [500ms + eigene Pause + Impuls u. Pause des anderen Servos] einen Impuls von 0,4 bis 2,5ms.
Also noch weiter außerhalb der Spezifikation als in deinem 1. Beispiel.

Frage: Setzt du die beiden Ports eigentlich irgendwo auf AUSGANG?

copcom-weber
27.12.2012, 21:58
habe es nun so aber so ist auch nichts:
while(true)
{
//for(x=4;x<25;x++)
//{
x=7;
servo1(x);
servo2(x);
//batpower();
//setCursorPosLCD(1,1);
//writeIntegerLCD(x,DEC);
//mSleep(550);
//}
//clearLCD();
}

der rest ist unverändert.
wie setzte ich diese denn auf ausgang mache ich das nicht schon mit den befehlen in den servo funktionen?

Dirk
27.12.2012, 22:01
Mit:
DDRC |= IO_PC4;
DDRC |= IO_PC6;
... im Hauptprogramm (also VOR der while(true)-Schleife)!

copcom-weber
27.12.2012, 22:10
danke das wars wie konnte ich das vergessen habe es im alten programm auch nun gehts danke an alle!

HeXPloreR
28.12.2012, 10:21
Das ist gut :)

Ich habe die HS 5645mg digital Servos von Hitec. Wenn der sein PWM Puls (einmalig) korrekt errechnet hat, dann bleibt er darauf stehen auch wenn man nichts mehr an ihn sendet.

Solange er anfänglich nichts korrektes erhalten hat, bleibt er kraftlos - auch unter Spannung.

Viel Spaß und Gruß

copcom-weber
29.12.2012, 14:39
Hallo nochmal

Jetzt reagieren die servos schonmal und nun will ich herausfinden welchen stellbereich ich fahren kann. ich mache es so:

for(x=3;x<25;x++)
{
servo1(x);
mSleep(400);
}

aber er reagiert nicht korrekt nur ca. 5 positionen und die sind nicht immer mit den gleichen zahlen ich weiß auch nicht. es wirkt als wäre die batterie leer aber die sind frisch geladen und wenn wieder x=3 ist dann fährt er schnell und sauber zurück.

HeXPloreR
29.12.2012, 17:07
Woher bekommt der Servo denn seine Positionsangabe her?
-wenn Du mir sagen kannst, welcher Teil vom Programm den Wert produziert. Dann wette ich mit Dir, fällt es Dir auch auf. Kleiner Tipp: Es ist unpraktisch den Positionswert in einer Schleife hochzählen zu lassen, da man dann ja nicht sieht wo der Servo aufhört auf die Werte zu reagieren (Min/Max).

Du solltest wohl erstmal den "neutral-Wert" finden.

Was passiert wenn Du in der Schleife den x-wert bei Servo1 z.B. "fest" auf 11 setzt?
Hinweis: wenn der Servo ständig gegen seine Max- und Min-Position fährt kann er beschädigt werden - denke das gilt auch noch für Digitale. Also achte darauf was der Servo macht wenn Du die Änderungen vornimmst.

Kann es sein das der Schleifenzähler gleichzeitig die Position vom Servo sein soll? - müsste der nicht seperat gehalten werden. Also eine entweder es ist eine Lokale Variable, dann mag das gehen; oder eine Globale - dann müßte sie doch einen eigenen Namen tragen, oder nicht?

copcom-weber
29.12.2012, 19:54
der code der schleife sieht so aus:

void servo1(int pos)//rechter Servo
{
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
}

while(true)
{
for(x=4;x<21;x++)
{

servo1(x);
setCursorPosLCD(1,1);
writeIntegerLCD(x,DEC);
mSleep(750);
}
clearLCD();
}

ich lasse mir es ja anzeigen und deswegen weis ich genau welche zahl ich den linken und rechten servoanschlag hat.
ja x wird ja hochgezählt und als stellwert übergeben. somit stellt er sich alle 750ms um und er sollte sich bewegen.

HeXPloreR
29.12.2012, 21:21
Nein, was du angezeigt bekommst ist nicht wie der Anschlag jeweils ist, sondern Deine berechneten Werte werden ausgegeben. Das ist schon mal ein großer Unterschied. Das anschlagen sollte ja verhindert werden und kann erstmal durch draufschauen beobachtet werden.

Wie groß ist der Stellbereich des Servos ( Winkelangabe)?

Der Servo fährt sauber und schnell zurück - zurück wohin - rechts oder links? Leider habe ich meinen Versuchsaufbau schon wieder unvollständig...in welche Richtung dreht der Servo wenn der PWM-Stellwert kleiner wird? - ich denke mal das komische Verhalten kommt daher das er auf einer Seite gegen den Anschlag fährt ... im msleep Takt.

Weil Du die Neutralstellung nicht kennst? Du kannst Dich schlecht an die Anschlage herantasten wenn Du diesen Wert nicht kennst. Vorher ist eher der Servo wahrscheinlich kaputt.

- - - Aktualisiert - - -


der code der schleife sieht so aus:

void servo1(int pos)//rechter Servo
{
PORTC |= IO_PC4;
sleep(pos);
PORTC &= ~IO_PC4;
sleep(50-pos);
}

while(true)
{
for(x=4;x<21;x++)
{

servo1(x);
setCursorPosLCD(1,1);
writeIntegerLCD(x,DEC);
mSleep(750);
}
clearLCD();
}
.

Ändere mal bei sleep(50-pos); die 50 in 200 zurück. Und setze manuel den Wert bei servo1(x), x in 100.

Was passiert?
Hält der Servo nun eine Position, oder versucht er immer noch alle 750ms weiter zu drehen?
Ist das dann ungefähr die Neutralstellung?

copcom-weber
30.12.2012, 17:18
also habe es versucht aber bei 100 geht garnichts sind ja auch 10ms das ist zuviel aber so ungefähr liegt der bereich bei 7 bis ca. 17 aber sie reagieren nicht auf alle zahlen muss einfach mal alle durchgehen und gucken welcher wann wie dreht.
probiere es jetzt einfach von 5 bis 20 nach und nach aus und mal gucken was die machen.

Habe es jetzt genau ausprobiert und herausgefunden das der eine von 9-21 und der andere von 5-19 hat und reagiert und ich eine pause zwischen die servoansteuerung machen muss dann gehts. wenn ich sie wirklich fast gleichzeitig drehn wollte haben sie vllt doch zuviel strom gezogen und somit die spannung für das andere signal quasi aufgefressen.

SlyD
01.01.2013, 14:50
Hallo,

hab den Thread nicht komplett gelesen, aber mal als Hinweis, hier gibts eine fertige Servo Lib:
(s. https://www.roboternetz.de/community/threads/40090-RP6Control-M32-Library-f%C3%BCr-8-Servos )

MfG,
SlyD