Servo "murmelt" die ganze Zeit

Hallo zusammen,
ich habe einige Servos an einem MEGA, um mit Spritzen Flüssigkeiten zu pumpen und zu mischen. Wenn die Servos in einer definierten Position sind, dann regeln sie alle paar Sekunden nach; das meine ich mit “murmeln”. Ich benutze die 1.5.2 IDE, die Servo-library und DES 806 BB MG Servos von Graupner (natürlich separat mit 5V versorgt).
Das Gemurmel nervt ganz schön und zieht auch Strom; das muss nicht sein, finde ich. Mein erster Ansatz war nun, nach dem Anfahren einer Position den Pin auf LOW zu legen, denn sonst liegt ja permanent das Regelsignal an. Womöglich fängt das Kabel auch Störungen ein?! Durch das Fehlen des Signals sinkt die Haltekraft, was aber nicht so schlimm wäre. Störender ist, dass das Servo nach einem Reset nicht mehr in die am Ende vom Setup angegebene Ausgangsposition fährt. Warum macht es das?
Hier noch der Code, soweit er fertig ist. Die Funktionsdefinitionen hab ich nicht mit kopiert, die setzen nur Pins rauf und runter.

#include <Servo.h>
#include <LiquidCrystal.h>
//#include <ADC.h>
//#include <Sleep.h>
//#include <Timer1.h>
//#include <Timer2.h>
#define ETS 0

//Analoge Eingänge
//Stromsensoren
int strom12V = A0;
int strom5V = A1;
// Potis 1-3
int pot1 = A2;
int pot2 = A3;
int pot3 = A4;
// Servo Feedback oder sonstige Potis
int pot4 = A5;
int pot5 = A6;
int pot6 = A7;
int pot7 = A8;
int pot8 = A9;
//Displaybuttons
int butl = A10; //Links
int butr = A11; //Rechts

//Servopins (wird weiter unten attached)
Servo servo5; //Pin 2
Servo servo4; //Pin 3
Servo servo3; //Pin 4
Servo servo2; //Pin 5
Servo servo1; //Pin 6

//Freie PWM-Pins
int pwm7 = 7;
int pwm6 = 8;
int pwm5 = 9;
int pwm4 = 10;

//Motortreiber
int inb = 11; //ccw input
int pelt = 12; //duty cycle
int ina = 13; //cw input

//Pins 14-21 (Kommunikation) nicht rausgefuehrt bis auf RX1/TX1 und SDA/SCL

LiquidCrystal lcd(32, 30, 22, 26, 24, 28); //Display Pins RS, E, D4, D5, D6, D7

// Thermometer auf pin 34
// RS485 enable auf Pin 36

//Switches
int Switch1 = 40;
int Switch2 = 42;
int Switch3 = 44;
int Switch4 = 46; 

//Ventile ueber ULN2803
int v9 = 23;
int v10 = 25;
int v11 = 27;
int v12 = 29;
int v13 = 31;
int v14 = 33;
int v15 = 35;
int v16 = 37;
int v1 = 39;
int v2 = 41;
int v3 = 43;
int v4 = 45;
int v5 = 47;
int v6 = 49;
int v7 = 51;
int v8 = 53;

int pos1 = 90; //Nullposition Servo1
int pos2 = 90; //Nullposition Servo2
int pos3 = 130; //Nullposition Magnet3
const int dist = 130; //Magnet weg vom Schlauch, Wert pr?fen!
const int prox = 50; //Magnet am Schlauch, Wert pr?fen!
int dval = 200; //delay value f?r die Pumpzyklen
int airval = 50; //delay f?r Luft Pumpen
int fluval = 25; //delay zum Abfallpumpen
int wval = 10; //delay nach Ventilumschalten
unsigned long time = millis();


void setup()
{
	//pinMode(0, INPUT); //RX0
	//pinMode(1, OUTPUT); //TX0
	pinMode(2, OUTPUT); //servo5
	digitalWrite (2, LOW);
	pinMode(3, OUTPUT); //servo4
	digitalWrite (3, LOW);
	pinMode(4, OUTPUT); //servo3
	digitalWrite (4, LOW);
	pinMode(5, OUTPUT); //servo2
	digitalWrite (5, LOW);
	pinMode(6, OUTPUT); //servo1
	digitalWrite (6, LOW);
	pinMode(7, OUTPUT); //pwm7
	digitalWrite (7, LOW);
	pinMode(8, OUTPUT); //pwm6
	digitalWrite (8, LOW);
	pinMode(9, OUTPUT); //pwm5
	digitalWrite (9, LOW);
	pinMode(10, OUTPUT); //pwm4
	digitalWrite (10, LOW);
	pinMode(11, OUTPUT); //INB
	digitalWrite (11, LOW);
	pinMode(12, OUTPUT); //PELT-PWM
	digitalWrite (12, LOW);
	pinMode(13, OUTPUT); //INA
	digitalWrite (13, LOW);
	//pinMode(14, OUTPUT); //TX3
	//pinMode(15, INPUT); //RX3
	//pinMode(16, OUTPUT); //TX2
	//pinMode(17, INPUT); //RX2
	//pinMode(18, OUTPUT); //TX1
	//pinMode(19, INPUT); //RX1
	//pinMode(20, ?); //SDA
	//pinMode(21, OUTPUT); //SCL
	pinMode(22, OUTPUT); //D7
	pinMode(23, OUTPUT); //v9
	digitalWrite (23, LOW);
	pinMode(24, OUTPUT); //D6
	pinMode(25, OUTPUT); //v10
	digitalWrite (25, LOW);
	pinMode(26, OUTPUT); //D5
	pinMode(27, OUTPUT); //v11
	digitalWrite (27, LOW);
	pinMode(28, OUTPUT); //D4
	pinMode(29, OUTPUT); //v12
	digitalWrite (29, LOW);
	pinMode(30, OUTPUT); //RS
	pinMode(31, OUTPUT); //v13
	digitalWrite (31, LOW);
	pinMode(32, OUTPUT); //E
	pinMode(33, OUTPUT); //v14
	digitalWrite (33, LOW);
	//pinMode(34, OUTPUT); //Tempsensoren
	pinMode(35, OUTPUT); //v15
	digitalWrite (35, LOW);
	pinMode(36, OUTPUT); //
	pinMode(37, OUTPUT); //v16
	digitalWrite (37, LOW);
	pinMode(38, OUTPUT); //
	pinMode(39, OUTPUT); //v1
	digitalWrite (39, LOW);
	pinMode(40, INPUT); //sw1
	pinMode(41, OUTPUT); //v2
	digitalWrite (41, LOW);
	pinMode(42, INPUT); //sw2
	pinMode(43, OUTPUT); //v3
	digitalWrite (43, LOW);
	pinMode(44, INPUT); //sw3
	pinMode(45, OUTPUT); //v4
	digitalWrite (45, LOW);
	pinMode(46, INPUT); //sw4
	pinMode(47, OUTPUT); //v5
	digitalWrite (47, LOW);
	pinMode(48, OUTPUT); 
	pinMode(49, OUTPUT); //v6
	digitalWrite (49, LOW);
	pinMode(50, OUTPUT);
	pinMode(51, OUTPUT); //v7
	digitalWrite (51, LOW);
	pinMode(52, OUTPUT);
	pinMode(53, OUTPUT); //v8
	digitalWrite (53, LOW);
	//Analoge Pins sind automatisch als Input definiert.

	//Display initialisieren
	lcd.begin(20, 4);
	lcd.clear();
	lcd.home();
	lcd.print("Initialisiere...");

	//Servos initialisieren
	servo1.attach(6);
	servo2.attach(5);
	servo3.attach(4);
	servo4.attach(3);
	servo5.attach(2);
        
        servo1.write(pos1);
        servo2.write(pos2);
        servo3.write(pos3);
	//	Serial.begin(115200);
}


void loop()
{
	analogWrite(6, LOW);
        analogWrite(5, LOW);
        analogWrite(4, LOW);
        analogWrite(3, LOW);
        analogWrite(2, LOW);//bringt die Servos zum Schweigen
        int Switch3stat = digitalRead(Switch3);
	int Switch4stat = digitalRead(Switch4);
	if (Switch4stat == HIGH)
	{
		//-------------------------------------------------------------------------------no 1
		loadairv16();
		delay(10);
		for(pos1 = 90; pos1 >= 65; pos1 -= 1)//Luft raus 500µL Servo 1
		{                              
			servo1.write(pos1);
			delay(dval);
		} 
		delay(500);//Druckausgleich abwarten
                alllow();
		for(pos1 = 65; pos1 <= 115; pos1 += 1)//Zellen und Lysepuffer mischen
		{                              
			loadlysis();
			servo1.write(pos1);
			delay(dval);
			pos1 += 1;
			loadcells();
			servo1.write(pos1);
			delay(dval);
			if(pos1 == 70)//bring in the beads!
			{
				pos1 += 1;
				loadbeads();
				servo1.write(pos1);
				delay(dval);
			}
		}//ca. 10 sek Füllzeit
		delay(2000);
		loadairv16();
		for(pos1 = 115; pos1 >= 125; pos1 += 1)//Luft nachziehen und alles in die Spritze holen
		{                              
			servo1.write(pos1);
			delay(dval);
		} 
		//sleep(3600000);//hier wird eigentlich 60 min incubiert!
		alllow(); //beendet no 1

Hat jemand schon mal sowas erlebt und behoben? Bin für jeden Hinweis dankbar. Schöne Grüße
Sebastian

godo:
Hallo zusammen,
ich habe einige Servos an einem MEGA, um mit Spritzen Flüssigkeiten zu pumpen und zu mischen. Wenn die Servos in einer definierten Position sind, dann regeln sie alle paar Sekunden nach; das meine ich mit “murmeln”. Ich benutze die 1.5.2 IDE, die Servo-library und DES 806 BB MG Servos von Graupner (natürlich separat mit 5V versorgt).
Das Gemurmel nervt ganz schön und zieht auch Strom; das muss nicht sein, finde ich. Mein erster Ansatz war nun, nach dem Anfahren einer Position den Pin auf LOW zu legen, denn sonst liegt ja permanent das Regelsignal an. Womöglich fängt das Kabel auch Störungen ein?! Durch das Fehlen des Signals sinkt die Haltekraft, was aber nicht so schlimm wäre. Störender ist, dass das Servo nach einem Reset nicht mehr in die am Ende vom Setup angegebene Ausgangsposition fährt. Warum macht es das?..

Hat jemand schon mal sowas erlebt und behoben? Bin für jeden Hinweis dankbar. Schöne Grüße
Sebastian

Ja, das kenne ich.
behoben habe ich es durch manuelle Ansteuerung der Servos.
Meine Vermutung ist, dass die Pulslänge, die die Servo.h erzeugt, nicht konstant ist. Daher immer ein kleiner Jitter.
Die Servo.h ist gut für dynamische Anwendungen, bei denen die Servos ständig in Bewegung sind. Für Statische Anwendungen funktioniert es nicht.
ich hatte mir eine kleine Funktion geschrieben (im anhang) ob das auch mit 5 Servos noch funktioniert, weiß ich nicht, mußt du probieren.

Du kannst aber auch die 20ms Pulszeit verlängern. Die meisten Servos können das und wenn die Abstände zu groß werden, reagieren sie darauf einfach in dem sie etwas langsamer werden.

Servo_refresh.ino (2.13 KB)

Hm.
Versuch mal, die Servos, wenn sie nicht benötigt werden, mit detach(); zu entkoppeln.
Musst sie dann allerdings jedes Mal, wenn du sie brauchst, wieder mit attach() einbinden, aber das sollte Störungen der Lib. verhindern.
Und natürlich den vorherigen Wert speichern (read(); ) und sofort nach dem attach(); wieder mit write(); hinschicken.

Das funktioniert allerdings nur, wenn die Servos nicht belastet werden, während der Stillstandszeiten.

Falls auch das noch nicht hilft, müsstest du die Servos komplett ausschalten, also auch deren Stromversorgung.

Danke für die Tips. Ich habe das mit den 20 ms probiert, aber das ist keine Lösung.
detach() funktioniert. Das Servo hat halt keine Haltkraft mehr, aber die Stromaufnahme geht gegen Null und es ist endlich still. Die Kraft des Servos ist natürlich auf den Widerstand des Getriebes reduziert, aber das reicht. Da ich langsam über eine for-Schleife den Wert erreiche, ist er auch der nächste Anfangswert, ich lese es nicht aus, und es klappt ohne Sprünge.
Schönen Dank und gute Nacht
Sebastian