Servo zittert im Projekt, aber nicht auf dem Steckbrett

Hi,

mein ein Servo hat in meinem Projekt (Motorradumbau) hat eine Art "Zittern".

Auf dem Steckbrett ist alles i.O.; (sowohl mit dem StarterKit Arduino Servo, als auch mit dem verbauten, digitalen, Projektservo).

Aber in dem Projekt verbaut zittert das Servo. Ich hab schon einen größeren ELKO verbaut und auch einen Widerstad in die Signalleitung gelegt. Leider ohne Erfolg. Die Verkabelung hat eine Länge von ca. 65 cm. Die Spannungsversorgung erfolgt extern.

Wie bekomme ich Ruhe in mein Servo? Ist es möglich, das SERVO nur, z.B., alle 200 Millisekunden anzusteuern? Es würde der Funktion keinen Abbruch tun. Würde es in der übrigen Zeit dennoch den definierten Winkel halten? Die Stromversorgung bliebe ja dennoch bestehen.

Viele Grüße

Christoph


#include <Servo.h>
#include <EEPROM.h>

Servo servo;

bool s1 = false;  //Taster Drosselklappe auf
bool s2 = false;  //Taster Drosselklappe zu
bool s3 = false;  //Taster Gangwahl auf raufschalten
bool s4 = false;  //Taster Gangwahl auf runterschalten
bool s5 = false;  //Taster Gangwahl zwangsweise auf rauf
bool s6 = false;  //Schalter System an oder aus
bool s7 = false;  //Schalter für Set Funktion
bool s8 = false;  //Tatser für Set Funktion
bool h1 = false;  //Signalhupe
bool sm = false;  //Startmodus false = aus (erster auf zweiter Gang im Überbrückermodus ohne das der Timer abläuft)



unsigned long timer1 = 0;   // Entpreller Timer s1
unsigned long timer2 = 0;   // Entpreller Timer s2
unsigned long timer3 = 0;   // Entpreller Timer s3
unsigned long timer4 = 0;   // Entpreller Timer s4
unsigned long timer5 = 0;   // Entpreller Timer s5
unsigned long timer6 = 0;   // Entpreller Timer s6
unsigned long timer7 = 0;   // Entpreller Timer s7
unsigned long timer8 = 0;   // Entpreller Timer s8
unsigned long timer9 = 0;   // Timer für Schaltdauer Überbrücker
unsigned long timer10 = 0;  // Timer für Wartezeit wenn anglerauf ist true bis Qs ist wieder in Funktion
unsigned long timer11 = 0;  // Timer für Wartezeit wenn Wechsel von RAUF auf RUNTER damit QS aus bevor Servo sich in Bewegung setzt
unsigned long timer12 = 0;  // Timer um bei Drückzeit von mehr als 3 Sekunden auf Überbrücker um in den Startmodus zu wechseln
unsigned long timer13 = 0;  // Timer um bei Drückzeit von mehr als 5 Sekunden auf Überbrücker den Startmodus zu deaktivieren
unsigned long timer14 = 0;  // Timer um Blinkmodus für LED RUNTER für Startmodus zu steuern
unsigned long timer15 = 0;  // Timer für Wartezeit zwischen s2 true und s2an false um Flattern im Zwischengas zu unterbinten


bool s1an = false;  //Zwischenvariable für s1
bool s2an = false;  //Zwischenvariable für s2
bool s3an = false;  //Zwischenvariable für s3
bool s4an = false;  //Zwischenvariable für s4
bool s5an = false;  //Zwischenvariable für s5
bool s6an = false;  //Zwischenvariable für s6
bool s7an = false;  //Zwischenvariable für s7
bool s8an = false;  //Zwischenvariable für s8
bool s9an = false;  //Hauptvariable für Blinkerfunktion der Startautomatik

bool RAUF = false;       // Ergebnis fuer raufschalten
bool RUNTER = false;     // Ergebnis für runterschalten
bool automatan = false;  // Ergebnis ob automat an sein soll
bool kalibran = false;   // Ergebnis ob Kalibrierung an sein soll

int setrauf;            // abgelesener winkel über poti bei raufschalten, in eeprom gespeichert
int setrunter;          // abgelesener winkel über poti bei runterschalten, in eeprom gespeichert
int set;                // abgelesener Winkel über poti

int anglerauf = 100;     //Servostellung set raufschalten --> 150 Platzhalter, eigentlich angelrauf = setrauf --> ACHTUNG; MANUELLE KALIBRIERUNG
int anglerunter = 90;     //Servostellung set runterschalten --> 40 Platzhalter, eigentlich angelrunter = setrunter --> ACHTUNG; MANUELLE KALIBRIERUNG

int zwangan = 2500;      //Schaltdauer überbrücker, zwangsweise raufschalten
int warteqs = 300;       //Wartezeit Schaltautomat ab anglerauf ist true
int blink = 400;         //Blinken in 0,5 Sekunden während Startmodus aktiv ist
int swz = 40;            //Standartwartezeit für Entpreller
int warteRunter = 1000;  //Wartezeit für Wechsevorgang wenn RUNTER true werden soll (s2 == false//timer 15)
int startmod = 3000;     //Drückzeit von 3 Sekunden auf Überbrücker um in den Startmodus zu wechseln
int startmodaus = 5000;  //Drückzeit von 5 Sekunden auf Überbrücker um den Startmodus zu verlassen
bool gsa = false;        //alter Gangstatus
bool gsn = false;        //neuer Gangstatus
int zaehler = 0;         //Zähler für Startmodus

float ovs = 0.9;  //obere Schwelle volatge --> 1 Platzhalter, eigentlich voltageKalibr --> ACHTUNG; MANUELLE KALIBRIERUNG
float uvs = 0.75;      //untere Schwelle voltage --> ovs *0,5


float voltageSoll;  //Umkehrspannung Drosselklappenpoti
float potiDrossel;  //Gasgriff
float voltage;      //Volt abhängig von Gasgriffposition

void setup() {


  servo.attach(10);  //Servomotor
  servo.write(anglerauf);
  Serial.begin(9600);

  pinMode(3, INPUT_PULLUP);   // Taster Drosselklappe auf
  pinMode(4, OUTPUT);         // Signalhupe Überbrücker --> ersatzweise grüne LED
  pinMode(5, INPUT_PULLUP);   // Taster Gangwahl auf raufschalten
  pinMode(6, INPUT_PULLUP);   // Taster Gangwahl auf runterschalten
  pinMode(7, INPUT_PULLUP);   // Taster Gangwahl zwangsweise auf rauf Überbrücker
  pinMode(8, INPUT_PULLUP);   // Schalter System an oder aus
  pinMode(9, OUTPUT);         // LED System ist an/rot
  pinMode(11, OUTPUT);        // LED System ist aus/grün
  pinMode(13, OUTPUT);        // LED Gangwahl auf raufschalten
  pinMode(12, OUTPUT);        // LED Gangwahl auf runterschalten
  pinMode(A1, INPUT_PULLUP);  // Schalter für Set Funktion an oder aus
  pinMode(A0, INPUT);         //Poti Spannung kalibr Funktion
  pinMode(A4, INPUT);         //Poti Drosselklappe
  pinMode(A5, OUTPUT);        //Schalter Schaltautomat --> ersatzweise rote LED led an = Qs ist an
}

void loop() {

  s1 = digitalRead(3);
  s3 = digitalRead(5);
  s4 = digitalRead(6);
  s5 = digitalRead(7);
  s6 = digitalRead(8);
  s7 = digitalRead(A1);
  s8 = digitalRead(A2);
  potiDrossel = analogRead(A4);
  gsn = digitalRead(3);





  if (s1 == true) {
    timer1 = millis();
  }

  if (s2 == true) {
    timer2 = millis();
  }

  if (s2 == false) {
    timer15 = millis();
  }

  if (s3 == true) {
    timer3 = millis();
  }

  if (s3 == true) {
    timer10 = millis();
  }

  if (s4 == true) {
    timer4 = millis();
  }

  if (s5an == false) {
    timer9 = millis();
  }

  if (s5 == true) {
    timer12 = millis();
    timer13 = millis();
    timer5 = millis();
  }

  if (s6 == true) {
    timer6 = millis();
  }

  if (s7 == true) {
    timer7 = millis();
  }

  if (s8 == true) {
    timer8 = millis();
  }

  if (RAUF == true) {
    timer11 = millis();
  }


  if (s7 == false && millis() - timer7 > swz) {
    s7an = true;
  } else {
    s7an = false;
  }

  if (s6 == false && millis() - timer6 > swz) {
    s6an = true;
  } else {
    s6an = false;
  }

  if (s3 == false && millis() - timer3 > swz) {
    s3an = true;
  } else {
    s3an = false;
  }

  if (s4 == false && millis() - timer4 > swz) {
    s4an = true;
  } else {
    s4an = false;
  }



  if (s6an == true) {  // Schalter System an
    automatan = true;
    kalibran = false;
  } else {  // Schalter System aus und Schalter Set Funktion an oder aus
    automatan = false;
  }

  if (s7an == true) {  // Schalter Set Funktion an
    if (automatan == false) {
      kalibran = true;
    }
  } else {
    kalibran = false;
  }


  if (automatan == true) {
    if (kalibran == false)  // Schalter System an und Schalter Set Funktion aus
    {
      automat();
    }
  } else {
    if (kalibran == true)  // Schalter System aus und Schalter Set Funktion an
    {
      kalibr();
    } else                 // Schalter System aus und Schalter Set Funktion aus
    {
      servo.write(anglerauf);
      RAUF = true;
    }
  }



  if (s3an == true) {  // LED Gangwahl auf raufschalten
    digitalWrite(13, true);
  } else {
    digitalWrite(13, false);
  }
  if (s4an == true) {  // LED Gangwahl auf runterschalten
    digitalWrite(12, true);
  } else {
    digitalWrite(12, false);
  }
  if (s6an == true) {  // LED System ist an
    digitalWrite(9, true);
  } else {
    digitalWrite(9, false);
  }
  if (s6an == false) {  // LED System ist aus
    digitalWrite(11, true);
  } else {
    digitalWrite(11, false);
  }
  if (RAUF == true && s3an == true && s5an == false && sm == false && millis() - timer10 > warteqs) {  //Relais Schaltautomat an bei Gangwahl auf rauf, aber nur dann wenn zwangsweise (s5an) rauf aus ist
    digitalWrite(A5, true);
  } else {
    digitalWrite(A5, false);
  }
}


//################################################################
//#                  Funktionen                                  #
//################################################################

void automat() {

  if (sm == true) {  // Wechsel in die Funktion Startmodus
    StartModus();
  }

  voltage = potiDrossel * (5 / 1023.0);      //Spannungsabgriff von dem Drosselklappenpoti


  // uvs = ovs * 0.50;                         //Definition untere Voltschwelle ist 50 % unterhalb der oberen Voltschwelle (früher auf RAUF/später auf RUNTER)

  if (RAUF == true) {                       //Wechsel von ovs auf uvs sobald RAUF anliegt
    voltageSoll = uvs;
  } else {
    voltageSoll = ovs;
  }



  if (voltage > voltageSoll) {              // ständiger Abgriff Drosselklappenpoti um RAUF oder RUNTEr zu definieren
    s2 = false;
  } else {
    s2 = true;
  }

  if (s1 == false && millis() - timer1 > swz) {  //Taster Drosselklappe offen
    s1an = true;
  } else {
    s1an = false;
  }

  if (s2 == false && millis() - timer2 > swz) {  //Droselklappenpoti --> Bedingung für Gas auf
    s2an = true;
  }

  if (s2 == true && millis() - timer15 > warteRunter) {  // Drosselklappenpoti --> Bedingung für Gas zu, mit Wartezeit um Flattern zu verhindern
    s2an = false;
  } else {
    s2an = true;
  }


  if (s5 == false && millis() - timer12 > startmod) {     //Startmodus (sm) = true wenn Überbrücker 3 Sek. gedrückt wird.
    sm = true;
  }

  if (s5 == false && millis() - timer13 > startmodaus) {  //Startmodus (sm) = false wenn Überbrücker 5 Sek. gedrückt wird.
    sm = false;
  }

  if (s5 == false && millis() - timer5 > 25) {
    s5an = true;
  }

  if (s5an == true && millis() - timer9 < zwangan) {    //Übersteuerung um mit Kupplung zu schalten während die Automatik an ist
    s5an = true;
  } else {
    s5an = false;
  }

  if (s5an == true && s3an == true && sm == false) {    //signalhorn das Übersteuerung aktiv ist und Mechanik den Schatvorgang abgeschlossen hat
    h1 = true;
  } else {
    h1 = false;
  }

  if (h1 == true) {
    digitalWrite(4, true);                          //Signahorn
    } else {
      digitalWrite(4, false);
    }



  if (s1an == true && s2an == false || s1an == true && s2an == true || s1an == false && s2an == true) { //Eigentlicher Schaltvorgang für RAUF und RUNTER
    RAUF = true;
    RUNTER = false;
  } else {
    RAUF = false;
    RUNTER = true;
  }

  if (RUNTER == true && s5an == false && millis() - timer11 > warteqs) { //Eigentlicher Schaltvorgang für den Überbrücker
    servo.write(anglerunter);
  } else {
    servo.write(anglerauf);
  }

  if (RAUF == true) {
    servo.write(anglerauf);
  }
  Serial.println(voltage);
  Serial.println(voltageSoll);
  Serial.println(s2an);
  
}

void StartModus() {

  if (sm == true) {         // Überbrücker ist aktiv
    s5an = true;
  }

  if (sm == false) {
    timer14 = millis();
  }

  if (sm == true && millis() - timer14 < blink) {   //Blinkprozess als LED RUNTER als Signal dass Startmodus aktiv ist
    s9an = true;
  }

  if (sm == true && millis() - timer14 > blink) {
    s9an = false;
  }

  if (sm == true && millis() - timer14 > 2 * blink) {
    timer14 = millis();
  }

  if (sm == false) {
    s9an = false;
  }

  if (s9an == true) {
    digitalWrite(12, true);
  }

  if (gsn != gsa) {
    if (gsn == false) {
      zaehler++;
    }
  }

  gsa = gsn;

  if (sm == true && zaehler >= 2) {  //Verlassen von sm (Startmodus) nachdem im zweiten Gang Vollgas anliegt
    sm = false;
    s5an = false;
  }

  if (sm == false) {
    gsn = true;
    gsa = true;
    zaehler = 0;
  }

  Serial.println(zaehler);
}

void kalibr() {

  digitalWrite(9, true);
  digitalWrite(11, true);


  set = analogRead(A0);

  set = map(set, 0, 1023, 0, 180);

  servo.write(set);
  Serial.println(set);
}

Setze Deinen Sketch bitte direkt ins Forum und in Codetags. Wie das geht, steht hier.
Ist die externe Versorgung die Bordspannung? Die ist elektrisch sehr versaut. Da musst Du viel Aufwand treiben, um die sauber zu bekommen. Nimm am Besten ein fertiges Teil dafür.

Gruß Tommy

Ja, ich nehme 12 Volt von der Bordspannung, die werden dann durch einen DC/DC Wandler auf 6,5 Volr reduziert. Wie bekomme ich die Spannung denn sauber? Würde dan ein Snubber helfen? Viele Grüße

Den Sketch mag ich nicht lesen da er viel zu kaotisch ist und keien Komentare vorhanden sind.
zB was macht dieses Codestück?

if (sm == false) {
    gsn = true;
    gsa = true;
    zaehler = 0;

Wieviel Strom kann das Netzteil / DC/DC Wandler liefern?
Wieviel Strom bracht der Servo?
Zittert der Servo auch wenn Du ihn mit einem ganz einfachen Sketch ansteuerst?

Grüße Uwe

Viel Raum für Einstreuungen von anderswo. Ich würde mir ein Scope anschaffen um das Problem einfacher einzukreisen und zu beheben.

Ist der Wert stabil?

Kann man auch schreiben als

digitalWrite(9, s6an);

Aber was ist 9 und was ist s6? Vergebe mal bessere Namen und benutze Konstanten

hi, nein, der Wert schwankt um 1Grad +-. Ich habs auch schon mit nem anderen Poti probiert, Ergebnis war dasgleiche. Da ja dieser Code im Steckbrett funktioniert aber im "Werkstück" halt nicht bzw dort dieses Zittern auftritt, vermute ich einfach, das das a der zu langen Verkabelung liegt. kann ich die zu lange Verkabelung "entsören"? Der DC DC Wandler liefert 2,5 A. vg

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.