PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servos tun nicht was sie sollen



topgunfb
10.06.2009, 12:07
Hi,

als Basis meines Greifarms V2 mit fünf Servos habe ich die M32-Libs von Dirk genommen, mit denen man bis zu 8 Servos an der M32 benutzen kann.

Problem:
die Servos machen einfach nicht das was sie sollen.
Bsp.:
initSERVO(SERVO1); --> Es passiert nix!
initSERVO(SERVO1 | SERVO2); ---> Servo 1 zittert wie blöd, geht aber an die Position, die in der Servolib.h eingestellt ist und zittert weiter, Servo2 fährt ganz nach rechts und will weiter raus. (Ich habe diverse Werte für RIGHT_TOUCH ausprobiert, es geht nix)
initSERVO(SERVO1 | SERVO2 | SERVO3 | SERVO4 | SERVO5);
---> alle fünf Servos fahren ganz nach rechts und wollen weiter, egal was in der Lib eingestellt ist.

Kann mir mal einer auf die Sprünge helfen, wo ich den Fehler mache?

BITTE BITTE !!!

Hier noch der Code zum Programm:


#include "RP6ControlServoLib.h"
#include "RP6ControlLib.h"

uint16_t pos_GREIFER = 0;
uint16_t pos_GELENK = 0;
uint16_t pos_NIVEAU = 0;
uint16_t pos_ARM_HOCH = 0;
uint16_t pos_ARM_SEIT = 0;

int main(void)
{
initRP6Control();
initSERVO(SERVO1 | SERVO2 | SERVO3 | SERVO4 | SERVO5);
startStopwatch2();

while(true)
{

if (getStopwatch2() > 48) {
servo1_position = pos_GREIFER;
servo2_position = pos_GELENK;
servo3_position = pos_NIVEAU;
servo4_position = pos_ARM_HOCH;
servo5_position = pos_ARM_SEIT;
pos_ARM_HOCH = 60;
pos_ARM_SEIT = 80;
}
setStopwatch2(0);
task_SERVO();
}
}
}



Ich weiß, theoretisch sollte hier ganr nix gehen. In der Servolib.h ist eingestellt, dass wenn keine Werte übergeben werden, die Servos nach links fahren sollen.

Hier die lib.h:

/*
#include "RP6ControlLib.h" // The RP6 Control Library.

// Servo constants:
#define SERVO1 0b00000001
#define SERVO2 0b00000010
#define SERVO3 0b00000100
#define SERVO4 0b00001000
#define SERVO5 0b00010000
#define SERVO6 0b00100000
#define SERVO7 0b01000000
#define SERVO8 0b10000000

/*define LEFT_TOUCH 80
#define RIGHT_TOUCH 80
#define MIDDLE_POSITION (RIGHT_TOUCH / 2)
#define PULSE_REPETITION 15 */
#define F_TIMER1 66667

#define LEFT_TOUCH_GREIFER 120
#define RIGHT_TOUCH_GREIFER 60
#define MIDDLE_POSITION_GREIFER (RIGHT_TOUCH / 2)
#define PULSE_REPETITION_GREIFER 15


#define LEFT_TOUCH_GELENK 110
#define RIGHT_TOUCH_GELENK 80
#define MIDDLE_POSITION_GELENK (RIGHT_TOUCH / 2)
#define PULSE_REPETITION_GELENK 15

#define LEFT_TOUCH_NIVEAU 100
#define RIGHT_TOUCH_NIVEAU 60
#define MIDDLE_POSITION_NIVEAU (RIGHT_TOUCH / 2)
#define PULSE_REPETITION_NIVEAU 15

#define LEFT_TOUCH_ARM_HOCH 80
#define RIGHT_TOUCH_ARM_HOCH 60
#define MIDDLE_POSITION_ARM_HOCH (RIGHT_TOUCH / 2)
#define PULSE_REPETITION_ARM_HOCH 17.5

#define LEFT_TOUCH_ARM_SEIT 80
#define RIGHT_TOUCH_ARM_SEIT 60
#define MIDDLE_POSITION_ARM_SEIT (RIGHT_TOUCH / 2)
#define PULSE_REPETITION_ARM_SEIT 17.5

// Servo ports:
#define SERVO1_PULSE_ON (PORTC |= IO_PC2) // PC2
#define SERVO1_PULSE_OFF (PORTC &= ~IO_PC2)
#define SERVO2_PULSE_ON (PORTC |= IO_PC3) // PC3
#define SERVO2_PULSE_OFF (PORTC &= ~IO_PC3)
#define SERVO3_PULSE_ON (PORTC |= IO_PC4) // PC4
#define SERVO3_PULSE_OFF (PORTC &= ~IO_PC4)
#define SERVO4_PULSE_ON (PORTC |= IO_PC5) // PC5
#define SERVO4_PULSE_OFF (PORTC &= ~IO_PC5)
#define SERVO5_PULSE_ON (PORTC |= IO_PC6) // PC6
#define SERVO5_PULSE_OFF (PORTC &= ~IO_PC6)
#define SERVO6_PULSE_ON (PORTC |= IO_PC7) // PC7
#define SERVO6_PULSE_OFF (PORTC &= ~IO_PC7)
#define SERVO7_PULSE_ON (PORTD |= IO_PD5) // PD5
#define SERVO7_PULSE_OFF (PORTD &= ~IO_PD5)
#define SERVO8_PULSE_ON (PORTD |= IO_PD6) // PD6
#define SERVO8_PULSE_OFF (PORTD &= ~IO_PD6)
// -----------------------------------------------------------
// Other possible ports for connecting servos to RP6Control:
//#define SERVOx_PULSE_ON (PORTA |= ADC6) // PA6
//#define SERVOx_PULSE_OFF (PORTA &= ~ADC6)
//#define SERVOx_PULSE_ON (PORTA |= ADC7) // PA7
//#define SERVOx_PULSE_OFF (PORTA &= ~ADC7)
// -----------------------------------------------------------

/************************************************** ***************************/
// Variables:

uint16_t servo1_position; // Servo 1 position [0..RIGHT_TOUCH]
uint16_t servo2_position; // Servo 2 position [0..RIGHT_TOUCH]
uint16_t servo3_position; // Servo 3 position [0..RIGHT_TOUCH]
uint16_t servo4_position; // Servo 4 position [0..RIGHT_TOUCH]
uint16_t servo5_position; // Servo 5 position [0..RIGHT_TOUCH]
uint16_t servo6_position; // Servo 6 position [0..RIGHT_TOUCH]
uint16_t servo7_position; // Servo 7 position [0..RIGHT_TOUCH]
uint16_t servo8_position; // Servo 8 position [0..RIGHT_TOUCH]

/************************************************** ***************************/
// Functions:

void initSERVO(uint8_t servos);
void startSERVO(void);
void stopSERVO(void);
void pulseSERVO(void);
void task_SERVO(void);

/************************************************** ****************************
* Additional info
* ************************************************** **************************
* Changelog:
* - v. 1.0 (initial release) 31.12.2008 by Dirk
*
* ************************************************** **************************
*/

/************************************************** ***************************/
// EOF

und die lib.c:

/*
#include "RP6ControlServoLib.h"
// Variables:

uint8_t usedservos;
uint8_t servo_on = FALSE;

uint16_t impulselength1 = 0;
uint16_t impulselength2 = 0;
uint16_t impulselength3 = 0;
uint16_t impulselength4 = 0;
uint16_t impulselength5 = 0;
uint16_t impulselength6 = 0;
uint16_t impulselength7 = 0;
uint16_t impulselength8 = 0;

volatile uint16_t intcounter = 0;

// Functions:

void initSERVO(uint8_t servos)
{
usedservos = servos; // Save used servos
impulselength1 = 0;
impulselength2 = 0;
impulselength3 = 0;
impulselength4 = 0;
impulselength5 = 0;
impulselength6 = 0;
impulselength7 = 0;
impulselength8 = 0;
if (servos & SERVO1) {DDRC |= IO_PC2; PORTC &= ~IO_PC2;}
if (servos & SERVO2) {DDRC |= IO_PC3; PORTC &= ~IO_PC3;}
if (servos & SERVO3) {DDRC |= IO_PC4; PORTC &= ~IO_PC4;}
if (servos & SERVO4) {DDRC |= IO_PC5; PORTC &= ~IO_PC5;}
if (servos & SERVO5) {DDRC |= IO_PC6; PORTC &= ~IO_PC6;}
if (servos & SERVO6) {DDRC |= IO_PC7; PORTC &= ~IO_PC7;}
if (servos & SERVO7) {DDRD |= IO_PD5; PORTD &= ~IO_PD5;}
if (servos & SERVO8) {DDRD |= IO_PD6; PORTD &= ~IO_PD6;}

cli();
// Timer 1: Normal port operation, mode 4 (CTC), clk/8
TCCR1A = (0 << COM1A1)
| (0 << COM1A0)
| (0 << COM1B1)
| (0 << COM1B0)
| (0 << FOC1A)
| (0 << FOC1B)
| (0 << WGM11)
| (0 << WGM10);
TCCR1B = (0 << ICNC1)
| (0 << ICES1)
| (0 << WGM13)
| (1 << WGM12)
| (0 << CS12)
| (1 << CS11)
| (0 << CS10);
OCR1A = ((F_CPU/8/F_TIMER1)-1); // 19 at 100kHz
startSERVO();
sei();
startStopwatch1(); // Needed for 20ms pulse repetition
}

void startSERVO(void)
{
TIMSK |= (1 << OCIE1A);
servo_on = TRUE;
}

void stopSERVO(void)
{
TIMSK &= ~(1 << OCIE1A);
servo_on = FALSE;
}

void pulseSERVO(void)
{
if (servo_on) {
if (usedservos & SERVO1) {
SERVO1_PULSE_ON; impulselength1 = LEFT_TOUCH_GREIFER + servo1_position;}
if (usedservos & SERVO2) {
SERVO2_PULSE_ON; impulselength2 = LEFT_TOUCH_GELENK + servo2_position;}
if (usedservos & SERVO3) {
SERVO3_PULSE_ON; impulselength3 = LEFT_TOUCH_NIVEAU + servo3_position;}
if (usedservos & SERVO4) {
SERVO4_PULSE_ON; impulselength4 = LEFT_TOUCH_ARM_HOCH + servo4_position;}
if (usedservos & SERVO5) {
SERVO5_PULSE_ON; impulselength5 = LEFT_TOUCH_ARM_SEIT + servo5_position;}
/*if (usedservos & SERVO6) {
SERVO6_PULSE_ON; impulselength6 = LEFT_TOUCH + servo6_position;}
if (usedservos & SERVO7) {
SERVO7_PULSE_ON; impulselength7 = LEFT_TOUCH + servo7_position;}
if (usedservos & SERVO8) {
SERVO8_PULSE_ON; impulselength8 = LEFT_TOUCH + servo8_position;}
*/ intcounter = 0;
}
}

ISR (TIMER1_COMPA_vect)
{
intcounter++;
if (intcounter == impulselength1) {SERVO1_PULSE_OFF;}
if (intcounter == impulselength2) {SERVO2_PULSE_OFF;}
if (intcounter == impulselength3) {SERVO3_PULSE_OFF;}
if (intcounter == impulselength4) {SERVO4_PULSE_OFF;}
if (intcounter == impulselength5) {SERVO5_PULSE_OFF;}
if (intcounter == impulselength6) {SERVO6_PULSE_OFF;}
if (intcounter == impulselength7) {SERVO7_PULSE_OFF;}
if (intcounter == impulselength8) {SERVO8_PULSE_OFF;}
}

void task_SERVO(void)
{
if (getStopwatch1() > 2) {TIMSK &= ~(1 << OCIE1A);}

if (getStopwatch1() > PULSE_REPETITION_GREIFER) { // Pulse every ~20ms
pulseSERVO(); // Servo pulse generation
if (servo_on) {TIMSK |= (1 << OCIE1A);}
setStopwatch1(0);
}
if (getStopwatch1() > PULSE_REPETITION_GELENK) { // Pulse every ~20ms
pulseSERVO(); // Servo pulse generation
if (servo_on) {TIMSK |= (1 << OCIE1A);}
setStopwatch1(0);
}

if (getStopwatch1() > PULSE_REPETITION_NIVEAU) { // Pulse every ~20ms
pulseSERVO(); // Servo pulse generation
if (servo_on) {TIMSK |= (1 << OCIE1A);}
setStopwatch1(0);
}


if (getStopwatch1() > PULSE_REPETITION_ARM_HOCH) { // Pulse every ~20ms
pulseSERVO(); // Servo pulse generation
if (servo_on) {TIMSK |= (1 << OCIE1A);}
setStopwatch1(0);
}

if (getStopwatch1() > PULSE_REPETITION_ARM_SEIT) { // Pulse every ~20ms
pulseSERVO(); // Servo pulse generation
if (servo_on) {TIMSK |= (1 << OCIE1A);}
setStopwatch1(0);
}

}



HILFE!!!


Gruß

topgunfb

topgunfb
10.06.2009, 12:11
Um irgendwelchen Frage entgegen zu wirken:
ARM_SEIT, ARM_HOCH sind die hier: http://www.conrad.de/goto.php?artikel=233751

NIVEAU, GELENK & GREIFER sind die hier: http://www.conrad.de/goto.php?artikel=230500

die Anschlüsse sind: PC2, PC3, PC4, PC5, PC6 an der M32
Strom bekommen die Servos aus zusätzlichen Batterien.

Gruß

topgunfb

Dirk
10.06.2009, 18:47
Hi topgunfb,

was soll dein Programm denn machen?
Du gibst allen Servos Werte (0), dann nach 50ms ARM_HOCH und ARM_SEIT zwei neue Werte (60, 80), die dann so bleiben.

1. Zum Testen würde ich für die Stopwatch2 z.B. Werte von 5000 (anstelle von 48 ) nehmen, damit jede Stellung 5s gehalten wird.

2. In dem if (getStopwatch2() > 5000) Teil würde ich als Test einen Zähler setzen und bei jedem Durchlauf (also alle 5s) per Zähler den Servos neue Werte zuweisen:
Wenn Zähler = 1 -> pos = 30
Wenn Zähler = 2 -> pos = 50 usw. (z.B. als switch-Konstrukt)

3. setStopwatch2(0) gehört ans Ende des if (getStopwatch2() > 5000) Teils, nicht in die Hauptschleife mit task_SERVO().

4. Irgendwie ist eine "}" zuviel. Da müßte der Compiler meckern.

Gruß Dirk

topgunfb
11.06.2009, 17:50
Hi Dirk,

danke für die Antwort. Sowas habe ich mir schon gedacht. (mal wieder zu blöd ... ;-) )

Die Klammer ist wirklich zuviel. Da geht nix. Die muss beim Kommentar entfernen reingerutscht sein.

Ich werds nochmal probieren und mich wieder melden.

Gruß

topgunfb

topgunfb
16.06.2009, 12:36
Hi,

scheinbar habe ich ein größeres Problem...
Hab die gesamte Verkabelung und Lötpunkte nochmal überarbeitet und komme auf keinen grünen Zweig.
Die Servos machen exht nicht das, was sie sollen.....

Ich poste heute, sofern die Zeit reicht, mal noch den Code und ein Video, damit es besser zu verstehen geht...



Danke + Gruß

topgunfb