Forum: Mikrocontroller und Digitale Elektronik Schrittmotoransteuerung


von Gerd (Gast)


Lesenswert?

Hallo zusammen,
Kann mir jemand verraten weshalb ich nicht von dem Linkslauf in den 
Rechtslauf umschalten kann. Hab ich die Bedingungen falsch gesetzt. Ich 
bitte dringend um Hilfe!!
1
#include <t89c51ac2.h> // Header für Controller "AT89C51AC3" 
2
#include <stdio.h> 
3
/*------------------------------------------------------------------- 
4
Deklarationen von Variablen und Konstanten 
5
--------------------------------------------------------------------*/ 
6
//unsigned char x; 
7
bit reslo; 
8
9
bit lislo; 
10
11
sfr eingang = 0x90; 
12
/*-------------------------------------------------------------------- 
13
Hauptprogramm 
14
----------------------------------------------------------------------*/ 
15
void re_slow(void); 
16
17
void li_slow(void); 
18
19
void zeit(int i, int k); //Prototypen-Anmeldung 
20
void main(void) 
21
{ 
22
    P2=0x00; 
23
    eingang=255; 
24
    reslo = 0; 
25
26
    lislo = 0; 
27
28
    while(1) 
29
    { 
30
        switch(eingang) 
31
        { 
32
        case 0xFE: 
33
            re_slow(); 
34
            break; 
35
36
        case 0xFB: 
37
            li_slow(); 
38
            break; 
39
40
        default: 
41
            //P4=0xFF; 
42
            break; 
43
        } 
44
    } 
45
} 
46
/*----------------------------------------------------------------------- 
47
Zusatzfunktionen 
48
-------------------------------------------------------------------------*/ 
49
50
void re_slow(void) // Funktion Rechtslauf langsam 
51
{ 
52
53
    reslo=1; 
54
    while(reslo) 
55
    {       
56
        if(P1_0==0){      // Hier komme ich nicht weiter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!????????????????????????? 
57
            P2=0x0C; // Bitmuster 1 Rechtslauf 
58
            zeit(5,3000); // Zeitverzögerung 
59
            P2=0x09; // Bitmuster 2 Rechtslauf 
60
            zeit(5,3000); 
61
            P2=0x03; // Bitmuster 3 Rechtslauf 
62
            zeit(5,3000); 
63
            P2=0x06; // Bitmuster 4 Rechtslauf 
64
            zeit(5,3000); 
65
            if (eingang == 0xEF) 
66
            { 
67
68
                //P2=0x00; 
69
                while(P1_0==0){}                     // Hier komme ich nicht weiter ich habe es mit Polling versucht!!!!!!!!!!!!!!!!!!!!!!!!!!!!?????????????????????????? 
70
                reslo = 0; 
71
72
            } 
73
        } 
74
    } 
75
} 
76
77
78
void li_slow(void) // Funktion Linkslauf langsam 
79
{ 
80
    lislo=1; 
81
    while(lislo) 
82
    {   
83
        if(P1_2==0){ 
84
            P2=0x06; // Bitmuster 1 Linkslauf 
85
            zeit(5,3000); 
86
            P2=0x03; // Bitmuster 2 Linkslauf 
87
            zeit(5,3000); 
88
            P2=0x09; // Bitmuster 3 Linkslauf 
89
            zeit(5,3000); 
90
            P2=0x0C; // Bitmuster 4 Linkslauf 
91
            zeit(5,3000); 
92
            if (eingang == 0xEF) 
93
            { 
94
                P2=0x00; 
95
                while(P1_2==0){} 
96
                lislo = 0; 
97
98
            } 
99
        } 
100
    } 
101
} 
102
103
void zeit(int i,int k) // Funktion Zeit 
104
{ 
105
    unsigned int x; 
106
    unsigned int y; 
107
    for(y=0;y<=i;y++) 
108
    { 
109
        for(x=0;x<=k;x++); //Int-Wert 62 ergibt 500 Mikrosekunden Delay 
110
    } 
111
}

von STK500-Besitzer (Gast)


Lesenswert?

Wird "eingang" auch irgendwo noch verändert?

von Karl H. (kbuchegg)


Lesenswert?

Deine AUswertung von 'eingang' ist mehr als suspekt.

1) Schreib das doch mit vernüftiger Schreibweise und nicht
   mit Hex-Zahlen

#define PIN_4   4

   if( eingang & (1 << PIN_4) )
   ergibt dann TRUE, wenn der Eingang am Bit 4 eine 1 hat

   if( !( eingang & (1 << PIN_4) ) )
   ergibt dann TRUE, wenn der Eingang am Bit 4 eine 0 führt

   Anstelle von 'PIN_4 nimmt man dann natürlich einen
   vernünftigen Namen, der die FUnktion des Eingangspins wiederspiegelt
   Ist da zb ein Roter Schalter am Port angeschlossen, dann
   könnte man nehmen

#define RED_SWITCH  4

    if( eingang & (1 << RED_SWITCH) )

    dann kann auch ein Blinder greifen, dass hier wohl eine AUswertung
    des roten SChalters erfolgen wird.

    Ist an diesem Pin eine Lichtschranke, die auslöst, wenn die Katzen-
    klappe ihren oberen Totpunkt erreicht hat, dann könnte das heißen

#define KLAPPE_OBEN  4

    if( eingang & (1 << KLAPPE_OBEN) )

     und wieder kann ein Blinder greifen, dass hier wohl die Abfrage
     sein wird, mit der die Endstellung der Katzenklappe überwacht
     wird.

2) In der Hauptschleife vergleichst du das Eingangsbyte mit 0xFE
   Innerhalb der Funktion aber mit 0xEF


Nimm solche Dinge nicht auf die leichte SChulter. Ob Programme leicht zu 
verstehen sind, ob man Fehler leicht findet, hängt nicht unwesentlich 
davon ab, wieviel Geschick du in ein LESBARES Programm steckst. Deine 
Hex-Zahlen sind aber nicht lesbar. Das ist einfach nur eine Zahl, die 
einem beim Programmlesen nichts erzählt, die einem nichts sagt. Ganz 
abgesehen davon, dass es leicht ist, an 2 verschiedenen Programmstellen 
einen Zahlendreher einzubauen ohne es zu merken. Mit ordentlichen Namen 
passiert das nicht.

von Karl H. (kbuchegg)


Lesenswert?

Das hier sieht auch suspekt aus
1
   while(reslo) 
2
    {       
3
        if(P1_0==0)
4
        {
5
6
            ....
7
8
            if (eingang == 0xEF) 
9
            { 
10
                while(P1_0==0)
11
                {
12
                }
13
14
                reslo = 0; 
15
16
            } 
17
        } 
18
    }

aus der äusseren while Schleife geht es nur dann raus, wenn reslo zu 0 
wird.
reslo kann aber nur dann 0 werden, wenn

 * P1_0   einen Wert von 0 hat

nur in dem Fall findet dann auch die Abfrage von eingang statt.

 * Kommt da der richtige Wert, dann fängt sich das Programm in einer 
while Schleife die solange läuft wie P1_0 gleich 0 ist.

 * P1_0 muss aber 0 gewesen sein, sonst wärst du überhaupt nie auf die 
Abfrage gekommen.

Ist das so gewollt?

von Gerd (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Wird "eingang" auch irgendwo noch verändert?

Nicht das ich wüsste, dies ist ein quellcode von meinem Lehrer. Dieser 
aber nicht fertig war. Ich habe versucht mittels polling einen Rechts 
und Linkslauf anzusteuern. Ehrlich gesagt kenn ich mich nicht wirklich 
aus und kann jetzt hier groß mitreden. Um jede Hilfe bin ich äußerst 
dankbar.

Lg

von Karl H. (kbuchegg)


Lesenswert?

Dazu müsste man erst mal wissen, was diese ganzen Eingänge steuern. Das 
ist (in meinen Augen) ein heilloses Ducheinander.

Wie wählst du aus, ob Rechts/Linslauf?
Wie findet sich das im Programm wieder?

(SChmeiss das Programm weg und schreib es neu. Da blickt doch kein 
Mensch mehr durch, wie das mit den Eingangsabfragen gedacht ist)

von Gerd (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Dazu müsste man erst mal wissen, was diese ganzen Eingänge steuern. Das
> ist (in meinen Augen) ein heilloses Ducheinander.
>
> Wie wählst du aus, ob Rechts/Linslauf?
> Wie findet sich das im Programm wieder?
>
> (SChmeiss das Programm weg und schreib es neu. Da blickt doch kein
> Mensch mehr durch, wie das mit den Eingangsabfragen gedacht ist)

Es wäre schön wenn ich das könnte, ich fühl mich nicht wirklich in der 
Lage gibt es hier vielleicht schon fertige Programme in c.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Gerd schrieb:
> gibt es hier vielleicht schon fertige Programme in c.

wird dann der Autor des fertigen Programmes auch gegenüber deinem Leher 
erwähnt und bekommt eine Note? Dann mach ich auch mit.

von Karl H. (kbuchegg)


Lesenswert?

Gerd schrieb:
> Karl Heinz Buchegger schrieb:
>> Dazu müsste man erst mal wissen, was diese ganzen Eingänge steuern. Das
>> ist (in meinen Augen) ein heilloses Ducheinander.
>>
>> Wie wählst du aus, ob Rechts/Linslauf?
>> Wie findet sich das im Programm wieder?
>>
>> (SChmeiss das Programm weg und schreib es neu. Da blickt doch kein
>> Mensch mehr durch, wie das mit den Eingangsabfragen gedacht ist)
>
> Es wäre schön wenn ich das könnte, ich fühl mich nicht wirklich in der
> Lage

Na komm.

Du wirst doch wohl einen Eingang abfragen können! Sonst muss ich mich 
schon fragen, warum du überhaupt auf die Idee kommst, du könntest da 
irgendwas programmieren.

Und die Ansteuerung des Schrittmotors ist doch ganz simpel
Nacheinander die 4 Werte an einem Port ausgeben und dazwischen ein wenig 
warten. Das kann man auch eleganter machen, wie es dein Lehrer dir 
vorgegeben hat, aber fürs erste ist es auch so ok.

Das ist doch nun wirklich keine Raketentechnik.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Das ist doch nun wirklich keine Raketentechnik.

1
..
2
int main()
3
{
4
  ...
5
6
  Endlosschleife {
7
8
    wenn der Eingang für rechts eingeschaltet ist {
9
      gib die 4 Werte in der richtigen Reihenfolge für
10
      Rechtslauf aus
11
    }
12
13
    sonst: wenn der Eingang für links eingeschaltet ist {
14
      gib die 4 Werte in der richtigen Reihenfolge für
15
      Linkslauf aus
16
    }
17
  }
18
}

fertig. WEnn da nicht noch irgendwelche Endschalter im SPiel sind, 
sondern es erst mal nur darum geht, dass sich der Motor überhaupt 
rechts/links dreht, dann wars das dann schon.

Jeder der eine LED abhängig davon ob ein Taster gedrückt ist einschalten 
kann, kriegt das hin.

von Gerd (Gast)


Lesenswert?

> Jeder der eine LED abhängig davon ob ein Taster gedrückt ist einschalten
> kann, kriegt das hin.
Leider sind noch Endschalter mit im Spiel ich baue Model So zusagen ein 
Rolltor einer Garage hierbei nutze ich Ribkontakte als Endschalter was 
muss ich bei der Programmierung dann beachten etwa mit Polling so wie 
ich es oben bereits versucht habe.

von Karl H. (kbuchegg)


Lesenswert?

Gerd schrieb:
>> Jeder der eine LED abhängig davon ob ein Taster gedrückt ist einschalten
>> kann, kriegt das hin.
> Leider sind noch Endschalter mit im Spiel

Dann gibt es eben noch jeweils eine Zusatzbedingung
1
  ...
2
3
  Endlosschleife {
4
5
    Wenn der Schalter für Rechtslauf eingeschaltet ist
6
    UND der Endschalter für den rechten Anschlag nicht eingeschaltet ist
7
8
       DANN gibt die 4 Werte für Rechtslauf in der richtigen
9
          Reihenfolge einmal aus
10
11
   ...

Ich wollte dir die Sache für deine ersten Schritte einfach machen, aber 
mir kommt vor, du stehst da wie die Maus vor der Schlange. Vor einem 
Bild einer Schlange, denn du hast schon Angst vor etwas, noch ehe du es 
probiert hast.

von Gerd (Gast)


Lesenswert?

Also soweit bin ich jetzt mal. Kann mir jemand sagen ob das soweit sinn 
macht und wie ich jetzt genau die Bedingungen mit den Endschaltern rein 
bekomm?

Ein Beispiel das sich an meinem Quelltext orientiert würde mir sehr 
weiterhelfen

Vielen Dank im Voraus.

von Gerd (Gast)


Lesenswert?

Gerd schrieb:
> Also soweit bin ich jetzt mal. Kann mir jemand sagen ob das soweit sinn
> macht und wie ich jetzt genau die Bedingungen mit den Endschaltern rein
> bekomm?
>
> Ein Beispiel das sich an meinem Quelltext orientiert würde mir sehr
> weiterhelfen
>
> Vielen Dank im Voraus.
1
 #include<t89c51ac2.h>
2
#include <stdio.h>
3
4
 
5
6
void verz(unsigned int zaehler);
7
void verz(unsigned int zaehler){
8
  unsigned int i;
9
  for(i=0;i<zaehler;i++){
10
    }
11
  }
12
13
 unsigned int zaehler=65000;
14
void main (void){
15
  P2=0;
16
  P1=0;
17
while(1){
18
  if(P1_0==1){
19
      P2=0x0C; // Bitmuster 1 Rechtslauf 
20
            verz(25000 ); // Zeitverzögerung 
21
            P2=0x09; // Bitmuster 2 Rechtslauf 
22
            verz( 25000);
23
            P2=0x03; // Bitmuster 3 Rechtslauf 
24
            verz(25000 ); 
25
            P2=0x06; // Bitmuster 4 Rechtslauf 
26
            verz(25000 );
27
      
28
      }
29
      else if(P1_1==1){
30
        P2=0x06; // Bitmuster 1 Linkslauf
31
      verz(25000 ); // Zeitverzögerung 
32
      P2=0x03; // Bitmuster 2 Linkslauf
33
      verz(25000 ); // Zeitverzögerung 
34
      P2=0x09; // Bitmuster 3 Linkslauf
35
      verz(25000 ); // Zeitverzögerung 
36
      P2=0x0C; // Bitmuster 4 Linkslauf
37
      verz(25000 ); // Zeitverzögerung 
38
         }
39
        } 
40
    
41
    
42
    
43
    }

von Hinz (Gast)


Lesenswert?

Wenn du deine Port_Pins schon nicht so benennst, dass man als 
Außenstehender direkt sieht, was wo dran hängt, beschreib das doch bitte 
in drei kurzen Sätzen.
Wo legst du in deinem Programm fest, was Eingang und was Ausgang ist?

von Gerd (Gast)


Lesenswert?

//P1_0 ist der Eingang für einen Linkslauf

//P1_1 ist der Eingang für den Rechtslauf

P2 ist der Ausgang

von Hinz (Gast)


Lesenswert?

Gerd schrieb:
> P2 ist der Ausgang
Dann steht zu vermuten, dass von dem Ausgang P2 nur das untere Nibble 
benutzt wird und darüber direkt die Phasensignale für den Schrittmotor 
ausgegeben werden. Richtig?

Warum legst du nicht einfach ein Array mit den Phasensignalen an und 
nimmst einen Phasenzähler, der bei Linkslauf inkrementiert und bei 
Rechtslauf dekrementiert wird.

Vorausgesetzt, deine beiden Signale für Linkslauf und Rechtslauf (P1_0 
und P1_1) treten nicht gleichzeitig auf, könnte das dann als Pseudocode 
so aussehen

PhaseCode [0..3] = (0x0c, 0x09, 0x03, 0x06)

TSTEP=25000
while (1)
  {
     if (P1_0)      Phase++     'Linkslauf
     else if (P1_1) Phase--     'Rechtslauf

     P2 = PhaseCode[Phase & 0x03)
     delay(TSTEP)
  }

von Gerd (Gast)


Lesenswert?

Es ist einfacher gesagt als getan !!!
Könntest du mir vielleicht so ein Quellcode mal schreiben ich komm 
einfach grad gar nicht mehr mit

von Karl H. (kbuchegg)


Lesenswert?

Hinz schrieb:

> Warum legst du nicht einfach ein Array mit den Phasensignalen an und
> nimmst einen Phasenzähler, der bei Linkslauf inkrementiert und bei
> Rechtslauf dekrementiert wird.

Machs ihm nicht zu schwer.
Der Mann hat schon Schwierigkeiten genug mit einem simplen logischen 
Und.

Du überforderst ihn gerade.

von Hinz (Gast)


Lesenswert?

Gerd schrieb:
> Es ist einfacher gesagt als getan !!!
Was fehlt dir denn?

Grundlage/Referenzen zu C findest du z.B. in
http://de.wikibooks.org/wiki/C-Programmierung

von Gerd (Gast)


Lesenswert?

was haltet ihr von dem Quelltext. Es scheint mir als wie es so 
funktionieren könnte. Also wenn ich den Taster P1_0 betätige wird der 
Rechtslauf betätigt, wenn jemand P1_1 zwischenzeitlich betätigt wird 
eine Verriegelung vorgenommen weil nur Eine Laufrichtung eingeschlagen 
werden kann das gleiche gilt auch anderst herum. Kann mir jemand sagen 
wie ich die direkte Umschaltung mache.

lg

1
#include <t89c51ac2.h> // Header für Controller "AT89C51AC3" 
2
#include <stdio.h>
3
4
#define stepper P1_0  //Eingang für Rechtslauf
5
#define stepper P1_1   //Eingang für Linkslauf
6
void delay();
7
8
void main()
9
10
11
{
12
        while(1){
13
    if(P1_0==0){
14
                  P2= 0x0C;     //P2 ausgang zum Schrittmotor 
15
                  delay();
16
                  P2 = 0x09;
17
                  delay();
18
                 P2 = 0x03;
19
                  delay();
20
                  P2 = 0x06;
21
                  delay();
22
          while(P1_1==0){}
23
    }   if(P1_1==0){
24
          P2= 0x06;
25
                  delay();
26
                  P2 = 0x03;
27
                  delay();
28
                   P2 = 0x09; 
29
                  delay();
30
                  P2 = 0x0C;
31
                  delay();
32
          while(P1_0==0){}
33
34
        }
35
36
        }
37
}
38
void delay(){
39
        unsigned char i,j,k;
40
        for(i=0;i<6;i++)
41
                for(j=0;j<255;j++)
42
                        for(k=0;k<255;k++);
43
}

von Gerd (Gast)


Lesenswert?

Kann man dieses Programm in einer Simulation testen um zu schauen, ob 
Schritte übersprungen werden??

von Karl H. (kbuchegg)


Lesenswert?

Dazu solltest du dich mal fragen, wie es eigentlich dazu kommt, dass 
Schritte übersprungen werden.

Das passiert nicht, weil die Steuerung die Schritte nicht erzeugt, 
sondern weil der Motor mit der Schritt-Geschwindigkeit nicht mehr 
mitkommt. Das kann sein, weil die Schrittgeschwindigkeit grundsätzlich 
schon zu hoch ist, das kann aber auch sein, weil der Motor banal gesagt, 
es nicht schafft, die Last in der vorgegebenen Zeit eben um einen 
Schritt zu bewegen. Und genau so wie auch du zb einen LKW nicht durch 
Seilziehen aus dem Stand heraus auf 5 km/h beschleunigen kannst (du 
kannst die 5km/h erreichen, wenn man dir genug Zeit lässt und du den LKW 
2 Stunden lang immer ein kleines bischen schneller ziehen kannst) 
genauso schafft es auch ein Schrittmotor nicht, aus den Stand heraus 
eine gewisse Geschwindigkeit zu erreichen, sondern er muss erst mal mit 
kleinen Drehzahlen anfangen um dann sukzessive schneller werden zu 
könnnen.

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.