Brushles ESC - Regelung - Drehzahlmessung

Hallo,
hab mein Projekt einer Fahrenden Bierkiste mit einem Brushlessmotor und einem ESC mittlerweile ganz gut zum laufen gebraucht.

Mit der Servo Library kann ich den Motor relativ schön ansteuern.
Ausgelesen wird dazu ein Poti, welches dann gemappt wird und den "Servo" also meinen ESC ansteuert.

Funktioniert auch ganz gut.
Zusätzlich hab ich mir dann noch die Funktion einer Rampe eingebaut, welche mir den Motor Langsam hochdrehen lässt. Das ganze hab ich mittlerweile auch ohne Delay hingebracht.

Was ich jetzt aber gerne noch hätte:
Wenn ich aus der Fahrt/ Rollendem Zustand vom Gas gehe und dann wieder beschleunigen will beginnt dir Rampe (wie soll es auch anders sein) von null weg hochzuzählen. Das Bedeutet aber das ich im ersten Moment keinen vortrieb habe, sondern erst wenn die Rampe dort angekommen ist, wo der Motor gerade "dreht"

Besteht die Möglichkeit einer Permanenten Signalzählung/ Drehzahlmessung und gleichzeitig darauf zu reagieren was mein Poti und die Rampe macht?

Ich hab das jetzt relativ unsauber mit einem zweiten kleinen Elektromotor gelöst, welcher von meinem Hauptmotor angetrieben wird. Dieser liefert eine Analoge Spannung welche ich am Analog eingang messen kann.
Dann wird beim Beschleunigen abgefragt was der Analogeingang macht (also im Prinzip die Drehzahl des Motors) Verglichen mit der Poti/Gas Stellung und die Rampe dann im Richtigen bereich wieder Fortgesetzt.

Besser würde mir aber ein Drehzahlmesser mit Impulszählung gefallen, aber mit PulseIn zb. verliere ich im Programm dann immer die Zeit des Zählen und das spürt man wieder also "Unterbrechung" beim weiter beschleunigen.

Deshalb die Frage, kann ich im Pulse Zählen, gleichzeitig eine Rampe bedienen, die auf Basis eines Analog Inputs anspricht?

Grüße

Martin

Ich stelle mit die Frage ob dies sein muss. Beim Copter hast du auch keine Rampen in den Motoren zu ansteuern. Im Auto ist ja auch keine Rampe beim beschleunigen. Diese gibt die allein die Last vor. UNd das macht ja der ESC damit er nicht aus dem Feld kippt. Wenn man also ein “Gaspedal/Gasgriff” hat mekt man selber wann es wieder losgeht. Gibt man einen kleineren Wert vor merkt man den Vortrieb ja auch erst wenn die Kiste so langsam ist bis die Solldrehzahl gleich oder Größer der Istdrehzahl ist.
Bei Brushless Motoren gibt es ja auch das regenerative Bremsung, wenn die zu stark ist kann die bei einigen ESC deaktiviern.
Gruß
DerDani

Ja muss ein :wink:
Bitte nicht böse nehmen die “Freche” Antwort.

Es ist so, das ich mein Gaspedal mit meinem Finger gar nicht so Feinfühlig anstellen kann, das ich nicht Rüwärts von meinem Fahrgerät fahre.
Handelt sich um einen 7000W Rotomax 100CC.

Der Regler selbst kann zwei verschiedene Rampen fahren, welche aber beide viel zu “scharf” sind. Deshalb die Rampe über den Arduino.

Zieh ich das Gas Auf Vollgas oder auch Dreiviertle, fährt dir Rampe bis zu diesem Punkt hoch.
Lasse ich das Gas los, springt die Rampe sofort auf den “kleineren” wert.

Mir gehts aber darum, das ich aus dem Rollenden zustand wieder sauber weiter beschleunigen kann.
Die Rampe braucht ca. 3 Sekunden bis sie voll auf gereht hat.

Wenn ich bei Vollgas kurz loslasse und dann wieder beschleunige, tut sich 2 Sekunden lang nix.

Des halb will ich gerne im Hintergrund die Drehzahl messen und diese dann eben mit der Rampe ableichen. Was mir relativ Primitiv mit dem kleinen Elektromotor als “Generator” und dann auf Analog Input ja gelungen ist.
Nur würd ich die Drehzahl eben gerne mittels Hallsensor Abgreifen.

Grüße

PulseIn zählt ja keine impulse sondern die Zeit solage ein signal HIG oder LOW ist und blockiert dabei den Arduino.

Die Lösung mit einem Tachogenerator (angetriebener kleiner Elektromotor) ist nicht die schlechteste.

Du kannst auch ein Lochrad mit eine Lichtschranke messen und daraus mit einem RC Glied eine Gleichspannung machen.

Du kannst auch die Impulse messen. Da gibt es 2 Möglichkeiten: für viele Impulse pro Sekunde die Anzahl der Impulse pro Meßdauer, bei wenigen Impulsen die Periodendauer des Signals.

Grüße Uwe

volvodani:
Ich stelle mit die Frage ob dies sein muss. Beim Copter hast du auch keine Rampen in den Motoren zu ansteuern. Im Auto ist ja auch keine Rampe beim beschleunigen. Diese gibt die allein die Last vor. UNd das macht ja der ESC damit er nicht aus dem Feld kippt. Wenn man also ein "Gaspedal/Gasgriff" hat mekt man selber wann es wieder losgeht. Gibt man einen kleineren Wert vor merkt man den Vortrieb ja auch erst wenn die Kiste so langsam ist bis die Solldrehzahl gleich oder Größer der Istdrehzahl ist.
Bei Brushless Motoren gibt es ja auch das regenerative Bremsung, wenn die zu stark ist kann die bei einigen ESC deaktiviern.
Gruß
DerDani

Aber Du als Fahrer des Autos gibst auch nicht "Kein Gas" oder "Vollgas". Ok, bei untermotorisierten Autos kann man das so machen. Bei einem 150PS Auto machst Du das nicht. Du stellst mit Deinem Fuß eine Beschleunigungsrampe ein, die sich aus Motorkraft, Automasse, Reibungsverluste und Steigung ergibt. Moderne Autos haben dann auch noch eine Schlupfkontrolle und ABS.

Ich glaube daß wenn man die Motore bei einer Bierkistenwagen zu schnell ansteuert dann hält einen wenig auf der Bierkiste.

Grüße Uwe

Mit dem "Generator" komme ich dem, was ich will schon sehr nahe.

Das Ansprechverhalten wird dadurch aus dem Rollenenden Zustand deutlich besser.

Wann spricht man von Vielen Impulsen und wann von Wenig? :wink:

Ich hab den Hallsensor am Stator verbaut, dieser Reagiert auf die Vorbeifahrenden Festmagneten am Rotor.
dort sind 20 Magneten, heißt pro umdrehung 20 "schaltungen" ergibt bei 7000 U/min -> 140000 Impulse in der Minute oder 2333,33 Pro Sekunde bei Vollgas. (Kann das der Arduino überhaupt????)

Bei Dementsprechend weniger Drehzahl, dann auch Weniger Impulse

Ein BLDC Motor braucht eine der Drehzahl entsprechende Ansteuerung, so wie man bei einem Verbrennungsmotor nicht einfach die Zündung auf die gewünschte Drehzahl einstellen kann und erwartet, daß der Motor dann schon irgendwie richtig darauf reagieren wird.

Zuerst wäre interessant zu wissen, wie der ESC auf Sprünge des Eingangssignals reagiert. Wird daraufhin der Motor sauber hochgefahren ist soweit alles okay.

Dann wäre interessant zu wissen was Dein Programm vorgibt. Eigentlich müßte das Eingangssignal immer der gewünschten Drehzahl entsprechen, d.h. der Motor hat ständig die Drehzahl, die Dein Programm vorgibt. Dann reicht es doch für sanfteres Hochfahren, einfach das Eingangssignal entsprechend langsam hochzufahren, ausgehend vom aktuell eingestellten Wert.

Der Motor bzw. im Prinzip der ESC reagiert recht Sauber und "Brav" auf Drehzahlsprünge, da dieser selbst in gewisser weise Rampen hoch und Runter fährt. Das Signal was ich dem ESC Schicke, ist im Prinzip nix anderes als ein Servosignal, ich verwende dafür eben auch die Servo Lib.

Mein Programm gibt im Prinzip anhand des Analog Potis dann den "Servowert" aus. Beim Beschleunigen wird dies eben über die Rampe langsam hochgefahren, beim Loslassen des "Gaspedals" springt der Wert nach unten.

Wozu brauchst Du dann noch die Drehzahl? Du kennst den aktuellen Servowert, den Du zuletzt ausgegeben hast, und fährst von dem zum neuen Wert eine Rampe hoch oder runter.

DrDiettrich:
Wozu brauchst Du dann noch die Drehzahl? Du kennst den aktuellen Servowert, den Du zuletzt ausgegeben hast, und fährst von dem zum neuen Wert eine Rampe hoch oder runter.

Weil wenn er mal vom Gas geht der Motor langsam ausläuft ( Ein Mann auf einer Bierkiste ist ja nicht wenig Masse) und wenn er während dieser Auslauffase wieder beschleunigen will, dann die Steuerung vom aktuellen Drehzahl starten muß und nicht von null.
Dazu muß die Steuerung wissen wie schnell der Motor dreht.

heini320:
Wann spricht man von Vielen Impulsen und wann von Wenig? :wink:

Das hängt von der gewünschten Regelansprechzeit ab. Wenn Deine Regelung nur alle Minute den Sollwert ändern soll dann sind 10 Sekunden Meßintervall schon kurz; Bei einer schnellen Regelung alle 0,1S ist ein Meßintervall von 0,05 schon zu lange. Im Meßintervall müssen schon einige Impulse ankommen da sonst eine genaue Messung unmöglich ist. zB hat man bei 2 Impulsen bis zu 50% Meßfehler weil ein dritter Impuls ja knapp nach dem Meßende kommen kann.

heini320:
Ich hab den Hallsensor am Stator verbaut, dieser Reagiert auf die Vorbeifahrenden Festmagneten am Rotor.
dort sind 20 Magneten, heißt pro umdrehung 20 "schaltungen" ergibt bei 7000 U/min -> 140000 Impulse in der Minute oder 2333,33 Pro Sekunde bei Vollgas. (Kann das der Arduino überhaupt????)

Bei Dementsprechend weniger Drehzahl, dann auch Weniger Impulse

KLeine Korrektur: Deiner Rechnung glaube ich nicht. Wenn der Motor 20 Magneten hat dann hat er 10 Polpaare. Das heißt dann 20 Signaländerungen ( H-L und L-H zusammengezählt) aber nur die Hälfte der Frequenz. Das bringt für die Messung aber keinen Unterschied.

70000 Impulse pro Minute sind fast 1200Hz. Das schafft der Arduino locker. in beiden Meßmethoden.

Die Frage ist was ist die Minimumdrehzahl die gemessen werden soll.

Grüße Uwe

@uwefed, endlich einer der versthet was ich meine :wink: mit dem wieder weiter beschleunigen. :slight_smile:

Also die Rampe die ich mit dem Arduino generiere, arbeitet für den ESC in einem Bereich von 25 bis 115 -> sind die Werte die ich als servo.write Rausschicke.

Bei 24 bewegt sich noch nichts, bei 25 dreht der Motor mit Minimaldrehzahl, bei 115 haben wir dann MAX erreicht.

Diese Triggere ich von 25 bis 45 in 35Mills nach oben
und von 45 bis 115 dann im Abstand von 20 Millis.
Heißt ich fahre etwas "langsamer" los, wenn das ganze dann im Rollen ist, wird schneller hochbeschleunigt.

Max drehzahl ist im Bereich von 7000, bei ca. 50 KM/H
Die Einschaltdrehzahlist is im Bereich von Schrittgeschwindigkeit ->5 - 6 kmh, also dementsprechend ca. 650 - 800 U/min, was der Motor minimum macht.

hier noch ein Link zu solchen Fahrzeugen, gefilmt mit meiner Helmkamera hierbei aber die Fahrzeuge alle Benzinbetrieben :slight_smile:

Hier im Anhang auch mal der code, der aktuell für das ganze verwendet wird.
Hoffe das es annähernd verständlich ist.

#include <Servo.h>;
Servo myservo;
////////////////////////////////////////////
//       Variablen - Potentiometer        //
////////////////////////////////////////////
  int potimin = 170;                            // min Wert am Analog eingang für das Gaspoti
  int potimax = 860;                            // Max Wert am Analog eingang für das Gaspoti
////////////////////////////////////////////
//       Variablen - Beschleunigung       //
////////////////////////////////////////////  
  const long beschleunigungstart = 35;        // Beschleunigung im unteren bereich
  const long beschleunigungfahrt = 20;        // beschleunigung im oberen Bereich
  int uebergangfahrt = 45;                    // übergang unterer zu oberer Bereich
////////////////////////////////////////////
//       Variablen - Drehzahlmesser       //
////////////////////////////////////////////  
  int dmmin = 0;         //Analogeingang      des "generators als Drehzahlmesser" minwert
  int dmmax = 750;       //Analogeingang      des "generators als Drehzahlmesser" maxwert
  int dmxmin = 10;       //                 MIN Wert, des Drehzahlessers umgewandelt für den ESC
  int dmxmax = 80;       //                 MAX Wert des Drehzhalmessers umgewandelt für den ESC
////////////////////////////////////////////


// mit diesen Variablen war es möglich schnell per Handy das ganze zu konfigurieren, deshalb wurden diese auch alle 
// im Kopf bereits deklariert um nicht Ständig im Programm hin und her zu scrollen, dieser obere Teil, passte perfekt
// auf das Handydisplay



int smooth;   // Variable um des Analogeingang des Drehzahlmessers/ Generators zu glätten
int x;        // x ist der Wert der dann als "Drehzahl" bzw. für die Weiterbeschleunigung zum einsatz kommt
int start = 16; // Regler Start also ein MIN welches der ESC einmal braucht um sauber einzuschalten
int poti;       // Variable des Gaspedal
int geschw;     // Variable des Drehzahlmessers
int vala;       // "gemapter" wert vom GAS Poti
int beschl = 24;

unsigned long previousMillis = 0;


void setup() 
{

myservo.attach(6);
delay (2000);
myservo.write(start);
delay (2000);
}


void loop()
{
geschw = analogRead(5);   // Auslesen des Drehzahlessers/ Generators
smooth = 0.6 * smooth + 0.4 * analogRead(5); // Glätten des Drehzalmessers/ Wert
x = map(smooth, dmmin, dmmax, dmxmin, dmxmax); // Mappen des Geglätteten Drehzahlmesser/ Wert

poti = analogRead(1); // Auslesen des Potis Gasgriff
vala = map(poti, potimin, potimax, 25, 115); // Mappen des Potis Gasgriff (damit der ESC umgehen kann)

  if (vala > 25 && beschl < vala)
  {
    if ((millis() - previousMillis) >= beschleunigungstart)             // in diesem Bereich wird die Beschleunigung
    {                                                                   // von null bzw. Start oder langsamen Rollen
      if (vala > x && beschl < x)                                       // gemacht.
      {
        beschl = x;
      }
    beschl++;
    myservo.write(beschl);
    previousMillis = millis();
    }
  }

  if (vala > 25 && beschl > uebergangfahrt)
  {
    if ((millis() - previousMillis) >= beschleunigungfahrt)         // in diesem Bereich wird die Beschleunigung 
    {                                                               // ab dem Punkt "Übergang Fahrt" bis MAX gemacht
      if (vala > x && beschl < x)
      {
        beschl = x;
      }   
    beschl++;
    myservo.write(beschl);
    previousMillis = millis();
    }
  }


  if (vala <= beschl)                                           // hier wird umgeschalten, wenn das Gaspoti Schlagartig
  {                                                             // verringert wird, das auch der Regler sofort
    beschl = vala;                                              // runtergeregelt wird
    myservo.write(beschl);
  }
  
}

bierkiste.ino (3.84 KB)

Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Tommy56:
Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

sollte funktioniert haben :wink:

Hallo,

ich kann Dir da jetzt nur ein Beispiel von der Antriebstechnik aus der Industrie geben. Znächst mal ist die Frage die ob der Antrieb bremsen kann. Wenn nicht wird die Rampe zum runterfahren ja durch die Schwungmassen und Reibung bestimmt. Wenn der Antrieb bremsen kann hängt es von der Bremsleistung ab. Reale Beispiele aus der Industrie sind Asynchon Motore am Frequenzumrichter. Soll da gebremst werden wird mit Bremswiderständen gearbeitet die die Bremsenergie verbraten, oder seit einigen Jahren gibt es Frequenzumrichter mit Vollbrücken die ins Netz zurück speisen können. In dem Fall spricht man von 4 Quadranten Antrieben.

Der bremsende Antrieb sollte also in jedem diesem Fall von der Rampe bestimmt werden und nicht von der Schwungmasse. Wenn dann aus der Ablauframpe wieder beschleunigt wird sollte der Rampengenerator eigentlich vom momentanen Wert aus wieder hochfahren, also nicht von Null. Dabei ist das eigendlich egal ob gesteuerter oder geregelter Betrieb. Abhilfe ist in dem Fall Bremsrampe langsamer machen. Schwierig ist das nun in dem Fall wenn die Schwungmasse unterschiedlich ist, dann ist die längste Rampe bestimmend.

Heinz

also ich hab keine aktive bremse. auch keine durch recuperation. bei uns wird nur mit den Füßen gebremst :slight_smile:

Frage: wer gibt denn die Soll-Geschwindigkeit vor? Der bemerkt doch, wann Beschleunigung einsetzt und wie stark sie ist, und kann selbst entsprechend nachregeln.

Ansonsten kann man Teile der AccelStepper Bibliothek benutzen, um die Rampen zu erzeugen. Ob die Magnete für ein stabiles Drehzahlsignal ausreichen, das muß man wohl ausprobieren und ggf. einen eigenen Sensor anbauen.

Hi

Ich sehe hier das Problem, daß man 'die Rampe runter' knapp über der aktuellen Drehzahl halten muß, da sonst die Ansteuerung eben AUS geht und beim nächsten Gas wieder bei Null anfängt.

MfG

Der bremsende Antrieb sollte also in jedem diesem Fall von der Rampe bestimmt werden und nicht von der Schwungmasse. Wenn dann aus der Ablauframpe wieder beschleunigt wird sollte der Rampengenerator eigentlich vom momentanen Wert aus wieder hochfahren, also nicht von Null. Dabei ist das eigendlich egal ob gesteuerter oder geregelter Betrieb. Abhilfe ist in dem Fall Bremsrampe langsamer machen. Schwierig ist das nun in dem Fall wenn die Schwungmasse unterschiedlich ist, dann ist die längste Rampe bestimmend.

Also Heinz
Du sagst man sollte eine Bremsrampe programmieren, das heißt beim Loslassen des Gas die Ansteuerung des Motors nicht sofort auf null regeln sonder langsam hinunterregeln und zwar langsamer als die Bierkiste von alleine stoppen würde. Dann wüßte man von wo man wieder starten müßte wenn man starten möchte.

Die Einschaltdrehzahlist is im Bereich von Schrittgeschwindigkeit ->5 - 6 kmh, also dementsprechend ca. 650 - 800 U/min, was der Motor minimum macht.

Also ca 1200 Hz max bis ca 10 Hz minimum. Für den gesamten Bereich ist eine Periodenzeitmessung sinnvoll.
Grüße Uwe

Mir geht gerade folgender Gedankengang durch den Kopf:

Du schreibst im Programm im Kommentar:
int x // Drehzahl für die Weiterbeschleunigung

Wenn jetzt deine Rampe zwar einerseits langsam hochläuft, dann müsste es gehen, dies in eine weitere Abhängigkeit von x zu setzen.

Sauber gemappt sollte ein bestimmtes x einem bestimmten servoWrite Wert entsprechen.

Wenn man ihm also nun sinngemäß sagt.

if servoWrite Wert kleiner als dem aktuellen x entsprechend, dann Rampe steil
else if servoWritewert >= dem aktuellen x Wert, dann Rampe flach.

Effekt:

Du rollst sagen wir 40 von 50 möglichen Km/h, nimmst Gas weg
ServoWrite Wert im Keller, X relativ hoch, leicht absinkend durch "Ausrollen"

Du gibst Gas, dein ServoWrite weg fährt steil hoch, bis er dem aktuellen X entspricht,
dann greift else if und der servoWrite Wert steigt wieder langsam, so wie die Rampe es vorgibt.
Steil hoch meint hier ebenfalls eine Rampe, die aber in etwa so bei 0,2 Sekunden im Hochlauf liegt, um es nicht zu ruckartig zu machen, der 100cc ist ja ein Torque-Monster.So wäre die Steile Rampe immer nur dann am Zuge, wenn bereits Drehzal der Räder anliegt, servowrite aber noch im Keller ist.
Aus dem Stand wären eide bei "Startbedingung" und damit als == vergleichbar, und die langsame Rampe wäre am Zug.
Kleine Differenz als Sicherheit einbauen, und dann sollte es laufen.

Der ESC spielt da mit, da sehe ich nicht das Problem.
Die Bremse des ESC kannst ja aus bekannten Gründen her eh nur bedingt, wenn nicht gar gar nicht nutzen, allein schon, wegen ihrer Startbedingung, das macht hier auch kaum Sinn, weil nicht regelbar.

In Ermangelung an Zeit und Hirnkapazität auf Grund des akuten Koffeinmangels als erste Ableitung der aktuellen Uhrzeit fühle ich mich allerdings nicht in der Lage, das jetzt in Code umzusetzen.