PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Ansteuerung mehrerer Servos mit M32



Ingo1988
08.08.2011, 14:39
Guten Tag,
ich möchte zwei Servos über die M32 ansteuern. Bisher hatte ich nur einen Servo, den ich per Hardware PWM angesteuert habe, dass hat auch hervorragend funktioniert. Jetzt ist die Frage, wie ich einen zweiten ansteuern kann ? Stellt die M32 2 PWM zur Verfügung? Ich habe leider keine Angaben dazu gefunden.

Ich habe auch bereits in vielen anderen Threads dazu gesucht, aber keine wirkliche Antwort auf meine Fragen gefunden.

Desweiteren habe ich versucht die Servos mit der Lib von Dirk anzusteuern. Allerdings waren hier die Bewgungen sehr ruckelig und der aktualisierungsimpuls war nur ca jede halbe Sekunden für kurze Zeit, sodass man den Servo obwohl er eine Position halten sollte von Hand bewegen konnte und er hat nur 2 mal pro Sekunde eine kurze Gegenreaktion gezeigt, auch hat es mit dieser Ansteuerung mehrere Zyklen gedauert, bis der Servo die korrekte Position erreicht hat!
Oder habe ich nicht die aktuelle Bibliothek von Drik benutzt?

Ich würde mich über weitere Infos zur Ansteuerung der Servos freuen, die diese Probleme lösen.

Lieben Gruß
Ingo

TrainMen
08.08.2011, 14:58
Hi,
also ich werde dir bei Deinem Problem nicht helfen können, ich kann dir aber aus meiner Erfahrung sagen, das sich meine Servos(7 stk. billig, ES05) sehr gut mit der der LIB von Dirk steuern lassen. Schnell fahren sie die Position an und ein drehen von Hand, wenn sie die Position halten, ist nicht möglich. Vielleicht liegt es an Deinem Code oder Deinen Servos. Zeig doch mal den Code und welche Servos benutzt Du ?
MfG TrainMen

Ingo1988
09.08.2011, 12:11
Guten Tag,
ich habe das jetzt nocheinmal ausprobiert und mir sind zwei Probleme aufgefallen. Als Servo verwende ich auch die ES05;)

1. Wenn der Servo eine größere Strecke überbrücken soll und dann bremst wird der RP6 resettet. Ich vermute mal das dann die Spannung einbricht, da beide Servos am gleichen vdd anschluss hängen. Deshalb denke ich sollte man Kondenstatoren verwenden ich weiß nur leider absolut nicht welche Kapazität sie haben sollten. Es würde mich freuen, wenn jemand sagen könnte welche Kondensatoren ich verwenden sollte und noch besser wie man berechnet welche Kondensatoren man braucht.

2. Ich habe das Programm einmal ohne den Rest meines eigentlichen Programms verwendendet. Das ist auch möglich. Also nur die Servosteuerung funktioniert problemlos. Schalte ich allerdings mein programm dazu funktioniert das ganze nicht mehr so fehlerfrei. Mein Programm ist die Bluetoothsteuerung mit Tracken, die ich auch hier vorgestellt habe. Hier werden alle 100ms Daten an den PC gesendet. Und es scheint mir, als behindern sich die beiden Programmteile. Das bisherige Programm arbeitet eigentlich nicht blockierend. Somit müsste das Problem bei der Servosteuerung liegen. Aber woher es genau kommt kann ich leider nicht sagen!

Am schönsten wäre es somit die Servos per hardware PWM anzusteuern. Weiß jemand ob davon 2 auf der M32 vorhanden sind?

Ich hoffe ihr könnt mir bei meinem Problemen weiterhelfen!!
Lieben Gruß

Dirk
09.08.2011, 17:38
@Ingo1988:

Zu 1:
Das ist ein Problem der Stromversorgung der Servos. Am besten nimmt man eine eigene Stromversorgung für die Servos.
Alternativ: Elko 470 uF /16V an die Servos.

Zu 2:
Der ATmega32 hat 4 PWM Kanäle: OC0, OC2, OC1A und OC1B.
OC1A nutzt du ja schon, OC2 ist der Beeper, OC0 ist LCD RS (LCD-Stecker, Pin 4).
OC1B ist STR vom IC3.
Im Prinzip sind also 3 der 4 PWM-Ausgänge belegt.
Wenn du das LCD nicht unbedingt brauchst, könntest du OC0 nehmen (am LCD-Stecker).

Weitere Infos: http://www.rn-wissen.de/index.php/RP6

Ingo1988
09.08.2011, 18:12
Das Display würde ich gern verwenden. Aber auf den Beeper kann ich verzichten. Kann ich somit auch oc2 verwenden? Funktioniert die Ansteuerung dann wie beim oc1a? Ich freue mich auf baldige Rückmeldung!

Lieben Gruß und vielen Dank für eure Unterstützung

Ingo1988
09.08.2011, 20:53
Ich werde dann wohl die PWM des Beeper verwenden. Ich habe die ServoLib die ich verwende auch mal dementsprechend umgeschrieben. Ich weiß allerdings nicht was ich bei TCCR2 hinschreiben muss. Zur Zeit ist es aus der Control Lib der M32 geklaut;) als der noch zum Beepen gedacht war.

Hier ist der Code:


/* ************************************************** **************************
* _______________________
* \| RP6 ROBOT SYSTEM |/
* \_-_-_-_-_-_-_-_-_-_/ >>> RP6 CONTROL
* ----------------------------------------------------------------------------
*
* ************************************************** **************************
*/

/************************************************** ***************************/
// Includes:

#include "RP6ControlServoLib.h"

/************************************************** ***************************/



//Servosteuerung

// Variablen:


uint16_t position_1=LEFT_TOUCH + MIDDLE_POSITION;
uint16_t position_2=LEFT_TOUCH + MIDDLE_POSITION;



/************************************************** ***************************/
// Funktionen:

/**
* Servoinitialisierung
*
* Call this once before using the servo function.
* Timer 1 is configured to work in "Phase and Frequency
* Correct PWM Mode".
*
*/
void initSERVO(void)
{
DDRD |= SERVO_1_OUT; // SERVO_OUT -> OUTPUT
DDRD |= SERVO_2_OUT; // SERVO_OUT -> OUTPUT

cli();
// Timer 1:
// Clear OC1A when up-counting and set OC1A when down-counting,
// mode 8 (PWM, Phase and Frequency Correct, TOP ICR1), clk/8
TCCR1A = (1 << COM1A1)
| (0 << COM1A0)
| (0 << COM1B1)
| (0 << COM1B0)
| (0 << FOC1A)
| (0 << FOC1B)
| (0 << WGM11)
| (0 << WGM10);
TCCR1B = (0 << ICNC1)
| (0 << ICES1)
| (1 << WGM13)
| (0 << WGM12)
| (0 << CS12)
| (1 << CS11)
| (0 << CS10);



TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS22) | (1 << CS21);

// Setze Servo Pulswiederholung auf 50 Hz
ICR1 = 20000; // 50Hz = clk / (2 * prescaler * ICR1)


//SERVO_1
// Setze Servostellung auf Mittelstellung (~1,5ms):
OCR1A = position_1;
OCR2 = position_2;

// Disable output compare A match interrupts:
TIMSK &= ~(1 << OCIE1A);

sei();
}

/**
* SET SERVO
*
* Das ist die Servopositionierung
* Der Servo wird mit 50 Hz beschaltet, somit amcht es keinen Sinn,
* die Funkrion öfter aufzurufen.
*
* pos = 0 : Left touch
* pos = MIDDLE_POSITION : Middle position
* pos = RIGHT_TOUCH : Right touch
*
* Bemerkung: Der Puls wird durch eine Hardware PWM generiert, so wird rechenzeit gespart!
*
*/

void setSERVO(uint16_t pos1,uint16_t pos2)
{

OCR1A = pos1;
OCR2 = pos2;
}

// Aufruf in aus PCConection
void setServoPosition(uint16_t pos1,uint16_t pos2){
position_1=pos1;
position_2=pos2;


if (position_1 > RIGHT_TOUCH+LEFT_TOUCH)
{
position_1 = RIGHT_TOUCH+LEFT_TOUCH;
}
if (position_1 < LEFT_TOUCH)
{
position_1 = LEFT_TOUCH;
}

if (position_2 > RIGHT_TOUCH+LEFT_TOUCH)
{
position_2 = RIGHT_TOUCH+LEFT_TOUCH;
}
if (position_2 < LEFT_TOUCH)
{
position_2 = LEFT_TOUCH;
}
}

/**
* SERVO TASK
*
* Hier wird die Position des Servos in der Variable pos gespeichert und
* danach von setServo eingestellt.
*
*/
void task_SERVO(void)
{
setSERVO(position_1,position_2); // aktualisiere die Servo Position
}
// EOF




Ich hoffe ihr wisst eine Antwort. Vielen Dank für eure Unterstützung!
Lieben Gruß
Ingo

radbruch
09.08.2011, 21:21
Vielleicht hilft dir das weiter, Stichwort ist Software-PWM:
https://www.roboternetz.de/community/showthread.php/41287-Libverträgliche-Servo-ISR

Ingo1988
09.08.2011, 21:48
Oh vielen dank
Das ist ja nochmal eine ganz andere Art der Servo Ansteuerung. Führt diese Art der Ansteuerung nicht zu Blockierungen? Dann wäre es ja noch eine Möglichkeit, die Servos anzusteuern.
Also empfiehlst du diese Art der Ansteuerung? Dann werde ich mich in den nächsten Tagen auch mal damit beschäftigen das auf die M32 anzuwenden.


Wenn jemand noch weitere Tipps oder Vorschläge hat würde ich mich darüber sehr freuen!

Lieben Gruß

radbruch
09.08.2011, 22:47
Hallo

Ja, das kann ich empfehlen. Vor allem das zweite Programm mit seinen wenigen ISR-Aufrufen eignet sich gut. Dazu noch ein Beispiel mit 8 Servos an einem 8MHz-Mega8: https://www.roboternetz.de/community/showthread.php/37418-walking-asuro

Die Timersetups und die OVL-ISR kannst du vom RP6 direkt aufs m32 übertragen; beide verwenden einen Mega32. Allerdings rennt dieser beim m32 mit 16MHz, deshalb muss man den Vorteiler (Prescaler) anpassen:

TCCR2 = (0 << WGM21) | (0 << COM20) | (1 << CS22) | (1 << CS20); // Normal Mode, prescaler /128 für m32 mit 16MHz

Gruß

mic

Ingo1988
14.08.2011, 17:32
Soo heute habe ich mal wieder weiter an meinem Roboter gearbeitet. Ich habe einen 1mF Elko eingebaut. Dieser verhindert einen Reset in den meisten Fällen. Lediglich wenn sich beide Servos zeitgleich über lange Strecken bewegen bricht die Spannung hin und wieder ein.

Und ich verwende jetzt das Programm von Radbruch, das er in dem von ihm genannten Thread vorgestellt hat. Das funktionitert auch sehr gut. genau so wie ich es mir erhofft hatte.

Vielen Dank für eure Mithilfe

Lieben Gruß

Ingo Hunfeld