Messgerät zum Erfassen der max. Stromaufnahme von Servos

Fertige Geräte mit Bilden, Schaltungen, Programmen vorstellen.
Antworten
Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Messgerät zum Erfassen der max. Stromaufnahme von Servos

Beitrag von Admin »

Ich habe gestern mal ein Gerät aufgebaut, mit dem man die Maximale Stromaufnahme eines Servos messen kann. Das Problem ist ja, dass so ein Servo sich nur kurz bewegt, so dass ich den aufgenommen Strom mit einem normalen Messgerät unmöglich sehen kann. Das sieht man gleich auch im Video, den ich hier reingestellt habe. Als ich die Spannung für den Servo eingeschalten habe, zeigte das Labornetzteil gerade mal 200-300mA. Also gar keine Chance den wahren Strom zu erfassen. Gerade der Anfahrstrom ist ja sehr hoch, ähnlich wie der Strom wenn der Servo stark belastet wird.

Also habe ich mir einen Arduino Mega geschnappt, ein Display 4x20 Zeichen, einen StromMessungsSensor bis 20 Ampere, ein Netzteil 5 Volt / 5 Ampere, einen Taster Schließer, und einen Servo für 20 kg, den ich gerade da liegen hatte. Das alles zusammengebaut, das Programm dazu geschrieben. Und fertig ist die Laube.

Der Arduino bewegt werend der Messungen laufend den Servo hin und her, und der Arduino misst die Stromstärke die der Servo über den Stromsensor aufnimmt. Der Strom wird alle paar Millisekunden gemessen, und wenn der neue gemessene Strom höher ist, wie der letzte gespeicherte und angezeigt, wird die Neue Messung gespeichert und angezeigt. Der Anlauf-Strom bei dem von mir verwendeten Servo ist offenbar so hoch, dass ich durch mechanische Belastung des Servos, den Strom kaum noch erhöhen kann.

Wenn ich mir das Gerät in ein Gehäuse einbaue, und somit als fertiges Gerät benutze, nehme ich dafür einen Arduino Uno. Für den Testaufbau habe ich einen Mega verwendet, weil gerade nur ein Mega auf den Testkonsolen frei war.

Hier ist mal der Video, den ich gestern dazu gemacht habe.

ACHTUNG !! Die GND/VCC Drähte vom Netzteil über den Sromsensor zum Servo in ausreichender Stärke für 5 Ampere auslegen!!

Hier habe ich noch die Schaltung, die dafür aufgebaut habe:
.
Max_Strommessung_Servo.JPG
Max_Strommessung_Servo.JPG (309.96 KiB) 1167 mal betrachtet
Und das Programm dazu:

Code: Alles auswählen

/* Programm zum Servostrom messen
   So kann man die max. Stromanforderung eines Servos rausfinden
   Der Servo sollte eine eigene, genügend starke Spannungsversorgung haben,
   dass er auch wirklich den Strom ziehen kann, den er benötigt.
   Die Neustart Taste setzt slle Werte zurück,
   und die Messung startet neu.
*/

#include <LiquidCrystal_I2C.h> // LCD Display
LiquidCrystal_I2C lcd(0x27, 20, 4);

#include <MobaTools.h>
MoToServo meinServo;
byte servo_pos0 = 0;
byte servo_pos1 = 180;

const byte ANALOG_PIN = A0; // Hier wird der Name vom Messeingang festgelegt
const int servoPin =  4;  // Anschluß für den Servo
const byte Neustart = 5; // Taster um Messung neu zu starten
byte Neustartstatus = 1;

byte PWM0_1 = 1;
float max1 = 0;      // Der Speicher für den ausgelesenen Analogwert vom Messbuchse
byte maxaktuell = 0;
float max2 = 0;       // Der Speicher für den ausgelesenen Max-Analogwert vom ADC
float max2alt = 0;    // Vergleichspeicher ob es neue Max-Werte gibt
float max3 = 0;       // Anzeigewert
byte zaehler = 0;

unsigned long startzeit = 0;
unsigned long endzeit = 0;
unsigned long Sekundenablauf01 = 0; // Servo-Drehrichtung nach 1,5 Sek. ändern
const unsigned long Pausezeit01 = 1500;
//====================================================================================
void setup(void)
{
  Serial.begin(115200);
  lcd.begin();
  lcd.backlight();
  lcd.clear();

  lcd.setCursor (0, 0);
  lcd.print (F("Strom ="));
  lcd.setCursor (14, 0);
  lcd.print (F("Ampere"));

  pinMode(Neustart, INPUT_PULLUP);

  meinServo.attach(servoPin); //Servo an Pin 4
  meinServo.setSpeed( 0 );    // Verfahrgeschwindigkeit einstellen
}
//===================================================================================
void loop(void) {
  // ----------------------------Neustart prüfen-------------------------------------
  Neustartstatus = digitalRead(Neustart); // Neistarttaste gedrückt?
  if (Neustartstatus == 0) // Wenn ja, alle Messwerte auf Null
  {
max1 = 0;
max2 = 0;
max2alt = 0;
max3 = 0;
zaehler = 0;
Neustartstatus = 1;
  }
  //--------------------------Zeit für die Durchlaufmessung------------------------------------------------
  startzeit = micros();
  max1 = analogRead (ANALOG_PIN); // Analogen Eingang A0 auslesen
  zaehler = zaehler + 1;
  max2 = max2 + max1;
  if (zaehler == 50)
  {
    max2 = max2 / 50;
    max2 = max2 - 510.50;
    if (max2 > max2alt)
    {
      max3 = max2 * 0.05;
      max2alt = max2;
      lcd.setCursor (8, 0);
      lcd.print (F("      "));
      lcd.setCursor (8, 0);
      lcd.print (max3);
    }

    zaehler = 0;
    max2 = 0;
  }

  //--------------------------Nach einer Sekunde PWM Wert ändern-----------------------------------------
  if (millis() - Sekundenablauf01 >= Pausezeit01)
  {
    if (PWM0_1 == 1)
    {
      meinServo.write(servo_pos1); //wird langsam  drehen
    }
    if (PWM0_1 == 0)
    {
      meinServo.write(servo_pos0); //wird langsam  drehen
    }
    PWM0_1 = !PWM0_1;
    Sekundenablauf01 = millis();
  }
  // -----------------------------------Laufzeittest-------------------------------------------------------
  endzeit = micros();
  Serial.println(endzeit - startzeit);
}

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Messgerät zum Erfassen der max. Stromaufnahme von Servos

Beitrag von Admin »

Achtung, wenn man die Anschlüße vertauscht, ist schnell Ende der Fahnenstange. Ich habe den Ausgang des Stromsensors aus versehen auf das PWM Signal gesteckt, anstatt auf den A0 Port. Und habe mich sehr gewundert, dass der plötzlich keinen Strom angezeigt hat.

Also wenn man angeschlossen hat, vielleicht nochmal die Richtigkeit der Anschlüße überprüfen und erst dann einschalten. :(o): Gut dass ich mir zum Testen nie einen Sensor kaufe, sondern immer wenigstens drei. :(oo): ......da waren es nur noch zwei :(o):

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Messgerät zum Erfassen der max. Stromaufnahme von Servos

Beitrag von Admin »

Ich fange gerade an, das Gerät zu bauen. Ich möchte aus dem Geräte ein bischen mehr machen, als nur ein Messegerät für die max Stromaufnahme eines Servos. Ich werde zwei bis drei verschiedenen Programme machen.
1. Eben diese maximale Stromaufnahme eines Servos.
2. Möchte ich einen Servo schrittweise bewegen, dass ich sehe welche Strecke er fahren kann.
3. Weiß ich noch nicht. :(o):

Na denn, bis demnächst in diesem Kino.

:(V):

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Messgerät zum Erfassen der max. Stromaufnahme von Servos

Beitrag von Admin »

So jetzt habe ich mal die Bilder gemacht, ein Video folgt nach. Ich habe die Spannungszuführung zu schmächtig ausgeführt. Wenn ich jetzt meinen 20kg Servo anstecke, bricht die Spannung, und somit auch der Strom, deutlich ein. Nicht so weit, dass das Arduino zusammenbricht, aber der Strom geht damit runter, somit wird nicht der echte, vom Servo gezogene Strom geliefert. Das ist natürlich Schwachsinn, denn genau dieser max. Strom soll ja gemessen werden. Da muss ich nochmal ran. Aber es funktioniert alles wie ich mir das ausgemahlt habe. Die Spannungs-Zuleitung verstärken, ist jetzt nicht so der große Aufwand. Aber bevor ich die Leitung verstärke, muss ich mich erst mal selber stärken. :hng: :(V):
.
Strommessung_ am_Servo.jpg
Strommessung_ am_Servo.jpg (187.77 KiB) 1096 mal betrachtet
.
In der ersten Zeile sieht man welches Programm gerade ausgewählt ist. "0" = nicht / "1" = Strommessung / "2" = den Servo in 18 Stufen von 0 - 180 PWM fahren. Immer hoch und zurück. Die Auswahl erfolgt mit dem Schalter oben, neben dieser Zeile im Display

In der dritten Zeile wird das Ergebnis der Strommessung Programm 1 angezeigt. Dabei wird der Servo laufend hin und her bewegt zwischen Pos.0 und Pos.180. Und alle paar ms wird der Strom gemessen. Dadurch steigt der angezeigte Stom immer wieder an, weil die Messung natürlich nicht immer genau die Stromspitze erreicht. Wenn ich die Messung erneut starten will, muss ich den WippTaster einmal kurz nach unten drücken. Dann kommt wieder der langsamme Anstieg des Stromes, und er sollte wieder in etwa da landen, wo er vorher auch war.

Den Auswahl - Schalter in Mittelstellung ist Programm "0", da wird im Moment noch nichts ausgeführt. Wenn mir was sinnvolles einfällt, kann sich das noch ändern.

In der vierten Zeile ist die Anzeige 18 Servo Schritte, die nach und nach auf Programm 2 ausgegeben werden. Ist die "18" Erreicht, geht es wieder rückwerts bis "0". Mit dem WippTaster kann ich nach unten diese Ausgabe wieder neu beginnen, oder nach oben den Servo auf Stufe 18 Stellen, und wieder langsamm die 18 Stufen nach unten bis "0" Fahren.
.
Strommessung_ am_Servo_02.jpg
Strommessung_ am_Servo_02.jpg (147.17 KiB) 1096 mal betrachtet
.
Hier ist noch das derzeitige Programm dazu:

Code: Alles auswählen

/* Programm zum Servostrom messen
   So kann man die max. Stromanforderung eines Servos rausfinden
   Der Servo sollte eine eigene, genügend starke Spannungsversorgung haben,
   dass er auch wirklich den Strom ziehen kann, den er benötigt.
   Die Neustart Taste setzt slle Werte zurück,
   und die Messung startet neu.
*/

#include <LiquidCrystal_I2C.h> // LCD Display
LiquidCrystal_I2C lcd(0x27, 20, 4);

#include <MobaTools.h>
MoToServo meinServo;
byte servo_pos0 = 0;
byte servo_pos1 = 180;

const byte ANALOG_PIN = A0; // Hier wird der Name vom Messeingang festgelegt
const byte PosControll = A1; // Server Positions Rückmeldung. Wenn vorhanden
const int servoPin =  4;  // Anschluß für den Servo
const byte Neustart = 9; // Taster um Messung neu zu starten oder ab
const byte auf = 8; // Richtung Steuern
const byte Prog1 = 10; // noch frei
const byte Prog2 = 11; // noch frei
byte Neustartstatus = 1;
byte Neustartstatus2 = 1;
byte Programmstatus = 0; // Programmauswahl Merker
byte ProgrammstatusAlt = 0; // Programmauswahl Merker alt
byte Prog1auswahl = 0;
byte Prog2auswahl = 0;
// -------Einstellungen für Programm 2 -----------------------
byte Stufe = 0; // Schrittzähler 0 - 25 für Programm 2
const byte StufePWM = 10; // PWM Wert je Stufe für Programm 2
const int Stopzeit = 1000; // Delay Zeit zwischen den Stufen
byte Richtung = 0; // Stufen Richtung
unsigned long Sekundenablauf02 = 0; // Pause zwischen den Schritten
const unsigned long Pausezeit02 = 1000;
// -------Einstellungen für Programm 1 -----------------------
byte PWM0_1 = 1;      // Servo Drehrichtung 0 oder 1
float max1 = 0;      // Der Speicher für den ausgelesenen Analogwert vom Messbuchse
byte maxaktuell = 0;
float max2 = 0;       // Der Speicher für den ausgelesenen Max-Analogwert vom ADC
float max2alt = 0;    // Vergleichspeicher ob es neue Max-Werte gibt
float max3 = 0;       // Anzeigewert
byte zaehler = 0;

unsigned long startzeit = 0;
unsigned long endzeit = 0;
unsigned long Sekundenablauf01 = 0; // Servo-Drehrichtung nach 1,5 Sek. ändern
const unsigned long Pausezeit01 = 1500;
//====================================================================================
void setup(void)
{
  Serial.begin(115200);
  lcd.begin();
  lcd.backlight();
  lcd.clear();

  lcd.setCursor (0, 2);
  lcd.print (F("Strom ="));
  lcd.setCursor (14, 2);
  lcd.print (F("Ampere"));
  lcd.setCursor (0, 1);
  lcd.print (F("===================="));
  lcd.setCursor (0, 0);
  lcd.print (F("Ausgew. Prog. = "));
  lcd.setCursor (0, 3);
  lcd.print (F("Stufe ="));

  pinMode(Neustart, INPUT_PULLUP);
  pinMode(auf, INPUT_PULLUP);
  pinMode(Prog1, INPUT_PULLUP);
  pinMode(Prog2, INPUT_PULLUP);

  meinServo.attach(servoPin); //Servo an Pin 4
  meinServo.setSpeed( 0 );    // Verfahrgeschwindigkeit einstellen
}
//===================================================================================
void loop(void) {
  //-------------------------- Programmschalter prüfen-----------------------------------------------------
  Prog1auswahl = digitalRead(Prog1); // Programmauswahl Schalter auf 1 ?
  Prog2auswahl = digitalRead(Prog2); // Programmauswahl Schalter auf 2 ?
  if (Prog1auswahl == 0) // Ist Programm 1 ausgewählt?
  {
    Programmstatus = 1;
  }
  if (Prog2auswahl == 0) // Ist Programm 2 ausgewählt?
  {
    Programmstatus = 2;
  }
  if ((Prog1auswahl == 1) && (Prog2auswahl == 1)) // Ist kein ausgewählt?
  {
    Programmstatus = 0;
  }
  if ((Programmstatus > ProgrammstatusAlt) || (Programmstatus < ProgrammstatusAlt))
  {
    lcd.setCursor (14, 0);
    lcd.print (F(" "));
    lcd.setCursor (14, 0);
    lcd.print (Programmstatus);
    ProgrammstatusAlt = Programmstatus;
  }
  //---------------------------------------------------------------------------------------------------------
  //--------------------------------- Programm 0 ------------------------------------------------------------
if (Programmstatus == 0)
  {
    // Noch keine Idee. :-))
  }
  //-----------------------------Ende Programm 0 ------------------------------------------------------------
  //--------------------------------- Programm 1 ------------------------------------------------------------
  if (Programmstatus == 1)
  {
    // ----------------------------Neustart prüfen-------------------------------------
    Neustartstatus = digitalRead(Neustart); // Neistarttaste gedrückt?
    if (Neustartstatus == 0) // Wenn ja, alle Messwerte auf Null
    {
      max1 = 0;
      max2 = 0;
      max2alt = 0;
      max3 = 0;
      zaehler = 0;
      Neustartstatus = 1;
      delay(20);
    }
    //--------------------------Zeit für die Durchlaufmessung------------------------------------------------
    startzeit = micros();
    max1 = analogRead (ANALOG_PIN); // Analogen Eingang A0 auslesen
    zaehler = zaehler + 1;
    max2 = max2 + max1;
    if (zaehler == 50)
    {
      max2 = max2 / 50;
      max2 = max2 - 520.50;
      if (max2 > max2alt)
      {
        max3 = max2 * 0.05;
        max2alt = max2;
        lcd.setCursor (8, 2);
        lcd.print (F("      "));
        lcd.setCursor (8, 2);
        lcd.print (max3);
      }

      zaehler = 0;
      max2 = 0;
    }

    //--------------------------Nach einer Sekunde PWM Wert ändern-----------------------------------------
    if (millis() - Sekundenablauf01 >= Pausezeit01)
    {
      if (PWM0_1 == 1)
      {
        meinServo.write(servo_pos1);
      }
      if (PWM0_1 == 0)
      {
        meinServo.write(servo_pos0);
      }
      PWM0_1 = !PWM0_1;
      Sekundenablauf01 = millis();
    }
  }
  // ---------------------------------- Programm 1 Ende ----------------------------------------------------
  // -------------------------------------- Programm 2 -------------------------------------------------------
  if (Programmstatus == 2)
  {
    Neustartstatus = digitalRead(Neustart); // Neistarttaste unten gedrückt?
    if (Neustartstatus == 0) // Wenn ja, auf Stufe 0 und Richtung 0 Zurück
    {
      Stufe = 0;
      Richtung = 0;
    }
    Neustartstatus2 = digitalRead(auf); // Neustart oben gedrückt?
    if (Neustartstatus2 == 0) // Wenn ja, auf Stufe 18 und Richtung 1 Zurück
    {
      Stufe = 18;
      Richtung = 1;
    }

    if (millis() - Sekundenablauf02 >= Pausezeit02)
    {
      lcd.setCursor (9, 3);
      lcd.print (F("           "));
      lcd.setCursor (9, 3);
      lcd.print (Stufe);
      lcd.print (F("  "));
      lcd.print (Stufe * StufePWM);
      lcd.print (F(" PWM"));
      meinServo.write(Stufe * StufePWM);
      // delay(Stopzeit);
      if ((Richtung == 0) && (Stufe <= 18))
      {
        Stufe = Stufe + 1;
      }
      if ((Richtung == 0) && (Stufe == 19))
      {
        Stufe = Stufe - 1;
        Richtung = 1;
      }
      if ((Richtung == 1) && (Stufe > 0))
      {
        Stufe = Stufe - 1;
      }
      if ((Richtung == 1) && (Stufe == 0))
      {
        Richtung = 0;
      }
      Sekundenablauf02 = millis();
    }
  }
  // -----------------------------------Programm 2 Ende ---------------------------------------------------
  // -----------------------------------Laufzeittest-------------------------------------------------------
  endzeit = micros();
  Serial.println(endzeit - startzeit);
}

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Messgerät zum Erfassen der max. Stromaufnahme von Servos

Beitrag von Admin »

So, das mit der Spannungszuführung ist auch korrigiert. Jetzt ist die Spannung stabil und der Strom da, wo er beim Testaufbau auch war.

Jetzt mache ich mal noch den Video.

Hier ist der Video.

Ich hatte beim entwickeln dieses Programmes immer höhere Ströme gemessen. über 2 Ampere bei dem Servo im Video. Da hatte ich im Programm noch etwas anders eingestellt. Ich fahre jetzt den Servo in 1,5 Sekunden für eine Richtung. Dabei wird er wirklich von PWM 0 - 180 gefahren, dann stoppt er, und dann bekommt er die Daten für die neue Richtung. Vorher hatte ich da 1,0 Sekunden Fahrzeit eingestellt. Wenn man das macht wird der Servo mit der Fahrt in eine Richtung nicht fertig. Das heißt, er fährt eine Richtung und bekommt wärend der Fahrt in die eine Richtung die Daten für die andere Richtung. Das heißt, er muss plötzlich in die andere Richtung fahren. Das braucht noch mehr Strom, weil er plötzlich gegen die Fahrtrichtung, in die andere Richtung vollgas fahren muss. Ich will ja eigentlich die max. Stromaufname bekommen, da wäre das alte Programm besser. Aber ich bin mir nicht sicher, ob der plötzliche Richtungswechsel, beim andauernden hin- und herfahren, nicht den Servo beschädigt. Und ich habe keine Lust jemanden einen neuen Servo zu spendieren, weil er mit meinem Programm, seinen Servo gekillt hat. :(o):

Wenn jemand sein Programm aber gerne so haben möchte, dass dieser plötzliche Wechsel, den Strom an die Oberkannte bringt, kann er das gerne machen. Dann ist in der Programm-Zeile "const unsigned long Pausezeit01 = 1500;" der Wert 1500 auf 1000 oder weniger einzustellen. Aber das ist eine Änderung ohne Gewähr. Wobei bei mir der Servo bei den ersten Programmtests bestimmt 200-300 mal auf diese Art hin und her gelaufen ist und er hat es mir nicht übel genommen. Aber wer weiß, jeder Servo ist da wohl anders. Ich habe es jetzt gerade nochmal getestet, da steigt der max. Strom von 1,77 Ampere im Video, auf 2,78 Ampere. Also ein deutlicher Unterschied. Wenn man wirklich den Max. Strom will, sollte man das wohl so machen.

Vielleicht habe ich da mein drittes Programm für diese Kiste gefunden. Dass man auf Programmstellung "0" mit der Wippe zwischen den Zeiten Laufzeiten hin und her Schalten kann, und dann auf Programm "1" mit der jeweils eingestellten Zeit arbeiten kann.

Hier ist das Bild von dem Test mit 1000ms Fahrwegezeit. Natürlich muss man dem Gerät den nötigen Strom zur Verfügung stellen. Ich betreibe die Kiste hier an einem Labornetzteil mit 5,1 Volt und 5 Ampere. Also erst wenn der Servo deutlich mehr als 4 Ampere braucht, würde es eng werden.
.
Strommessung_ am_Servo_03.jpg
Strommessung_ am_Servo_03.jpg (159.38 KiB) 1065 mal betrachtet

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Messgerät zum Erfassen der max. Stromaufnahme von Servos

Beitrag von Admin »

Ich habe mir heute ein neues Konzept für die Stromessung überlegt. Ich habe jetzt eine eher niedrige max - Strommessung gemacht, weil ich befürchte, dass der Testlauf mit maximaler Stromlast, das heißt, ich fahre eine Richtung mit Vollgas und dann ein fliegender Richtungswechsel gegen den Schwung der vorhergehenden Fahrt. Das sorgt im Vergleich zur Anfahrt aus dem Stand, bei meinem 20kg Servo für 1 Ampere mehr. Also 2 Ampere Anfahrstrom aus dem Stand heraus, oder 3 Ampere Anfahrstrom, aus der Fahrt in die Gegenrichtung herraus.

Jetzt will ich drei verschiedene Ströme messen und darstellen.
Die erste Messung läuft wärend des Anfahren aus der Gegenrichtung, wie gerade oben beschieben.
Die zweit Messung ist dann das anfahren aus dem Stand, also die mildere Varianten.
Die dritte Messung soll dann nur die reine Fahrt nach dem Anfahren sein.
Also auf meinen großen Testservo hier bezogen. Messung eins = 3 Ampere, Messung zwei = 2 Ampere, Messung drei = 300 - 400 mA. So hat man dann eine Ahnung, was der Servo in den jeweiligen Einsätzen an Strom benötigt, um das Netzgerät, oder den Akku, richtig dimmensionieren zu können. Die Stromfrage entstand aus dem Problem heraus, das einer den benötigten Akku einschätzen wollte, für ein Gerät, dass sich auf 6 Füßen, mit je drei Servos, Vorwärts bewegt. Also 18 Servos mit je 20kg Kraft. Das ist dann schon eine Hausnummer, die man richtig einschätzen sollte. Sonst wird das ein Flopp.

Jetzt muß ich aber mein Programm erst mal ganz schön umbauen, dass die Kiste diese Messungen automatisch nacheinander durchführen kann. Aber so wirds mir wenigstens nicht langweilig. :(o): :(o):

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Messgerät zum Erfassen der max. Stromaufnahme von Servos

Beitrag von Admin »

So ich habe jetzt das Programm umgebaut, so dass ich die automatisch die drei Strom-Messungen mache.
Hier mal das Programm. Es ist noch ein bischen konfuss, weil ich mache Speicherlöschungen mehrfach, also an mehreren Stellen durchführe. Bis das Resultat passt. Da muss ich noch ein bischen nacharbeiten. Aber im Moment habe ich keine Lust. Es macht das was ich will, an den feinheiten arbeite ich noch nach.

Code: Alles auswählen

/* Programm zum Servostrom messen
   So kann man die max. Stromanforderung eines Servos rausfinden
   Der Servo sollte eine eigene, genügend starke Spannungsversorgung haben,
   dass er auch wirklich den Strom ziehen kann, den er benötigt.
   Die Neustart Taste setzt slle Werte zurück,
   und die Messung startet neu.
*/

#include <LiquidCrystal_I2C.h> // LCD Display
LiquidCrystal_I2C lcd(0x27, 20, 4);

#include <MobaTools.h>
MoToServo meinServo;
byte servo_pos0 = 0;
byte servo_pos1 = 180;

const byte ANALOG_PIN = A0; // Hier wird der Name vom Messeingang festgelegt
const byte PosControll = A1; // Server Positions Rückmeldung. Wenn vorhanden
const int servoPin =  4;  // Anschluß für den Servo
const byte Neustart = 9; // Taster um Messung neu zu starten oder ab
const byte auf = 8; // Richtung Steuern
const byte Prog1 = 10; // noch frei
const byte Prog2 = 11; // noch frei
byte Neustartstatus = 1;
byte Neustartstatus2 = 1;
byte Programmstatus = 0; // Programmauswahl Merker
byte ProgrammstatusAlt = 3; // Programmauswahl Merker alt
byte Prog1auswahl = 0;
byte Prog2auswahl = 0;
// ---------------------Einstellungen für Programm 2 ---------------------------------
byte Stufe = 0; // Schrittzähler 0 - 25 für Programm 2
const byte StufePWM = 10; // PWM Wert je Stufe für Programm 2
const int Stopzeit = 1000; // Delay Zeit zwischen den Stufen
byte Richtung = 0; // Stufen Richtung
unsigned long Sekundenablauf02 = 0; // Pause zwischen den Schritten
const unsigned long Pausezeit02 = 1000;
// ----------------------Einstellungen für Programm 1 --------------------------------
//----------------------------max. Messung--------------------------------------------
byte PWM0_1 = 1;      // Servo Drehrichtung 0 oder 1
float max1 = 0;      // Der Speicher für den ausgelesenen Analogwert vom Messbuchse
byte maxaktuell = 0;
float max2 = 0;       // Der Speicher für den ausgelesenen Max-Analogwert vom ADC
float max2alt = 0;    // Vergleichspeicher ob es neue Max-Werte gibt
float max3 = 0;       // Anzeigewert
byte zaehler = 0;
//-----------------------------allgemein----------------------------------------------
byte Steuerung = 1;   // Den Ablauf der Messungen steuern
//-----------------------------min. Messung-------------------------------------------
byte minPWM0_1 = 1;      // Servo Drehrichtung 0 oder 1
float min1 = 0;      // Der Speicher für den ausgelesenen Analogwert vom Messbuchse
byte minaktuell = 0;
float min2 = 0;       // Der Speicher für den ausgelesenen Max-Analogwert vom ADC
float min2alt = 0;    // Vergleichspeicher ob es neue Max-Werte gibt
float min3 = 0;       // Anzeigewert
byte minzaehler = 0;
const unsigned long Brueckenzeit = 100;
unsigned long Sekundenablauf03 = 0; // Messzeit Pausieren
unsigned long Pausezeit03 = 1000;
const unsigned long Messzeit = 600;
unsigned long Sekundenablauf04 = 0; // Messzeit min. Strom
unsigned long Pausezeit04 = 1000;
unsigned long startzeit = 0;
unsigned long endzeit = 0;
unsigned long milliablaufzeit = 0;
//------------------------------------------------------------------------------------
unsigned long Sekundenablauf01 = 0; // Servo-Drehrichtung nach 1,5 Sek. ändern
unsigned long Pausezeit01 = 1000;
byte Durchgaenge = 0;
//====================================================================================
void setup(void)
{
  Serial.begin(115200);
  lcd.begin();
  lcd.backlight();
  lcd.clear();

  lcd.setCursor (0, 2);
  lcd.print (F("Amp="));
  lcd.setCursor (0, 1);
  lcd.print (F("===================="));
  lcd.setCursor (0, 0);
  lcd.print (F("Ausgew. Prog. = "));
  lcd.setCursor (0, 3);
  lcd.print (F("Stufe ="));

  pinMode(Neustart, INPUT_PULLUP);
  pinMode(auf, INPUT_PULLUP);
  pinMode(Prog1, INPUT_PULLUP);
  pinMode(Prog2, INPUT_PULLUP);

  meinServo.attach(servoPin); //Servo an Pin 4
  meinServo.setSpeed( 0 );    // Verfahrgeschwindigkeit einstellen
}
//===================================================================================
void loop(void) {
  milliablaufzeit = millis();
  //-------------------------- Programmschalter prüfen-----------------------------------------------------
  Prog1auswahl = digitalRead(Prog1); // Programmauswahl Schalter auf 1 ?
  Prog2auswahl = digitalRead(Prog2); // Programmauswahl Schalter auf 2 ?
  if (Prog1auswahl == 0) // Ist Programm 1 ausgewählt?
  {
    Programmstatus = 1;
  }
  if (Prog2auswahl == 0) // Ist Programm 2 ausgewählt?
  {
    Programmstatus = 2;
  }
  if ((Prog1auswahl == 1) && (Prog2auswahl == 1)) // Ist kein ausgewählt?
  {
    Programmstatus = 0;
  }
  if ((Programmstatus > ProgrammstatusAlt) || (Programmstatus < ProgrammstatusAlt))
  {
    lcd.setCursor (16, 0);
    lcd.print (F(" "));
    lcd.setCursor (16, 0);
    lcd.print (Programmstatus);
    ProgrammstatusAlt = Programmstatus;
  }
  //---------------------------------------------------------------------------------------------------------
  //--------------------------------- Programm 0 ------------------------------------------------------------
  if (Programmstatus == 0)
  {
    // Noch keine Idee. :-))
  }
  //-----------------------------Ende Programm 0 ------------------------------------------------------------
  //--------------------------------- Programm 1  -----------------------------------------------------------
  if (Programmstatus == 1)
  {
    //-------------------------------Messungen Koordinieren--------------------------------------------------
    //-----------------------Strom erster Teil---------------------------------------------------------------
    if (Steuerung == 1)
    {
      if (Durchgaenge == 0)
      {
        Pausezeit01 = 200;
      }
      if (Durchgaenge == 30)

      {
        lcd.setCursor (4, 2);
        lcd.print (F("      "));
        lcd.setCursor (4, 2);
        lcd.print (max3);
        Steuerung = 2;
        Durchgaenge = 0;
        max1 = 0;
        max2 = 0;
        max2alt = 0;
        max3 = 0;
        zaehler = 0;
      }
    }
    //-----------------------Strom zweiter Teil-------------------------------------------------------------
    if (Steuerung == 2)
    {
      if (Durchgaenge == 0)
      {
        Pausezeit01 = 1500;
      }
      if (Durchgaenge == 10)

      {
        lcd.setCursor (8, 2);
        lcd.print (F(" =     "));
        lcd.setCursor (10, 2);
        lcd.print (max3);
        Durchgaenge = 0;
        max1 = 0;
        max2 = 0;
        max2alt = 0;
        max3 = 0;
        min1 = 0;
        min2 = 0;
        min2alt = 0;
        min3 = 0;
        zaehler = 0;
        Steuerung = 3;
      }
    }
    //-----------------------Strom dritter Teil------------------------------------------------------------
    if (Steuerung == 3)
    {
      if (Durchgaenge == 0)
      {
        Pausezeit01 = 1500;
        zaehler = 0;
        min1 = 0;
        min2 = 0;
        min2alt = 0;
        min3 = 0;
      }
      if (Durchgaenge == 5)
      {
        lcd.setCursor (14, 2);
        lcd.print (F(" =    "));
        lcd.setCursor (16, 2);
        lcd.print (min3);
        Steuerung = 4;
        Durchgaenge = 0;
        max1 = 0;
        max2 = 0;
        max2alt = 0;
        max3 = 0;
        min1 = 0;
        min2 = 0;
        min2alt = 0;
        min3 = 0;
        zaehler = 0;
      }
    }

    //---------------------------------Koordination Ende-----------------------------------------------------
    // ----------------------------Neustart prüfen-----------------------------------------------------------
    Neustartstatus = digitalRead(Neustart); // Neistarttaste gedrückt?
    if (Neustartstatus == 0) // Wenn ja, alle Messwerte auf Null
    {
      max1 = 0;
      max2 = 0;
      max2alt = 0;
      max3 = 0;
      zaehler = 0;
      Neustartstatus = 1;
      Steuerung = 1;
      Durchgaenge = 0;
      min1 = 0;
      min2 = 0;
      min2alt = 0;
      min3 = 0;
      lcd.setCursor (3, 2);
      lcd.print (F("                 "));
      delay(20);
    }
    //---------------------------------- Messung -----------------------------------------------------------
    if ((Steuerung == 1) || (Steuerung == 2))
    {
      max1 = analogRead (ANALOG_PIN); // Analogen Eingang A0 auslesen
      zaehler = zaehler + 1;
      max2 = max2 + max1;
      if (zaehler == 50)
      {
        max2 = max2 / 50;
        max2 = max2 - 520.50;
        if (max2 > max2alt)
        {
          max3 = max2 * 0.05;
          max2alt = max2;
        }
        zaehler = 0;
        max2 = 0;
      }
    }
    //-------------------------------------minimal Messung--------------------------------------------------
    if (Steuerung == 3)
    {
      if (milliablaufzeit - Sekundenablauf03 >= Brueckenzeit)
      {
        if (milliablaufzeit - Sekundenablauf04 < Messzeit)
        {
          min1 = analogRead (ANALOG_PIN); // Analogen Eingang A0 auslesen
          zaehler = zaehler + 1;
          min2 = min2 + min1;
          if (zaehler == 50)
          {
            min2 = min2 / 50;
            min2 = min2 - 520.50;
            if (min2 > min2alt)
            {
              min3 = min2 * 0.05;
              min2alt = min2;
            }
            zaehler = 0;
            min2 = 0;
          }
        }
      }
    }
    //--------------------------Nach einer Sekunde PWM Wert ändern-----------------------------------------
    if (Steuerung < 4)
    {
      if (millis() - Sekundenablauf01 >= Pausezeit01)
      {

        Sekundenablauf04 = millis();
        if (PWM0_1 == 1)
        {
          meinServo.write(servo_pos1);
          Durchgaenge = Durchgaenge + 1;
          if (Steuerung == 3)
          {
            Sekundenablauf03 = millis();
            Sekundenablauf04 = millis();
          }
        }
        if (PWM0_1 == 0)
        {
          meinServo.write(servo_pos0);
          Durchgaenge = Durchgaenge + 1;
          if (Steuerung == 3)
          {
            Sekundenablauf03 = millis();
            Sekundenablauf04 = millis();
          }
        }
        PWM0_1 = !PWM0_1;
        Sekundenablauf01 = millis();
      }
    }
    //----------------------------------PWM Wert Ändern Ende------------------------------------------------
  }
  // ---------------------------------- Programm 1 Ende ----------------------------------------------------
  // -------------------------------------- Programm 2 -------------------------------------------------------
  if (Programmstatus == 2)
  {
    Neustartstatus = digitalRead(Neustart); // Neistarttaste unten gedrückt?
    if (Neustartstatus == 0) // Wenn ja, auf Stufe 0 und Richtung 0 Zurück
    {
      Stufe = 0;
      Richtung = 0;
    }
    Neustartstatus2 = digitalRead(auf); // Neustart oben gedrückt?
    if (Neustartstatus2 == 0) // Wenn ja, auf Stufe 18 und Richtung 1 Zurück
    {
      Stufe = 18;
      Richtung = 1;
    }

    if (millis() - Sekundenablauf02 >= Pausezeit02)
    {
      lcd.setCursor (9, 3);
      lcd.print (F("           "));
      lcd.setCursor (9, 3);
      lcd.print (Stufe);
      lcd.print (F("  "));
      lcd.print (Stufe * StufePWM);
      lcd.print (F(" PWM"));
      meinServo.write(Stufe * StufePWM);
      // delay(Stopzeit);
      if ((Richtung == 0) && (Stufe <= 18))
      {
        Stufe = Stufe + 1;
      }
      if ((Richtung == 0) && (Stufe == 19))
      {
        Stufe = Stufe - 1;
        Richtung = 1;
      }
      if ((Richtung == 1) && (Stufe > 0))
      {
        Stufe = Stufe - 1;
      }
      if ((Richtung == 1) && (Stufe == 0))
      {
        Richtung = 0;
      }
      Sekundenablauf02 = millis();
    }
  }
  // -----------------------------------Programm 2 Ende ---------------------------------------------------
}
Ein Bild vom Ergebnis bringen ich noch nach, nen Video wahrscheinlich auch noch, dass man den neuen Ablauf sieht. :(V):
.
Stromessung_Servo_01.jpg
Stromessung_Servo_01.jpg (182.15 KiB) 1005 mal betrachtet
Hier hat sich jetzt die dritte Zeile geändert. Das "A" für Ampere, der erste Wert ist der max Strom wofür der Servos schnell hin und her bewegt wird, ohne Stopps dazwischen. Der zweite Wert ist wieder ein max Strom bei dem das Anfahren dess Servos nach Stillstand gemessen wird. Der dritte Wert zeigt einen min-Strom Wert an, den der Servo nach dem anfahren braucht. Dafür lasse ich den Servo anfahren, warte aber mit der Messung 100ms, und messe dann für 800ms. Die 100ms Wartezeit ohne Messung, sorgen dafür, dass der Anfahrstrom nicht mitgemessen wird.

In der vierten Zeile hat sich nichts geändert. Da werden wieder die 18 Schritte in zehner PWM Stufen abgezeigt und der Servo entsprechend bewegt.

Was mich jetzt etwas wundert, ich hatte mit dem alten Programm einen deutlicheren Unterschied im Strom, zwischen der ersten und der zweiten Anfahr - Methode. Da bekam ich bei schnellen Richtungswechel aus voller Fahrt etwa 3 Ampere Anfahrstom, und bei einer Pause zwischen den Richtungen nur so 2,4 bis 2,5 Ampere. Jetzt bekomme ich den hohen Strom gar nicht mehr, auch wenn ich wieder da alte Programm reinlade. Als logische Erklärung habe ich nur, dass sich das Verhalten des Servos geändert hat. Ich bekomme bei der Messung mit dem alten Programm etwa 2,65 Amper max und bei der Messung mit dem Neuen Programm auch. Das neue hat ja wie im oberen Bild zu sehen, Strom max. = 2.66 Ampere, Strom Anfahren mit Pause, 2.59 Ampere, min. Strom nach dem anfahren 0,35 Ampere. Also die beiden max.-Strom Werte, sind ziehmlich gleich. :eek:

Mein kleinster Servo, der SG90 hat folgende Werte. Max. Strom 1,0 Ampere, schonend anfahren 0,79 Ampere, nach der Anfahrt 0,07 Ampere, also 70mA.
Bei einem zweiten Durchgang waren es 0,96 / 0,59 / 0,11 Ampere.
Ein dritter Durchgang war dann 0,92 / 0,87 / 0,10 Ampere.
Die abweichenden Ergebnisse haben wohl ein bischen mit der Motor-Themperatur zu tun.

Antworten

Zurück zu „Fertige Projekte Vorstellen“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast