Go Down

Topic: Bürstenmotor mit ESC über Arduino steuern (Read 1 time) previous topic - next topic

DollyBird

Hi,

der Code der funktioniert:

Code: [Select]
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:

Code: [Select]
#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.

michael_x

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

Dein Hauptprogramm macht in Wirklichkeit
Code: [Select]
    if(state == 'V')
    {
       servo.write(90);  // Geradeaus
       analogWrite(ESCPin, 255); // Vollgas
    }

DollyBird

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:

Code: [Select]
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.

agmue

#18
Jan 21, 2018, 05:13 pm Last Edit: Jan 21, 2018, 06:26 pm by agmue
(Ich wundere mich eigentlich, dass dein analogWrite-Beispiel so gut funktioniert)
Ich auch, aber ich hätte da eine Vermutung:

Testprogramm:
Code: [Select]
int ESCPin = 6; // Basisfrequenz für Pins 5 und 6 ist 62500 Hz

Hauptprogramm:
Code: [Select]
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.

DollyBird

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.

ElEspanol

#20
Jan 21, 2018, 06:13 pm Last Edit: Jan 21, 2018, 06:19 pm by ElEspanol
Hier herrscht offenbar viel Verwirrung und Halbwissen
1. 20 ms entsprechen 50Hz, nicht 50000
2. ESC hat nichts mit brushless, bürstenlos zu tun. Es gibt ESC auch für Bürstenmotore, wie in diesem Fall
3. Die 20 ms Zykluszeit stammen noch aus analog Zeiten, so aus Anfang der 70er Jahre, als die ersten Proportionalfernsteuerungen raus kamen. Viele aktuelle Servos und RC Anlagen benutzen das aber heute noch, aus Gründen der Kompatibilität über Herstellergrenzen hinweg.
4. Aktuelles Equipment kann auch an PWM mit 490Hz funktionieren, muss aber nicht. An 31,250Hz oder höher tut es mit an Sicherheit grenzender Wahrscheinlichkeit nicht.
5. Die 1-2 ms für das Steuersignal sind möglichst einzuhalten. Du kannst nun selber ausrechnen, auf wieviel Hz du max. kommst. Die 20ms stammen daher, dass früher 8 Kanäle im PPM übertragen wurden. 8 mal 2ms + Sync-Zeit = 20 ms. Inzwischen gibt es auch andere Raster, da viele RC-Anlagen mehr als 9 Kanäle per PPM übertragen. Vor allem Digitalservos fressen heutzutage fasst alles, von 0,1ms an.
6. Der ESC benötigt offensichtlich die Einlernphase JEDESMAL, wenn er vom Strom getrennt wurde.


Also bau dir einen „Servotester", mit dem du austesten kannst, wie die Einlernphase funktioniert und bau diese dann ins setup vom Sketch ein.
In diesem Sketch hat delay im loop absolut nichts verloren

agmue

Die Frequenzangaben für PWM:

Base frequencies:
o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
o The base frequency for pins 5 and 6 is 62500 Hz.


ElEspanol

Habe ich was gegenteiliges geschrieben? Im Pkt. 4 habe ich mich doch recht vorsichtig ausgedrückt

agmue

Ich wollte nur die Quelle für die Frequenzen ergänzen, falls es jemanden interessieren sollte.

Bei Durchsicht der Programme war mir aufgefallen, daß der TO mit unterschiedlichen Pins operiert, die unterschiedliche PWM-Frequenzen abgeben. Das könnte ja irgendwas bedeuten.

Wäre das 62500 Hz / 1024 =  61 Hz (~16 ms) einen Versuch wert?

postmaster-ino

Hi

Da Es ja irgendwie in einer Konstellation klappt, sollten wir hier mit Buddeln anfangen.
Ich habe das verlinkte Datenblatt nur überflogen (damals wusste ich ja auch noch nicht, ob's Das überhaupt ist).
Sollte sich darin ein Passus befinden, welchen Knopf man wie drücken muß AN DER FERNBEDIENUNG, kann man dieses Verhalten im Arduino nach'bauen'.
Wenn statt Dessen (also statt 'Vollgas' steht Da was von 2ms Impulslänge), kann man auch mit diesen Werten was brauchbares bauen.

MfG

ElEspanol

Wenn das Datenblatt das richtige ist, bleiben die Einstellungen im ESC gespeichert. Schon um das Teil korrekt zu programmieren, sollte man einen kleinen Sketch schreiben.
Kompliziert ist das ganze aber nicht. M.M.n. Sollte man aber unbedingt mit der Servo Lib arbeiten. Sieht mir doch arg nach 50Hz aus, sprich alle 20ms einen Impuls von 1-2ms

dony

#26
Jan 22, 2018, 12:04 am Last Edit: Jan 22, 2018, 01:23 am by dony
Hallo,

Funktioniert das mit der Bluetooth Verbindung? Wenn nicht, würde ich das zuerst getrennt probieren. (Natürlich kannst Du auch das Ansteuern zu erst probieren, aber getrennt)

Ich habe in meinen Anfängen ein 'Roboter' Auto gebaut, das man mittels Bluetooth und App steuern konnte.
Ich hab dafür aber nur Zahlen (Integer) verwendet. Wie ich auch gerade sehe, ist hier ein längeres delay() drinnen, wahrscheinlich, hat das Ganze deshalb nicht besonders gut funktioniert.  :smiley-confuse:
Code: [Select]
// in der loop
if (BTserial.available()) { 
  int type = BTserial.read();
  comMsg = BTserial.parseInt();  // Die comMsg muss deklariert werden
  Serial.println(comMsg);  // So siehst du was ankommt.
  // delay(50);
}

BTSerial bezieht sich auf SoftwareSerial.
Musst du Buchstaben nehmen? Ich finde mit Zahlen (int oder byte) geht das leichter.

Wenn die Bluetooth Verbindung funktioniert, dann musst Du dich nur noch um das richtige Ansteuern kümmern.
Du kannst es natürlich machen wie Du willst aber trotz mehrfachen lesen, Blick nicht ganz durch was jetzt genau funktioniert und was nicht.

Ganz unten im Datenblatt steht bei Fehlerquellen "Fahrzeug fährt nicht rückwärts":
"Sender Einstellung nach der Vollgaseinstellung verändert. Neue Einstellung nach dem Wechseln des Senders durchführen. überprüfen ob die Flückwärtsfunktion eingeschaltet ist." <- das hast Du ja bereits probiert. Aber was ist mit dem Text in Kursiv? Ohne das Teil in der Hand zu haben ist es etwas kompliziert, das alles Nachzuvollziehen.

Lt. Datenblatt soll der Gasregler auf die Mittelstellung gestellt werden, erst danach, nach vorne Bewegen um Rückwärts zu fahren. Aber Achtung, was ist die Mittelstellung als Signal, vielleicht ein 50% PWM. Wie auch immer, Du kannst folgendes probieren.
Code: [Select]
analogWrite(pin, 128);
delay(50); // Nur zum testen und wenn dann gehört das ins Setup da Handshake
analogWrite(pin, 200);  // oder: analogWrite(pin, 100); oder die for Schleife


Falls Du es noch nicht mit der Servo lib versucht hast, solltest Du das zumindest versuchen. Über eine Möglichkeit ohne lib kann man dann immer noch nachdenken, das sage ich nur weil Du gemeint hast, Du musst es ohne lib programmieren.

lg dony
edit: @DollyBird: In Deiner for Schleife wird immer 5 dazugezählt, hast du es mit Einzel Schritten probiert (i++)?
Bitte Code in Codetags, </> (erster) Button in der Toolbar.
Schnell was umstellen: Alerts->Settings |->Look and Layout->Use full editor in Quick Reply
Grüße, Donny

ElEspanol

Solange da nichts fundiertes zurück kommt, bin ich raus. Das ist ja schlimmer wie stochern im Nebel. Und interessant zu wissen wäre es, ob der TE überhaupt versteht, was wir schreiben. Da habe ich nämlich große Zweifel. Aber dann soll er es wenigstens sagen.

DollyBird

Danke für die vielen Antworten! Ich verstehe was ihr hier schreibt, konnte bisher aber nicht mehr antworten.
Ich werde es später doch noch einmal mit der Servo lib versuchen, aber vorher das ESC kalibrieren. Dann melde ich mich noch mal.

DollyBird

#29
Jan 22, 2018, 02:39 pm Last Edit: Jan 22, 2018, 03:31 pm by DollyBird
Ich hab nun verschiedenes probiert und das ist mein Zwischenstand:

Code: [Select]
#include <SoftwareSerial.h>
#include <Servo.h>

SoftwareSerial BT(12, 13);
// creates a "virtual" serial port/UART
// connect BT module TX to D10
// connect BT module RX to D11

//Bluetooth Status (HC-05) Pin STATE an Pin 2 von Arduino
  const int BTState = 2;

//Servo
Servo servo;
Servo esc;
int speed=50; //speed = 50%?

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() {
 BT.begin(9600);    // set the data rate for the SoftwareSerial port   
 pinMode(BTState, INPUT);     
 //pinMode(13, OUTPUT);
 servo.attach(9);//Servo an Pin 9
 esc.attach(10);
  setSpeed(50);
 //BT.println("Hello from Arduino");
}

int state; // stores incoming character from other device

void loop() {
//setSpeed(speed);
  if(digitalRead(BTState) == LOW)   //wenn keine Verbindung, STOP
  {
    setSpeed(50);
  }
 
  if (BT.available()>0)
  // if text arrived in from BT serial...
  {
    state = BT.read();

    //speed=a.toInt();

    if(state == 'V')
    {
      setSpeed(50); //Stop
    }
    else if(state == 'R')
    {
      setSpeed(100);  //keine Reaktion
    }
    else if(state == 'L')
    {
      setSpeed(0);    //Vorwärts
    }
  }
}


Ich hab mich nun doch dafür entschieden die servo lib für das esc zu verwenden und es funktioniert! Zumindest Vollgas vorwärts und Stop. Das Rückwärtsfahren ist eingeschaltet bei dem ESC, aber hat bisher nicht funktioniert. Aber da ich morgen eine wichtige Klausur schreibe werde ich heute wahrscheinlich nicht mehr damit weitermachen.
Schon mal ein großes Danke an alle!

Go Up