Ich habe eine frage zum Arduino und DC Motor.
Auf YT habe ich ein Video mit Skript gefunden um einen Motor anzusteuern,
leider funktioniert irgendwas nicht so richtig bei mir.
Laut Anleitung kann man per Serielle Monitor Geschwindigkeit und Drehrichtung des Motors
bestimmen. Bei mir geht leider nur eine Drehrichtung un der Motor hört nach 2 Sekunden auf zu drehen.
Ich finde den Fehler einfach nicht, der einzige Unterschied ist der Motortreiber Chip.
In der Anleitung soll es ein L239B sein, ich habe aber nur einen L239DNE, kann es wohl daran liegen?
Ich bestehe sogar auf diverse Links (bitte klickbar, also URL-Tags).
Von der Bezeichnung her ist's zumindest die gleiche 'Familie' - worin sich B und DNE unterscheiden, kann man wohl den Tiefen der Datenblätter entnehmen, selber hatte ich mit diesem Stein noch Nichts zu tun (hätte jetzt L298 oder so was erwartet ).
Dann: YT-Videos sind nicht der Weisheit letzter Schluss - böse Zungen behaupten sogar: ein großer Teil ist einfach nur Mist, Der zufällig sogar funktioniert.
So ganz ohne Link ist Das aber auch hier - schwierig.
Dein Sketch (beim Arduino heißt der Code nicht Script) bitte in Code-Tags (</>-Button).
Wenn WARNUNGEN kommen, Diese gerne auch - Wenn der Kompiler geschwätziger sein soll (und Ja, soll Der!!), in den Voreinstellungen die ausführlichen Ausgaben aktivieren (2 Häkchen).
Alles, was rot ist, könnte zu einem Problem werden.
Anbei das Bild vom Aufbau und das Sketch und der Link zum Video.
/* Robotic Tutorials
* 14.04.2018
* Tutorial #12 - Gleichstrommotor
*
* Mit diesem Programm könnt ihr über den Serial Monitor eine Zahl zwischen -255 und +255
* eingeben und so die Drehzahl und Drehrichtung des über den L293B-Chip angeschlossenen
* Gleichstrommotor steuern.
*
* Verwendete Verbindungen:
* Arduino - L293B
* DP1 - I3
* DP2 - I4
* DP3 - CE2
*/
// Variablen für die Pins am Arduino
// Der Enable-Pin muss ein PWM-Pin sein
const int enablePin = 3;
const int inputA = 2;
const int inputB = 1;
// Variablen für die serielle Eingabe der Geschwindigkeit
int eingabeSerial = 0;
int eingabeKorrigiert = 0;
// Funktion für die Ansteuerung des Motors
int setMotor(int wert);
void setup() {
Serial.begin(9600); // Beginn der seriellen Kommunikation
for(int i=1; i<4; i++) { // Lege Pins als OUTPUTs fest
pinMode(i, OUTPUT); }
}
void loop() {
while(Serial.available() == 0) {} // Warte auf serielle Eingabe
eingabeSerial = Serial.parseInt(); // Schreibe serielle Eingabe in Variable (parseInt() lässt nur ganze Zahlen als Eingabe zu)
if( eingabeSerial > 255) { eingabeKorrigiert = 255; } // Korrigiert Eingaben >255 zum Maximalwert 255
else if( eingabeSerial < -255) { eingabeKorrigiert = -255; } // Korrigiert Eingaben <-255 zum Minimalwert -255
else {eingabeKorrigiert = eingabeSerial; } // Schreibt korrekte Eingaben in Variable
setMotor(eingabeKorrigiert); // Schreibt auf die Input-Pins des L293 (s.u.)
Serial.println(eingabeKorrigiert); // zeigt die aktuelle "Drehzahl" im Serial Monitor an
}
int setMotor(int wert) {
if(wert == 0) {
digitalWrite(enablePin, LOW); } // Halte den Motor an
else if(wert > 0) { // Lege Drehrichtung fest, sende "Drehzahl" an den Enable-Pin
digitalWrite(inputA, HIGH);
digitalWrite(inputB, LOW);
analogWrite(enablePin, wert); }
else {
digitalWrite(inputA, LOW); // wie oben, nur andere Drehrichtung und ändern der eingegebenen
digitalWrite(inputB, HIGH); // "Drehzahl" in einen positiven Wert
analogWrite(enablePin, -wert); }
}
Dann musst Du aber auch die FOR für die OUTPUTs anpassen.
Allgemein ist es keine gute Idee, hier wieder mit magic-numbers zu hantieren - die 1-3 in der FOR-Schleife haben keinen Bezug auf die oben eingetragenen Pin-Nummern.
Wenn ich nur Eines davon anpasse, bekomme ich seltsame Phänomene - weil ein Output eben auf INPUT steht und ich durch das digitalWrite nur den PullUp ein/aus schalte.
Die Klammern beim IF bitte zukünftig in der Zeile des IF, des ELSE - lässt den Sketch optisch zusammen rücken.
STRG+T rückt auf Klammerebene ein - entfernt aber keine überflüssigen Leerzeichen!!
postmaster-ino:
Dann: YT-Videos sind nicht der Weisheit letzter Schluss - böse Zungen behaupten sogar: ein großer Teil ist einfach nur Mist, Der zufällig sogar funktioniert.
Wobei das verlinkte Video diese Aussage bestätigt. Denn der ganze Mist, der hier schon angesprochen wurde, stammt aus selbigem Video.
Habe die Pins nun ohne die for Schleife auf Output gesetzt, und Pin 4 anstatt Pin 1 genommen.
Funktioniert.
Allerdings läuft der Motor noch immer nur 2 Sekunden.
Irgendwas setzt mir den Wert vom Pin 3 auf Null, dadurch läuft der Motor nur ganz kurz.
Wenn ich das Arduino starte, wartet er auf eine Eingabe im Serial Monitor, wenn ich diese dann mache,
läuft das Sketch, aber es wartet dann nicht mehr oben beim Serial.available, sondern läuft noch mal durch,
da aber keine Eingabe getätigt wurde ist der Wert dann natürlich null.
Ein delay 1sec. am ende des Sketch brachte keine Verbesserung.
Habe es heraus gefunden, ich muss den Cache der Seriellen Schnittstelle löschen.
Ich habe dann einfach die Schnittstelle beendet und neu geöffnet.
/* Robotic Tutorials
* 14.04.2018
* Tutorial #12 - Gleichstrommotor
*
* Mit diesem Programm könnt ihr über den Serial Monitor eine Zahl zwischen -255 und +255
* eingeben und so die Drehzahl und Drehrichtung des über den L293B-Chip angeschlossenen
* Gleichstrommotor steuern.
*
* Verwendete Verbindungen:
* Arduino - L293B
* DP1 - I3
* DP2 - I4
* DP3 - CE2
*/
// Variablen für die Pins am Arduino
// Der Enable-Pin muss ein PWM-Pin sein
const int enablePin = 3;
const int inputA = 2;
const int inputB = 4;
// Variablen für die serielle Eingabe der Geschwindigkeit
int eingabeSerial = 0;
int eingabeKorrigiert = 0;
// Funktion für die Ansteuerung des Motors
int setMotor(int wert);
void setup() {
Serial.begin(9600); // Beginn der seriellen Kommunikation
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
}
void loop() {
Serial.println("vor serial.available");
while(Serial.available() == 0) {} // Warte auf serielle Eingabe
Serial.println("Nach Serial.avaibale");
eingabeSerial = Serial.parseInt(); // Schreibe serielle Eingabe in Variable (parseInt() lässt nur ganze Zahlen als Eingabe zu)
if( eingabeSerial > 255) { // Korrigiert Eingaben >255 zum Maximalwert 255
eingabeKorrigiert = 255;
}
else if( eingabeSerial < -255) { // Korrigiert Eingaben <-255 zum Minimalwert -255
eingabeKorrigiert = -255;
}
else { // Schreibt korrekte Eingaben in Variable
eingabeKorrigiert = eingabeSerial;
}
setMotor(eingabeKorrigiert); // Schreibt auf die Input-Pins des L293 (s.u.)
Serial.println(eingabeKorrigiert); // zeigt die aktuelle "Drehzahl" im Serial Monitor an
Serial.println("Ende");
}
int setMotor(int wert) {
if(wert == 0) { // Halte den Motor an
digitalWrite(enablePin, LOW);
}
else if(wert > 0) { // Lege Drehrichtung fest, sende "Drehzahl" an den Enable-Pin
digitalWrite(inputA, HIGH);
digitalWrite(inputB, LOW);
analogWrite(enablePin, wert);
}
else {
digitalWrite(inputA, LOW); // wie oben, nur andere Drehrichtung und ändern der eingegebenen
digitalWrite(inputB, HIGH); // "Drehzahl" in einen positiven Wert
analogWrite(enablePin, -wert);
}
Serial.end();
Serial.begin(9600);
}
Schuss ins Blaue:
Du sendest CR+LF als Zeilenende im Terminal und nue eines der Zeichen wird von parseint() 'abgebaut'.
Dadurch kommt der 2.te Durchganz, weil ja 'noch was' in der Warteschlange steht - bei diesem Parsen wird NICHTS vor dem Zeilenende gefunden - was zu Null wird (oder der Rückgabewert wird daraufhin von parseint nicht verändert ... kA) - und Du hast Deine Null, der Motor steht.
neuling321:
Dann wäre das mit der Schnittstelle schliessen und wieder öffnen der richtige weg oder?
nein ,
du solltes alles auslesen , bzw nur dann was machen wenn das Endzeichen erkannt wurde.
ich hab das mal q&d umgebaut (nicht getestet)
Nachtrag Monitor auf "neue Zeile" einstellen
/* Robotic Tutorials
14.04.2018
Tutorial #12 - Gleichstrommotor
Mit diesem Programm könnt ihr über den Serial Monitor eine Zahl zwischen -255 und +255
eingeben und so die Drehzahl und Drehrichtung des über den L293B-Chip angeschlossenen
Gleichstrommotor steuern.
Verwendete Verbindungen:
Arduino - L293B
DP1 - I3
DP2 - I4
DP3 - CE2
*/
// Variablen für die Pins am Arduino
// Der Enable-Pin muss ein PWM-Pin sein
const int enablePin = 3;
const int inputA = 2;
const int inputB = 4;
// Variablen für die serielle Eingabe der Geschwindigkeit
int eingabeSerial = 0;
int eingabeKorrigiert = 0;
// Funktion für die Ansteuerung des Motors
int setMotor(int wert);
void setup() {
Serial.begin(9600); // Beginn der seriellen Kommunikation
pinMode(enablePin, OUTPUT);
pinMode(inputA, OUTPUT);
pinMode(inputB, OUTPUT);
}
void loop() {
while (Serial.available() > 0) {
eingabeSerial = Serial.parseInt(); // Schreibe serielle Eingabe in Variable (parseInt() lässt nur ganze Zahlen als Eingabe zu)
if (Serial.read() == '\n') { // Eingabe abgeschlossen
auswerten();
}
}
} // loop ende
void auswerten() {
if ( eingabeSerial > 255) {
eingabeKorrigiert = 255;
}
else if ( eingabeSerial < -255) {
eingabeKorrigiert = -255;
}
else {
eingabeKorrigiert = eingabeSerial;
}
setMotor(eingabeKorrigiert); // Schreibt auf die Input-Pins des L293 (s.u.)
Serial.println(eingabeKorrigiert); // zeigt die aktuelle "Drehzahl" im Serial Monitor an
}
int setMotor(int wert) {
if (wert == 0) {
digitalWrite(enablePin, LOW);
} // Halte den Motor an
else if (wert > 0) { // Lege Drehrichtung fest, sende "Drehzahl" an den Enable-Pin
digitalWrite(inputA, HIGH);
digitalWrite(inputB, LOW);
analogWrite(enablePin, wert);
}
else {
digitalWrite(inputA, LOW); // wie oben, nur andere Drehrichtung und ändern der eingegebenen
digitalWrite(inputB, HIGH); // "Drehzahl" in einen positiven Wert
analogWrite(enablePin, -wert);
}
}
Der L293B hat keine Schutzdioden am Ausgang. Er schafft 1,2A pro Ausgang. Um diesen zu Benutzen müssen 2 Dioden pro Ausgang dazugeschaltet werden.
Der L293D hat integrierte Schutzdioden. Er schaft nur 0,6A (nehme an daß die Dioden Platz auf dem Siliziumchip brauchen und darum die Ausgangstransistoren kleiner sein müssen bzw die Dioden auch Verlustleistung produzieren und darum weniger Verlustleistung für den Ausgangstransitor bleibt. )