www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Hexabot und Servoproblemchen.


Autor: chriss (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

dieses Projekt entstand aus dem Spruch "Hey, wir haben noch Platz auf 
einem Nutzen, ca. in der Größe einer Zigarettenschachtel! Muss die 
Gerberdaten wohl morgen früh haben." Also schnell eine Platine für einen 
Hexabot zusammengetüddelt (Anhang) und weg damit. Seit das Teil aus dem 
Haus ist hab ich dann mal ein bisschen Mechanik gefräst. Auf den Fotos 
im Anhang kann man eine Lochrasterkarte mit einem mega8 sehen der nur 
mal schnell da war um das ganze Teil mal auf "eigene Beine" zu stellen 
(alle Pins für 18,ms low dann 1,5ms high... sagt jetzt nichts dazu...). 
Auf dem Bild sind alle Servos in Mittelstellung. So "schwebt" der Körper 
ca. 1,5 - 2cm über dem Boden.

Hier mal ein paar Daten zusammengefasst:

- Gewischt (Alu, 18 Servos, ca. 230 Schrauben mit Unterlegscheibe, 
Spannring, Mutter, Platine, Akkus): ca. 2kg
- Pollin Funkkamera ;)
- 2 LiIon Akkus aus einem Notebook

Platine:
- ATmega2560 (1280/640)
- 16MHz
- serielle Bluetoothverbindung
- RFM12
- ISP
- Uartanschluss
- 8 LEDs frei programmierbar
- Resettaster
- 1 Taster frei programmierbar
- 24 Ausgänge für Servos
- I2C / TWI
- Power LED
- Spannungsregler für 3,3V

Ich glaub das wars im Großen und Ganzen. Ich weiß, die Pins sind 
garantiert total grottig gewählt. Wie gesagt die Zeit war zu knapp ;)

So jetzt mein Problem: WIE erzeuge ich auf einem ATmega (erstmal für den 
mega8, da die andere Platine erstmal ankommen muss und bestückt werden 
muss) 18 Software PWMs? Die Müssen ja nicht wirklich genau sein... Ein 
"paar" Schritte pro Gelenk die ich anfahren kann reichen ja. Habe hier 
irgendwo eine Routine gefunden mit der ich 8 Servos per Timer ansteuern 
kann aber das bringt mich nicht so richtig weiter. Vllt sollte man dazu 
sagen dass ich bei dem Atmega8 momentan mit dem internen 8MHz Quarz 
arbeite.

Kennst jemand eine schnelle Möglichkeit um die Servos einzeln 
anzusteuern? Am liebsten wäre mir irgendeine Routine bei der ich einfach 
nur 18 verschiedene Variablen irgendeinen Wert geben muss der dann vom 
jeweiligen Servo angefahren wird.

PS: Wenn jemand an den CAD Datenoder Gerberfiles interessiert ist 
einfach laut schreien. Die CAD Daten besitze ich im dxf und cam Format 
soviel ich weiß... muss ich auf meinem anderen Rechner nachgucken ;)

Wäre super wenn mir jemand bei der Programmierung hilft :)

Chriss

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
chriss schrieb:

> So jetzt mein Problem: WIE erzeuge ich auf einem ATmega (erstmal für den
> mega8, da die andere Platine erstmal ankommen muss und bestückt werden
> muss) 18 Software PWMs?

So:

Modellbauservo Ansteuerung
letzter Abschnitt

Das Prinzip lässt sich problemlos auch auf 18 Servos erweitern.

Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay vielen Dank erstmal da werde ich mich dann morgen mal durchwühlen 
:)

Autor: Rainer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist auch noch was zu lesen.

http://www.roboternetz.de/phpBB2/viewtopic.php?t=14220

Gruß Rainer

Autor: chriss (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Also die Ansteuerung hier aus dem Forum funktioniert schonmal ganz gut. 
Solang sich alle Servos in Mittelstellung befinden. Wenn ich eins der 18 
Servos jetzt in Endposition fahren will dann fangen ein paar andere 
(nicht alle) wie wild an zu zucken... vllt  könnt ihr mir ja helfen ;)
Programm steck ich mal in den Anhang.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So
ISR (TIMER2_COMP_vect) 
{
  ....

  //
  // den Puls des aktuellen Servos beenden
  //
  GELENK1_PORT &= ~ServoPuls[ServoId];
  GELENK2_PORT &= ~ServoPuls[ServoId];
  GELENK3_PORT &= ~ServoPuls[ServoId];

  ....

  //
  // die Ausgangsleitung fuer dieses Servo auf 1; den Puls beginnen
  //
  GELENK1_PORT |= ServoPuls[ServoId];
  GELENK2_PORT |= ServoPuls[ServoId];
  GELENK3_PORT |= ServoPuls[ServoId];

  ....

geht das nicht. Du musst die 18 Servos hintereinander ansteuern, nicht 
in 3 Gruppen parallel. Schliesslich läuft der Timer ja immer nur für die 
Zeit des jeweils nächsten Servos.

ISR (TIMER2_COMP_vect) 
{
  ...

  //
  // den Puls des aktuellen Servos beenden
  //
  if (ServoId < 6)
    GELENK1_PORT &= ~ServoPuls[ServoId];
  else if (ServoId < 12)
    GELENK2_PORT &= ~ServoPuls[ServoId];
  else
    GELENK3_PORT &= ~ServoPuls[ServoId];

  ....
  //
  // die Ausgangsleitung fuer dieses Servo auf 1; den Puls beginnen
  //
  if (ServoId < 6)
    GELENK1_PORT |= ServoPuls[ServoId];
  else if (ServoId < 12)
    GELENK2_PORT |= ServoPuls[ServoId];
  else
    GELENK3_PORT |= ServoPuls[ServoId];

  ....

Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uh doofer Fehler danke dunktiniert :)
dann lassen wir das Teil mal laufen...

Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich werde aus diesem Teil hier noch nicht ganz schlau:
    ServoValue[0] += 2;
    if( ServoValue[0] > 2*CENTER )
      ServoValue[0] -= 2*CENTER;
Hier soll ein Servo mit einer bestimmten Geschwindigkeit angesteuert 
werden. Aber wie wird das gemacht? Ich werde aus dem Code noch nicht so 
ganz schlau...
Und wie kann ich das Servo jetzt in eine bestimmte Position außer 
Links/Mitte/Rechts fahren?

Chriss

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
chriss schrieb:
> Ich werde aus diesem Teil hier noch nicht ganz schlau:
>
>     ServoValue[0] += 2;
>     if( ServoValue[0] > 2*CENTER )
>       ServoValue[0] -= 2*CENTER;
> 
> Hier soll ein Servo mit einer bestimmten Geschwindigkeit angesteuert
> werden. Aber wie wird das gemacht? Ich werde aus dem Code noch nicht so
> ganz schlau...

Der Code soll einfach nur IRGENDEINE Ansteuerung der Servos machen. 
Irgendeine, so dass die Servos unabhängig voneinander irgendetwas tun. 
Mehr steckt da nicht dahinter. Für dich ist dieser Code uninteressant, 
weil er nicht zur eigentlichen Servoansteuerung gehört, sondern 
demonstrieren soll, dass die Servoansteuerung funktioniert.

Der Code stellt bei jedem Durchlauf das Servo ein kleines Stückchen 
weiter und wenn es am Ende angelangt ist, dann fährt es in einem Rutsch 
wieder an die Anfangsposition zurück.



> Und wie kann ich das Servo jetzt in eine bestimmte Position außer
> Links/Mitte/Rechts fahren?

Indem du den einzelnen Variablen ServoValue[x] Werte zuweist. Fertig. 
Einfach nur einen Wert zuweisen und das Servo fährt an die entsprechende 
Position.
   ServoValue[0] = 0;           // Servo 0 fährt ganz nach links
   _delay_ms( 1000 );
   ServoValue[0] = 2*CENTER;    // Servo 0 fährt ganz nach rechts
   _delay_ms( 1000 );
   ServoValue[0] = CENTER;      // und Servo 0 fährt wieder in die Mitte
   _dleay_ms( 1000 );

   ServoValue[1] = 0;
   ServoValue[2] = 0;           // jetzt fahren Servo 1 und 2 ganz nach links
   _delay_ms( 1000 );
   ServoValue[1] = CENTER;
   ServoValue[2] = CENTER;      // und wieder zurück zur Mitte

   ....

Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soo da bin ich nochmal...

Ich habe es jetzt endlich mal geschafft meine Platine mit dem mega2560 
zu bestücken. Erstmal eine LED blinken lassen -> Platine funktioniert.

Jetzt habe ich das Servoprogramm in versucht in den µC zu laden. Bekomme 
aber schon beim Compilieren bekomme ich folgende Fehlermeldungen:
Build started 11.4.2011 at 16:21:28
avr-gcc  -mmcu=atmega2560 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
../main.c:39: warning: 'TIMER2_COMP_vect' appears to be a misspelled signal handler
../main.c: In function 'TIMER2_COMP_vect':
../main.c:62: error: 'OCR2' undeclared (first use in this function)
../main.c:62: error: (Each undeclared identifier is reported only once
../main.c:62: error: for each function it appears in.)
../main.c: In function 'InitServo':
../main.c:84: error: 'OCR2' undeclared (first use in this function)
../main.c:85: error: 'TIMSK' undeclared (first use in this function)
../main.c:85: error: 'OCIE2' undeclared (first use in this function)
../main.c:86: error: 'TCCR2' undeclared (first use in this function)
make: *** [main.o] Error 1
Build failed with 7 errors and 1 warnings...

Kann mir jemand helfen? Hat ja scheinbar alles was mit dem Timer für die 
Servos zu tun...

Danke schonmal
chriss

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>../main.c:85: error: 'TIMSK' undeclared (first use in this function)

Der ATMega2560 hat z.B. kein TIMSK-Register. Jeder Timer hat ein eigenes 
TIMSK0, TIMSK1...

Nimm dir das Datenblatt und sieh nach wie deine Register richtig heißen.

MfG Spess

Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank :) Werde ich dann gleich mal ausprobieren wenn ich zuhause 
bin :)

chriss

Autor: Tip (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo die Register sind, steht im Datenblatt
Wie die Register heißen, steht im Header-File

Autor: chriss (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mahlzeit,

ich komme mit den Servos einfach nicht weiter. Ich weiß absolut nicht 
wie ich das mit dem Timer machen muss... Habe bis jetzt fast 
ausschließlich auf dem ATmega8 programmiert. Da gabs so viele Beisiele 
die man sich einfach zusammenbasteln konnte :) Jetzt bin ich mit dem 
mega2560 Datenblatt total überfordert. Kann mir mal jemand einen 
anschubs geben was ich alles ändern muss? Lade den Code aus dem Tutorial 
nochmal mit hoch.

Danke
chriss

Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
keiner?

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Chriss,
auch wenn es etwas hart klingt, aber programmieren besteht nicht daraus, 
aus dem Internet Codeschnipsel zusammenzukopieren und bei Problemen 
diese vom Forum lösen zu lassen. Du leidest am Guttenbergsyndrom.

Hier wurde dir doch ein Haufen Ansätze gezeigt, jetzt bist du dran.
Beginne mit einem Servo, wenn das zu viel ist fange mit einer LED an, 
aber nicht Code kopieren, sondern selber schreiben, ohne zu spicken.

Trau dich, du kannst mehr als du denkst.
Viel Erfolg, Udo

Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also ne LED bekomm ich schon hin das ist wohl kein problem ;)
Der Roboter läuft auch schon (so halbwegs, stolpert mehr). Allerdings 
auf der Basis eines ATmega8. Das Problem was ich jetzt habe ist halt den 
Code auf einen mega2560 zu bekommen da blicke ich einfach nicht durch 
die ganzen Timer-Register durch...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.