Hallo,
ich hatte bereits in einem früheren Beitrag eine Frage zur geplanten
Verstelleinheit gestellt.
Dieses Thema habe ich nun lösen können.
Jetzt geht es aber nochmal um das Verfahren der Einheit selbst.
Ich habe dazu folgenden Arduino-Code geschrieben, welcher aber nicht im
Ansatz dies tut, was er soll.
Vorhaben ist folgendes:
Da keine Positionserfassung möglich ist, mache ich eine Referenzfahrt.
Dessen Ergebnis ist die Zeit in der Variable "vvRef100"
Über die Variable "vf" soll der Verfahrweg von 0-100% angegeben werden
können
Die Variable "pos" soll den aktuellen Positionswert enthalten und wenn
der neue rechnerische Positionswert mehr als 500 millis abweicht soll
verfahren werden, bis zum erreichen +- 10 millis des Sollwerts.
Es verfährt der Motor aber bei jeder Vorgabe größer 0 und die Variable
"pos" wird auch nicht verändert, obwohl ich die verfahrene Zeit ja beim
Anhalten einberechne.
Was mache ich falsch?
Variablendeklaration:
unsigned long vvRef100;
unsigned long TvfStart;
unsigned long pos;
signed long pos_rech[3];
int vf = 0;
int vfr = 0;
Loop:
pos_rech[0] = pos + 500;
pos_rech[1] = pos - 500;
pos_rech[2] = ((vvRef100 / 100) * vf);
pos_rech[3]=(millis() - TvfStart);
if (pos_rech[0] < pos_rech[2] && vfr == 0) {
driver.motorAReverse(motorSpeed);
TvfStart = millis();
vfr = 1;
}
else if (pos_rech[1] > pos_rech[2] && vfr == 0) {
driver.motorAForward(motorSpeed);
TvfStart = millis();
vfr = 2;
}
else if (millis() - TvfStart > pos_rech[2] - 10 && millis() -
TvfStart < pos_rech[2] + 10) {
driver.motorAStop();
if (vfr = 1) {
pos = (pos + pos_rech[3]);
}
if (vfr = 2) {
pos = (pos - pos_rech[3]);
}
vfr = 0;
befehl = 0;
Serial.print("pos_neu "); Serial.println(pos);
Es ist so wunderschön, dass jeder hier nun weiß, was du genau vorhast. Also ran an die Tastatur und mache dir die Mühe zu beschreiben, wie deine Verstelleinheit aussieht. Oder setzte einen Link.
Pffffffffff schrieb: > Es ist so wunderschön, dass jeder hier nun weiß, was du genau vorhast. du etwa nicht? :)))) OK: du bist nicht allein ..... ich hatte das Programm abgetippt aber hier hat sich auch nichts verstellt!
Du willst eine Sollposition über die Zeit anfahren? Ich nehme an mit einem einfachen DC-Motor?
Ich verstehe die Argumentation zum Aussehen der Verstelleinheit nicht. Mir geht es um den Code, warum dieser nicht das tut was ich beschrieben habe. Der Motor fährt mit entsprechendem Treiber problemlos. @crazyhorse: Ja genau es soll die Position per Zeit mit einem DC-Motor angefahren werden. Hoch präzise muss das ganze nicht sein. Hier nochmal der Code hoffentlich richtig eingefügt.
1 | unsigned long vvRef100; |
2 | unsigned long TvfStart; |
3 | unsigned long pos; |
4 | signed long pos_rech[3]; |
5 | int vf = 0; |
6 | int vfr = 0; |
7 | |
8 | void loop(){ |
9 | pos_rech[0] = pos + 500; |
10 | pos_rech[1] = pos - 500; |
11 | pos_rech[2] = ((vvRef100 / 100) * vf); |
12 | pos_rech[3]=(millis() - TvfStart); |
13 | if (pos_rech[0] < pos_rech[2] && vfr == 0) { |
14 | driver.motorAReverse(motorSpeed); |
15 | TvfStart = millis(); |
16 | vfr = 1; |
17 | }
|
18 | else if (pos_rech[1] > pos_rech[2] && vfr == 0) { |
19 | driver.motorAForward(motorSpeed); |
20 | TvfStart = millis(); |
21 | vfr = 2; |
22 | }
|
23 | else if (millis() - TvfStart > pos_rech[2] - 10 && millis() - TvfStart < pos_rech[2] + 10){ |
24 | driver.motorAStop(); |
25 | |
26 | if (vfr = 1) { |
27 | pos = (pos + pos_rech[3]); |
28 | }
|
29 | if (vfr = 2) { |
30 | pos = (pos - pos_rech[3]); |
31 | }
|
32 | vfr = 0; |
33 | befehl = 0; |
34 | Serial.print("pos_neu "); Serial.println(pos); |
35 | }
|
Christoph W. schrieb: > if (vfr = 1) > if (vfr = 2) Meckert der Compiler da nicht? Tut normalerweise nicht das was du wahrscheinlich erwartest. Oder kann man das in der Arduinowelt so schreiben?
H.Joachim S. schrieb: > Meckert der Compiler da nicht? Tut normalerweise nicht das was du > wahrscheinlich erwartest. > Oder kann man das in der Arduinowelt so schreiben? Das ist erlaubte C Syntax, ABER trotzdem nicht sinnvoll, da die entspr. Anweisung immer ausgeführt wird. Also schreib da nun "==" ... und schau weiter.
Na klar ist formal korrekt. Ich bekomme bei solchen Sachen aber ein Warnung.
H.Joachim S. schrieb: > Oder kann man das in der Arduinowelt so schreiben? Die Arduniowelt ändert nichts an den Vorgaben durch die verwendete Programmiersprache. Und natürlich versteht der GCC das, weil die Schreibweise in C, C++ usw. eine zulässige Operation ist. Eben die große Freiheit von C & Co. ...
H.Joachim S. schrieb: > Christoph W. schrieb: >> if (vfr = 1) >> if (vfr = 2) > > Meckert der Compiler da nicht? Tut normalerweise nicht das was du > wahrscheinlich erwartest. > Oder kann man das in der Arduinowelt so schreiben? Ja stimmt. Ich werde dies korrigieren und Rückmeldung geben. Danke für den Hinweis.
Habe es mit der korrigierten Abfrage versucht. Es klappt aber nicht so wie ich es mir vorstelle. Vorgabewert waren 10% debug-Werte erhalte ich folgende: vvRef100 41406 pos_neu 8261 Kann mir jemand sagen, warum beim Wert "pos_neu" das recht exakt doppelte vom zu erwartenden Wert raus kommt. Ich komm hier nicht dahinter.
JensM schrieb: > Array pos_rech ist 3 Elemente groß. > Du benutzt aber 4. > Das geht schief. Ich dachte 0 ... 3 = 4 Lieg ich da falsch?
Christoph W. schrieb: > JensM schrieb: >> Array pos_rech ist 3 Elemente groß. >> Du benutzt aber 4. >> Das geht schief. > > Ich dachte 0 ... 3 = 4 > > Lieg ich da falsch? Es ist richtig. Die Ordinalzahlen 0 ... 3 nummerieren 4 Elemente. Aber: In einer C-Deklaration eines Arrays steht in den eckigen Klammern, die Anzahl_ der Elemente und _nicht die höchste Ordinalzahl (Index). Das Ding hat tatsächlich nur 3 Elemente.
1 | signed long pos_rech[3]; |
1 | pos_rech[3]=(millis() - TvfStart); |
das passt nicht.
Für meine Begriffe unerwartet, dass der Compiler bei einem expliziten, d.h. literalen Index, der zu hoch ist, keinen Fehler oder wenigstens eine Warnung ausgibt.
H.Joachim S. schrieb: > Warnungen sind doch zum ignorieren da.... :-) Ach, dafür sind die. Ich hab mich schon gewundert.
STK500-Besitzer schrieb: >
1 | > signed long pos_rech[3]; |
2 | >
|
> >
1 | > pos_rech[3]=(millis() - TvfStart); |
2 | >
|
> > das passt nicht. Bitte kläre mich auf, was passt nicht?
Theor schrieb: > Für meine Begriffe unerwartet, dass der Compiler bei einem expliziten, > d.h. literalen Index, der zu hoch ist, keinen Fehler oder wenigstens > eine Warnung ausgibt. Die Arduino-IDE gibt keine Warnung aus.
Christoph W. schrieb: > Bitte kläre mich auf, was passt nicht? Das sagte man doch mehrfach!
1 | signed long pos_rech[4]; // wenn du 0..3 ansprechen willst, |
2 | // dann musst du hier vier Elemente definieren!
|
3 | |
4 | pos_rech[3]=(millis() - TvfStart); |
H.Joachim S. schrieb: > Warnungen sind doch zum ignorieren da.... :-) Ach deswegen sind die Warnungen in der Arduino IDE standardmäßig deaktiviert. Jetzt verstehe ich es endlich. Christoph W. schrieb: > Die Arduino-IDE gibt keine Warnung aus. Zwei Dumme - ein Gedanke. Spaß beiseite: Das ist ein ein ganz dummer Fehler, ich kann nicht verstehen, warum die Arduino Macher daran immer noch festhalten.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.