Forum: Mikrocontroller und Digitale Elektronik Schrittmotor


von Jan W. (magictyphoon)


Lesenswert?

Hallo...

Warscheinlich wurde es hier schon oft geschrieben...
Bin neu hier und habe ein Problem...

Ich komme mit meinem Sketch nicht weiter.
Ich will, das der Schrittmotor anfängt zu drehen, sobald der Pin 13 ein 
HIGH-Signal erhält und sobald das HIGH-Signal weg ist soll er weiter 
drehen. Zusätzlich soll der Motor bei jedem Step intern gezählt werden 
und sobald eine Summe von 200 Steps erreicht ist, soll er in den 
Ruhemodus gesetzt werden und auf einen neuen Impuls warten.


void setup()
{
  DDRB=0x0F;
  PORTB=0x00;
}

int zeit;
int count=0;

void loop()

{
   {
       if (digitalRead(13)==1)
       //Kein Plan zum stopen und counter einzusetzen

       else
               zeit=3;
               PORTB=0x0A;
               delay(zeit);
               count=count+1;

               PORTB=0x09;
               delay=(zeit);
               count=count+1;

               PORTB=0x05;
               delay(zeit);
               count=count+1;

               PORTB=0x06;
               delay(zeit);
               count=count+1;

      if (count <200) // Schleife wiederholen ?!

         }

}


Weis Jemand rat?

von phul (Gast)


Lesenswert?

Und was stimmt nun nicht?

Außerdem ist der Code unlesbar so, benutz code tags

von phul (Gast)


Lesenswert?

Da fehlen außerdem mehrere geschweifte Klammern, das kann unmöglich 
kompilieren so

von Helmut -. (dc3yc)


Lesenswert?

Ausserdem ist ein = zuviel.

von Jan W. (magictyphoon)


Lesenswert?

Habe bisher keine Fehler. Motor dreht. Komme jedoch nicht auf die 
Lösung.

Das Programm habe ich mit dem Handy hier hinein geschrieben, da ich kein 
Internet für'n Rechner habe.

Währe trorzdem für eine brauchbare Lösung dankbar...

von Jan W. (magictyphoon)


Angehängte Dateien:

Lesenswert?

So sieht der Sket zur Zeit aus...

von c r (Gast)


Lesenswert?

Jan W. schrieb:
> Habe bisher keine Fehler. Motor dreht.

So wie das da steht, ist das kein gültiger C-Code, irgendwas 
verschweigst du also.

Jan W. schrieb:
> Komme jedoch nicht auf die
> Lösung.

Ah, eine Hausaufgabe also. Dann liefer doch wenigstens die tatsächliche 
Aufgabenstellung.

Jan W. schrieb:
> da ich kein
> Internet für'n Rechner habe.

Hotspot kennste?
Auch ein abfotografierter Bildschirm mit dem wahren Code wäre besser als 
völlig falsch abgetippter.

Helmut -. schrieb:
> Ausserdem ist ein = zuviel.

Bitte was?!

von c r (Gast)


Lesenswert?

Jan W. schrieb:
> So sieht der Sket zur Zeit aus...

Und das kompiliert? Schlag mal nach, wie die Klammern bei if...else in C 
gesetzt werden. So macht das keinen Sinn.

von Christian M. (Gast)


Lesenswert?

Schon wieder: Code als Bildschirm-abfotografie. Nein!

Gruss Chregu

von Jan W. (magictyphoon)


Angehängte Dateien:

Lesenswert?

Habe kein Internet für'n Rechner.
Auch kein HotSpot oder so.
Bin über 40 und kein Schuljunge mehr.

Will einfach via Tastendruck das programm starten.
Nach durchlaufen der angegeben und erreichten Countermenge soll er 
wieder darauf warten, das eine Taste gedrückt wird.

Was ist daran jetzt verheimlicht?
Mein Bildschirm ist ok.
Als Beweis, das es MEIN Bildschirm ist, habe ich meinen Namen auf ein 
Blatt Paier geschrieben.

von Wolfgang (Gast)


Lesenswert?

Jan W. schrieb:
> Weis Jemand rat?

In der AN_8017 Atmel AppNote AVR446 - Linear speed control of stepper 
motor findest du ein bisschen Lesestoff und Code zu Beschleunigungs- und 
Bremsrampen mit Anhalten auf einer bestimmten Position aka nach 
bestimmter Schrittzahl:
http://ww1.microchip.com/downloads/en/AppNotes/doc8017.pdf
http://ww1.microchip.com/downloads/en/AppNotes/AVR446.zip

von c r (Gast)


Lesenswert?

Jan W. schrieb:
> Was ist daran jetzt verheimlicht?

Ganz einfach: Das ist kein gültiger C++ Code, kann also nicht 
kompilieren, kann also den Motor nicht betreiben.

Was auch immer auf deinem Arduino o.ä. läuft, dieser Code ist es nicht.

von Jan W. (magictyphoon)


Angehängte Dateien:

Lesenswert?

Habe auf etwas einfacheres gehofft wie z.B. einen Sketch der mir 
erzählt, wie ich an die Counterdaten komme, welche in der Variabel 
abgelegt sind und diese ausgelesen werden können um den Motor oder das 
Programm zu stoppen. Dachte jetzt nicht, das ich hier mit Frequenzen und 
klein Omega arbeiten soll. Kreisfrequenzen passen da irgendwie nicht zu.

Aber das hat man davon, wenn man als Neuling eine banale Frage stellt, 
wird alles hinterfragt und als eventueller Lügner/Heimlichtuer 
hingestellt...

Macht man das bei einfachen Fragen so?
Dachte, das hier geholfen wird...

von Jan W. (magictyphoon)


Lesenswert?

Währe es in BASIC vom Commodore64, währe es für mich kein Problem aber 
dies hier ist anders. Der Aufbau, die Abfrage, und und und...

Ist halt kein BASIC

von Jan W. (magictyphoon)


Angehängte Dateien:

Lesenswert?

c r schrieb:
> Was auch immer auf deinem Arduino o.ä. läuft, dieser Code ist es nicht.

Doch  !

von STK500-Besitzer (Gast)


Lesenswert?

Jan W. schrieb:
> Wäre es in BASIC vom Commodore64, währe es für mich kein Problem aber
> dies hier ist anders. Der Aufbau, die Abfrage, und und und...
>

Jan W. schrieb:
> Ist halt kein BASIC

Programmieren ist unabhängig von der (Programmier-)Sprache.
Um das von die geschilderte Problem zu lösen, solltest du dir einen 
Ablaufplan aufmalen.
Der gilt sprachübergreifend (zumindest für prozedurale Sprachen).

Pseudocode:
In der Loop:
liegt am Pin High an? ==> setze einen Merker

ist der Merker gesetzt?
==> mache nächsten Schrittmotor-Schritt (und das restliche Geraffel)

wurde Schritt-Nummer 200 oder höher ausgeführt? ==> Setze Merker zurück

Das darfst du jetzt als Ablaufplan aufmalen (Papier und Stift hast du ja 
offensichtlich).

von c r (Gast)


Lesenswert?

Kann noch jemand anderes einen Blick auf den Code werfen und mir 
bestätigen oder widersprechen, wenn ich sage, dass das kein syntaktisch 
korrekter C-Code ist?

mMn ist der gesamte Code in der void loop() in einem sinnlosen Block 
eingeklammert (gut, das ist an der Stelle egal) dafür fehlen beim 
if...else sämtliche notwendigen Klammern.

Wie kann das kompilieren?

von Thomas R. (Gast)


Lesenswert?

Helmut -. schrieb:
> Ausserdem ist ein = zuviel.

und wo soll das sein??

von c r (Gast)


Lesenswert?

Thomas R. schrieb:
> Helmut -. schrieb:
> Ausserdem ist ein = zuviel.
>
> und wo soll das sein??

Ich hoffe das soll ein Trollversuch sein. Wenn dann ist das ganze '==1' 
überflüssig

von STK500-Besitzer (Gast)


Lesenswert?

Jan W. schrieb:
> {
>        if (digitalRead(13)==1)

müsste man schon mal gegeneinander tauschen
1
>        if (digitalRead(13)==1)
2
> {

Jan W. schrieb:
> else
// hier fehlt eine "{"
>                zeit=3;
>                PORTB=0x0A;
>                delay(zeit);
>                count=count+1;
>
>                PORTB=0x09;
>                delay=(zeit);
>                count=count+1;
>
>                PORTB=0x05;
>                delay(zeit);
>                count=count+1;
>
>                PORTB=0x06;
>                delay(zeit);
>                count=count+1;
// und hier "}"
Was natürlich sinnfrei ist, da immer alle vier Schritte azsgeführt 
werden.
Ob das delay() auch mit Variablen funktioniert, weiß ich nicht, da ich 
sowas nicht benutzte (es sei denn, es handelt sich um das Delay eines 
RTOS/Betriebssystems).

von c r (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Ob das delay() auch mit Variablen funktioniert

Das tut es, zumindest der Teil müsste tun, was man erwartet.

von Hugo H. (hugohurtig1)


Lesenswert?

Richtig formatiert - und das mach auch die Arduino-IDE, sieht es so aus:
1
void setup()
2
{
3
  DDRB = 0x0F;
4
  PORTB = 0x00;
5
}
6
7
int zeit;
8
int count = 0;
9
10
void loop()
11
12
{
13
  {
14
    if (digitalRead(13) == 1)
15
      //Kein Plan zum stopen und counter einzusetzen
16
17
      else
18
        zeit = 3;
19
        
20
    PORTB = 0x0A;
21
    delay(zeit);
22
    count = count + 1;
23
24
    PORTB = 0x09;
25
    delay = (zeit);
26
    count = count + 1;
27
28
    PORTB = 0x05;
29
    delay(zeit);
30
    count = count + 1;
31
32
    PORTB = 0x06;
33
    delay(zeit);
34
    count = count + 1;
35
36
    if (count < 200) // Schleife wiederholen ?!
37
38
    }
39
40
}

Und korrekt compiliert ird das nicht:

C:\Users\Dieter\Documents\Arduino\sketch_jan12a\sketch_jan12a.ino: In 
function 'void loop()':

sketch_jan12a:17:7: error: expected primary-expression before 'else'

       else

       ^~~~

sketch_jan12a:25:18: error: assignment of function 'void delay(long 
unsigned int)'

     delay = (zeit);

                  ^

sketch_jan12a:25:18: error: cannot convert 'int' to 'void(long unsigned 
int)' in assignment

sketch_jan12a:38:5: error: expected primary-expression before '}' token

     }

     ^

exit status 1
expected primary-expression before 'else'

von Jan W. (magictyphoon)


Lesenswert?

STK500-Besitzer schrieb:
> Ob das delay() auch mit Variablen funktioniert

Würde ich das delay erst nach allen 4 setzen, so läuft es in den 4 sehr 
schnell und macht erst nach den 4 eine verzögerung.

So hat jeder Schritt seine eigene verzögerung, läuft daher rund und 
würde nicht nach jedem 4.'ten stottern.

von Jan W. (magictyphoon)


Lesenswert?

Bei //Schleife wiederholen

und

//Kein Plan zum Stoppen war nicht fertig.

Sieh dir die anderen Fotos an und vergleiche.

von c r (Gast)


Lesenswert?

Hugo H. schrieb:
> Und korrekt compiliert ird das nicht:

Danke!

Womit wir wieder bei

Jan W. schrieb:
> c r schrieb:
> Was auch immer auf deinem Arduino o.ä. läuft, dieser Code ist es nicht.
>
> Doch  !

Wären. Nein, kann er nicht. Der läuft nirgends. Du übersiehst irgendwo 
eine Fehlermeldung, die dir sagt, dass das Kompilieren und Hochladen 
fehlgeschlagen ist.

von Wolfgang (Gast)


Lesenswert?

c r schrieb:
> Und das kompiliert? Schlag mal nach, wie die Klammern bei if...else in C
> gesetzt werden. So macht das keinen Sinn.

Lass dich nicht durch die Einrückungen irritieren. Die sind dem Compiler 
egal.

Hugo H. schrieb:
> Und korrekt compiliert ird das nicht:

Dann solltest du vielleicht das
1
zeit=500;
 aus dem Photo nicht unterschlagen.

Jan W. schrieb:
> 20200112_131229.jpg

von STK500-Besitzer (Gast)


Lesenswert?

Jan W. schrieb:
> Würde ich das delay erst nach allen 4 setzen, so läuft es in den 4 sehr
> schnell und macht erst nach den 4 eine verzögerung.
>
> So hat jeder Schritt seine eigene verzögerung, läuft daher rund und
> würde nicht nach jedem 4.'ten stottern.

Wie du dein Programm aufbaust, ist mir egal, da es deinen Anforderungen 
genügen soll.
Irgendwie kümmerst du dich um nebensächliche Details statt mal das 
Grundproblem in Angriff zu nehmen.


PS: ich bin auch schon länger Ü40, und bringe mir gerade erfolgreich die 
(C-)Programmierng unter Linux bei.

von c r (Gast)


Lesenswert?

Wolfgang schrieb:
> Lass dich nicht durch die Einrückungen irritieren. Die sind dem Compiler
> egal.

Ich weiß, die sind mir beim Versuch einen Sinn in der Klammersetzung zu 
finden auch garnicht aufgefallen.

von Hugo H. (hugohurtig1)


Lesenswert?

Wolfgang schrieb:
> Dann solltest du vielleicht daszeit=500; aus dem Photo nicht
> unterschlagen.

Das Foto ist mir Wurscht. Das "zeit = 500;" hat nichts (aber auch gar 
nichts) mit der Übersetzbarkeit zu tun.

von Hugo H. (hugohurtig1)


Lesenswert?

Wolfgang schrieb:
> Lass dich nicht durch die Einrückungen irritieren. Die sind dem Compiler
> egal.

Du bist echt ein Held. Das soll helfen, die Lesbarkeit (und 
Zusammenhänge) zu verdeutlichen. Wer das nicht rafft sollte besser Bingo 
spielen :-)

Jetzt - nur für Dich - was soll das bewirken:
1
 if (count < 200) // Schleife wiederholen ?!
2
3
    }

??

: Bearbeitet durch User
von c r (Gast)


Lesenswert?

Hugo H. schrieb:
> Das "zeit = 500;" hat nichts (aber auch gar nichts) mit der
> Übersetzbarkeit zu tun.

Der if Block muss entweder explizit einen leeren Codeblock {} enthalten, 
oder eine primary expression, ohne die Zuweisung fehlt beides.

Spätestens im else Block geht ohne {} aber nichts mehr

von STK500-Besitzer (Gast)


Lesenswert?

c r schrieb:
> Der if Block muss entweder explizit einen leeren Codeblock {} enthalten,
> oder eine primary expression, ohne die Zuweisung fehlt beides.

ein ";" würde schon reichen, ist aber nicht so aussagekräftig wie ein 
Codeblock.

von Jan W. (magictyphoon)


Lesenswert?

c r schrieb:
> Spätestens im else Block geht ohne {} aber nichts mehr

Den If - Else Block habe ich in {} gesetzt.
Würde ich das Else allein in {} setzen, so schreit das nach einem If, 
welches nicht gesetzt wurde.

Die Variable zeit=500 habe ich als Tester. Leider ist das nicht der 
gewünschte effekt.

von Hugo H. (hugohurtig1)


Lesenswert?

c r schrieb:
> Der if Block muss entweder explizit einen leeren Codeblock {} enthalten,
> oder eine primary expression, ohne die Zuweisung fehlt beides.

Wo steht das?

von Wolfgang (Gast)


Lesenswert?

Hugo H. schrieb:
> Du bist echt ein Held. Das soll helfen, die Lesbarkeit (und
> Zusammenhänge) zu verdeutlichen. Wer das nicht rafft sollte besser Bingo
> spielen :-)

Falsche Einrückungen, die nichts mit dem zu tun haben, was der Compiler 
sieht, sind eher irreführend.

Die ganzen Portzuweisungen/Delay im Eröffnungspost/Screenshot sieht der 
Compiler nicht als Bestandteil der if-else-Struktur.

von Jan W. (magictyphoon)


Lesenswert?

Wie stelle ich es also an, das:

1. Programm wartet auf Tastendruck
2. Taste betätigt
3. Motor dreht und Programm zählt seine Schritte
4. Schritte nicht erreicht zurück zu 3.
5. Schritte erreicht, Motor stoppt und zurück zu 1.


Ich komm nicht drauf... ?

von Hugo H. (hugohurtig1)


Lesenswert?

Wolfgang schrieb:
> Falsche Einrückungen, die nichts mit dem zu tun haben, was der Compiler
> sieht, sind eher irreführend.

Ja.

Wolfgang schrieb:
> Die ganzen Portzuweisungen/Delay im Eröffnungspost/Screenshot sieht der
> Compiler nicht als Bestandteil der if-else-Struktur.

Ja. Deswegen sollten die auch nicht eingerückt sein. Gut erkannt.

von c r (Gast)


Lesenswert?

Jan W. schrieb:
> Den If - Else Block habe ich in {} gesetzt.
> Würde ich das Else allein in {} setzen, so schreit das nach einem If,
> welches nicht gesetzt wurde.

Nochmal: Zieh dir ein beliebiges Codebeispiel zu if else in C++ rein. 
Deine Klammern ergeben keinen Sinn.

Hugo H. schrieb:
> Wo steht das?

Beispielsweise in deiner Fehlerausgabe oben

von c r (Gast)


Lesenswert?

Jan W. schrieb:
> Wie stelle ich es also an, das:
>
> 1. Programm wartet auf Tastendruck
> 2. Taste betätigt
> 3. Motor dreht und Programm zählt seine Schritte
> 4. Schritte nicht erreicht zurück zu 3.
> 5. Schritte erreicht, Motor stoppt und zurück zu 1.
>
> Ich komm nicht drauf... ?

Garnicht, ohne deinen bestehenden Code zu fixen.

von Hugo H. (hugohurtig1)


Lesenswert?

c r schrieb:
> Beispielsweise in deiner Fehlerausgabe oben

Nochmal für Dich: Wo steht dass

c r schrieb:
> Der if Block muss entweder explizit einen leeren Codeblock {} enthalten,
> oder eine primary expression, ohne die Zuweisung fehlt beides.

Nicht hier - sondern generell?

von c r (Gast)


Lesenswert?

Hugo H. schrieb:
> Nochmal für Dich: Wo steht dass

Hugo H. schrieb:
> C:\Users\Dieter\Documents\Arduino\sketch_jan12a\sketch_jan12a.ino: In
> function 'void loop()':
>
> sketch_jan12a:17:7: error: expected primary-expression before 'else'
>
>        else
>
>        ^~~~

Hugo H. schrieb:
> Nicht hier - sondern generell?

Keine Ahnung. In der C-Spezifikation wohl.

von Jan W. (magictyphoon)


Lesenswert?

Jan W. schrieb:
> Wie stelle ich es also an, das:
>
> 1. Programm wartet auf Tastendruck
> 2. Taste betätigt
> 3. Motor dreht und Programm zählt seine Schritte
> 4. Schritte nicht erreicht zurück zu 3.
> 5. Schritte erreicht, Motor stoppt und zurück zu 1.
>
> Ich komm nicht drauf... ?

Wie würde der Sketch dazu aussehen?

von STK500-Besitzer (Gast)


Lesenswert?

c r schrieb:
> Jan W. schrieb:
>> Wie stelle ich es also an, dass:
>>
>> 1. Programm wartet auf Tastendruck
>> 2. Taste betätigt
>> 3. Motor dreht und Programm zählt seine Schritte
>> 4. Schritte nicht erreicht zurück zu 3.
>> 5. Schritte erreicht, Motor stoppt und zurück zu 1.
>>
>> Ich komm nicht drauf... ?
>
> Gar nicht, ohne deinen bestehenden Code zu fixen.

alles in der Loop makrieren und die Entf-Taste drücken ;)

Der Pseudocode klingt nach eine GOTO-Verwender.
Wie würdest du das denn in BASIC schreiben?

Beitrag #6104105 wurde vom Autor gelöscht.
von Hubert G. (hubertg)


Lesenswert?

Es gibt für Arduino Beispielcode für Schrittmotoren.
Dein Code kann nicht funktionieren und die IDE kompiliert das auch 
nicht, bzw. bringt eine Fehlermeldung.

von Jan W. (magictyphoon)


Angehängte Dateien:

Lesenswert?

STK500-Besitzer schrieb:
> Der Pseudocode klingt nach eine GOTO-Verwender.
> Wie würdest du das denn in BASIC schreiben?

So würde ich es schreiben:

von magictyphoon (Gast)


Lesenswert?

Also wie bekomme ich es hin, das dieser
1
void setup() 
2
{
3
 DDRB=0x0F;
4
 PORTB=0x00;
5
}
6
int zeit;
7
int count=0;
8
9
void loop() 
10
11
 {
12
    if (digitalRead(13)==1)
13
       zeit=500;
14
       // Die obere Zeile (zeit=500) ist soweit ohne belang
15
     
16
                    
17
    else
18
    
19
       zeit=3;
20
            PORTB=0x0A; //1
21
            delay(zeit);
22
            count=count+1;
23
          
24
            PORTB=0x09; //2
25
            delay(zeit);
26
            count=count+1;
27
            
28
            PORTB=0x05; //3
29
            delay(zeit);
30
            count=count+1; 
31
                       
32
            PORTB=0x06; //4
33
            delay(zeit);
34
            count=count+1;     
35
 }

Code mit eingebautem Counter und auf Tastendruck wartend seine Runden 
macht und danach wieder in Wartestellung geht ?!?

Beispiel siehe Commodore BASIC Bild

von Lenny D. (le-do)


Lesenswert?

Die Diskussion scheint etwas chaotisch zu verlaufen, so wie ich das sehe 
gilt folgendes:
- der Code aus dem ersten Post funktioniert nicht, Hugo hat ihn ja 
kopiert und kompiliert, siehe Fehlermeldungen in seinem Post. Es fehlen 
Anweisungen im if(digitalRead==...) oben und im letzten if(count<200)
- Der Code aus dem Handyfoto im zweiten Post hingegen funktioniert, tut 
aber nicht was du gerne hättest. Hier steht jeweils mindestens eine 
Zeile in jeder if()-Anweisung, der code ist also syntaktisch korrekt.
- Versuche bitte den nochmal 1:1 (wirklich 1:1) abzutippen oder wie 
vorgeschlagen einen mobilen Hotspot vom Handy einrichten (dein 
Handy-Internet per WLAN an den PC freigeben also, gibt es genug 
Anleitungen im Netz für Smartphones)
EDIT: Ok immerhin ist das jetzt der echte Code aus dem Handyfoto, das 
ist besser.

Damit der Code korrekt funktioniert muss er besser geklammert werden. 
Nach loop(){{ ... }} kommen 2 Klammerpaare, eines ist überflüssig.
Nach if()... else ... kommt jeweils keine Klammer, das ist fatal. Nur 
die 1 nächste Anweisung wird als Teil des Blocks interpretiert. Beim 
else heißt das also
1
...
2
else
3
    zeit=3; //Teil des else-Blocks
4
        PORTB=0x0A; //*nicht Teil des else-Blocks, wird immer ausgeführt*
5
        //übrigens völlig unabhängig von Einrückung, nur von {}
6
    // und zu weit eingerückt, unübersichtlich
 wird nur konditional ausgeführt, die Zeilen danach die die Schritte 
ausführen aber immer!

Aktuell sollte also der Motor schnell drehen wenn man nichts drückt und 
langsamer solange der Pin mit dem Taster high ist. Ist das so?

: Bearbeitet durch User
von Jan W. (magictyphoon)


Lesenswert?

Lenny D. schrieb:
> Aktuell sollte also der Motor schnell drehen wenn man nichts drückt und
> langsamer solange der Pin mit dem Taster high ist. Ist das so?

Falsch. Er ist langsam, wenn kein HIGH ist und schnell, wenn HIGH ist


Habe mein Handy nun über die Fritzbox mit USB über Theatering oder sowas 
eingerichtet...

: Bearbeitet durch User
von Jan W. (magictyphoon)


Lesenswert?

Hier nochmal der Code, der nun direkt aus meinem Arduino-Sketch kommt:
1
void setup() 
2
{
3
 DDRB=0x0F;
4
 PORTB=0x00;
5
}
6
int zeit;
7
int count=0;
8
9
void loop() 
10
11
 {
12
    if (digitalRead(13)==1)
13
        zeit=500;
14
        
15
       // Die obere Zeile (zeit=500) ist soweit ohne belang
16
     
17
                    
18
    else
19
    
20
       zeit=3;
21
            PORTB=0x0A; //1
22
            delay(zeit);
23
            count=count+1;
24
          
25
            PORTB=0x09; //2
26
            delay(zeit);
27
            count=count+1;
28
            
29
            PORTB=0x05; //3
30
            delay(zeit);
31
            count=count+1; 
32
                       
33
            PORTB=0x06; //4
34
            delay(zeit);
35
            count=count+1;     
36
 }

von Jan W. (magictyphoon)


Lesenswert?

Lenny D. schrieb:
> Aktuell sollte also der Motor schnell drehen wenn man nichts drückt und
> langsamer solange der Pin mit dem Taster high ist. Ist das so?


Er ist Langsam, wenn nichts gedrückt ist und schnell, wenn gedrückt ist.
Warum das genau anders herum ist, weis ich auch nicht.

von Lenny D. (le-do)


Lesenswert?

Hm interessant entweder habe ich einen Denkfehler oder dein Taster ist 
zB gegen Masse und nicht gegen 5V. Wie ist der Taster angeschlossen? Hat 
er einen Pullup/Pulldown-Widerstand oder undefinierten Pegel wenn nicht 
betätigt?

Wenn der Taster nach +5V betätigt und im offenen Zustand ein Pulldown zu 
GND existiert müsste dieser Code hier (fast) wie gewünscht 
funktionieren, siehe Kommentare.
Code compiliert OK, Funktional ungetestet:
1
int zeit; //Deklarationen würde ich vor erster Funktion schreiben
2
int count=0;
3
4
5
void setup() 
6
{
7
  DDRB=0x0F;
8
  PORTB=0x00;
9
}
10
11
12
void loop() {
13
  if (digitalRead(13)==1) {
14
    //Pin 13 ist HIGH -> Motor soll mit 200-Schritt-Abfolge beginnen
15
    count = 0; //am einfachsten indem man Counter zurücksetzt
16
    //TODO: darüber nachdenken was bei mehrfachem Betätigen, Taster halten und bei Prellen passiert
17
    //aktuell: count=0 wird immer wieder ausgefürt werden, solange Taster HIGH
18
    // -> Bewegung beginnt erst mit Loslassen des Tasters
19
20
    //keine Motor-Bewegung, kein Delay -> loop() wird sofort wieder durchlaufen bis Taster losgelassen
21
  }
22
  else {
23
    //Pin 13 ist LOW -> entweder soll Bewegung gestartet werden bis count=200 oder wenn
24
    // count bereits > 200, soll nichts passieren bis Taster erneut gedrückt.
25
    if (count<200) {
26
      // Motor soll sich drehen, also machen wir pro Iteration zB 4 Schritte:
27
      zeit=3;
28
      PORTB=0x0A; //1
29
      delay(zeit);
30
      count=count+1;
31
      
32
      PORTB=0x09; //2
33
      delay(zeit);
34
      count=count+1;
35
      
36
      PORTB=0x05; //3
37
      delay(zeit);
38
      count=count+1; 
39
               
40
      PORTB=0x06; //4
41
      delay(zeit);
42
      count=count+1; 
43
    }
44
    //else: count >200, nichts zu tun
45
  }
46
}

von Theor (Gast)


Lesenswert?

@ Jan

Es scheint mir ein bisschen schwierig Dir einen Rat zu geben.
Das liegt daran, dass Du teilweise ein wenig zu wissen scheinst, 
andererseits aber auch einige Grundlagen in C(++) nicht.
Ausserdem scheinst Du im Moment noch Schwierigkeiten damit zu haben, 
Vorgänge die unabhängig voneinander sind gedanklich vorzustellen und 
irgendwie schriftlich oder bildhaft vorzustellen.

An sich ist nämlich, das Problem ganz einfach zu lösen. Man muss nur 
wissen wie :-)

Aber der Ablauf des Threads und Dein Verhalten hat die Leute auch ein 
wenig unlustig gemacht, Dir was zu erklären oder Dir einfach die Lösung 
hinzuschreiben. Abgesehen davon, liest sich Deine Frage so, dass man Dir 
relativ viele Dinge auf einmal erklären müsste. Das fängt bei der 
Codeformatierung schon an, die allein schon einige Klarheit bringen 
könnte. Das Wesentliche ist aber daran, dass Dir vorläufig die 
"Denkweise" fehlt um zwei in gewisser Weise gleichzeitig ablaufende 
Vorgänge zu beschreiben (sei es in der Form eines Textes in natürlicher 
Sprache oder eine Skizze, sei es in der Form von Code). Das kann man 
zwar erklären, aber erfahrungsgemäß hilft es eigentlich nur an dem 
Knochen mal herumzukauen, selbst wenn dabei keine Lösung ensteht.

Es bleiben daher im Moment nur zwei Möglichkeiten, denke ich.

1. Du lernst zunächst erstmal anhand von sehr einfachen Beispielaufgaben 
weiter C(++). Du schiebst das Projekt insgesamt erstmal auf.

2. Du teilst das Projekt in zwei Teile au, die Du später zusammenführst.
a) Reaktion auf die Tasterbetätigung mit einer LED anstelle des 
Schrittmotors. Dabei wirst Du feststellen, dass Du einen Fall des 
Ablaufs noch nicht berücksichtigt hast.
b) Steuerung des Schrittmotors. Dabei wirst Du vermutlich zunächst auf 
eine sehr simple Lösung kommen, die sich aber nicht einfach mit a) 
zusammenführen lässt. Es wäre gut, wenn Du erstmal so weit gehst um das 
Problem selbst zu "erleben" und dann eine gezieltere Frage stellen 
kannst.

Als direkten Hinweis möchte ich Dir Vorschlagen, mal über Schleifen in 
C(++), insbesondere do-while- und while-Schleifen nachzulesen und 
einfach mal zu versuchen deine Basic-Varianten mit goto als solche 
Schleifen auszudrücken.
Ich kann mir vorstellen, dass meine Vorschläge Dir möglicherweise als 
unnötige Umwege erscheinen und sie Dich vielleicht frustrieren, weil es 
scheinbar "nicht weiter geht" damit. Aber vielleicht kannst Du mir doch 
glauben, dass solche Versuche und die Fehler die man dabei macht, eine 
sehr wertvolle Lernerfahrung sind. Das haben alle guten Programmierer 
einmal durchgemacht und es ist absolut keine Schande.
Erwäge das doch bitte einmal in Ruhe.

Viel Erfolg.

von c r (Gast)


Lesenswert?

TO geht auf Hinweise auf grundlegendste Fehler im Code nicht ein, selbst 
wenn jemand die Komplettlösung liefert, wird er keine Ahnung haben, 
warum es funktioniert und was vorher falsch war.

von Wolfgang (Gast)


Lesenswert?

Jan W. schrieb:
> Hier nochmal der Code, der nun direkt aus meinem Arduino-Sketch kommt:

Der ist immer noch irreführend eingerückt.

von Jan W. (magictyphoon)


Lesenswert?

Na danke... Werde auf Theor's Rat eingehen und mich schlau machen.

Wie oben beschrieben bin ich ein Newbie.

Das ich einen pinMode(pin, typ) auch besetzen kann weis ich auch.

Fand es schade, das man hier am Anfang behauptete, das ich Schüler wäre 
und irgendwelche Tatsachen verheimliche... Diffamierungen sind schei** 
!!

Von cr
>selbst wenn jemand die Komplettlösung liefert, wird er keine Ahnung haben

Finde dieses Zitat schon ziehmlich anmaßend und frech !!!


Werde mich anders behelfen da hier ....... Naja...

von Wolfgang (Gast)


Lesenswert?

Wolfgang schrieb:
> Der ist immer noch irreführend eingerückt.

p.s.
Rufe in der Arduino IDE im Menü Werkzeuge mal die Funktion 
Automatische Formatierung auf.
Dann sollte dir klar werden, wo die Formatierung nicht zum Inhalt 
passen.

von c r (Gast)


Lesenswert?

Jan W. schrieb:
> Finde dieses Zitat schon ziehmlich anmaßend und frech !!!

Ich finde es anmaßend und frech eine Frage zu stellen und die Antworten 
zu ignorieren. Immerhin investieren hier Fremde unentgeltlich Zeit in 
deine Probleme.

Jan W. schrieb:
> Werde mich anders behelfen da hier ....... Naja...

Dir hilft nur auf den Arsch setzen und C++ Grundlagen lernen.

von Theor (Gast)


Lesenswert?

Jan W. schrieb:
> Na danke... Werde auf Theor's Rat eingehen und mich schlau machen.
>
> Wie oben beschrieben bin ich ein Newbie.
>
> Das ich einen pinMode(pin, typ) auch besetzen kann weis ich auch.
>
> Fand es schade, das man hier am Anfang behauptete, das ich Schüler wäre
> und irgendwelche Tatsachen verheimliche... Diffamierungen sind schei**
> !!
>
> Von cr
>>selbst wenn jemand die Komplettlösung liefert, wird er keine Ahnung haben
>
> Finde dieses Zitat schon ziehmlich anmaßend und frech !!!
>
>
> Werde mich anders behelfen da hier ....... Naja...

Ich verstehe Dich, denke ich.

Allerdings würde ich Dir raten, die Bezeichnung als Schüler nicht allzu 
sehr zu dramatisieren.
Erst einmal ist Schüler sein, an sich nichts Schlimmes, oder? Und dann 
lernen intelligente Menschen ihr Leben lang; wenn auch formal nicht als 
"Schüler", so doch faktisch.
Ich denke auch, dass das Wort "verschweigen" nicht allzu sehr 
überbewertet werden darf. Zwar hat es auch eine negative Bedeutung, aber 
die Unterstellung ist hier nicht auf bösartige Motive gerichtet sondern 
auf unbekannte Motive.
Insgesamt, wenn auch unangenehm, würde ich Diffamierung doch eher für 
nicht gegeben halten. Der Ton in diesem Thread ist vergleichsweise 
recht moderat.
Im allgemeinen ist ein rauher Ton eher ein Zeichen dafür, dass man sich 
- mit Verlaub - irgendwie falsch verhalten hat. (Das gilt allerdings 
nicht immer und bei manchen Antwortern hier im Forum garnicht).

Du solltest auch bedenken, dass hier Fragesteller der verschiedensten 
Schattierungen erscheinen. Biite fasse das Folgende als einfache 
Beobachtung auf, nicht als Versuch Dich zu erniedrigen: Deine ersten 
Posts machen, auch bei wohlwollender Interpretation, den Eindruck, 
sorry, eines Schülers, der irgendwie in Zeitdruck geraten ist, der 
morgen noch eine Aufgabe abgeben muss. Leider stellt sich hier in 
solchen Fällen häufig heraus, dass nicht viel gelernt wurde.
Bei allem menschenlichen Respekt muss ich auch leider sagen, dass Du, 
wohl unabsichtlich, den Anschein erweckst, als wenn Du Dich im Moment 
stark übernimmst und einen eher fordernden Ansatz in der Kommunikation 
hast.
Und ich vermute, Du kannst dem zustimmen, dass Deine Kenntnisse und 
Erfahrungen vergleichsweise begrenzt sind.

Dazu kommt, dass Du bisher keinerlei Versuch einer Erklärung Deiner 
Gedankengänge und Entwürfe unternommen hast, und auch keinerlei Analyse 
(und sei sie noch so falsch) geliefert hast. Das erweckt den Anschein, 
als wenn Du selbst, nochmal sorry, nichts leisten willst.

Solche Kritik hinzunehmen, muss einem Erwachsenen der im Leben steht, 
sehr hart ankommen. Andereseits, wer von uns - und ich sicher auch nicht 
- kann schon von sich sagen, dass er alles schon weiß und alles schon 
kann. Jeder von uns muss ab und zu, auch im sozialen Bereich - mal eine 
Kröte schlucken. Das ist menschlich. :-)
Man kann nur versuchen sich selbst treu zu bleiben und gleichzeitg auch 
die andere Seite zu sehen. Man muss nicht aller Kritik zustimmen (Deine 
Kritiker sind auch nur Menschen), aber es lohnt sich doch erstaunlich 
oft, zumindest mal über anderer Leute Aussagen nachzudenken.

In dem Zusammenhang rate ich Dir wärmsten einemal den Artikel 
https://www.mikrocontroller.net/articles/Netiquette und die darin 
verlinkten Seiten.

Mit guten Wünschen, insbesondere weiterem Erfolg ...

von Theor (Gast)


Lesenswert?

Na siehste? Ich hätte meinen Beitrag auch noch einmal lesen sollen. 
Schrecklich viele Rechtschreib- und Grammatikfehler. :-)

von MaWin (Gast)


Lesenswert?

Jan W. schrieb:
> Wie stelle ich es also an, das:
>
> 1. Programm wartet auf Tastendruck
> 2. Taste betätigt
> 3. Motor dreht und Programm zählt seine Schritte
> 4. Schritte nicht erreicht zurück zu 3.
> 5. Schritte erreicht, Motor stoppt und zurück zu 1.
>
> Ich komm nicht drauf... ?
1
#include <Stepper.h>
2
Stepper stepper(200, 8, 9, 10, 11);
3
bool buttondown;
4
loop()
5
{
6
   bool buttonnow=digitalRead(13);
7
   if(buttonnow&&!buttondown)
8
   {  
9
       stepper.setSpeed(30);
10
       stepper.step(200);
11
   }
12
   buttondown=buttonnow;
13
   delay_ms(10);
14
}

von Jan W. (magictyphoon)


Lesenswert?

Danke für den Sketch...

Leider ist der für mein Uno oder Nano dafür nicht geeignet. 
Fehlermeldung: Fehler beim Kompilieren für das Board.

Mittlerweile fuchse ich mich da rein.

Habe es bisher soweit, das der Motor dreht, sobald der Taster 
geschlossen ist und aufhört, wenn er losgelassen wird.

Nun fehlt mir nur noch das er weiter dreht, solange der counter nicht 
erreicht ist.

von c r (Gast)


Lesenswert?

Jan W. schrieb:
> Fehlermeldung: Fehler beim Kompilieren für das Board.

Das ist leider nicht sehr aussagekräftig. Die Arduino IDE bietet in den 
Einstellungen ausführlichere Ausgaben beim Kompilieren und Hochladen an, 
aktivier das mal.

Dann
1
#include <Stepper.h>
2
Stepper stepper(200, 8, 9, 10, 11);
3
bool buttondown;
4
5
void setup() {
6
  // set the speed of the motor to 30 RPMs
7
  stepper.setSpeed(30);
8
}
9
10
void loop()
11
{
12
   bool buttonnow=digitalRead(13);
13
   if(buttonnow&&!buttondown)
14
   {  
15
       stepper.step(200);
16
   }
17
   buttondown=buttonnow;
18
   delay(10);
19
}

Bei der loop() fehlte der Typ void und noch 2 Arduino spezifische 
Fehler, probier den mal.
Das kompiliert auf jeden Fall schonmal.

von Hubert G. (hubertg)


Lesenswert?

Jan W. schrieb:
> Habe es bisher soweit, das der Motor dreht, sobald der Taster
> geschlossen ist und aufhört, wenn er losgelassen wird.

Wenn du den Code von "c r" nicht verwenden willst / kannst, dann zeig 
noch mal deinen. Die Abfrage der Schrittanzahl gehört nach der 
Tastenabfrage. Es gibt allerdings noch weiter Möglichkeiten.

von Lenny D. (le-do)


Lesenswert?

Meinen zweiten Post hast du gesehen?
Nicht so elegant wie die Verwendung der Stepper library, aber sollte 
zumindest tun...

von Johannes S. (Gast)


Lesenswert?

@Jan:
Das delay() sieht erstmal einfach für so eine Aufgabe aus, führt aber zu 
dem Problem das du siehst: währed des delay rennt der µC nur im Kreis 
und macht nix anderes.
Sinnvoller ist es erstmal diese zwei Aufgaben in Unterprogrammen zu 
definieren, z.B.: checkButtons() und processStepper(). Diese werden 
ständig in loop() aufgerufen und dürfen nicht blockieren.
In checkButtons() ist das einfach, digitalRead wird schnell ausgeführt, 
das kann man einfach aufrufen und auswertern.
Das processStepper() darf nicht mit delays blockieren, hier ist eine 
mögliche Lösung eine State Machine. D.h., die Funktion wird aufgerufen, 
guckt in welchem Zustand sie ist, macht was und ist erstmal fertig. Für 
das warten musst du dann mit millis() die aktuelle Zeit abfragen und 
wenn die Zeit für einen Schritt abgelaufen ist auf den nächsten Schritt 
weiterschalten.

Beispiel schnell zusammengehackt, nicht getestet:
1
int state = 0;
2
int waitTime = 0;
3
int steps = 0;
4
unsigned long timeStart;
5
6
void processStepper()
7
{
8
  if (waitTime > 0) {
9
    if (millis() > timeStart + waitTime) {
10
      waitTime = 0;    // time elapsed
11
    } else {
12
      return;          // timer is running, wait
13
    }
14
  }
15
16
  switch (state) {
17
    case 0:
18
      return;        // nothing to do
19
      break;
20
    case 1:
21
      PORTB=0x0A;    // setze Ausgang für step1
22
      state++;       // next step
23
      waitTime = 50; // set wait Time
24
      timeStart = millis();
25
      break;
26
    case 2:
27
      PORTB=0x09;    // setze Ausgang für step2
28
      state++;       // next step
29
      waitTime = 50; // set wait Time
30
      timeStart = millis();
31
      break;
32
    case 3:
33
      PORTB=0x05;    // setze Ausgang für step1
34
      state++;       // next step
35
      waitTime = 50; // set wait Time
36
      timeStart = millis();
37
      break;
38
    case 4:
39
      PORTB=0x06;    // setze Ausgang für step2
40
      steps--;
41
      if (steps > 0) {
42
        state = 1;   // goto first step
43
        waitTime = 50; // set wait Time
44
        timeStart = millis();
45
      } else {
46
        state = 0;   // stop
47
      }
48
      break;
49
  }
50
}
51
52
void startStepper(int nSteps) 
53
{
54
  steps = nSteps;
55
  state = 1;
56
}

von Jan W. (magictyphoon)


Lesenswert?

Johannes S. schrieb:
> Das delay() sieht erstmal einfach für so eine Aufgabe aus, führt aber zu
> dem Problem das du siehst: währed des delay rennt der µC nur im Kreis
> und macht nix anderes.

Er soll ja in dieser Zeit auch nichts anderes machen. Sobald ein Tadter 
gedrückt wurde, soll das Programm starten und der Motor laufen, auch 
nach dem loslassen des Tasters. Während die Schleife läuft, zählt ein 
Counter jeden Schritt von 0-199. Nachdem der Counter sein Soll erreicht 
hat, stoppt der Motor und das Programm wartet wieder auf den Taster.

Bin grad auf Arbeit. Etwas fehlt noch. Aber so ungefähr...
1
void setup() 
2
{ 
3
  DDRB=0x0F; 
4
  PORTB=0x00; 
5
} 
6
7
int zeit; 
8
int count=0;;
9
10
void loop() 
11
12
13
   if (digitalRead(13)==0);
14
15
     {
16
       zeit=3; 
17
       PORTB=0x0A; //1 
18
       delay(zeit); 
19
       count=count+1; 
20
21
       PORTB=0x09; //2 
22
       delay(zeit); 
23
       count=count+1; 
24
       
25
       PORTB=0x05; //3 
26
       delay(zeit); 
27
       count=count+1; 
28
29
       PORTB=0x06; //4 
30
       delay(zeit); 
31
       count=count+1; 
32
     }

von Hubert G. (hubertg)


Lesenswert?

1
int zeit; 
2
int count=0;
3
int run;
4
5
void setup() 
6
{ 
7
  DDRB=0x0F; 
8
  PORTB=0x00; 
9
  zeit=50; 
10
} 
11
12
void loop(){ 
13
14
15
 if ((digitalRead(13)==0)&& (run==0)){ // Wenn Taste gedrückt und kein Lauf
16
      run = 1;
17
  }
18
   if ((count <300)&&(run == 1)){
19
          
20
       PORTB=0x0A; //1 
21
       delay(zeit); 
22
       count=count+1; 
23
24
       PORTB=0x09; //2 
25
       delay(zeit); 
26
       count=count+1; 
27
       
28
       PORTB=0x05; //3 
29
       delay(zeit); 
30
       count=count+1; 
31
32
       PORTB=0x06; //4 
33
       delay(zeit); 
34
       count=count+1; 
35
     }
36
     else{
37
      run = 0;
38
      count = 0;
39
      PORTB=0x00; 
40
      }
41
}

So läuft der Code mal. Wie weit sinnvoll sei dahin gestellt.

von Jan W. (magictyphoon)


Lesenswert?

Habs komplett hinbekommen... Dank der einfühlsamen Worte von Theor.

Habe es gestern Abend mit einer While-Schleife erledigt und einer 
Abfrage wie weit der Counter ist. Selbst eine LED leuchtet über einen 
anderen Pin, solange es läuft.

Werde mir jetzt noch ein paar Gedanken über ein Tipp-Betrieb machen und 
dann ist's vollbracht.


Theard kann geschlossen werden.

??

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.