Bürstenmotor mit ESC über Arduino steuern

Hallo zusammen,

ich möchte einen Bürstenmotor mit ESC über ein Arduino Uno via Bluetooth steuern. Zuerst habe ich diesen Code ausprobiert, hat auch wunderbar funktioniert (noch ohne Bluetooth).

#include <Servo.h>

//Bluetooth angeschlossen an Tx und Rx
  int bluetoothTx = 1;
  int bluetoothRx = 0;
 // int BTState = 2;

Servo esc;

void setSpeed(int speed)
{
//  instructions
  int angle = map(speed, 0, 100, 0 ,180);     //geht von 0 bis 100, wird geändert zu 0 bis 180
  esc.write(angle);
}

void setup()
{
  esc.attach(10);
  setSpeed(0);
  //pinMode(BTState, INPUT);
}

void loop()
{
  int speed;

 
  //Vorwärts fahren
 
  //sweep back down to 0 speed
  for(speed = 95; speed > 0; speed -= 5)
  {
    setSpeed(speed);
    delay(1000);
  }
 
  //sweed up from 0 to maximum speed in 20 seconds
  for(speed = 0; speed <= 100; speed += 5)
  {
    setSpeed(speed);
    delay(1000);
  }

  setSpeed(0);
  delay(5000);

}

Das ESC und der Bürstenmotor sind von/in einem RC Auto verbaut. Die benötigte App dazu habe ich selbst entwickelt und ich kann damit nach links/rechts lenken, die Bluetooth-Kommunikation funktioniert.
Das ESC ist übrigens für Vorwärts, Rückwärts und Bremsen geeignet, allerdings habe ich es bisher nur zum Vorwärtsfahren bekommen. Angeblich soll es mit "esc.write()" auch rückwärts gehen, aber das hat bisher nicht funktioniert. Was kann ich tun?

Mein anderes (größeres) Problem ist, sobald ich das Auto einschalte läuft der Motor mit Vollgas los, obwohl ich im setup "esc.write(0)" oder in einer anderen Variante "setSpeed(0)" geschrieben hab. Das gleiche habe ich auch im loop versucht, mit dem gleichen Ergebnis.
Ich habe keine Ahnung was das Problem ist, schließlich soll der Motor nur laufen wenn er ein entsprechendes Signal erhält. Ich habe etliche Foren und Webseiten durchforstet, habe aber keine Lösung gefunden. Ich hoffe ihr könnt mir helfen!

LG

DollyBird:
Das ESC und der Bürstenmotor ...

Welche?

Das sind die Zeiten, die die Bibliothek verwendet:

#define MIN_PULSE_WIDTH       544     // the shortest pulse sent to a servo  
#define MAX_PULSE_WIDTH      2400     // the longest pulse sent to a servo 
#define DEFAULT_PULSE_WIDTH  1500     // default pulse width when servo is attached

Passen die zum ESC?

Meine Herangehensweise: Du könntest das Bibliotheksbeispiel Knob.ino verwenden und write(val) durch writeMicroseconds(value) ersetzen. Natürlich die Werte in map() anpassen und mit Serial.print anzeigen. Dann siehst Du, was der ESC bei welchem Wert macht.

Dass in deinem RC Auto ein ESC siztzt, weiss dein Arduino nicht.
Der "sieht" nur einen normalen Servo, dem er Winkel-Werte von 0 .. 180 als Zahl zwischen 0 und 100 vorgibt.
Das ist zwar schön, hat aber mit deinem Thread - Titel nicht viel zu tun.

Die Servo - Bibliothek macht aus dem Winkel eine PPM mit im Durchschnitt 1500 µs (ca +-500µs) langen Pulsen in einem ca. 20 ms großen Interval. Diese kommen so auch im Fernsteuerempfänger an und sind der Eingang in den ESC-Controller, der dann -völlig anders- den Motor mit Drehstrom versorgt.

ESC-Motoren haben übrigens keine Bürsten.

Michael, da verwechselst du was, Drehzahlregler – Wikipedia, ESC ist allgemein Drehzahlregler im Modellbau.

0-180 ist der Steuerbereich von Vollgas Vorwärtsgang bis Vollgas Rückwärtsgang. Stillstand ist bei 90

Dies sind normalerweise aber Drehwinkel beim Servo. Die o.g. Angaben in der Lib über die Pulsweite passen i.d.R. Aber nicht zu einem ESC (und zu normalen Servos auch nicht).
Nimm lieber Werte von 1100 bis 1900, wobei 1500 Stillstand bedeutet.

Michael, da verwechselst du was

Ja sorry, ich dachte, er wollte die ESC-Firmware für die Elektronik, die das Drehfeld für die Motor-Wicklungen erzeugt, per Arduino realisieren.
Nur die Servo-artige normale Ansteuerung (rund um Neutral = Mitte = 90° = 1500µs Pulsbreite) hielt ich für zu trivial. :wink:

Ob manesc.write(90)oderesc.writeMicroseconds(1500)schreibt, macht keinen Unterschied.

Auch ob das nun letztendlich Geschwindigkeit und Drehrichtung eines ESC-Motors oder die Stellung des Hebels eines Servos vorgibt, merkt der Arduino-Pin nicht.

Wo jeweils die Min und Max Grenzen liegen, ist nicht nur bei Servos unterschiedlich...
Bin mir nichtmal sicher, ob der Winkel, um den sich ein Servo-Hebel bewegt, tatsächlich genau dem Zahlenwert entspricht. :confused:

Eventuell mal die Bedienungsanleitung des Reglers lesen.
Car-Regler haben so ihre kleinen Tücken, die verhalten sich nur im Prinzip wir Servos- in Wirklichkeit aber ist da viel mehr dahinter.
Teils müssen sie bei jedem Neustart kalibriert werden (oft indem man einmal Vollgas, einmal voll zurück steuert), teilweise nur einmal, bei manchen ist die Geschwindigkeit rückwärts programmierbar, bei anderen ist sie begrenzt, und die Bremsen sind eine ganz eigene Geschichte- da gibts alles mögliche zwischen "gar keine, wir bremsen einfach mit weeeenig Gas rückwärts" bis hin zur echten Feststellbremse.
Ich hab nen Regler, der beim rückwärts steuern ungefähr zwei Sekunden lang proportional bremst, dann jedoch, abhängig von der Knüppelstellung, direkt auf rückwärts umschaltet (das kann dann auch Vollgas sein), nen anderen, bei dem ich die Bremscharakteristik einstellen kann (fast bis hin zum ABS), bei dem muss nach dem Bremsen neutral gesteuert werden, dann geht er in den Rückwärtsgang- kurz gesagt: auf Verdacht ist das aussichtslos.
Anlaufschutz gibts auch noch (nicht bei allen)....und weitere Features. Kann man alles in nem Programm berücksichtigen- wenn man es weiss.

Hier hilft echt nur die Bedienungsanleitung des Reglers weiter- und wenn nicht, dann zurück zum Händler mit dem Schrott. Ordentliche Regler haben eine Anleitung, aus der man all das entnehmen kann.

Eigentlich ist es das Sinnvollste, eine ausreichend starke H-Brücke zu nehmen, und den Rest selber zu machen, das ist entschieden weniger Aufwand, als die Tücken so eines Reglers zu umschiffen. Allerdings: sowas kostet in der Liga um 50A dann einiges....aber ein guter RC-Regler auch!

Hallo,

Hier geht es in etwa um das selbe.
Da hat offensichtlich ein analogWrite(pin, 128); // (0-255) geholfen. Ließ Dir das durch, es würde jetzt wenig Sinn machen, dasselbe hier nochmals zu posten.

Nur das wichtigste: Solche Systeme funktionieren manchmal so: 0 = Rückwärts aber Stopp, 60 = langsam Rückwärts, 127 = Vollgas Rückwärts. 128 oder 90° = Stopp und 129-255 ist Vorwärts, 255 = Vollgas.

lg dony

Das ESC und der Bürstenmotor sind von/in einem RC Auto verbaut.

Ob der TE überhaupt eine Doku hat?

Ich würde es einfach ausprobieren. Entweder mit der alten Fernsteuerung oder mit dem Beispielsketch, da allerdings den Potiwert auf 1000 bis 2000 mappen und auch seriell ausgeben.

Abwer warten wir mal, bis DollyBird sich wieder meldet.

Danke für die vielen, schnellen Antworten!

Da ich möglichst ohne lib programmieren soll (Anweisung von meinem Lehrer), habe ich es jetzt mit analogWrite probiert. Den Servo zum Lenken kann ich übrigens prima mit der Servo lib steuern.

Um erst einmal zu testen ob es funktioniert und wie, habe ich diesen Code verwendet:

int ESCPin = 9;
int val = 0;
void setup() {
  // put your setup code here, to run once:
pinMode(ESCPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

for(val = 0; val <= 255; val += 5)
 {
   analogWrite(ESCPin, val);
   delay(100);
 }
}

Das hat soweit auch wunderbar funktioniert, also habe ich es in mein Hauptprogramm eingebaut. Nun piept das ESC aber immer als Zeichen dass es nicht programmiert ist. Das ergibt für mich überhaupt keinen Sinn. Ich habe dann auch andere Pins ausprobiert und den Servo zum Lenken angeschlossen, daran liegt es nicht.

Zum Thema Anleitung: Beides war im Modellbausatz dabei, ich habe auch im Internet kaum Informationen dazu gefunden, außer die technischen Daten.
Das ESC das ich verwende: TBLE-02
Technische Daten:

  • EFR: Vorwärts/Bremse/Rückwärts
  • Leistungsabgabe: Vorwärts 100%, Rückwärts 50%
    Der Motor: TBLM-01S
    Der Bausatz ist von Tamiya.

Das Einzige, das ich in meinem Hauptprogramm anders gemacht habe ist, dass ich keine for-Schleife verwende und an die Stelle von val einen tatsächlichen Wert eingebe.

Als ich angefangen habe, hatte ich überlegt eine H-Brücke zu verwenden, aber es müsste auch ohne gehen. Noch dazu ist der Platz im Auto begrenzt. Eine H-Brücke würde zwar noch rein passen (gerade so), aber das wäre eine letzte Option.

Hi

Durch den Fahrtregler wirst Du wohl keine H-Brücke brauchen, wobei mir die Bilder bei der Suche nach TBLE-02 eher nach BLDC aussehen ... ok, der Motor ist ja auch BLDC :wink:

Das Piepsen des ESC wird daran liegen, daß Dieses eine Art 'Kennenlern-Sequenz' erwartet, damit der Motor passend angesteuert werden kann.
Das kann ein
0...Vollgas Vor ... 0 ... Vollgas Zurück ... 0
sein, oder irgend eine andere Kombination, mit Der man dem ESC sagen kann, was gerade gewünscht ist.
Dazu sollte sich was in der Beschreibung finden lassen.

H-Brücke für einen Drehstrom-Motor wird langsam schon komplizierter, da das ESC Das aber schon übernimmt (zumindest sind dort ziemlich fette Strippen dran, Die zufällig 1:1 auf den Motor passen), wird so was bei Dir nicht gebraucht.

Kann sein, daß das Hochzählen des val Wert dieses 'Kennenlernen' darstellt.

MfG

Hi,
Genau, das hatte ich irgendwo gelesen, dass das ESC die H-Brücke "ersetzt".

Was genau meinst du mit Kennenlern-Sequenz? Muss ich das ESC kalibrieren?
Wenn ich das Auto einschalte piept das ESC einmal "länger" und leuchtet grün, das bedeutet laut Anleitung dass Rückwärtsfahren eingeschaltet ist, und dann gibt der Motor Gas, wenn ich das programmiert habe. Sonst, wenn ich es nicht benutze, also nur Spannung angeschlossen habe, dann piept es dauerhaft kurz und blinkt grün, das, soweit ich gelesen habe, bedeutet dass es nicht angeschlossen ist.
Normalerweise wird das ESC, sowie der Lenkservo, von einem fertigen Sender und Empfänger gesteuert, aber diese möchte ich mit einem Arduino als Empfänger und mit dem Smartphone als Sender ersetzen.

Ich habe die for-Schleife in mein Hauptprogramm eingefügt, sodass bei einem bestimmten Signal der Motor allmählich beschleunigt. Der Lenkservo, der gleichzeitig angesteuert wird reagiert, aber das ESC überhaupt nicht.

Hi

Bei dem ESC müsste irgendwo beistehen, wie Dieses in Betrieb genommen werden muß.
Selber bin ich RC-technisch nicht sonderlich bewandert, hätte akut nur einen kleinen Quadrocopter, Der nach Einschalten (=Akku anstecken) von der Fernsteuerung 0...Vollgas...0 'sehen' will, damit sich beide Geräte verbinden.
Das dürfte hier aber eine einfache Routiene sein, daß der Quadrocopter sich nicht 'irgend eine Fernbedienung' sucht um dann im Himmel zu verschwinden.

Passt dieses 'Datenblatt' zu Deinem Regler?
PDF, tamiya.de

Darin werden Blink-Codes genannt - hast Du Solche?

MfG

Hi,

genau diese Anleitung habe ich.
Das Einzige, das mir jetzt einfällt ist einen normalen Sender und Empfänger zu verwenden um das ESC zu kalibrieren, vielleicht funktioniert es dann. Das kann ich allerdings erst im Laufe der Woche tun, da ich selbst soetwas nicht habe.

Ich finde es nur seltsam dass das ESC "läuft" wenn ich den kurzen Code verwende, es aber nicht reagiert wenn ich es über Bluetooth anspreche. Das ergibt für mich keinen Sinn.

Den grün -rot - Blinkrhythmus hatte ich, als ich die Settaste betätigt hatte. Aber wie ich das in der Anleitung lese hat das nur etwas damit zu tun ob Rückwärtsfahren möglich ist oder nicht.

Hi

Wenn ein Beispiel funktioniert, muß 'der Rest' eigentlich auch tun.
Was passiert, wenn Du den funktionierenden Code auf Deine Bedürfnisse anpasst?
Wie sprichst Du das ESC 'ohne BT' an?
Und wie mit?

Der Arduino ist ja 'nur' der Empfänger für die BT-Daten, also Deine Fahrbefehle.
Damit hat das ESC ja gar Nichts zu tun, die Initialisierung wird in beiden Fällen gleich sein.

Was ich mir vorstellen kann: Sobald Du BT benutzt, kommt der Servo-Ausgang durcheinander und das ESC sieht nur noch Müll - könnte Das sein?

Wie viel von den blauen Zähnen musst Du auskommentieren, bevor das ESC den Motor wieder dreht?
(dafür von Unten nach Oben alle BT-Befehle einzeln raus nehmen, Sketch aufspielen und schauen, ob sich irgend was tut)

MfG

PS: Das Datenblatt hättest Du oben dann bereits verlinken können, auch die Nennung, daß die Blink-Signale bei Dir 'so und so' aussehen lässt erahnen, bis wohin wir kommen und wo die Probleme anfangen.

analogWrite (PWM 0..100% bei 490 Hz) und Servo-Ansteuerung (1..2ms alle 20 ms) sind ja grundverschieden,
kommt so ein ESC-Regler ohne weiteres mit beidem zurecht?

Auch abwechselnd ? Oder muss er dafür durch sein Setup?
(Ich wundere mich eigentlich, dass dein analogWrite-Beispiel so gut funktioniert)

Hi,

der Code der funktioniert:

int ESCPin = 6;
int val = 0;
void setup() {
pinMode(ESCPin, OUTPUT);
}

void loop() {

for(val = 0; val <= 255; val += 5)
 {
   analogWrite(ESCPin, val);
   delay(100);
 }
}

Mein Hauptprogramm:

#include <Servo.h>
#include <SoftwareSerial.h>


SoftwareSerial BT(12, 13);
int BTState = 2;


Servo servo;
char state; // stores incoming character from other device

int ESCPin = 10;
int val = 0;

void setup() {
  servo.attach(9);
  pinMode(ESCPin, OUTPUT);
  BT.begin(9600);

}


void loop() {

  analogWrite(ESCPin, val);

  if(BT.available())
  {
    state = (BT.read());
  
    if(state == 'V')
    {
      servo.write(90);
      for(val = 0; val <= 255; val += 5){
      analogWrite(ESCPin, val);
      }
    }
    if(state == 'R')
    {
      servo.write(160);
    }
    if(state == 'L')
    {
      servo.write(50);
    }
  }
}

Auf die Idee es mit analogWrite() zu probieren bin ich gekommen, als ich gelesen hab dass man damit Motoren über ein ESC steuern kann. digitalWrite() würde auch gehen, kann aber nur HIGH und LOW. Die Servo lib ist auch dafür geeignet ein ESC anzusteuern, das hatte ich als erstes probiert, das hat auch funktioniert. Wenn ich es allerdings in meinem Hauptprogramm verwendet habe, ist der Motor gleich in Vollgas gelaufen und ist in diesem Zustand geblieben.

Also ich benutze entweder das eine, oder das andere, aber nicht beides in einem Code. Das würde wohl nicht funktionieren.

Der wesentliche Unterschied ist das "fehlende" delay(100); in deinem Hauptprogramm.
Damit kannst du die for-Schleife vergessen.

Dein Hauptprogramm macht in Wirklichkeit

    if(state == 'V')
    {
       servo.write(90);  // Geradeaus
       analogWrite(ESCPin, 255); // Vollgas
    }

Hi,

das wäre erst mal gar nicht das Problem. Auch wenn ich die for-Schleife weglasse und für val einen festen Wert angebe piept und blinkt das ESC in kurzen Abständen grün. Es reagiert auch nicht auf das Bluetooth Signal.

Ich habe jetzt nochmal versucht das ESC mit der Settaste einzustellen und diesen Code verwendet:

int ESCPin = 10;
int val = 0;
void setup() {
  // put your setup code here, to run once:
pinMode(ESCPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
analogWrite(ESCPin, val);
for(val = 0; val <= 255; val += 5)
 {
   analogWrite(ESCPin, val);
   delay(100);
 }

 for(val = 255; val >= 0; val -=5)
 {
  analogWrite(ESCPin, val);
  delay(100);
 }

 delay(100);
}

Nun verhält es sich nach dem Einschalten:

  • blinkt in kurzen Abständen grün und piept (dauert ein paar Sekunden)
  • gibt für ca. 1 Sekunde Vollgas
  • blinkt ein wenig länger grün und piept einmal (als Zeichen dass es ein Signal hat)
  • dann führt es den Code aus
    Und so geht es in Dauerschleife.

Die einzige Lösung, die mir jetzt noch einfällt, die eventuell etwas bringen könnte, das ESC mit einem vorgesehenen Sender und Empfänger einzustellen. Ich bin wirklich ratlos wieso es am Anfang mal kurz Gas gibt und erst dann den eigentlichen Code ausführt.

michael_x:
(Ich wundere mich eigentlich, dass dein analogWrite-Beispiel so gut funktioniert)

Ich auch, aber ich hätte da eine Vermutung:

Testprogramm:

int ESCPin = 6; // Basisfrequenz für Pins 5 und 6 ist 62500 Hz

Hauptprogramm:

int ESCPin = 10; // Basisfrequenz für Pins 3, 9, 10, und 11 ist 31250 Hz

Möglicherweise werden die 62500 Hz eher als die 31250 Hz anstelle der eigentlich notwendigen 50000 Hz (=20 ms) vom ESC akzeptiert.

EDIT: Vermutung gestrichen.

Hi,

ich habe Pin 6 und danach Pin 5 ausprobiert. Nach dem Einschalten piept und blinkt (grün) es einmal länger, so wie wenn es ein Signal hat, dann piept und blinkt (grün) es mit kurzen Zeitabständen. So verhält es sich wenn ich das ESC gar nicht im Code habe.