Hallo folgendes Problem ich versuche gerade einen DC-Motor mit einem L293d zufällig anzusteuern. Das der Motor nach einer gewissen zeit zufällig seine Drehzahl ändert habe ich hingekriegt. nun versuche ich die Dreh Richtung zufällig zu ändern. Jemand eine Idee wie sich das umsetzen lässt?
LG Tim
bzw kann ich mir vom einer zufällig generierten Zahlenfolge (0,1) oder (1,0) irgendwie die werte rausnehmen und als high bzw low verwenden?
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.
mfg ein Moderator.
Moin @timb683,
wie das Umschalten der Drehrichtung geht, ist hier zu nachzulesen:
https://starthardware.org/motorsteuerung-mit-einem-h-bridge-ic/
Letztlich ist es nur das Umschalten HIGH/LOW der Motorpins:
digitalWrite(motor1_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
digitalWrite(motor1_B,LOW);
digitalWrite(motor1_A,LOW); // A = LOW and B = HIGH means the motor will turn left
digitalWrite(motor1_B,HIGH);
Da für LOW der Wert 0 und für HIGH ein Wert ungleich 0 verwendet werden, kannst Du diese Werte durch 0 bzw. 1 ersetzen:
byte stateA = HIGH; // entspricht stateA = 1;
byte stateB = LOW; // entspricht stateB = 0;
digitalWrite(motor1_A, stateA);
digitalWrite(motor1_B, stateB;
stateA = 0;
stateB = 1;
digitalWrite(motor1_A, stateA);
digitalWrite(motor1_B, stateB;
Falls Du Probleme mit der Umsetzung hast, bitte Deinen Code (in code-Tags!) posten ...
Gruß
ec2021
danke sehr das hilft mir schon weiter.
Weist du zufällig wie ich werte einer zahlenfolge in einzelne variablen packe das ich diese nutzen kann?
Bin dabei ein kleines Beispiel zu schreiben ...
Folgt hier (sobald fertig
):
/*
Forum: https://forum.arduino.cc/t/dc-motor-mit-l293d-zufallig-ansteuern/1210964/6
Wokwi: https://wokwi.com/projects/386922640522676225
*/
const byte motorA = 12;
const byte motorB = 8;
unsigned long zuletzt = 0;
byte stateA = 0;
void setup() {
Serial.begin(115200);
pinMode(motorA, OUTPUT);
pinMode(motorB, OUTPUT);
controlMotor(stateA,stateA);
randomSeed(millis());
}
void loop() {
if (millis()-zuletzt >= 2000){
zuletzt = millis();
stateA = random(2);
Serial.println(stateA);
controlMotor(stateA,!stateA);
}
}
void controlMotor(byte A, byte B){
digitalWrite(motorA, A);
digitalWrite(motorB, B);
}
Zum Ausprobieren auf Wokwi: https://wokwi.com/projects/386922640522676225
Bei "random(2)" wird 0 automatisch als unterer Wert und 1 als oberer Wert ausgegeben (die Zahl in der Klammer ist exklusiv ).
Wie @jremington gepostet hat, kann man statt "random(2)" auch
"random(untererWert, ObererWertPlusEins)" schreiben. Das ist dann interessant, wenn der Wertebereich eben nicht bei Null anfangen soll.
Das Beispiel auf Wokwi ist natürlich keine vollwertige Motorsteuerung, sollte aber genügen, das Prinzip aufzuzeigen.
Siehe dazu auch hier: https://www.arduino.cc/reference/de/language/functions/random-numbers/random/
Top
int dir = random(0,2); // liefert 0 oder 1
Danke sehr ich probiere es direkt aus.
Man sollte evtl. beim Richtungswechsel eine kleine Pause einbauen...
Und statt
random(2); // 0 oder 1
eine Zufallszahl ermitteln lassen, die angibt, wie lange der Motor in eine Richtung laufen soll.
Dann ist man nicht auf ganze Vielfache von 2000 ms festgelegt.
Ich habe das jetzt mal aus probiert. mein problem ist das der motor über einen controller (L293d) angesteuert wird. wenn ich im code das digital write für den pin der low sein soll weg lasse liegt da immer noch 5v an da ich eine um schaltung habe für modus 1 (feste geschwindkeit und drehrichtung) und einen 2. modus für zufällige drehrichtung und geschwindkeit.
ich habe mal den code mit rein kopiert vllcht kann mir ja jemand helfen.
int rueckwaerts = 8;
int vorwaerts = 7;
int schalternormal = 6;
int schalterzufall = 5;
int pwmsignalmotor = 3;
int normal;
int zufall;
long randomdrehzahl;
long randomrichtung;
void setup() {
pinMode (pwmsignalmotor, OUTPUT);
pinMode (vorwaerts, OUTPUT);
pinMode (rueckwaerts, OUTPUT);
pinMode (schalternormal , INPUT);
pinMode (schalterzufall, INPUT);
randomSeed(analogRead(0));
}
void loop() {
randomdrehzahl = random(60, 255);
randomrichtung = random(1, 2);
normal = digitalRead (schalternormal);
zufall = digitalRead (schalterzufall);
if (normal ==1)
{
digitalWrite(rueckwaerts, 0);
digitalWrite(vorwaerts, 1);
analogWrite (pwmsignalmotor, 60);
}
if (zufall ==1)
{
digitalWrite(vorwaerts, 0);
digitalWrite(rueckwaerts, 1);
analogWrite (pwmsignalmotor, randomdrehzahl);
delay(2000);
}
}
Na da sind mehrere "Haken" in Deinem Sketch:
- Du verwendest "pinmode(...,INPUT);" anstelle von "pinMode(...,INPUT_PULLUP);" Sind Deine Schalter mit externen Pullup-Widerständen ausgestattet?
- Du vertraust darauf, dass Deine Schalter nicht prellen (zumindest der "normal"-Schalter, der zufall-Schalter wird über delay() ausgebremst).
- Du verwendest delay(2000) anstatt einer millis()-Funktion; das begrenzt die Reaktionszeit Deines Sketches im Fall "zufall == 1".
- Du veränderst die randomdrehzahl extrem häufig in der loop(); ist das gewollt?
- randomrichtung wird falsch gesetzt und dann aber auch nirgends verwendet. ( random(1, 2) ergibt immer nur 1, da es der unterste Wert ist und 2 nie erreicht werden kann.)
Dies ist noch nicht optimal, sollte aber schon mal funktionieren ... ![]()
/*
Forum: https://forum.arduino.cc/t/dc-motor-mit-l293d-zufallig-ansteuern/1210964/6
Wokwi: https://wokwi.com/projects/387026261224121345
*/
const int rueckwaertsPin = 8;
const int vorwaertsPin = 7;
const int schalternormalPin = 6;
const int schalterzufallPin = 5;
const int pwmsignalmotorPin = 3;
int normal;
int zufall;
long randomdrehzahl;
long randomrichtung;
void setup() {
pinMode (pwmsignalmotorPin, OUTPUT);
pinMode (vorwaertsPin, OUTPUT);
pinMode (rueckwaertsPin, OUTPUT);
pinMode (schalternormalPin, INPUT_PULLUP);
pinMode (schalterzufallPin, INPUT_PULLUP);
randomSeed(analogRead(0));
}
void loop() {
randomdrehzahl = random(60, 255);
randomrichtung = random(0, 2); // ergibt 0 oder 1 !!!!! Die 2 wird nicht erreicht!!
normal = digitalRead (schalternormalPin);
zufall = digitalRead (schalterzufallPin);
if (normal == 1)
{
setMotor(true,60);
delay(20); // Poor man's debouncing ...
}
if (zufall == 1 || !normal)
{
setMotor(randomrichtung,randomdrehzahl);
delay(2000);
}
}
void setMotor(boolean Vorwaerts, int tempo) {
if (Vorwaerts) {
digitalWrite(rueckwaertsPin, 0);
digitalWrite(vorwaertsPin, 1);
} else {
digitalWrite(rueckwaertsPin, 1);
digitalWrite(vorwaertsPin, 0);
}
analogWrite (pwmsignalmotorPin, 60);
}
Zum Testen https://wokwi.com/projects/387026261224121345
Ist tatsächlich nur ein erster "Wurf" nahe dran an Deinem Code...
Moin ich habe meine Schalter mit 10k Ohm wiederständen ausgestattet (U=9V)
Was bedeutet das die Schalter Prellen?
Momentan verändert sich der Zufall alle 2 sec das ist aber nur zum testen später soll das alle 10 oder 15 Sekunden passieren
Danke für die verbesserte Version.
Also wenn du die Pins des Mikrocontroller‘s auf 9V ziehst, tut ihm das nicht gut. Die Pins sollten nicht mit mehr als VCC belastet werden.
super es funktioniert.
jetzt noch eine frage.
mein kipp schalter hat 3 stellungen: 0,1,2
Bei Null soll garnichts passieren. bei 1 Normal. bei 2 der zufall.
wenn er bei null stehen soll könnte ich doch einfach hinter die ifs jeweils ein else hinzufügen in welchem steht:
else
{
setMotor(false,0);
}
oder?
Ich schrieb oben ja schon "erster Wurf, nah an Deinem Code" ...
(Unter uns: Das war die Umschreibung für: Der Code ist noch sehr verbesserungswürdig ...
.)
Ich habe ihn nah an Deinem Sketch belassen, a) aus Zeitgründen und b) damit Du die Änderungen besser nachvollziehen kannst.
Hier mal ein Code, der das tun sollte, was Du beschreibst, aber nicht gerade "gut" ist:
/*
Forum: https://forum.arduino.cc/t/dc-motor-mit-l293d-zufallig-ansteuern/1210964/6
Wokwi: https://wokwi.com/projects/387096253175049217
*/
const int rueckwaertsPin = 12;
const int vorwaertsPin = 8;
const int schalternormalPin = 6;
const int schalterzufallPin = 5;
const int pwmsignalmotorPin = 3;
int normal;
int zufall;
long randomdrehzahl;
long randomrichtung;
void setup() {
pinMode (pwmsignalmotorPin, OUTPUT);
pinMode (vorwaertsPin, OUTPUT);
pinMode (rueckwaertsPin, OUTPUT);
pinMode (schalternormalPin, INPUT_PULLUP);
pinMode (schalterzufallPin, INPUT_PULLUP);
randomSeed(analogRead(0));
}
void loop() {
randomdrehzahl = random(60, 255);
randomrichtung = random(0, 2); // ergibt 0 oder 1 !!!!! Die 2 wird nicht erreicht!!
normal = digitalRead (schalternormalPin);
zufall = digitalRead (schalterzufallPin);
if (normal == 1)
{
setMotor(true,60);
delay(20); // Poor man's debouncing ...
} else {
if (zufall == 1)
{
setMotor(randomrichtung,randomdrehzahl);
delay(500);
} else {
digitalWrite(rueckwaertsPin, 0);
digitalWrite(vorwaertsPin, 0);
}
}
}
void setMotor(boolean Vorwaerts, int tempo) {
if (Vorwaerts) {
digitalWrite(rueckwaertsPin, 0);
digitalWrite(vorwaertsPin, 1);
} else {
digitalWrite(rueckwaertsPin, 1);
digitalWrite(vorwaertsPin, 0);
}
analogWrite (pwmsignalmotorPin, 60);
}
Siehe https://wokwi.com/projects/387096253175049217
Für eine solche Aufgabe, wie diese hier, bietet sich eine kleine Zustandsmaschine (state machine) an. Dabei teilt man die gewünschten Funktionen auf und schreibt sie als separate Anteile, die je nach Zustand der Maschine durchlaufen oder eben nicht durchlaufen werden. Das verbessert sowohl die Übersicht als auch die Erweiterbarkeit des Programms und verringert die Notwendigkeit sich u.U. in verschachtelte if/else Geschichten hineindenken zu müssen ...
Du musst beispielsweise die Richtung und die Geschwindigkeit nicht jedesmal in der loop() neu setzen, es genügt das einmal zu tun und dann auf den Zustand des Schalters zu reagieren.
Hier mal eine schnelle Lösung (die sicher auch noch verbessert werden kann):
/*
Forum: https://forum.arduino.cc/t/dc-motor-mit-l293d-zufallig-ansteuern/1210964/6
Wokwi: https://wokwi.com/projects/387097065989298177
*/
const int rueckwaertsPin = 12;
const int vorwaertsPin = 8;
const int schalternormalPin = 6;
const int schalterzufallPin = 5;
const int pwmsignalmotorPin = 3;
struct buttonType {
byte pin;
byte state = LOW;
byte lastState = LOW;
unsigned long lastChange = 0;
void init(byte aPin) {
pin = aPin;
pinMode(pin, INPUT_PULLUP);
}
boolean isHigh() {
byte actState = digitalRead(pin);
if (actState != lastState) {
lastChange = millis();
lastState = actState;
}
if (actState != state && millis() - lastChange > 20) {
state = actState;
}
return state;
}
};
buttonType normal, zufall;
enum stateType {START, ZUFALL, WARTEN};
stateType state = START;
int drehzahl;
int richtung;
unsigned long zufallsDauer = 2000;
void setup() {
Serial.begin(115200);
pinMode (pwmsignalmotorPin, OUTPUT);
pinMode (vorwaertsPin, OUTPUT);
pinMode (rueckwaertsPin, OUTPUT);
normal.init(schalternormalPin);
zufall.init(schalterzufallPin);
randomSeed(analogRead(0));
}
void loop() {
stateMachine();
}
void stateMachine() {
static unsigned long startTime = 0;
switch (state) {
case START:
if (normal.isHigh()) {
setMotor(true, 60);
state = WARTEN;
Serial.println("WARTEN");
} else {
if (zufall.isHigh()) {
Serial.println("ZUFALL");
state = ZUFALL;
} else {
setMotor(true, 0);
}
};
break;
case ZUFALL:
if (millis() - startTime >= zufallsDauer) {
startTime = millis();
drehzahl = random(60, 255);
richtung = random(0, 2); // ergibt 0 oder 1 !!!!! Die 2 wird nicht erreicht!!
zufallsDauer = random(1,6)*1000UL;
setMotor(richtung, drehzahl);
Serial.print("Zufallsdauer: ");
Serial.println(zufallsDauer);
}
if (!zufall.isHigh()) {
setMotor(true,0);
state = START;
Serial.println("ZUFALL to START");
}
break;
case WARTEN:
if (!normal.isHigh()) {
Serial.println("WARTEN to START");
state = START;
}
break;
}
}
void setMotor(boolean Vorwaerts, int tempo) {
if (tempo == 0) {
digitalWrite(rueckwaertsPin, 0);
digitalWrite(vorwaertsPin, 0);
analogWrite (pwmsignalmotorPin, 0);
return;
}
if (Vorwaerts) {
digitalWrite(rueckwaertsPin, 0);
digitalWrite(vorwaertsPin, 1);
} else {
digitalWrite(rueckwaertsPin, 1);
digitalWrite(vorwaertsPin, 0);
}
analogWrite (pwmsignalmotorPin, tempo);
}
Zum Ausprobieren: https://wokwi.com/projects/387097065989298177
Viel Spaß!
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.