Hallo zusammen,
ich sitze seit fast zwei Stunden hier und finde den Fehler nicht,
weshalb ich nun die letzte Instanz (nämlich dieses Forum) gewählt habe,
um meinen Fehler zu finden.
Es geht darum, zwei DC-Motoren anzusteuern (H-Brücke), das Ganze
funktioniert auch hardcodiert einwandfrei, wenn ich meinen Arduino Nano
flashe, und mittels H-Brücke die angeschlossenen Motoren ansteuere.
Siehe Code:
Serial.begin(BAUDRATE);// Baudrate für Terminalprogramm
28
pinMode(STATUS_LED,OUTPUT);// Status-LED am Arduino Nano initialisieren (dig. Ausgang)
29
30
pinMode(PIN_CLOCKWISE_DIR[0],OUTPUT);// setzt entsprechende Pins des Arduinos auf "Ausgang"...
31
pinMode(PIN_COUNTERCLOCKWISE_DIR[0],OUTPUT);
32
pinMode(PWM_SIGNALS[0],OUTPUT);
33
pinMode(PIN_CLOCKWISE_DIR[1],OUTPUT);
34
pinMode(PIN_COUNTERCLOCKWISE_DIR[1],OUTPUT);
35
pinMode(PWM_SIGNALS[1],OUTPUT);
36
37
digitalWrite(PIN_CLOCKWISE_DIR[0],LOW);// setzt sämtliche Drehrichtungs-Zustände auf "Low"...
38
digitalWrite(PIN_COUNTERCLOCKWISE_DIR[0],LOW);
39
digitalWrite(PIN_CLOCKWISE_DIR[1],LOW);
40
digitalWrite(PIN_COUNTERCLOCKWISE_DIR[1],LOW);
41
42
43
}
44
45
46
voidloop()
47
{
48
/* Derzeit auskommentiert, hier funktioniert alles einwandfrei!
49
motorGo(0,CLOCKWISE,128);
50
motorGo(1,CLOCKWISE,128);
51
delay(5000);
52
*/
53
54
if(get_X_from_Joystick()<=518)// wenn eingelesene X-Achse vom Joystick nach "links" geht,....
55
{
56
57
motorOff(1);// ...stoppe linken Motor....
58
59
unsignedinty=518-get_X_from_Joystick();
60
unsignedintpwm_signal=y/4;
61
Serial.println(y);
62
motorGo(0,CLOCKWISE,pwm_signal);// ...stelle Drehzahl des rechten Motors entsprechend der Position des Potis
63
Serial.println("PWM: ");
64
Serial.println(pwm_signal);
65
66
if(get_Y_from_Joystick()>=526)// Wenn gleichzeitig beim nach "links" drücken des Joysticks der Joystick nach "vorne" geschoben wird....
67
{
68
motorGo(1,COUNTERCLOCKWISE,(get_X_from_Joystick()/4));// ...schalte zusätzlich den linken Motor entsprechend der Y-Position des Joysticks
69
}
70
}
71
}
Die beiden Motoren werden über einen Joystick gesteuert. Schiebe ich den
Joystick ganz nach links, erhalte ich einen ADC-Wert von annähernd 0.
Schiebe ich den Joystick ganz nach rechts, erhalte ich entsprechend
einen ADC-Wert von annähernd 1023. In der Mittelstellung
("Leerlaufposition" des Joysticks) erhält man demnach einen Wert von
ungefähr 528.
Die Werte stimmen auch via Terminalausgabe korrekt überein, die mir der
Arduino auch wunderbar ausgibt ("Serial.println()"), allerdings
übernimmt der Arduino irgendwie nicht die Werte, die er vom ADC
(Joystick) eingelesen hat, wenn er die Funktion "motorGo(...)" aufruft.
Kodiere ich (wie ganz am Anfang der loop()-Funktion) einen festen
PWM-Wert, wird auch alles korrekt angesteuert (derzeit auskommentiert).
Warum aber steuert der Arduino denn nicht mittels "motorGo(...);" den
Motor entsprechend an, wenn ich den Joystick bewege?
Das Ganze funktioniert wiegesagt einwandfrei, solange man den PWM-Wert
"hardkodiert" der Funktion als Argument übergibt.
Hier der Code der Funktion motorGo():
Das Terminal gibt auch die richtigen PWM-Werte aus, die ich der Funktion
übergebe. Warum aber steuert der Arduino kein PWM-Signal an die H-Brücke
aus, in Abhängigkeit von der Joystick-Bewegung "nach links"?
"motorOff(...)" schaltet einfach den jeweiligen Motor aus.
Ich hoffe, ich konnte mich entsprechend ausdrücken.
Bei Fragen stehe ich jederzeit zur Verfügung.
Das Projekt betrifft den "motorisierten Kinderwagen", deshalb zwei
Motoren zum Lenken, die über einen Joystick gesteuert werden sollen.
Vielen Dank schon mal!
Grüße
erst fragst du ab, ob der Wert kleiner oder gleich 518 ist, um das eine
zu tun, und später dann, ob er größer als 526 ist. Das kann aber nie
wahr sein, da er die Abfrage nur erreicht, wenn der Wert kleiner als 518
ist.
Du musst die beiden Abfragen entkoppeln, also nacheinander ausführen.
>Du musst die beiden Abfragen entkoppeln, also nacheinander ausführen.
Das verstehe ich nicht ganz, denn wenn er an die Codestelle nicht
hinkäme, warum führt er den darüber/darunterliegenden Befehl mit
"Serial.println(..);" aus und nicht den motorGo() ?
Joh schrieb:> unsigned int y = 518 - get_X_from_Joystick();Joh schrieb:> allerdings übernimmt der Arduino irgendwie nicht die Werte, die er vom ADC> (Joystick) eingelesen hat, wenn er die Funktion "motorGo(...)" aufruft.
Was heißt "übernimmt der Ardnuino nicht". Der ist doch nicht plötzlich
schreibgeschützt ;-)
Allerdings können bei denem Programm Joystickpositionen über 518 nicht
richtig funbktionieren. 0 ist die kleinste Zahl, die in dein y
reinpasst.
STK500-Besitzer schrieb:> erst fragst du ab, ob der Wert kleiner oder gleich 518 ist, um das eine> zu tun, und später dann, ob er größer als 526 ist. Das kann aber nie
1. get_X_from_Joystick()
2. get_Y_from_Joystick()
warum sollte das "nie erreicht werden"? es sind 2 verschiedene Werte,
warum auch immer... (ich hätte auch angenommen, dass der Joystick nur
auf einer Achse benutzt wird)
>(ich hätte auch angenommen, dass der Joystick nur>auf einer Achse benutzt wird)
Nein, denn ich möchte damit ja "vorwärts"/"rückwärts" und gleichzeitig
"links/"rechts" steuern.
Auf der Y-Achse verhält sich der Wertebereich übrigens im selbigen.
Kann es sein, dass du da x und y durcheinandergebracht hast?
Außerdem solltest du mal genau die Werte ausgeben, die du mit if
überprüfst und an motorGo übergibst.
>Kann es sein, dass du da x und y durcheinandergebracht hast?>Außerdem solltest du mal genau die Werte ausgeben, die du mit if>überprüfst und an motorGo übergibst.>Serial.println(whatever);>if( whatever >= 526 )>{> unsigned int motorValue=get_X_from_Joystick() / 4;> Serial.println(motorValue);> motorGo(1,COUNTERCLOCKWISE,motorValue);>}
Ich überprüfe ja die Werte per Terminal. Terminal liefert die korrekten
Werte, während ich den Joystick bewege, der Arduino "schickt" aber
leider nicht das entsprechende Tastverhältnis an die H-Brücke.
Die unterste If-Anweisung kann übrigens bzgl. "Logik" vernachlässigt
werden.
Das Entscheidende liegt in der motorGo() in der if-Anweisung zwischen
den beiden Serial.println().
Grüße und danke für eure rege Hilfe.
nimm das motoroff() aus der schleife raus. Du rechnest rum, setzt in
Motorgo() den motor, und nach dem return aus der Funktion wird beim
nächsten Schleifendurchlauf der Motor sofort wieder ausgeschaltet.
Ausserdem : Im auskommentierten Text schaltest du Motor 0 und 1 ein, im
jetzigen Programm geht aber alles auf Motor 1. Ist evtl. der Motor an
den falschen Anschlüssen?
>nimm das motoroff() aus der schleife raus.
motoroff() schaltet den Motor-1 ab. Motor-1 befindet sich auf der linken
Seite, Motor-0 auf der Rechten.
Möchte ich also nach links fahren (Joystick nach ganz links, während
Y-Achse des Joysticks==0), schaltet/blockiert der Motor-1 und es dreht
nur Motor-0.
Das ist von Nöten, damit nur der Rechte dreht, sodass man damit
"elektrisch lenkend" um die Kurve kommt (Heckantrieb).
>und nach dem return aus der Funktion wird beim>nächsten Schleifendurchlauf der Motor sofort wieder ausgeschaltet
Das return liefert nur einen Wert, der dem der Achse entsprechenden
Wertes entspricht.
Mehr macht diese Funktion ja nicht, als das Poti des Joysticks über den
ADC einzulesen um dann diesen Wert "gewandelt" als PWM-Wert
(Tastverhältnis) zu übergeben.
>Im auskommentierten Text schaltest du Motor 0 und 1 ein, im>jetzigen Programm geht aber alles auf Motor 1.
Dann sollte sich aber doch wenigstens einer der beiden angeschlossenen
Motoren bewegen, die das ja auch tun, wenn ich die ersten Zeilen der
loop() in den Code nehme. ;-)
Verdrahtungsfehler kann ich somit ausschließen, und es soll ja
tatsächlich nur der eine Motor drehen, während der andere blockiert (a
la Panzer-Lenkungsprizip).
Grüße
Joh schrieb:> Ich überprüfe ja die Werte per Terminal. Terminal liefert die korrekten> Werte, während ich den Joystick bewege, der Arduino "schickt" aber> leider nicht das entsprechende Tastverhältnis an die H-Brücke.
Jetzt mal Butter bei die Fische:
Angenommen dein Joystick liefert einen hohen Wert (bspw. 900), welchen
Wert besitzt dann pwm in motorGo() und welchen Wert erwartest du?
>Angenommen dein Joystick liefert einen hohen Wert (bspw. 900)
Tut er ja nicht, sonst bekäme ich ja auch nicht die Ausgabe via Terminal
mit der vorangehenden If-Anweisung "if( get_X_from_Joystick() <= 518 )",
weshalb ich ja sagte, dass die Terminal-Ausgaben korrekt sind, aber
nicht durch "motorGo()" angenommen werden.
Wäre der Wert > 900, käme er ja garnicht in die If-Anweisung.
Da ich aber den Joystick "ganz nach links drücke" und somit der zu
übergebende Wert 128 entspricht, sollte sich der Motor bewegen.
Zumindest sehe ich das so...
ok, das MotorOn(0,..) hatte ich übersehen. So sollte ja zumindest Motor
0 laufen.
Ist die Portzuordnung richtig, nicht das du z. B. die Richtung von Motor
0 setzt und PWM von Motor 1? Ansonsten sollte ja, wenn Joystick X einen
Wert nahe 0 liefert, motorGo(0,CLOCKWISE,129) ausgeführt werden, was ja
ziemlich genau dem auskommentierten Aufruf entspricht.
nur einen der beiden Motoren abschaltet? Nimm es doch mal (testweise)
raus oder bau es in deinen derzeit auskommentierten Testcase mit ein.
Wird in motorGo irgendwas aktiviert, das nicht beliebig schnell
hintereinander aufgerufen werden darf? In deinem Testcase hast du ja ein
5-Sekunden-Delay, bevor wieder ein motorGo auf dem gleichen Motor
aufgerufen wird.
MfG, Arno
Hi,
wo ist denn die Funktion getXFromJoystick()?
Zur Sicherheit würde ich am Anfang der loop den Wert auslesen und
speichern
uint16_t x = getXFromJoystick();
Hat sich der Wert geändert von der einen Abfage zur nächsten, kann es
sein, dass der Wert > 518 ist und deine Rechnung 518-neuer Wert einen
Überlauf ergibt.
1. uint16_t x = getXfromJoystick();
if (500 <= x && 600 >= x)
{
//Motor stopp
}
else if(500 > x)
{
//Motor links
}
else if (600 < x && 1023 >= x)
{
//motor rechts
}
else
{
//error
}
>Ist die Portzuordnung richtig, nicht das du z. B. die Richtung von Motor>0 setzt und PWM von Motor 1?
Dann würde auch das Auskommentierte nicht richtig funktionieren, wenn da
eine Port-Zuordnung inkorrekt wäre, was es aber tut. -Nämlich richtig zu
funktionieren.
>Ansonsten sollte ja, wenn Joystick X (...)
Ja genau so sehe ich das auch! :-) Das ist ja genau das Problem.
>nur einen der beiden Motoren abschaltet? Nimm es doch mal (testweise)>raus oder bau es in deinen derzeit auskommentierten Testcase mit ein.
Ich habe vorher in der Loop(), bevor ich das ganze If-Gedönse
programmiert habe, mit motorOff() beide Motoren korrekt abgeschaltet und
anschließend durch motorGo() während der Laufzeit des Programms auch
wieder korrekt eingeschaltet...und wieder ausgeschaltet...und wieder
eingeschaltet.
somit kann ich ausschließen, dass motorOff() nicht nur einen/keinen/den
"falschen" Motor ausschaltet.
Diese 5 Sekunden habe ich übrigens selbst eingebaut, damit ich sehe, ob
mein geflashtes Programm auch tatsächlich auf dem Chip gelandet ist ;-)
Da standen auch schon "1 Sekunde" und "500 ms" drin, was dem Ganzen
somit keinen Abbruch getan hat.
Grüße und wiedermals: Danke schonmal für eure Mühe! Ich bin froh, dass
ihr mir helft!
Joh schrieb:>>Ist die Portzuordnung richtig, nicht das du z. B. die Richtung> von Motor>>0 setzt und PWM von Motor 1?> Dann würde auch das Auskommentierte nicht richtig funktionieren, wenn da> eine Port-Zuordnung inkorrekt wäre, was es aber tut. -Nämlich richtig zu> funktionieren.
Nein, bei dem auskommentierten Code startest du ja beide Motoren. Also
falls du z.B. die Richtung von Motor 0 und 1 verwechselst, wäre nach dem
ersten motorGo(0) die Richtung von Motor 1 und die PWM von Motor 0
korrekt, nach dem zweiten motorGo(1) stimmt auch die Richtung von Motor
0 und die PWM von Motor 1, nach beiden Aufrufen drehen sich also beide
Motoren...
Oder hast du das auch einzeln probiert?
MfG, Arno
Joh schrieb:> Dann würde auch das Auskommentierte nicht richtig funktionieren, wenn da> eine Port-Zuordnung inkorrekt wäre, was es aber tut. -Nämlich richtig zu> funktionieren.
im auskommentierten Testcode schaltest du aber beide Motoren
gleichzeitig, im fertigen Programm aber Motor 0 und 1 unabhängig, und
Motor 1 immer wieder aus. Klappt denn der Testfall auch wenn du nur
einen der MotorOn-Aufrufe ausführst?
Joh schrieb:> Das Terminal gibt auch die richtigen PWM-Werte aus, die ich der Funktion> übergebe. Warum aber steuert der Arduino kein PWM-Signal an die H-Brücke> aus, in Abhängigkeit von der Joystick-Bewegung "nach links"?> "motorOff(...)" schaltet einfach den jeweiligen Motor aus.
Bist du sicher, dass es so richtig ist ?
Hier ein Screenshot mit Code und Terminal (siehe Anhang).
Ich habe auch in der goMotor() den Wert auf "1" geändert, was zu keinem
brauchbaren Ergebnis führte.
Probier als Testprogramm mal nur das in der loop():
motorOff(0);
motorOff(1);
motorGo(0,CLOCKWISE,129);
delay(5000);
motorOff(0);
delay(5000);
motorGo(0,COUNTERCLOCKWISE,129);
delay(5000);
motorOff(0);
delay(5000);
motorGo(1,CLOCKWISE,129);
delay(5000);
motorOff(1);
delay(5000);
motorGo(1,COUNTERCLOCKWISE,129);
delay(5000);
motorOff(1);
delay(5000);
Damit sollte Motor 0 ja 5 sek vorwärts laufen, dann 5 sek aus bleiben,
dann 5 sek rückwärts laufen und wieder 5 sek pause. Ich hab mal 129 als
PWM-Wert genommen weil das ja im seriellen protokoll auch verwendet
wird.
Danach passiert dasselbe für Motor 1.
Wenn das klappt sind die motorOn und motorOff-Prozeduren erstmal in
Ordnung.
Aha, ändere ich in der If-Anweisung den Aufruf der motorGo() auf
"COUNTERCLOCKWISE" um, kommt zumindest beim Betätigen des Joysticks
"nach links" ein PWM-Signal an. Drehen tut jedoch keiner der Motoren.
>Wenn das klappt sind die motorOn und motorOff-Prozeduren erstmal in>Ordnung.
Dein "Programm" funktioniert tadellos. Genau wie du es beschreibst,
verhalten sich die Motoren, nachdem ich es in die loop() kopiert habe.
Jetziger Status wie im Listing:
Motor "knackert" bzw. PWM-Signal kommt an Motor-1 an, wenn ich den
Joystick bewege. Das ist schon mal "mehr" als vorher.
Leider bewegt sich Motor-1 trotzdem keinen Ruck.
Kommentiere ich die If-Anweisung nach dem ersten motorGo() aus ("
if( get_Y_from_Joystick() >= 526 ) "), kommt auch kein
PWM-Signal mehr an der H-Brücke an, was ich ebenfalls nicht verstehe.
Wiegesagt, dein Programm lief einwandfrei.
Ich hab die Loop() mal was geändert:
1. die Joystickpositionen werden nur einmal pro Schleife gelesen, damit
kann es keine inkonsistenten Zustände geben wenn sich die
Joystickposition während eines Schleifendurchlaufs ändert.
2. am Ende der else-pfad war verkehrt, dieses else bezieht sich nur auf
das zweite if. Dadurch wurden die Motoren sofort wieder ausgeschaltet
wenn 'if( get_X_from_Joystick() >=538 )' nicht erfüllt war, also immer
dann wenn die erste if-Bedingung true war.
Mir ist doch noch was aufgefallen:
in der motorOff-Prozedur schaltest du die Richtungs-Pins beider Motoren
aus, und dann die PWM des übergebenen Motors. Du solltest da aber nur
den übergebenen Motor ändern, damit der andere Motor weiterlaufen kann.
@HG:
Danke für deine Mühe!
Ich schaue es mir an und berichte.
Jetzt ist leider mein Nano abgebrannt, da ich mich auf dem Steckbrett
"versteckt" habe, vor lauter Aufregung.
Es funktioniert nun alles soweit, die Motoren hörten auf die
Joystick-Befehle.
Ein kleiner Tipp noch wg übersichtlichkeit:
mach für jeden motor ne eigene funktion, wenn du das nicht um weitere
motoren ergänzen willst. Macht den code nicht schneller, aber besser zu
lesen, wenn ein x motor und ein y motor da ist.
x = readJoyX();
y = reayJoyY();
handleMotorX();
if( x < wert){
handleMotorY();
}
Also danke erstmal für eure Hilfe!
Wiegesagt, als letztes hat der Code so funktioniert wie er sollte, ich
habe dann nur noch mit CLOCKWISE und COUNTERCLOCKWISE herumgespielt.
Dummerweise vergaß ich, die Versorgungsspannung abzuklemmen, als ich den
Arduino aus dem Sockel auf meiner Leiterplatte gezogen habe und ihn dann
während die Versorgungsspannung an der Leiterplatte anlag wieder
reingesteckt.
Daraufhin hat es in einer "Ecke" des kleinen ATmega ordentlich geblitzt
und geraucht.
Frage: Kann das mit der Software zusammenhängen? Oder lag es schlichtweg
daran, dass ich den Arduino im laufenden Betrieb in den Sockel der
Leiterplatte steckte?
Hier nochmal mein komplettes Listing im Anhang, welches das
"Platinen-Gewitter" verursachte...
Gruß
> Daraufhin hat es in einer "Ecke" des kleinen ATmega ordentlich> geblitzt und geraucht.> Kann das mit der Software zusammenhängen?
Ich glaube, du hast zu viel Star Trek geschaut. Da blitzt und raucht die
Elektronik auch andauernd ohne kaputt zu gehen.
Joh schrieb:> Frage: Kann das mit der Software zusammenhängen? Oder lag es schlichtweg> daran, dass ich den Arduino im laufenden Betrieb in den Sockel der> Leiterplatte steckte?
Das wird nicht an der Software liegen, sondern am Einstecken bei
eingeschalteter Spannung.
Hallo zusammen.
Ich habe es heute mit einem neuen Arduino versucht, hochgeladen habe ich
zuletzt den von mir hier zuletzt hochgeladenen Code.
Das Bluetooth-Modul scheint seit dem letzten "Aufblitzen" des alten
Arduino-Boards geschossen zu sein.
Komisch ist auch, dass über das Terminal nichts ausgegeben wird, wenn
ich den Joystick in die besagte Position bewege. Das Motormodul wird
jedoch richtig angesteuert, sodass sich einer der beiden Motoren
entsprechend der Knüppelposition "nach links" bewegt. Der andere Motor
dreht jedoch nicht, wenn ich den Knüppel "nach vorne" drücke.
1) Wie kann es sein, dass Serial.println() nicht mehr den AD-Wert im
Terminal ausgibt, seitdem ich den neuen Arduino verwende?
2) Wie kann es sein, dass das Bluetooth-Modul nun auch nicht mehr
reagiert/vermutlich kaputt ist?
Hier nochmal der Code im Anhang:
https://www.mikrocontroller.net/attachment/highlight/324132
Komplexe Probleme zerlegt man in viele kleine einfache.
Sowohl das Blutooth Modul als auch die Funktion serial.println() kannst
du einzeln mit einem minimalen Testprogramm überprüfen. Wenn das klappt,
wird dein Anwendungsprogramm die Fehlerursache sein.
Nachtrag:
Die "Serial.println()"-Methoden wurden bei mir im Programm vor dem
Flashen natürlich ent-kommentiert, sodass sie somit während der Laufzeit
eine Terminalausgabe liefern sollten.
Hallo Leute,
ich muss euch nochmal fragen, wegen meiner Joystick-Problematik zum
genannten Projekt.
Der Joystick wird nach links bewegt, und der MOTOR_RECHTS wird
angesteuert so wie er soll. Je nach Intensität des "nach links-Drückens"
wird der Motor entsprechend mit der PWM angesteuert. Soweit so gut.
Jetzt habe ich versucht, dass wenn man den Joystick gleichzeitig wenn
man ihn nach "vorne" drückt, der zweite Motor (MOTOR_LINKS) entsprechend
der Intensität des "nach vorne-Drückens" per PWM angesteuert wird.
(siehe Anhang)
Dies funktioniert aber nicht. MOTOR_RECHTS tut was er soll, MOTOR_LINKS
macht keinen Mucks. Auch nicht, wenn ich den Knüppel nur nach vorne
schiebe...aber das kommt später.
Nun eine kleine "Skizze", welche AD-Werte man geliefert bekommt, wenn
man nach links/rechts bzw vor/zurück den Joystick bewegt:
1020
^
|
|
|
0 <------ 516 -----> 1020
|
|
|
0
In den If-Anweisungen habe ich eine kleine Toleranz eingebaut, da die
Mittelstellung des Joysticks nicht immer exakt "516" liefert.
Irgendwo habe ich da wohl noch einen Denkfehler...
Hier der Code der besagten Abfragen:
1
voidloop()
2
{
3
if(get_X_from_Joystick()<=518)// wenn eingelesene X-Achse vom Joystick nach "links" geht,....
4
{
5
unsignedintx=518-get_X_from_Joystick();
6
unsignedintpwm_signal_x=(x/4);
7
8
motorGo(MOTOR_RECHTS,COUNTERCLOCKWISE,pwm_signal_x);// ...stelle Drehzahl des rechten Motors entsprechend der Position des Potis
9
Serial.println("X-PWM: ");
10
Serial.println(pwm_signal_x);
11
12
13
if(get_Y_from_Joystick()>=526)// Wenn gleichzeitig beim nach "links" drücken des Joysticks der Joystick nach "vorne" geschoben wird....
14
{
15
Serial.println("JETZT Y!");
16
unsignedintdiff=504;
17
floatfaktor=0.5;
18
unsignedintpwm_signal_y=faktor*256;
19
Serial.println("Y-PWM: ");
20
Serial.println(pwm_signal_y);
21
motorGo(MOTOR_LINKS,COUNTERCLOCKWISE,pwm_signal_y);// ...schalte zusätzlich den linken Motor entsprechend der Y-Position des Joysticks
22
}
23
}
Könnt ihr mir auf die Sprünge helfen, warum der MOTOR_LINKS nicht
anläuft, obwohl im Terminal die richtigen AD-gewandelten Y-Werte
ausgegeben werden, die ich dann der motorGo()-Funktion übergebe?
Vielen Dank!
Hallo Stefan,
>Erzähle uns erstmal, welche Ausgaben du im fehlerfall von
Die Ausgaben sind im angehängten Screenshot im Terminal zu sehen.
Ich habe meinen Code ein wenig erweitert, sodass nun das "nur nach
vorwärts-Drücken" zumindest einigermaßen funktioniert. Nach "10 Uhr"
drücken funktioniert aber nach wie vor nicht.
Bei "nur nach vorne" drücken (weder nach links noch nach rechts) laufen
zwar beide Motoren an (siehe Code), jedoch gehen sie auf volle Leistung
ganz am Anfang, wenn ich den Joystick nur ganz leicht nach vorne drücke.
Danach lassen sich beide Motoren parallel abhängig von der Intensität
des nach Vornedrückens drehzahlsteuern.
Hier der aktualisierte Code. Im alten Code habe ich gesehen, dass
keinerlei Bezug zur aktuellen X-Position des Joysticks implementiert
war. Dies habe ich nun nach meinem Dafürhalten entsprechend abgeändert.
Es führt aber dennoch zu keinem Ergebnis, wenn ich den Joystick nach
links und gleichzeitig nach "oben" drücke (ein Motor bleibt immer
"AUS").
1
voidloop()
2
{
3
if(get_X_from_Joystick()<=518)// wenn eingelesene X-Achse vom Joystick nach "links" geht,....
4
{
5
unsignedintx=518-get_X_from_Joystick();
6
unsignedintpwm_signal_x=(x/4);
7
8
motorGo(MOTOR_RECHTS,COUNTERCLOCKWISE,pwm_signal_x);// ...stelle Drehzahl des rechten Motors entsprechend der Position des Potis
9
Serial.println("X-PWM: ");
10
Serial.println(pwm_signal_x);
11
12
13
if(get_Y_from_Joystick()>=526)// Wenn gleichzeitig beim nach "links" drücken des Joysticks der Joystick nach "vorne" geschoben wird....
motorGo(MOTOR_LINKS,COUNTERCLOCKWISE,pwm_signal_y);// ...schalte zusätzlich den linken Motor entsprechend der Y-Position des Joysticks
22
}
23
}
24
25
26
27
if(((get_X_from_Joystick()>=510)|(get_X_from_Joystick()<=526))&(get_Y_from_Joystick()>=566))// wenn Joystick nur nach vorne geht und nicht nach links oder rechts....
Also wenn du die Bewegung überlagern willst, geht's am besten wenn du
die 2 Bewegungen zuerst einzeln berechnest und dann vereinst (da kommen
jetzt halt die Vorlieben von dir vor:
a) y Achse gibt Drehrate vor
b) y Achse gibt Kurvenradius vor
c) ...
)
Ich möchte halt "einfach" folgendes Szenario implementieren:
- Wenn NUR nach links gedrückt wird (ohne nach "oben"), soll ein Motor
stillstehen und nur ein Motor drehen (der Rechte)
- Wenn WÄHREND links gedrückt wird nach oben gedrückt wird, sollen
beide Motoren entsprechend X-/Y-AD-Wert laufen
- Szenario für rechts/rechts+runter/nur runter ensprechend Punkt 1) und
2)
Gruß
Ich hoffe, ihr könnt mir noch irgendwie weiterhelfen. Ansonsten werde
ich mal das spezielle Problem in einem neuen Beitrag eröffnen (auch wenn
mich dafür der Admin hier im Forum hassen wird) ;-)
Grüße und Danke, dass ihr stets Ohr seid!
Joh
Kann es sein, dass du einen Kurzschluss zwischen zwei Leiterbahnen hast?
Teste mal folgendes
1
voidloop()
2
{
3
Serial.println("A");
4
motorGo(MOTOR_LINKS,CLOCKWISE,100);
5
motorGo(MOTOR_RECHTS,CLOCKWISE,100);
6
delay(2000);
7
8
Serial.println("B");
9
motorGo(MOTOR_LINKS,COUNTERCLOCKWISE,100);
10
motorGo(MOTOR_RECHTS,CLOCKWISE,100);
11
delay(2000);
12
13
Serial.println("C");
14
motorGo(MOTOR_LINKS,COUNTERCLOCKWISE,100);
15
motorGo(MOTOR_RECHTS,COUNTERCLOCKWISE,100);
16
delay(2000);
17
18
Serial.println("D");
19
motorGo(MOTOR_LINKS,CLOCKWISE,100);
20
motorGo(MOTOR_RECHTS,COUNTERCLOCKWISE,100);
21
delay(2000);
22
}
Bei diesem Programm müssten beide Motor ständig laufen, und zwar zeitich
versetzt immer abwechselns vorwärts und rückwärts.
Erzähl mal, was dabei heraus kommt.
Wenn das nicht klappt, dann steckt der Fehler vermutlich in der
Hardware. Man könnte dann ja mal die Signale kontrollieren (notfalls mit
LED's), die vom µC zum Motortreiber gehen.
Hallo Stefan,
die beiden Motoren drehen gleichzeitig und wechseln ihre Drehrichtung.
Auch im Terminal sieht man die Ausgabe (siehe Anhang) von "A", "B", "C"
und "D".
Gruß
Wenn X < 518 ist, dann macht er oben was, und unten macht er was
anderes. Das ist widersprüchlich.
Außerdem ist das "&" Zeichen falsch, es muss && heissen.
Ich befürchte, dass deine Logik "Beim Lenken soll nur ein Motor drehen"
nicht klappen wird. Stell Dir vor, du fährst vollgas vorwärts und lenkst
dann ein bisschen nach inks. Dann wird einer der beiden Motor abrupt
stoppen und dein Gefährt versuchen, sich fast auf der Stelle nach links
zu drehen. Das kann nicht gut gehen.
Ich würde deine Aufgabe daher völlig anders angehen.
Zuerst würde ich die Werte der Joystick ADC's zunächst in X un Y
Koordinaten umrechnen, so dass sowohl Y als auch X die Werte -512 bis
+511 annehmen können. X=0/Y=0 wäre der Mittelpunkt, die Ruheposition.
Die Y-Achse bestimmt die Geschwindigkeit, wobei negative Werte
"Rückwärts" bedeuten.
Die X-Achse bestimmt die Lenkung, wobei negative Werte "nach links"
bedeuten und positive Werte "nach rechts" bedeuten.
Wenn sowohl die Lenkung als auch die Geschwindigkeit nahe dem Ruhepunkt
0 sind, dann sollen die Motoren gar nicht drehen.
Auf Geschwindigkeit und Lenkung berechnest du die Drehzahl und Richtung
der Motoren. Positive zahlen=vorwärts, negative Zahlen=rückwärts.
Dann rechnest du diesn beiden Motorwerte in Richtungs-Signale und PWM
Werte um. Potitiv/Negative bestimmt die Richtung und als PWM Wert
verwendest du den Absolut-Wert der Zahl. Also z.B würde -200 Rückwärts
mit PWM 200 bedeuten.
Ungetesteter Pseudo Code:
1
lenkung=512-get_X_from_Joystick();
2
geschwindigkeit=512-get_Y_from_Joystick();
3
4
if(abs(lenkung)>20&&abs(geschwindigkeit)>20)
5
{
6
motorLinks=geschwindigkeit+lenkung;
7
motorRechts=geschwindigkeit-lenkung;
8
9
pwmLinks=abs(motorLinks)/4;
10
pwmRechts=abs(motorRechts)/4;
11
12
if(pwmLinks<0)
13
{
14
motorGo(MOTOR_LINKS,COUNTERCLOCKWISE,pwmLinks);
15
}
16
else
17
{
18
motorGo(MOTOR_LINKS,CLOCKWISE,pwmLinks);
19
}
20
21
if(pwmRechts<0)
22
{
23
motorGo(MOTOR_RECHTS,COUNTERCLOCKWISE,pwmRechts);
24
}
25
else
26
{
27
motorGo(MOTOR_RECHTS,CLOCKWISE,pwmRechts);
28
}
29
}
30
else
31
{
32
motorOff(0);
33
motorOff(1);
34
}
Die ganzen Variablen solltest du zum Debuggen wieder mit println
ausgeben.
Folgende Funktionen ergeben sich aus dem obigen Code:
Wenn der Joystick nur in der Y-Achse betätigt wird, fahren beide Motoren
gleich schnell vorwärts und Rückwärts.
Wenn der Joystick nur in der X-Achse betätigt wird, dreht sich das
Gefährt aus der Stelle.
Wenn der Joystick während der Fahrt nach links oder rechts bewegt wird,
lenkt er in diese Richtung.
Eventuell möchtest du der Lenkung etwas weniger Priorität geben, damit
das Gefährt nicht allzu krasse Lenkmanöver vollführt. Du könntest dazu
den "geschwindigkeit" Wert mit 1,5 Multiplizieren und dafür den
"lenkung" Wert durch 1,5 dividieren.
Dies alles geht allerdings davon aus, dass PWM-Wert = Geschwindigkeit
ist. Für erste Versuche mag das ausreichen. Für ein angenehmes
Fahrverhalten wirst du allerdings Odometrie-Sensoren brauchen, sowie
zwei PI-Regler (einen für die Geschwindigkeit und einen für die
Lenkung). Außerdem wirst du eventuell noch auf das Problem Stoßen, dass
die beiden Motoren unterschiedlich effizient sind, so dass das Gefährt
nicht korrekt geradeaus fährt. Das ist sogar sehr warscheinlich, wenn
beim Vorwärtsfahren ein Motor links herum dreht und der andere rechts
herum (aufgrund der spiegelverkehrten Einbaulage).
Stefan U. schrieb:> Also vermutlich kein Hardware defekt.>> Dein letzter Quelltext sieht schon wieder wirr aus.> if( get_X_from_Joystick() <= 518 )> {> tuwas> }>> if( ( (get_X_from_Joystick() >=510) | (get_X_from_Joystick() <=526)) &> (get_Y_from_Joystick() >=566 ))> {> tu was anderes> }>> Wenn X < 518 ist, dann macht er oben was, und unten macht er was> anderes. Das ist widersprüchlich.>> Außerdem ist das "&" Zeichen falsch, es muss && heissen.
Fiel mir auch gerade auf - und das | muss || heißen.
Unterschied zwischen bitweisen und logischen Verknüpfungen.
MfG, Arno
Hi
Verstehe ich Dich richtig:
Nur Links/Rechts steuert jeweils den gegenüberliegenden Motor mit 100%
vorwärts an
Nur Vor/Zurück steuert beide Motoren mit je 100% vor/zurück an
Vor-Links wäre somit linke Motor 100%, rechte Motor 200%
- da 200% blöd sind, beide Werte proportional runterrechnen
-> linke Motor 50%, rechte Motor 100% (also Beide :2, um auf Maximum von
100 zu kommen)
Würde mir für beide Motoren die Soll-Drehzahl durch die
Joystick-Position errechnen und dann sehen, ob ein Wert davon >100 oder
<-100 (wenn Rückwärts als negativer Wert erscheint) ist und dann auf
'maximal 100%' runter rechnen.
(wenn der absolut-Wert 120 ist, dann durch 1,2 teilen - hoffe,
verständlich genug beschrieben)
MfG
> Nur Links/Rechts steuert jeweils den gegenüberliegenden Motor mit 100%
vorwärts an
Nein 50% - wenn du keine Prio-Faktoren verwendest.
> Nur Vor/Zurück steuert beide Motoren mit je 100% vor/zurück an
Nein, auch hier sind es 50% - wenn du keine Prio-Faktoren verwendest.
Die Extreme wären dann die äußeren vier Ecken des Joysticks, nur da
würden die Motoren 100% bekommen. Das ist so auch absolut richtig. Wenn
du 5kmH vorwärts fährst und dann lenkst, muss ein Motor noch schneller
drehen und einer nlangsamer, ansonsten ändert sich die Geschwindigkeit.
Und dann würde die Y-Achse nicht mehr das bewirken, wass der Bediener
erwarten würde.
Hallo zusammen.
Ich habe nun mal Stefans Pseudocode in meinen Code kopiert und ihn
getestet.
Ich habe den Variablen den Datentyp "unsigned int" gegeben und alles
soweit 1:1 übernommen.
Die Variablen lasse ich über das Terminal ausgeben
Nach dem Flashen und dem Ausführen des Terminals erhalte ich folgende
Werte (siehe Screenshot im Anhang).
Direkt nach dem Flashen dreht einer der Motoren auf max. Drehzahl,
irgendwie lässt sich schon etwas steuern, aber nicht für mich
nachvollziehbar.
Ich hoffe die Terminalausgabe kann weiterhelfen?!
Ich versuche mal anhand des Codes von Stefan weiter zu experimentieren..
Grüße und Danke für den Code! :)
> Ich habe den Variablen den Datentyp "unsigned int" gegeben und> alles soweit 1:1 übernommen.
Wie passen dort negative Werte rein? Verstehst du die Bedeutung von
"unsigned"?