Forum: Mikrocontroller und Digitale Elektronik Nochmal Verstelleinheit


von Christoph W. (christoph_4)


Lesenswert?

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);

von Pffffffffff (Gast)


Lesenswert?

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.

von Joachim B. (jar)


Lesenswert?

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!

von H.Joachim S. (crazyhorse)


Lesenswert?

Du willst eine Sollposition über die Zeit anfahren? Ich nehme an mit 
einem einfachen DC-Motor?

von Wolfgang (Gast)


Lesenswert?

Christoph W. schrieb:
> Was mache ich falsch?

Um dein Programm fehlen die Code-Tags
1
[c]<code>[/c]

von Christoph W. (christoph_4)


Lesenswert?

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
}

von H.Joachim S. (crazyhorse)


Lesenswert?

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?

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

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.

von H.Joachim S. (crazyhorse)


Lesenswert?

Na klar ist formal korrekt.
Ich bekomme bei solchen Sachen aber ein Warnung.

von Wolfgang (Gast)


Lesenswert?

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. ...

von Christoph W. (christoph_4)


Lesenswert?

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.

von Christoph W. (christoph_4)


Lesenswert?

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.

von Christoph W. (christoph_4)


Lesenswert?

Hallo,

hat niemand eine Idee?

von JensM (Gast)


Lesenswert?

Array pos_rech ist 3 Elemente groß.
Du benutzt aber 4.
Das geht schief.

von Christoph W. (christoph_4)


Lesenswert?

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?

von STK500-Besitzer (Gast)


Lesenswert?

Christoph W. schrieb:
> Lieg ich da falsch?

nein.

von Theor (Gast)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

1
signed long pos_rech[3];
1
 pos_rech[3]=(millis() - TvfStart);

das passt nicht.

von Theor (Gast)


Lesenswert?

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.

von H.Joachim S. (crazyhorse)


Lesenswert?

Warnungen sind doch zum ignorieren da.... :-)

von STK500-Besitzer (Gast)


Lesenswert?

H.Joachim S. schrieb:
> Warnungen sind doch zum ignorieren da.... :-)

Ach, dafür sind die. Ich hab mich schon gewundert.

von Christoph W. (christoph_4)


Lesenswert?

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?

von Christoph W. (christoph_4)


Lesenswert?

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.

von HildeK (Gast)


Lesenswert?

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);

von Stefan F. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.