Hallo an das Forum,
Ich benötige Hilfe bei meinem Projekt. Unzwar möchte ich meinen 5V Schrittmotor über eine App sich vorwärts und rückwärts drehen lassen. Das vorwärts drehen hat glücklicherweise geklappt. Jetzt habe ich versucht den sketch so zu erweitern, dass bei Empfang einer 2 über ein HC-05 BT-Modul sich der Schrittmotor entgegen dem Uhrzeigersinn dreht. Leider dreht sich jetzt gar nichts mehr. Kann mir jemand sagen wo der Fehler in meiner Logik ist? Hab schon Verschiedenes probiert leider ohne Erfolg. Motortreiber: ULN2003; Board: Arduino UNO
#include <SoftwareSerial.h>
#include <Stepper.h>
// Definieren der Pins für die Verbindung zum Bluetooth-Modul
#define BT_RX_PIN 1
#define BT_TX_PIN 0
// Definiere die Anschlüsse des Schrittmotors
#define IN1 8
#define IN2 10
#define IN3 9
#define IN4 11
// Erstellen eines SoftwareSerial-Objekts für die Kommunikation mit dem Bluetooth-Modul
SoftwareSerial bluetooth(BT_RX_PIN, BT_TX_PIN);
// Konfiguriere den Schrittmotor
const uint16_t stepsPerRevolution = 2048;
Stepper myStepper(stepsPerRevolution, IN1, IN2, IN3, IN4);
bool motorOn = false;
char command;
void setup() {
// Öffnen der seriellen Verbindung für die Kommunikation mit dem Computer
Serial.begin(9600);
// Öffnen der seriellen Verbindung für die Kommunikation mit dem Bluetooth-Modul
bluetooth.begin(9600);
// Setze die Geschwindigkeit des Schrittmotors in Umdrehungen pro Minute (UPM)
myStepper.setSpeed(1); // Experimentiere mit verschiedenen Werten für die Geschwindigkeit
myStepper.step(0);
// Warten, bis das Bluetooth-Modul initialisiert ist
delay(1000);
}
void loop() {
// Überprüfen, ob Daten von der seriellen Verbindung des Computers empfangen wurden
if (Serial.available()) {
// Lesen der empfangenen Daten von der seriellen Schnittstelle des Computers
char dataToSend = Serial.read();
Serial.println(dataToSend);
// Senden der Daten an das Bluetooth-Modul
bluetooth.write(dataToSend);
}
if (bluetooth.available()) {
// Lesen der empfangenen Daten vom Bluetooth-Modul
char command = bluetooth.read();
// Wenn der Befehl '1' ist, schalte den Motor ein
if (command == '1') {
if (motorOn == false) { // wenn Motor noch nicht läuft
motorOn = true; // Motor soll laufen
}
}
// Wenn der Befehl '0' ist, schalte den Motor aus
else if (command == '0') {
// Setze den Motor auf Ruhezustand
motorOn = false;
delay(5); // Warte für 5 Milli Sekunden
}
// Wenn der Befehl '2' ist, schalte den Motor ein (Rückwärts)
else if (command == '2') {
// Motor soll laufen
motorOn = true;
delay(5); // Warte für 5 Milli Sekunden
}
if (motorOn == true && command == '1') {
// wenn der Motor laufen soll
myStepper.step(stepsPerRevolution / 1024);
}
// -> motor dreht ca. 1.8° / loop Durchgang, so kann er jederzeit gestoppt werdem
else if (motorOn == true && command == '2') {
myStepper.setSpeed(-1);
myStepper.step(stepsPerRevolution / 1024);
}
}
}
Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.
Als Erklärung, warum sich gar nichts mehr drehte, kann ich die folgendes sagen, damit Du lernen kannst. Ich habe, da der Motor immer mit der selben geschwindigkeit drehen soll, die Anweisung 'myStepper.setSpeed()' nur einmal im setup() festgelegt. mit myStepper.setSpeed(-1) bei der Auswertung, wo Du das Empfangen des Befehls '2' abhandelst, schaltest Du die geschwindigkeit des Steppers auf 0, da die stepper-lib einen negativen Wert beim speed als speed = 0 errechnet. Und weil die Funktion myStepper.setSpeed() den übergebenen Wert speichert, bleibt das solange erhalten, bis myStepper.setSpeed() erneut aufgerufen wird. Es hat sich also deshalb nichts mehr gedreht, weil Du die geschwindigkeit in dem Moment wo Du das erste Mal '2' gesendet hast, auf 0 gesetzt hast. @Microbahner hat Dir ja jetzt schon gezeigt, wie du den Motor rückwärts laufen lassen kannst. Ich wollte Dir nur erklären , warum es so, wie Du es probiert hast, nicht funktioniert.
Ich hab es probiert. Leider klappt es immer noch nicht.
#include <SoftwareSerial.h>
#include <Stepper.h>
// Definieren der Pins für die Verbindung zum Bluetooth-Modul
#define BT_RX_PIN 1
#define BT_TX_PIN 0
// Definiere die Anschlüsse des Schrittmotors
#define IN1 8
#define IN2 10
#define IN3 9
#define IN4 11
// Erstellen eines SoftwareSerial-Objekts für die Kommunikation mit dem Bluetooth-Modul
SoftwareSerial bluetooth(BT_RX_PIN, BT_TX_PIN);
// Konfiguriere den Schrittmotor
uint16_t stepsPerRevolution = 2048;
Stepper myStepper(stepsPerRevolution, IN1, IN2, IN3, IN4);
bool motorOn = false;
char command;
void setup() {
// Öffnen der seriellen Verbindung für die Kommunikation mit dem Computer
Serial.begin(9600);
// Öffnen der seriellen Verbindung für die Kommunikation mit dem Bluetooth-Modul
bluetooth.begin(9600);
// Setze die Geschwindigkeit des Schrittmotors in Umdrehungen pro Minute (UPM)
myStepper.setSpeed(1); // Experimentiere mit verschiedenen Werten für die Geschwindigkeit
myStepper.step(0);
// Warten, bis das Bluetooth-Modul initialisiert ist
delay(1000);
}
void loop() {
// Überprüfen, ob Daten von der seriellen Verbindung des Computers empfangen wurden
if (Serial.available()) {
// Lesen der empfangenen Daten von der seriellen Schnittstelle des Computers
char dataToSend = Serial.read();
Serial.println(dataToSend);
// Senden der Daten an das Bluetooth-Modul
bluetooth.write(dataToSend);
}
if (bluetooth.available()) {
// Lesen der empfangenen Daten vom Bluetooth-Modul
char command = bluetooth.read();
// Wenn der Befehl '1' ist, schalte den Motor ein
if (command == '1') {
if (motorOn == false) { // wenn Motor noch nicht läuft
motorOn = true; // Motor soll laufen
}
}
// Wenn der Befehl '0' ist, schalte den Motor aus
else if (command == '0') {
// Setze den Motor auf Ruhezustand
motorOn = false;
delay(5); // Warte für 5 Milli Sekunden
}
// Wenn der Befehl '2' ist, schalte den Motor ein (Rückwärts)
else if (command == '2') {
// Motor soll laufen
motorOn = true;
delay(5); // Warte für 5 Milli Sekunden
}
if (motorOn == true && command == '1') {
// wenn der Motor laufen soll
myStepper.step(stepsPerRevolution / 1024);
}
// -> motor dreht ca. 1.8° / loop Durchgang, so kann er jederzeit gestoppt werdem
else if (motorOn == true && command == '2') {
myStepper.step(-stepsPerRevolution / 1024);
}
}
}
Wie hast Du den Motor angeschlossen? Hast Du die mittleren Drähte noch gekreuzt? Dann geht es nicht, weil die jetzt im Sketch vertauscht sind. 2x gekreuzt = wieder ungekreuzt.
Also der Schrittmotor lief jetzt wieder. Die ganze Zeit jedoch gegen den Uhrzeigersinn. Jetzt habe ich die mittleren Drähte vertauscht jetzt dreht er sich die ganze Zeit im Uhrzeigersinn. Egal ob ich den Button für Vorwärts oder Rückwärts drücke es ist immer ein und dieselbe Richtung.
So Philipp, hab es Dir angepasst, so läüft jetzt der Motor vorwärts, wenn Du '1' sendest und rückwärts, wenn Du '2' sendest, und stoppt, wenn Du '0' sendest. hab Dir wieder im Sketch kommentiert, wie ich es gelöst habe.
```cpp
// Mit diesem Sketch macht der Motor nach dem senden von '1' eine Umdrehung (360°) und stoppt dann.
// ebenso wird der Motor gestoppt, wenn Du '0' sendest.
// wenn Du wieder '1' sendest, startet der motor eine neue volle Umdrehung.
// wichtig bei dieser art der Steuerung ist, dass Du mit Ausnahme des des kurzen delay(5) beim auswerten der '0'
// keine weiteren Delays in loop() hast, sonst dreht der motor nicht sauber, sondern stottert.
#include <SoftwareSerial.h>
#include <Stepper.h>
// Definieren der Pins für die Verbindung zum Bluetooth-Modul
// Hier habe ich dier die PINs für das Bluetooth Modul angepasst, du musst
// natürlich auch dein Modul an diese Pins anschliessen.
#define BT_RX_PIN 3
#define BT_TX_PIN 2
// Definiere die Anschlüsse des Schrittmotors
// hier musste ich die zuweisungen ändern. sonst hat der Motor keine Kraft.
// sollte jetzt Dein motor falsch herum drehen, dann wähle folgende Reihenfolge:
// IN1 auf 11 , IN2 auf 9 , IN3 auf 10 , IN4 auf 8
#define IN1 8
#define IN2 10
#define IN3 9
#define IN4 11
// Erstellen eines SoftwareSerial-Objekts für die Kommunikation mit dem Bluetooth-Modul
SoftwareSerial bluetooth(BT_RX_PIN, BT_TX_PIN);
// Konfiguriere den Schrittmotor
const uint16_t stepsPerRevolution = 2048; // Schritte pro Umdrehung des Motors
Stepper myStepper(stepsPerRevolution, IN1, IN2, IN3, IN4);
int8_t motorOn = 0; // Merker, dass der Motor laufen muss
void setup() {
// Öffnen der seriellen Verbindung für die Kommunikation mit dem Computer
Serial.begin(9600);
// Öffnen der seriellen Verbindung für die Kommunikation mit dem Bluetooth-Modul
bluetooth.begin(9600);
// Setze die Geschwindigkeit des Schrittmotors in Umdrehungen pro Minute (UPM)
myStepper.setSpeed(12); // Experimentiere mit verschiedenen Werten für die Geschwindigkeit
// Hier war Dein Fehler, dass der Wert von 30 zu hoch ist für Deinen Motor,
// da kann er nicht mehr anlaufen und bleibt einfach stehen
// 12 ist das maximum dass dieser motor bei 5 Volt zum anlaufen schafft ohne schritte
// zu verlieren., bei dieser Art der steuerung
myStepper.step(0);
// Warten, bis das Bluetooth-Modul initialisiert ist
delay(1000);
}
void loop() {
// Überprüfen, ob Daten von der seriellen Verbindung des Computers empfangen wurden
if (Serial.available()) {
// Lesen der empfangenen Daten von der seriellen Schnittstelle des Computers
char dataToSend = Serial.read();
Serial.println(dataToSend);
// Senden der Daten an das Bluetooth-Modul
bluetooth.write(dataToSend);
}
// Überprüfen, ob Daten vom Bluetooth-Modul empfangen wurden
if (bluetooth.available()) {
// Lesen der empfangenen Daten vom Bluetooth-Modul
char command = bluetooth.read(); //bluetooth
// Wenn der Befehl '1' ist, schalte den Motor ein
if (command == '1') {
motorOn = 1; // Motor soll im Uhrzeigersinn laufen
}
else if (command == '2') {
motorOn = -1; // Motor soll im Gegen-Uhrzeigersinn laufen
}
// Wenn der Befehl '0' ist, schalte den Motor aus
else if (command == '0') {
// Setze den Motor auf Ruhezustand
motorOn = 0; // Motor Stopp
delay(5); // Warte für 5 Milli Sekunden
}
}
if (motorOn != 0) { // wenn der Motor laufen soll
myStepper.step(motorOn * (stepsPerRevolution / 1024)); // -> motor dreht ca. 1.8° / loop Durchgang, so kann er jederzeit gestoppt werdem
// durch die Multiplikation von (stepsPerRevolution / 1024) mit motorOn werden die Schritte entweder
// Positiv (wenn motorOn 1 ist) oder negativ (wenn MotorOn -1) ist, so wird die Drehrichtung festgelegt.
}
}
Vielen Dank für die Hilfe. Jetzt funktioniert alles wie es soll. Das mit der Berechnung in welche Richtung sich der Motor bewegt war eine echt gute Idee. Was war genau der Fehler bei meinem sketch? Und dann wollte ich noch wissen ob das ganze Projekt auch genauso mit einem Arduino Nano funktioniert? Ich will den Aufbau noch verkleinern.
Also, der eigentliche fehler war, dass Du zum rückwärts Drehen in jedem Loopdurchgang als Entscheudungs-kriterium ob rückwärts gedreht werden muss, die Variable command herangezogen hast. diese Variable wird aber in jedem loop Durchgang neu befüllt mit dem Wert der vom Bluetooth modul kommt. Ich bin mir nicht ganz sicher, ob sich der Wert auch ändert, wenn nichts gesendet wurde, das müsste ich noch ausprobieren. jedenfalls hat command nicht lange genug den wert '2' um für in mehreren loopdurchgängen benutzt werden zu können. Darum speichere ich die gewünschte Drehrichtung in der Variable motorOn (zuvaor hab ich die nur benutzt, um zu speichern, ob der Motor drehen oder stehen soll. darum reichte da auch ein bool) jetzt speichere ich in dieser Variable auch noch die info, in welche Richtung gedreht werden soll, darum habe ich den Variablen-Typ iin ein int8_t geändert. Die int8_t Variable benotigt gleichviel Speicherplatz wie eine bool Variable, kann jedoch auch negative Werte aufnehmen. Somit konnte ich alle 3 zustände, also vorwärts , rückwärts und Stopp in einer einzigen Variablen unterbringen und diese auch zur berechnung dr zu fahrenden Schritte nutzen, da sich die Variable ausschliesslich dann ändert, wenn wirklich ein neues Komando vom HC05 angekommen ist.
Ja , du kannst den Sketch unverändert auch auf dem Nano laufen lassen, da gleicher Prozessor, und die Pins ausreichend identisch sind.