Forum: Compiler & IDEs "wenn Ausgang != Eingang mach was" - Brett vorm Kopf


von Danny (Gast)


Lesenswert?

Hey zusammen, einen schönen Sonntag wünsche ich!

Ich möchte eine Schützüberwachung realisieren, sprich feststellen wenn 
ein angesteuertes Schütz entweder kleben bleibt oder nicht anzieht.

Das Schütz wird mit log.1 angesteuert, der Eingang liefert bei 
Ansteuerung log.0.

Eigentlich ganz einfach dachte ich. Denn wenn beide Signale log.1 sind 
oder beide log.0 sind liegt ein Fehler vor (natürlich wird die 
Ansprechzeit des Schützes berücksichtigt).


Ich dachte diese Zeile wär der Schlüssel zum Erfolg...

if( (PINB & (1<<PB2)) == (PINC & (1<<PC0)) )

...aber die Geschichte klappt nur beim klebenbleiben des Schützes, 
sprich Ausgang=0 und Eingang=0 (angesteuert). Für den entgegengesetzten 
Fall klappt es nicht...

Ich habe alle möglichen Umstellungen, XOR mit Negierung probiert, sehe 
aber nun nach 1,5 Std den Wald vor lauter Bäumen nicht mehr.

Hat jemand von Euch einen Tipp für mich?

Danke und Gruß
Danny

von Michael U. (amiga)


Lesenswert?

Hallo,

passt doch alles...

(PINB & (1<<PB2)) ergibt 0x00000100
(PINC & (1<<PC0)) ergibt 0x00000001

warum sollte da ein Vergleich wahr werden?

Ich vermute jetzt mal, Du findest selbst eine Lösung?

Gruß aus Berlin
Michael

von Stefan E. (sternst)


Lesenswert?

(PINB & (1<<PB2) ist entweder 0 oder 4, je nach Zustand des Bits.
(PINC & (1<<PC0) ist entweder 0 oder 1, je nach Zustand des Bits.
Jetzt klarer, warum deine Zeile nicht funktioniert?

Wenn du auf logische Gleichheit prüfen willst, muss beides auf 0/1 
reduziert werden.

von Danny (Gast)


Lesenswert?

ich war der Meinung bei das beim Vergleich (==) der Ausdruck in den 
Klammern in 0/1 umgesetzt, bzw. so gewertet wird... und nun fragt bitte 
nicht warum :)


wie schaut denn für diesen Fall eine elegante Lösung aus?
Folgendes ist denke ich leicht verständlich und funktioniert aber platt 
gefragt: "macht man das so"?   :)

if( ((PINB & (1<<PB2))>>PB2) == (PINC & (1<<PC0)) )

von Stefan E. (sternst)


Lesenswert?

Viele Wege führen nach Rom:
1
(PINB&(1<<PB2))>>PB2
2
(PINB&(1<<PB2))?1:0
3
!!(PINB&(1<<PB2)
4
(PINB&(1<<PB2))==(1<<PB2)
5
(PINB&(1<<PB2))!=0
6
(PINB&(1<<PB2))>0
7
(_Bool)(PINB&(1<<PB2))
Nimm einfach den, der dir am besten gefällt.

von Sam .. (sam1994)


Lesenswert?

Viel andere Möglichkeiten hast du in C nicht (Das meiste von Stefan ist 
umgestellt), außer irgendetwas exotisches:
1
if((PINB | PINC) & ((1<<PB2)|(1<<PC0)) - 1 >= 4) //PB2 == PC0

von Stefan E. (sternst)


Lesenswert?

Samuel K. schrieb:
> Das meiste von Stefan ist umgestellt

Was meinst du damit? Das sind alles Möglichkeiten, um die linke Seite 
des == von 0/4 auf 0/1 zu reduzieren.

von Jim M. (turboj)


Lesenswert?

Was spricht dagegen, einfach alles zur 1 zu shiften?
1
if( (PINB >> PB2)&1) == (PINC >>PC0) &1 )

Das scheint mir die kürzeste Variante zu sein.

von Sam .. (sam1994)


Lesenswert?

Stefan Ernst schrieb:
> Was meinst du damit? Das sind alles Möglichkeiten, um die linke Seite
> des == von 0/4 auf 0/1 zu reduzieren.

Das gleiche Prinzip. Das Grundgerüst der Prüfung (=Vergleich der Bits) 
bleibt gleich.

von Stefan E. (sternst)


Lesenswert?

Samuel K. schrieb:
> Das gleiche Prinzip. Das Grundgerüst der Prüfung (=Vergleich der Bits)
> bleibt gleich.

Achso. Jedenfalls funktioniert dieses "Grundgerüst" wenigstens, im 
Gegensatz zu deiner Lösung. ;-)

von Danny (Gast)


Lesenswert?

Hey,

vielen Dank für Eure schnelle Hilfe!

Ich habe es nun beim >>PB2 gelassen, nun wirds wenigstens ein 
entspannter Abend :)

von Simon K. (simon) Benutzerseite


Lesenswert?

Leute, Leute, Leute. Code muss selbsterklärend sein!

Was spricht gegen:
1
if ( ((PINB & (1<<PB2)) &&  (PINC & (1<<PC0)))
2
 || !((PINB & (1<<PB2)) && !(PINC & (1<<PC0))) )
3
{ 
4
    Alles in Ordnung
5
}else
6
{   
7
    Unterschiedlich
8
}

Ist allerdings ungetestet.

von Sam .. (sam1994)


Lesenswert?

Ersetze das && durch || und es funktioniert.

Ich finde es kryptischer. Ich finde Code sollte kurz sein, dann muss man 
weniger lesen.

von Stefan E. (sternst)


Lesenswert?

Samuel K. schrieb:
> Ersetze das && durch || und es funktioniert.

Nein, das passt schon so, außer dass das erste ! etwas verrutscht ist.
!(( -> (!(

von Stefan E. (sternst)


Lesenswert?

Simon K. schrieb:
> Leute, Leute, Leute. Code muss selbsterklärend sein!

"selbsterklärend" liegt aber zum Teil auch im Auge des Betrachters. ;-)

Ich würde z.B. folgende Variante als noch "selbsterklärender" 
favorisieren:
1
if ((_Bool)(PINB & (1<<PB2)) == (_Bool)(PINC & (1<<PC0)))

von Sam .. (sam1994)


Lesenswert?

Stimmt, ich war irgendwie beim bitweisen &.

Da fällt mir ein: Warum nicht kompliziert? Dann lernt man wenigstens 
komplizierter zu denken.

von Simon K. (simon) Benutzerseite


Lesenswert?

Stefan Ernst schrieb:
> Simon K. schrieb:
>> Leute, Leute, Leute. Code muss selbsterklärend sein!
>
> "selbsterklärend" liegt aber zum Teil auch im Auge des Betrachters. ;-)
>
> Ich würde z.B. folgende Variante als noch "selbsterklärender"
> favorisieren:
>
1
if ((_Bool)(PINB & (1<<PB2)) == (_Bool)(PINC & (1<<PC0)))

Und was ist _Bool? Wo gibt es den Datentyp? Und zwar in einer derartigen 
Definition, dass er das von dir gewünschte Verhalten erzeugt?

von Simon K. (simon) Benutzerseite


Lesenswert?

Samuel K. schrieb:
> Stimmt, ich war irgendwie beim bitweisen &.
>
> Da fällt mir ein: Warum nicht kompliziert? Dann lernt man wenigstens
> komplizierter zu denken.

Aus einem einfachen Grund: Wartbarkeit. Wenn man irgendwann mal wieder 
nach ein paar Jahren was ändern oder debuggen möchte und dann sowas 
sieht:
1
(PINB&(1<<PB2))>>PB2

Dann ist man erst mal damit beschäftigt das Statement zu verstehen. Da 
das Statement aber nicht viel "Geschäftslogik" in sich verbirgt ist das 
sinnlos verschwendete Lebenszeit.

von Stefan E. (sternst)


Lesenswert?

Simon K. schrieb:
> Und was ist _Bool? Wo gibt es den Datentyp? Und zwar in einer derartigen
> Definition, dass er das von dir gewünschte Verhalten erzeugt?

Im C-Standard seit C99.

von Simon K. (simon) Benutzerseite


Lesenswert?

Stefan Ernst schrieb:
> Simon K. schrieb:
>> Und was ist _Bool? Wo gibt es den Datentyp? Und zwar in einer derartigen
>> Definition, dass er das von dir gewünschte Verhalten erzeugt?
>
> Im C-Standard seit C99.

Okay, dann ist die Variante lesbarer. Vorausgesetzt man kennt den _Bool 
Typen. ;-)

Wenn C99, dann sollte der GCC (das gewählte Subforum) das auch 
unterstützen.

von Peter D. (peda)


Lesenswert?

1
if( !(PINB & (1<<PB2)) == !(PINC & (1<<PC0)) )

Die Erklärung ist, der !-Operator liefert 0 (falsch) oder 1 (wahr) als 
Ausgabe.
Als Eingabe gilt aber 0 = falsch, !0 = wahr.
Er wandelt also int in bool um.

In diesem Fall stört die Negation nicht, da auf beiden Seiten.
Profis schreiben oft auch:
1
if( !!(PINB & (1<<PB2)) == !!(PINC & (1<<PC0)) )
Damit entfällt die Negation und man wird mit dem Holzhammer drauf 
hingewiesen, das bool rauskommen soll.


Peter

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.