Forum: Mikrocontroller und Digitale Elektronik Variablen vergleichen


von Andi (Gast)


Lesenswert?

hallo leute,
bin noch relativer anfänger in c programmierung und habe darum eine 
frage zur programmierung, die für viele von euch leicht zu beantworten 
sein dürfte:

ich habe ein programm in dem ich i, a, n und  p vergleichen will.

aber mein programm funktioniert nicht weil ich glaub ich es falsch 
geschrieben habe:

mein ausschnitt:

if(i==0 & a==0 & n==0& p>100 )

kann man das so schreiben?

gruß

von Matthias L. (Gast)


Lesenswert?

1
if  (  i==0 && a==0 && n==0  && p>100 )

von Martin M. (martin69)


Lesenswert?

muß so geschrieben werden:

if ( (i==0) && (a==0) && (n==0) && (p>100) )

von Andi (Gast)


Lesenswert?

Danke schon mal für eure antworten.
nur welcher von den beiden Vorschlägen ist der Richtige?

Ich habe jetzt mal durchprobiert aber keiner dieser Vorschläge führt zum 
Ziel.

Wer kann mir sagen wie es richtig geht?

gruß

von Karl H. (kbuchegg)


Lesenswert?

Beide sind identisch.
Die Klammern sind an dieser Stelle nicht notwendig, schaden aber auch 
nicht

> Ich habe jetzt mal durchprobiert aber keiner dieser Vorschläge
> führt zum Ziel.

Dein Problem liegt an einer anderen Stelle

von Mano W. (Firma: ---) (manow)


Lesenswert?

schau dir mal das an (Rangfolge der Operatoren)

http://pronix.linuxdelta.de/C/standard_C/c_programmierung_30.shtml

dann wird dir klar welche der beiden Lösungen funktioniert (oder beide)? 
Es ist die Priorität der Operatoren == und && interessant!

(Bezogen auf die Klammerung, nicht auf dein Problem!!!)

von Wolfgang Mües (Gast)


Lesenswert?

Beide sind richtig. Die Klammern um die inneren Ausdrücke sind optional.

Poste doch mal einen größeren Ausschnitt aus Deinem Programm, und 
berichte mal, was es macht und was nicht.

von Andi (Gast)


Lesenswert?

mein Programm steuert 2 Servos von einem Schwenkarm mit einem Greifer. 
Hier der größere Programmausschnitt.



#include "RP6RobotBaseLib.h"

uint8_t i;
uint8_t a;
uint8_t n;
uint8_t p;
uint8_t z;

void task_servo(void)
{

if(getStopwatch1() >100 || z==1) // Greifer schließen
{
while(i<52)
{
writeString_P("Greifer schließen\n");
PORTC |=(1<<0);
mSleep(1);
PORTC &=~ (1<<0);
mSleep(19);
i++;}
}


if(i>50)  // Schwenkarm nach oben
{
while(a<52)
{
writeString_P("Schwenkarm nach oben\n");
PORTC |=(1<<1);
mSleep(2);
PORTC &=~ (1<<1);
mSleep(18);
i==0;
a++;}
}


if(a>50) // Greifer öffnen
{
while(n<100)
{
writeString_P("Greifer öffnen\n");
PORTC |=(1<<0);
mSleep(2);
PORTC &=~ (1<<0);
mSleep(18);
a==0;
n++;}

}

if(n>98) //Schwenkarm wieder nach unten
{
while(p<102)
{
writeString_P("Schwenkarm wieder nach unten\n");
PORTC |=(1<<1);
mSleep(1);
PORTC &=~ (1<<1);
mSleep(19);
n==0;
p++;}
}

if(p>100)
{p==0;}
}

void ZyklusKomplett(void)
{
if((i==0) && (a==0) && (n==0) && (p==0)  )

  {z==1;
  writeString_P("Zyklus komplett\n");  //Zyklus komplett
  }

if(z==1 & p==0)  //Zyklus nicht komplett
  {z==0;
  writeString_P("Zyklus nicht komplett\n");}
}


int main(void)
{
initRobotBase();
startStopwatch1();
ZyklusKomplett();
mSleep(1000);
setStopwatch1(0);

DDRC |=(1<<1);    //PORT 1 von Register C als Ausgang
DDRB &=~(1<<0);  //PORT 0 von Register B als Eingang
DDRC &=~(1<<6);  //PORT 6 von Register C als Eingang
DDRC |= (1<<0);  //PORT 0 von Register C als Ausgang




while(1)
{task_servo();
}

}

von Andi (Gast)


Lesenswert?

Zur Erklärung. Der Arm startet mit geöffneten Greifer und ist in der 
unteren Endlage.

Mit dem Programm soll er zuerst den Greifer schließen, dann nach oben 
schwenken, dann den Greifer wieder öffnen und dann wieder nach unten 
schwenken.

Bis dahin funktioniert das Programm einwandfrei.

Nur hab ich es so programmiert das es dann wieder von vorne also wieder 
mit dem zugreifen beginnen soll aber das funktioniert irgendwie nicht.

gruß

von Mano W. (Firma: ---) (manow)


Lesenswert?

1
  {z==0;

Diese Zeile bringt nichts! Du vergleichst z auf 0, ist das wirklich 
gewollt oder möchtest Du eine Zuweisung von z = 0? (kommt zwei Mal vor)
1
  if(z==1 & p==0)

schreibt man mit logischen Unds && und nicht mit & bitweise Unds

von Andi (Gast)


Lesenswert?

An der Zeile liegts aber auch nicht.
Das Problem ist, dass Zyklus Komplett nie ausgeführt wird. Bis dahin 
funktioniert alles aber dann hängts.

Ja du hast recht jetzt hab ich das Programm nochmal abgeändert, aber es 
funktioniert immer noch nicht:

#include "RP6RobotBaseLib.h"

uint8_t i;
uint8_t a;
uint8_t n;
uint8_t p;
uint8_t z;

void task_servo(void)
{

if(getStopwatch1()>200 || z==1) // Greifer schließen
{
while(i<52)
{
writeString_P("Greifer schließen\n");
PORTC |=(1<<0);
mSleep(1);
PORTC &=~ (1<<0);
mSleep(19);
i++;}
}


if(i>50)  // Schwenkarm nach oben
{
while(a<52)
{
writeString_P("Schwenkarm nach oben\n");
PORTC |=(1<<1);
mSleep(2);
PORTC &=~ (1<<1);
mSleep(18);
i==0;
a++;}
}


if(a>50) // Greifer öffnen
{
while(n<100)
{
writeString_P("Greifer öffnen\n");
PORTC |=(1<<0);
mSleep(2);
PORTC &=~ (1<<0);
mSleep(18);
setStopwatch1(0);
a==0;
n++;}

}

if(n>98) //Schwenkarm wieder nach unten
{
while(p<102)
{
writeString_P("Schwenkarm wieder nach unten\n");
PORTC |=(1<<1);
mSleep(1);
PORTC &=~ (1<<1);
mSleep(19);
n==0;
p++;}
}

if(p>100)
{p==0;
setStopwatch1(0);}
}

void ZyklusKomplett(void)
{
if((i==0) && (a==0) && (n==0) && (p==0)  )

  {z==1;
  writeString_P("Zyklus komplett\n");  //Zyklus komplett
  }


}


int main(void)
{
initRobotBase();
startStopwatch1();
ZyklusKomplett();
mSleep(1000);
setStopwatch1(0);

DDRC |=(1<<1);    //PORT 1 von Register C als Ausgang
DDRB &=~(1<<0);  //PORT 0 von Register B als Eingang
DDRC &=~(1<<6);  //PORT 6 von Register C als Eingang
DDRC |= (1<<0);  //PORT 0 von Register C als Ausgang




while(1)
{task_servo();
}

}

von Sven P. (Gast)


Lesenswert?

- [ c ] zum Formatieren, sonst Dateianhang
- ordentlich einrücken
- da steht immer noch == als Zuweisung

von Andi (Gast)


Lesenswert?

Wo meinst du genau? Falls du z==1 meinst, kann ich nur sagen, dass das 
so gewollt ist.

nämlich deshalb:
1
if(getStopwatch1() >100 || z==1) // Greifer schließen

von Mano W. (Firma: ---) (manow)


Lesenswert?

Deine DDR setzt Du auch ziemlich spät, hab ich gerade gesehen. Hat das 
einen besonderen Grund?

Ich würd das auch ein wenig anders schreiben... Einfach mal im Tutorial 
hier nachlesen und ein wenig C Grundlagen noch mal anschauen
1
int main(void)
2
{
3
   DDRC |=(1<<1);    //PORT 1 von Register C als Ausgang
4
   DDRB &=~(1<<0);  //PORT 0 von Register B als Eingang
5
   DDRC &=~(1<<6);  //PORT 6 von Register C als Eingang
6
   DDRC |= (1<<0);  //PORT 0 von Register C als Ausgang
7
8
   initRobotBase();
9
   startStopwatch1();
10
   ZyklusKomplett();
11
   mSleep(1000);
12
   setStopwatch1(0);
13
14
  .
15
  .
16
  .

von Mano W. (Firma: ---) (manow)


Lesenswert?

Andi wrote:
> Wo meinst du genau? Falls du z==1 meinst, kann ich nur sagen, dass das
> so gewollt ist.
>
> nämlich deshalb:
>
>
1
if(getStopwatch1() >100 || z==1) // Greifer schließen

schau mal deinen Code an wo Du vergleiche machst, die nichts bringen, 
statt Zuweisung

 == und = ist nicht das gleiche!!!

von Andi (Gast)


Lesenswert?

Ne, das war keine Absicht, jetzt hab ich es mal umgeändert aber an dem 
liegt es auch nicht.

Aber mein Problem besteht immer noch: Zyklus komplett wird nicht 
ausgeführt:

1
#include "RP6RobotBaseLib.h"
2
3
uint8_t i;
4
uint8_t a;
5
uint8_t n;
6
uint8_t p;
7
uint8_t z;
8
9
void task_servo(void)
10
{
11
12
if(getStopwatch1()>200 || z==1) // Greifer schließen 
13
{
14
while(i<52)
15
{
16
writeString_P("Greifer schließen\n");
17
PORTC |=(1<<0);
18
mSleep(1);
19
PORTC &=~ (1<<0);
20
mSleep(19);
21
i++;}
22
}
23
24
25
if(i>50)  // Schwenkarm nach oben
26
{
27
while(a<52)
28
{
29
writeString_P("Schwenkarm nach oben\n");
30
PORTC |=(1<<1); 
31
mSleep(2);
32
PORTC &=~ (1<<1);
33
mSleep(18);
34
i==0;
35
a++;}
36
}
37
38
39
if(a>50) // Greifer öffnen                                      
40
{
41
while(n<100)
42
{
43
writeString_P("Greifer öffnen\n");
44
PORTC |=(1<<0);
45
mSleep(2);
46
PORTC &=~ (1<<0);
47
mSleep(18);
48
setStopwatch1(0);
49
a==0;
50
n++;}
51
52
}
53
54
if(n>98) //Schwenkarm wieder nach unten
55
{
56
while(p<102)
57
{
58
writeString_P("Schwenkarm wieder nach unten\n");
59
PORTC |=(1<<1);
60
mSleep(1);
61
PORTC &=~ (1<<1);
62
mSleep(19);
63
n==0;
64
p++;}
65
}
66
67
if(p>100)
68
{p==0;
69
setStopwatch1(0);}
70
}
71
72
void ZyklusKomplett(void)
73
{
74
if((i==0) && (a==0) && (n==0) && (p==0)  )
75
  
76
  {z==1;
77
  writeString_P("Zyklus komplett\n");  //Zyklus komplett
78
  }
79
  
80
81
}
82
83
84
int main(void)
85
{
86
initRobotBase();
87
88
DDRC |=(1<<1);    //PORT 1 von Register C als Ausgang
89
DDRB &=~(1<<0);  //PORT 0 von Register B als Eingang
90
DDRC &=~(1<<6);  //PORT 6 von Register C als Eingang
91
DDRC |= (1<<0);  //PORT 0 von Register C als Ausgang
92
93
94
95
96
startStopwatch1();
97
ZyklusKomplett();
98
mSleep(1000);
99
setStopwatch1(0);
100
101
102
while(1)
103
{task_servo();
104
}
105
106
}

von Falk W. (dl3daz) Benutzerseite


Lesenswert?

Andi wrote:
...
1
> p++;}
2
> }
Jetzt ist p>0!
1
> if(p>100)
2
> {p==0;
Damit setzt Du p NICHT auf Null. p=0 wäre richtig.
1
> setStopwatch1(0);}
2
> }
3
> 
4
> void ZyklusKomplett(void)
5
> {
6
> if((i==0) && (a==0) && (n==0) && (p==0)  )
Da p hier ungleich 0 ist, wird diese Bedingung nie erfüllt.

Falk
P.S.: Das Ganze ist sehr unübersichtlich. Globale Variablen mit einem 
Zeichen. Das macht es sehr schwer, den Code zu lesen.

von Andi (Gast)


Lesenswert?

1
 schau mal deinen Code an wo Du vergleiche machst, die nichts bringen,
2
statt Zuweisung
3
4
 == und = ist nicht das gleiche!!!

an welchen Stellen muss ich dann ihrer Meinung nach etwas ändern?

von Mano W. (Firma: ---) (manow)


Lesenswert?

über all da wo Du eine Zuweisung = machen möchtest aber einen Vergleich 
machst, denn einfach vergleichen und das Ergebnis von einem Vergleich 
nirgends sichern bringt sehr wenig.

von Andi (Gast)


Lesenswert?

1
Damit setzt Du p NICHT auf Null. p=0 wäre richtig.

Das kann aber nicht sei. Jetzt hab ich es gerade mal mit p=0 probiert. 
Und jetzt bleibt das Programm dauerhaft in der Schleife
1
while(p<102)
2
{
3
writeString_P("Schwenkarm wieder nach unten\n");
4
PORTC |=(1<<1);
5
mSleep(1);
6
PORTC &=~ (1<<1);
7
mSleep(19);
8
n==0;
9
p++;}

von Bernd G. (bege)


Lesenswert?

Mann oh Mann !

Variablen Zuweisung mit '='  z.B.  a=0;  setzt 'a' auf Null

Doppeltes Gleichheitszeichen nur bei Vergleichen z.B. if (a==0) {} fragt 
a auf Null ab, der Block wird ausgeführt wenn die Variable a tatsächlich 
den Wert 0 hat.

Überprüfe mal die Stellen, an denen du i,a,n,p auf Null und z auf 1 
setzen willst !

Gruß Bernd

von Falk W. (dl3daz) Benutzerseite


Lesenswert?

Andi wrote:
>
1
Damit setzt Du p NICHT auf Null. p=0 wäre richtig.
>
> Das kann aber nicht sei.

Doch, das muß sein. Mit p=0 setzt Du die Variable p auf 0. Mit p==0 
vergleichst Du p mit 0 ohne das Ergebnis auszuwerten. (Der Compiler 
merkt sowas auch und läßt das gleich weg)

> Jetzt hab ich es gerade mal mit p=0 probiert.
> Und jetzt bleibt das Programm dauerhaft in der Schleife

Welchen Wert hat p jetzt? Wenn p<100 ist, ist da was faul...

>
1
while(p<102)
2
> {
3
> writeString_P("Schwenkarm wieder nach unten\n");
4
> PORTC |=(1<<1);
5
> mSleep(1);
6
> PORTC &=~ (1<<1);
7
> mSleep(19);
8
> n==0;
9
> p++;}
10
>

von PeterL (Gast)


Lesenswert?

if (!i && !a && !n && !p)
{z==1;....

von Andi (Gast)


Lesenswert?

oh ja danke. Tut mir echt leid, dass ich heute erst jetzt kapier was ihr 
mir sagen wolltet.

jetzt funktioniert das Programm einwandfrei:

1
#include "RP6RobotBaseLib.h"
2
3
uint8_t i;
4
uint8_t a;
5
uint8_t n;
6
uint8_t p;
7
uint8_t z;
8
9
void task_servo(void)
10
{
11
12
if(getStopwatch1()>200 || z==1) // Greifer schließen 
13
{
14
while(i<52)
15
{
16
writeString_P("Greifer schließen\n");
17
PORTC |=(1<<0);
18
mSleep(1);
19
PORTC &=~ (1<<0);
20
mSleep(19);
21
i++;}
22
}
23
24
25
if(i>50)  // Schwenkarm nach oben
26
{
27
while(a<52)
28
{
29
writeString_P("Schwenkarm nach oben\n");
30
PORTC |=(1<<1); 
31
mSleep(2);
32
PORTC &=~ (1<<1);
33
mSleep(18);
34
i=0;
35
a++;}
36
}
37
38
39
if(a>50) // Greifer öffnen                                      
40
{
41
while(n<100)
42
{
43
writeString_P("Greifer öffnen\n");
44
PORTC |=(1<<0);
45
mSleep(2);
46
PORTC &=~ (1<<0);
47
mSleep(18);
48
setStopwatch1(0);
49
a=0;
50
n++;}
51
52
}
53
54
if(n>98) //Schwenkarm wieder nach unten
55
{
56
while(p<102)
57
{
58
writeString_P("Schwenkarm wieder nach unten\n");
59
PORTC |=(1<<1);
60
mSleep(1);
61
PORTC &=~ (1<<1);
62
mSleep(19);
63
n=0;
64
p++;}
65
}
66
67
if(p>100)
68
{p=0;
69
setStopwatch1(0);}
70
}
71
72
void ZyklusKomplett(void)
73
{
74
if((i==0) && (a==0) && (n==0) && (p==0)  )
75
  
76
  {z=1;
77
  writeString_P("Zyklus komplett\n");  //Zyklus komplett
78
  }
79
  
80
81
}
82
83
84
int main(void)
85
{
86
initRobotBase();
87
88
DDRC |=(1<<1);    //PORT 1 von Register C als Ausgang
89
DDRB &=~(1<<0);  //PORT 0 von Register B als Eingang
90
DDRC &=~(1<<6);  //PORT 6 von Register C als Eingang
91
DDRC |= (1<<0);  //PORT 0 von Register C als Ausgang
92
93
94
95
96
startStopwatch1();
97
ZyklusKomplett();
98
mSleep(1000);
99
setStopwatch1(0);
100
101
102
while(1)
103
{task_servo();
104
}
105
106
}


Wie ihr seht bin ich noch ziemlicher Anfänger. Aber ich beginne erst im 
Oktober mit Elektrotechnik studieren, drum habe ich mir meine C 
Kenntnisse bisher komplett selber beibringen müssen.

Danke nochmal an alle
danke nochmal an alle

von Falk W. (dl3daz) Benutzerseite


Lesenswert?

Andi wrote:
> oh ja danke. Tut mir echt leid, dass ich heute erst jetzt kapier was ihr
> mir sagen wolltet.
>
> jetzt funktioniert das Programm einwandfrei:

...

> Wie ihr seht bin ich noch ziemlicher Anfänger. Aber ich beginne erst im
> Oktober mit Elektrotechnik studieren, drum habe ich mir meine C
> Kenntnisse bisher komplett selber beibringen müssen.

Das Programm mag funktionieren, der Grund dafür ist aber nicht zu 
erkennen ;-)

Wenn Du C lernen willst, kaufe Dir ein Buch (Ich kann keines empfehlen, 
"C for Atari ST" ist nicht mehr erhältlich) und arbeite es durch.

Ich würde C auch eher am Rechner lernen, wo man einen ordenlichen 
Debugger hat etc....

Viel Erfolg,
Falk

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.