Servo Position-Halten - Adruino Nano

Benutzeravatar
telicopter
Beiträge: 1864
Registriert: 09.12.2009 20:04:50
Wohnort: NRW, Krefeld...

#31 Re: Servo Position-Halten - Adruino Nano

Beitrag von telicopter »

Ich kann, wie gesagt, in ein paar Tagen mal danach schauen. Prinzipiell sollte die RCArduinoFastLib funktionieren. Ich habe auch schon ein, zwei Projekte damit umgesetzt. Die Delay-Funktion ist aber generell eher zu vermeiden, da sie halt für den Bestimmten Zeitraum alle anderen Prozesse lahmlegt. Das freut die entsprechenden PWM Signale der Servos natürlich überhaupt nicht
Grüße Tim

Jeder LOGO hat ein "LOGO" Logo, ...ist doch logo!
Never run a changing System!
Benutzeravatar
TheManFromMoon
Beiträge: 3235
Registriert: 19.01.2005 11:05:48
Wohnort: Bad Malente
Kontaktdaten:

#32 Re: Servo Position-Halten - Adruino Nano

Beitrag von TheManFromMoon »

Das Delay hatte ich schon auskommentiert. Trotzdem hängen die Servos nicht an den Knüppeln....
Benutzeravatar
tracer
Operator
Operator
Beiträge: 63774
Registriert: 18.08.2004 18:50:03
Wohnort: Kollmar
Kontaktdaten:

#33 Re: Servo Position-Halten - Adruino Nano

Beitrag von tracer »

TheManFromMoon hat geschrieben:// lets set a standard rate of 50 Hz by setting a frame space of 10 * 2000 = 3 Servos + 7 times 2000
  CRCArduinoFastServos::setFrameSpaceA(SERVO_FRAME_SPACE,7*2000);
Ich habe keinen Arduino greifbar, aber müssten das nicht 17*2000 sein?

Edit: Je nachdem, wie man den Kommentar interpretiert, ist es 10*2000, oder halt 17*2000, aber 7*2000 erscheint mir zu wenig.
Benutzeravatar
TheManFromMoon
Beiträge: 3235
Registriert: 19.01.2005 11:05:48
Wohnort: Bad Malente
Kontaktdaten:

#34 Re: Servo Position-Halten - Adruino Nano

Beitrag von TheManFromMoon »

Merker für mich selbst:

8-Channel PWM or Servo FeatherWing Add-on For All Feather Boards AF2928
https://www.ebay.de/itm/8-Channel-PWM-o ... 2249002946
EAN: 4060137021015
Adafruit Nr: 2928

Adafruit 12-Channel 16-bit PWM LED Driver - SPI Interface
https://www.ebay.de/itm/Adafruit-12-Cha ... 2373316564
EAN: 4060137024689
Adafruit Nr: 1455

Adafruit 16-Channel 12-bit PWM Servo Driver I2C Interface PCA9685 Robot G42
https://www.ebay.de/itm/Adafruit-16-Cha ... 2248004016
Adafruit Nr: 815

Adafruit 24-Channel 12-bit PWM LED Driver - SPI Interface
https://www.ebay.de/itm/Adafruit-24-Cha ... 2373316655
EAN: 4060137024696
Adafruit Nr: 1429

PCA9685 Servomotor Driver | 16-Kanal Treiber 12-bit | PWM & I2C F Arduino Robot
https://www.ebay.de/itm/PCA9685-Servomo ... 1309292808
CubaLibreee
Beiträge: 1947
Registriert: 08.09.2013 15:35:26

#35 Re: Servo Position-Halten - Adruino Nano

Beitrag von CubaLibreee »

Mein Nano wurde heute verschickt. Somit spiel ich bald mit... :mrgreen:

Danke Leute echt...
Benutzeravatar
TheManFromMoon
Beiträge: 3235
Registriert: 19.01.2005 11:05:48
Wohnort: Bad Malente
Kontaktdaten:

#36 Re: Servo Position-Halten - Adruino Nano

Beitrag von TheManFromMoon »

Also ich habe in der Zwischenzeit mal n bisschen gelesen und komme zum Schluss:
Wenn man das richtig machen will, dann macht man sowas mit Hardware und nicht mit Software.
Das Problem bei der Software ist, dass der Prozessor und das Programm sich die ganze Zeit darum kümmern müssen präzise PWM Signale für die Servos aufzubereiten und zur Verfügung zu stellen UND dazu noch den eigentlichen Programmcode abzuarbeiten.
Das beißt sich, und daher wird es immer wieder zu irgendwelchen Problemen kommen.
Besser ist der Hardware Weg.
Da kümmert sich der Prozessor um das eigentliche Programm.
Per I²C werden die Soll-Positionen an den PWM Chip übertragen.
Und der PWM Chip kümmert sich nur um die adäquate Erzeugung der Servoansteuerung.

Ich glaube das dies wesentlich stabiler läuft als eine Softwareemulation der Signale.
Nun habe ich nach Chips gesucht, die das machen.
Leider habe ich keine kleinsten Chips mit wenigen Kanälen gefunden, sondern quasi nur den PCA9685 mit gleich 16 Kanälen.


Der Adafruit 1455 scheint nicht gut für Servos geeignet zu sein. Der Chip braucht wohl pausenlos Signale vom Controller und ist daher nicht so gut geeignet für Servoansteuerung. Das steht so in der Beschreibung. Schade eigentlich, der ist schön klein :-(

Der Adafruit 1429 soll auch nicht für Servos geeignet sein. Der Chip braucht wohl pausenlos Signale vom Controller und ist daher nicht so gut geeignet für Servoansteuerung. Das steht so in der Beschreibung.

Bleiben noch der Adafruit 2928 (8 Kanal) und der Adafruit 815 (16 Kanal).
Da die beide den gleichen Chip haben, gleich angesteuert werden und fast gleich groß sind würde ich den Adafruit 815 mit 16 Kanälen wählen, auch wenn man nur 3-4 Kanäle braucht. Dann hat man noch ne Menge Kanäle in Reserve, man weiß ja nie :-)

Oder eben den China Klon (wie auch immer das geht für 1,68€ inklusive Versand aus China?!?!)
Der Adafruit 815 hat noch einen Reverse Polarity Schutz, den ich beim China Klon nicht sehen konnte. Ansonsten dürften die von der Funktion ähnlich sein.

Ich werde mir jetzt mal 2 Stück (immer gleich zwei, kann ja sein das man einen aus Versehen kaputtmacht oder einer von Haus aus defekt ist oder auf dem Versandweg kaputtgeht) von dem hier bestellen (günstiger Preis aus Deutschland kurze Lieferzeit, Kondensator ist bestückt):
https://www.ebay.de/itm/PCA9685-16-Kana ... 3285067342

Dauert also ein paar Tage bis der hier ist....

Lieben Gruß,
Chris
CubaLibreee
Beiträge: 1947
Registriert: 08.09.2013 15:35:26

#37 Re: Servo Position-Halten - Adruino Nano

Beitrag von CubaLibreee »

Heheee Chris.
Mach dir jaaa keinen Stress deswegen! Wenn das nicht möglich ist kann ich immer noch bei den alten Modulen bleiben. Kann dir bei Interesse auch mal ein Bild zukommen lassen der Hardware. Ich kann damit nicht viel anfangen... Aber ist für mich halt nicht zufrieden stellend da die Servogeschwindigkeit am Knüppel unabhängig ist.
Benutzeravatar
TheManFromMoon
Beiträge: 3235
Registriert: 19.01.2005 11:05:48
Wohnort: Bad Malente
Kontaktdaten:

#38 Re: Servo Position-Halten - Adruino Nano

Beitrag von TheManFromMoon »

Das kann man ganz einfach selber programmieren. Das ist kein Hexenwerk.
Übrigends finde ich dein Projekt hammergeil. Hätte ich auch gerne.
Und wenn ich einfach helfen kann, dann tue ich das :D
CubaLibreee
Beiträge: 1947
Registriert: 08.09.2013 15:35:26

#39 Re: Servo Position-Halten - Adruino Nano

Beitrag von CubaLibreee »

Der EC650 liegt ausgeschlachtet in ner Kiste. Habe dafür keine Verwendung mehr... :mrgreen:
Benutzeravatar
telicopter
Beiträge: 1864
Registriert: 09.12.2009 20:04:50
Wohnort: NRW, Krefeld...

#40 Re: Servo Position-Halten - Adruino Nano

Beitrag von telicopter »

Ich habe das Ganze jetzt doch mal mit der Standard Servo Library durchgezogen. Mit ein wenig Filterung der Eingangswerte ist auf jeden Fall schon mal Ruhe bei den Servos. Das ganze geht natürlich etwas auf Kosten der Reaktionsfreudigkeit, aber da es sich um einen Bagger und keinen 3D-Heli handelt, sollte das wohl zu verkraften sein. :wink: Die Fahrgeschwindigkeit ist abhängig vom Knüppelausschlag ( Alle Einstellungen können in den Defines gemacht werden). Ich habe zwar versucht, die Servoposition möglichst oft zu aktualisieren, aber da die Ablaufgeschwindigkeit des Programms hier der begrenzende Faktor ist und die Positionsaktualisierung mit diskreten Werten erfolgt, lässt sich ein leichtes Ruckeln nicht verhindern. Je langsamer der Ausleger bewegt wird bzw. je langsamer das Servo reagiert, desto geringer ist das Ruckeln natürlich. Um hier noch zu optimieren, müsste der Code an gewissen Stellen noch etwas eingestampft und gesäubert werden, um die Updaterate entsprechend zu erhöhen. Oder einfach langsame Analogservos benutzen. :mrgreen:

Ihr könnt ja mal probieren, ob es bei euch auch läuft.


Grüße
Tim

Code: Alles auswählen


#include <Servo.h>

#define RC1_PIN 5       //Empfänger Steuer-Kanal D5
#define RC2_PIN 6       //Empfänger Steuer-Kanal D6
#define RC3_PIN 7        //Empfänger Steuer-Kanal D7
#define SERVO1_PIN 8    //Servosteuerleitung D8
#define SERVO2_PIN 9    //Servosteuerleitung D9
#define SERVO3_PIN 10    //Servosteuerleitung D10

#define RC_MIN  1000      //Maximale und minimale Pulslänge 
#define RC_MAX  2000
#define MAX_SPEED 50      //Maximale Geschwindigkeit bei Knüppelvollausschlag (Microsekunden-Inkrement je Berechnungsschritt)
#define RC_TOTZONE 10     //Totzone um die Knüppelmitte
#define RC_INPUT_TOLERANCE 35     //Toleranzbereich der RC-EIngangssignale in Microsekunden
#define LM_SIZE 2         //Breite des Laufenden Mittelwert-Filters

Servo servo_1;
Servo servo_2; 
Servo servo_3;

unsigned int prevPulse [3] = {0, 0, 0};    //letzte berechnete Pulsweite
unsigned int actPulse [3] ={0, 0, 0};      //aktuelle berechnete Pulsweite
unsigned int LM[LM_SIZE][3];              // Letzte Messungen
unsigned int sum [3]= {0, 0, 0};          //Summe aller Messungen
int channelPin[3] = {RC1_PIN, RC2_PIN, RC3_PIN};       //Array mit den Servobelegungen
unsigned int servoPosition[3] = {1500, 1500, 1500};   //aktuelle Servoposition als Pulsweite
byte index = 0;     //Position im Array der Messwerte



void setup()
{
  servo_1.attach(SERVO1_PIN);
  servo_2.attach(SERVO2_PIN);
  servo_3.attach(SERVO3_PIN);

  InitializeLMArray();    //Initialisierung der Filterfunktion
  
  Serial.begin(115200);
}

void loop()
{
  readChannelFiltered();
}

/*****************************************************************************************************************************
// Funktion zum Simulieren der Hydraulik-Eigenschaften
//
*****************************************************************************************************************************/
unsigned int Hydraulik(int pulse, int servoNr )
{
  if (abs( pulse - 1500) <= RC_TOTZONE)   //Anpassung der RC-Totzone in der Knüppelmitte
  {
    pulse = 1500;
  }
  
  int correction = map(pulse, RC_MIN, RC_MAX, -MAX_SPEED, MAX_SPEED); 
  servoPosition[servoNr]  +=  correction;

  if ( servoPosition[servoNr] <= RC_MIN  )
  {
    servoPosition[servoNr] = RC_MIN;
  }
  if ( servoPosition[servoNr] >= RC_MAX)
  {
     servoPosition[servoNr] = RC_MAX;
  }
  return servoPosition[servoNr];
}

/*****************************************************************************************************************************
// Funktion zum Auslesen und Filtern der RC-Eingangskanäle mithilfe eines laufenden Mittelwertfilters
//
*****************************************************************************************************************************/
void readChannelFiltered()
{

   for (int i = 0; i <= 2 ; i++)
   {
      unsigned int currPulse = pulseIn(channelPin[i], HIGH, 25000);  //Aufnahme der RC-Pulsweite
      if(currPulse == 0)
      {
        currPulse = 1500;  //Ausgabe des Neutralwertes, wenn kein gültiger Puls vorhanden
      }
 
 
      sum [i] -= LM[index][i];    //Berechnung des gleitenden Mittelwertes
      LM[index][i] = currPulse;
      sum[i] += LM[index][i];

      actPulse[i] =  sum [i] / LM_SIZE;   //Gleitender Mittelwert wird zur aktuellen Pulsweite
      
      
      if ( abs (prevPulse[i] - actPulse[i]) <= RC_INPUT_TOLERANCE)    //Unterdrückung von Servozittern durch die Einführung eines Toleranzbereiches 
      {                                                               //Wenn neuer Wert innerhalb der Toleranz liegt, wird der alte Wert weiterverwendet
         actPulse[i] = prevPulse[i];
      }
     
      prevPulse[i] = actPulse[i];
      
     servo_1.writeMicroseconds(Hydraulik(actPulse[0], 0)); //Möglichst häufige Ansteuerung der Servos für einen flüssigeren Lauf
     servo_2.writeMicroseconds(Hydraulik(actPulse[1], 1));
     servo_3.writeMicroseconds(Hydraulik(actPulse[2], 2));
   }
   
   index++;
   index = index % LM_SIZE;
}

/*****************************************************************************************************************************
// Initialisierungsfunktion zum Auffüllen aller Arraywerte 
//
*****************************************************************************************************************************/
void InitializeLMArray()
{
  while ( index < LM_SIZE)
  {
   for (int i = 0; i <= 2 ; i++)
   {
    
      unsigned int currPulse = pulseIn(channelPin[i], HIGH, 25000);  //Aufnahme der RC-Pulsweite
      if(currPulse == 0)
      {
        currPulse = 1500;   //Ausgabe des Neutralwertes, wenn kein gültiger Puls vorhanden
      }
 
      sum [i] -= LM[index][i];    //Berechnung des gleitenden Mittelwertes
      LM[index][i] = currPulse;
      sum[i] += LM[index][i];

      actPulse[i] =  sum [i] / (index + 1 );   //Gleitender Mittelwert wird zur aktuellen Pulsweite
      
      
      if ( abs (prevPulse[i] - actPulse[i]) <= RC_INPUT_TOLERANCE)    //Unterdrückung von Servozittern durch die Einführung eines Toleranzbereiches 
      {                                                               //Wenn neuer Wert innerhalb der Toleranz liegt, wird der alte Wert weiterverwendet
         actPulse[i] = prevPulse[i];
      }
     
      prevPulse[i] = actPulse[i];
   }

    servo_1.writeMicroseconds(1500); //Servoposition in Neutrallage halten bis Initialisierung beendet
    servo_2.writeMicroseconds(1500);
    servo_3.writeMicroseconds(1500);
   
   index++;
  }
  index = 0;
}


Grüße Tim

Jeder LOGO hat ein "LOGO" Logo, ...ist doch logo!
Never run a changing System!
Benutzeravatar
telicopter
Beiträge: 1864
Registriert: 09.12.2009 20:04:50
Wohnort: NRW, Krefeld...

#41 Re: Servo Position-Halten - Adruino Nano

Beitrag von telicopter »

Die Werte für den Filter und die Toleranz- und Totzone sind wahrscheinlich vom verwendeten Empfänger abhängig. Ich könnte mir vorstellen, dass mein verwendeter 5€ Orange RX Empfänger nicht allzu saubere Signale ausgibt.

Ich habe hier noch ein kleines Video hochgeladen. Man sieht, dass ich nicht der geborene Baggerfahrer bin. :mrgreen: Aber prinzipiell lassen sich alle Funktionen in verschiedenen Geschwindigkeiten steuern, wobei es sich bei dem untersten Servo um ein flinkes Digital-Exemplar handelt und entsprechend etwas mehr ruckelt. Die maximale Geschwindigkeit lässt natürlich im Code mit dem MAX_SPEED Parameter verringern.

Grüße Tim

Jeder LOGO hat ein "LOGO" Logo, ...ist doch logo!
Never run a changing System!
Benutzeravatar
tracer
Operator
Operator
Beiträge: 63774
Registriert: 18.08.2004 18:50:03
Wohnort: Kollmar
Kontaktdaten:

#42 Re: Servo Position-Halten - Adruino Nano

Beitrag von tracer »

Klasse, Tim.
CubaLibreee
Beiträge: 1947
Registriert: 08.09.2013 15:35:26

#43 Re: Servo Position-Halten - Adruino Nano

Beitrag von CubaLibreee »

Ich seh uwar mit meinem Telefon das Video gerade nicht und mein Nano ist auch noch nicht da, aber ich sag mall, ihr seit so geil.

Inzwischen sind 4 Leute dran. Natürlich poste ich letzt endlich den Besten Code. Und wer auf die Messe kommt, von den vier, falls wir es schaffen, bekommt Bier bis zum abwinken. Oder auch n Kaffee...

Edit:
hey das sieht doch richtig geil aus! Und auf jeden Fall flüssiger als die Kaufmodule!!! Hoffentlich kommen morgen meine Nanos...!!! Ich werde berichten!!! :mrgreen:

Aber ehrlich. Ich hab mir den Code angesehen. Das hätte ich niemals hin bekommen!!! Ich glaub ich würd nicht mal LED on off hin bekommen! Wird das dann über die ausgemusterte Servosteuerung umsetzen egal...

Das Forum ist doch nicht Tod!!! Es ist klein aber verdammt fein! :P

Danke
CubaLibreee
Beiträge: 1947
Registriert: 08.09.2013 15:35:26

#44 Re: Servo Position-Halten - Adruino Nano

Beitrag von CubaLibreee »

ich habe 5 Nano bestellt und werde jeden Code, der noch kommen sollte, testen. :mrgreen:
Zuletzt geändert von CubaLibreee am 26.07.2018 13:26:18, insgesamt 2-mal geändert.
CubaLibreee
Beiträge: 1947
Registriert: 08.09.2013 15:35:26

#45 Re: Servo Position-Halten - Adruino Nano

Beitrag von CubaLibreee »

Und da ihr sooo fleißig ward, bekommt ihr auch das noch:

https://youtu.be/-S05rjSU6Cs
Antworten

Zurück zu „Servos“