Wie Kodierschalter auswerten?

OP #2140260
Lesenswert?

Hi an alle,

habe einen Kodierschalter
http://www.conrad.at/ce/de/product/705462/HEXADEZIMAL-CODIERSCHALTER-EINSTELLSCHL

und möchte nun wissen wie ich zum Beispiel auswerten kann ob die Zahl 2 
beim einstellen ausgewählt wurde.

Vielleicht kann mir da jemand weiterhelfen?

Beim DIP Schalter war das etwas leichter, da gab es gleich viel Pins wie 
Zahlen und somit konnte ich jeden Pin auf einen Port am MCU legen und 
dann mittels Pull Up Resistor nach "Strom" oder "nicht Strom" abfragen.

Aber beim Kodierschalter habe ich echt keine Ahnung wie ich das an 
meinem atmega168 realisiern kann.

Danke für die Hilfe.
Gast #2140382
Lesenswert?

El Nino schrieb:

> Beim DIP Schalter war das etwas leichter, da gab es gleich viel Pins wie
> Zahlen und somit konnte ich jeden Pin auf einen Port am MCU legen und
> dann mittels Pull Up Resistor nach "Strom" oder "nicht Strom" abfragen.
>
> Aber beim Kodierschalter habe ich echt keine Ahnung wie ich das an
> meinem atmega168 realisiern kann.

Zahl einlesen und feddig. Es ist nur etwas leichter als beim 
Dip-Schalter,
da Du keine 16 Eingänge brauchst, sondern nur vier...
Gruss
Harald
OP #2140398
Lesenswert?

Danke für die vielen Antworten.

Habe mir das Datenblatt nun angesehen.

Wenn ich das richtig interpretiere, dann hat der Kodierschalter 6 Pins.
c,1,2,4,8

Wobei C 2mal da ist.

Ich kenne das C von Buttons mit C NC NO.
Da muss man das C mit GND verbinden.

Ist dies hier auch so?

C mit GND verbinden
1 mit bsp. PC2
2 mit bsp. PC3
4 mit bsp. PC4
8 mit bsp. PC5

Dann bei den Ports am MCU den Pullup Resistor aktivieren.
Und dann wie bei dem DIP Schalter schauen ob an dem PIN high oder low 
vorzufinden ist.

Stimmt das so? Oder habe ich da einen Denkfehler?
Gast #2140407
Lesenswert?

El Nino schrieb:
> Beim DIP Schalter war das etwas leichter, da gab es gleich viel Pins wie
> Zahlen und somit konnte ich jeden Pin auf einen Port am MCU legen und
> dann mittels Pull Up Resistor nach "Strom" oder "nicht Strom" abfragen.

Und was ist da jetzt anders? Du hast 4 Schalter in dem Gehäuse, die du 
einliest.
#2140428
Lesenswert?

El Nino schrieb:
> Wenn ich das richtig interpretiere, dann hat der Kodierschalter 6 Pins.

Also ich seh' da nur fünf.

C an GND und die anderen 4 an den Controllerport. Pullups auf High und 
fertig.

El Nino schrieb:
> Und dann wie bei dem DIP Schalter schauen ob an dem PIN high oder low
> vorzufinden ist.

Nicht an DEM Pin, sondern alle 4 zusammen als Zahl von 0 - 15 einlesen.

mfg.
#2140487
Lesenswert?

Etwas tricky wird es dann auch beim Umschalten eines solchen Schalters.
Da kannst du zeitweise "falsche" Zwischen-Zustände erhalten, da ein 
Schalter evtl. früher schließt oder öffnet als ein anderer.
Daher ist zu empfehlen, wenn sich am Portzustand etwas ändert, eine 
Weile zu warten (z.B. 0.1s), und den Portzustand dann noch einmal 
abzufragen.
Erst wenn beide Abfragen identisch sind, den neuen Wert verarbeiten.
OP #2140528
Lesenswert?

Thomas Eckmann schrieb:
> Also ich seh' da nur fünf.

Ich habe den Kodierschalter vor mir liegen und er hat 6 Pins wie auch in 
dem Datenblatte zu erkennen ist.

Muss ich dann einfach beide Cs auf GND legen?

Thomas Eckmann schrieb:
> Nicht an DEM Pin, sondern alle 4 zusammen als Zahl von 0 - 15 einlesen.

Ich hätte das so gelöst:
(Pseudo Code)
If(PC2 high && PC3 high && PC4 high && PC5 high)
{
zahl=16;
}

Oder meintest du das?

Aber so muss ich dann 16 Zustände abfragen. Oder gibt es da eine 
schlauere Variante?

Tim R. schrieb:
> eine Weile zu warten (z.B. 0.1s), und den Portzustand

Danke für den Tipp.

Vlad Tepesch schrieb:
> bitweise negation nicht vergessen da low-Aktiv, wenn gegen GND

Danke.
Gast #2140536
Lesenswert?

El Nino schrieb:
> If(PC2 high && PC3 high && PC4 high && PC5 high)
> {
> zahl=16;
> }
Der geht aber nur von 0 bis 15
Das ist einfach binär codiert die Zahl, wie mit 4 Dil Schaltern auch.
Wo ist das Problem?
0101 ist eine 5
1000 ist eine 8
...
einfach an Bit 0 - 3 eines Ports hängen und auslesen. der Wert ist dann 
schon genau die Zahl (richtig herum und ggf. invertieren)
Gast #2140541
Lesenswert?

Hi

>Aber so muss ich dann 16 Zustände abfragen. Oder gibt es da eine
>schlauere Variante?

Die vier Bits ergeben schon die Zahl. Wenn du den Schalter an Pin0..3 
eines Ports anschließt reicht (Pseudocode)

  zahl = (PINx & 0x0F)

MfG Spess
#2140551
Lesenswert?

El Nino schrieb:
> Muss ich dann einfach beide Cs auf GND legen?

In der Logiktabelle ist nur ein C. Aber egal. Wenn die beide mit C 
beschriftet sind, legst du beide auf GND.

El Nino schrieb:
> If(PC2 high && PC3 high && PC4 high && PC5 high)
> {
> zahl=16;
> }

Quark.

Nehmen wir mal das als Beispiel:

El Nino schrieb:
> C mit GND verbinden
>
> 1 mit bsp. PC2
>
> 2 mit bsp. PC3
>
> 4 mit bsp. PC4
>
> 8 mit bsp. PC5


char nIn;

nIn = (PINC >> 2) & 0x0F; //Jetzt steht in nIn ein Wert von 0 - 15

switch(nIn)
{
  case 0:

  break;

  case 1:

  usw.

}

mfg.
#2140557
Lesenswert?

ich glaube du solltest dich generell mal mit themen wie binärsystem und 
hexadezimalzahlen beschäftigen sowie "bitoperationen".

wenn dein unterstes bit des codierschalters an PC2 angeschlossen wird, 
reicht es den 8-bit port abzufragen und folgendes zu machen:

schalterzustand = ((PC >> 2) ^ 0x0F) & 0x0F;

wobei PC der 8-bittige zustand des gesamten ports C ist.
zu beachten ist, dass die pins des schalters in der richtigen 
reihenfolge angeschlossen sind:

beide C an GND
pin 1 -> PC2
pin 2 -> PC3
pin 4 -> PC4
pin 8 -> PC5

pullups (z.B. 10k) an PC2..PC5 nicht vergessen
OP #2141300
Lesenswert?

Thomas Eckmann schrieb:
> nIn = (PINC >> 2) & 0x0F; //Jetzt steht in nIn ein Wert von 0 - 15

Vielen Dank für deine gute Ausführung.

Jetzt bin ich noch nicht so fit mit der Thematik um es ganz 
nachvollziehen zu können.

Kann mir jemand sagen ob ich das richtig interpretiere?

Bei mir besteht PINC aus PC0..PC5
Das bedeutet das Register von PINC sieht so aus 000000 wenn es noch 
"jungfreulich" ist.

Wenn ich nun (PINC >> 2) durchführe, dann erhalte ich 110000

Anschließend (PINC >> 2) & 0x0F ergibt 110000
Aber warum verschiebt man hier um zwei 1ser nach rechts?

Angeschlossen sind die Pins an PC2..PC5.

Wenn ich an dem Schalter Z.b.: auf die Nummer 3 drehe, was passiert dann 
genau? Es greift der Pullup Resistor welcher an dem Pin aktiviert wurde 
und setzt dann im Register PINC eine 0 oder eine 1?

Muss ich dann aufpassen, dass ich die Anschlusspins des Kodierschalters 
folgendermaßen anschließe? Pin1 auf PC2, Pin2 auf PC3, Pin4 auf PC4, 
Pin8 auf PC5. Ist das korrekt?

Ich versteh nicht warum dann in nIn die aktuelle Zahl steht.

Vielleicht kann mir jemand helfen das zu verstehen.

Vielen Dank.
Gast #2141373
Lesenswert?

>Aber beim Kodierschalter habe ich echt keine Ahnung wie ich das an
>meinem atmega168 realisiern kann.
Also,wenn du mit einen atmega168 umgehen kannst, dann ist doch so ein 
Kodierschalter ein Klacks für dich. Wenn nicht, dann lass es sein.
Dann bist du ungeeignet für Elektronik.
Sagt dir BCD etwas?
#2141396
Lesenswert?

Die Zahlen von 0 bis 15


   Dezimal  Hex   Binär         Dezimal   Hex    Binär

      0      0    0000             8       8     1000
      1      1    0001             9       9     1001
      2      2    0010            10       A     1010
      3      3    0011            11       B     1011
      4      4    0100            12       C     1100
      5      5    0101            13       D     1101
      6      6    0110            14       E     1110
      7      7    0111            15       F     1111


Wichtig: Ob Dezimal oder Hex oder Binär ist einerlei. Das sind nur 
andere Schreibweisen für immer das selbe.

Von deinem Codierschalter kriegst du die Leitungen schon binär codiert. 
Die 4 Leitungen codieren bereits Zahlen. Du kannst also die 4 Leitungen 
vom Port nehmen (je nachdem wie du sie angeschlossen hast, musst du sie 
noch invertieren, damit aus einer 1 eine 0 wird und umgekehrt) und du 
hast bereits die Zahl, die dir die Schalterstellung codiert.

Jetzt hast du aber deine 4 Leitungen nicht beginnend mit PC0 
angeschlossen, sondern beginnend mit PC2. Also so


             000000     ==  0
             000100     ==  1
             001000     ==  2
             001100     ==  3
             010000     ==  4
             .....

wenn du daher das was du vom Pin liest um 2 Stellen nach rechts rückst 
...

                             +---- die beiden Stellen löschen durch >> 2
                             |
                             v
       000000   -->    0000 00   -->   0000   == 0
       000100   -->    0001 00   -->   0001   == 1
       001000   -->    0010 00   -->   0010   == 2
       001100   -->    0011 00   -->   0010   == 3
        ....            ....           ....

... dann erhältst du unmittelbar deine Codierschalterstellung
#2141404
Lesenswert?

El Nino schrieb:
> Aber warum verschiebt man hier um zwei 1ser nach rechts?

Weil der erste Anschluß des Schalters an PINC2 des Controllers geht.
Deshalb verschiebt man das um 2 nach rechts, dann liegt er im Controller 
da wo er hingehört, nämlich auf Bit0. Und die anderen 3 entsprechend.

El Nino schrieb:
> Es greift der Pullup Resistor welcher an dem Pin aktiviert wurde
>
> und setzt dann im Register PINC eine 0 oder eine 1?

Bei einer 3 wird GND an PINC2 und PINC3 gelegt. Wenn man das jetzt so 
einliest: char nIn = ~((PINC >> 2) & 0x0F); steht in nIn eine 3.

Die Tilde vor dem Ausdruck negiert das Ganze, da die Logik am Port 
Low-Aktiv ist.

El Nino schrieb:
> Pin1 auf PC2, Pin2 auf PC3, Pin4 auf PC4,
>
> Pin8 auf PC5. Ist das korrekt?
Ja.

So. Und jetzt guckst du dir im Tutorial das Kapitel "Bitmanipulation" an 
und machst das mit den LEDs, wie Hannes Lux das vorgeschlagen hat.

mfg.
OP #2141438
Lesenswert?

Thomas Eckmann schrieb:
> So. Und jetzt guckst du dir im Tutorial das Kapitel "Bitmanipulation" an
>
> und machst das mit den LEDs, wie Hannes Lux das vorgeschlagen hat.

Danke für die ausführliche Antwort. Jetzt habe ich es schon besser 
verstanden. Mache mich gleich an die Arbeit.

Karl Heinz Buchegger schrieb:
> ... dann erhältst du unmittelbar deine Codierschalterstellung

Danke für die Aufstellung der Bitweisen Verschiebung. Jetzt kommt 
langsam Licht ins Dunkel.
Gast #2141643
Lesenswert?

Michael_ schrieb:
> Dann bist du ungeeignet für Elektronik.
> Sagt dir BCD etwas?

Warum dann noch mehr Verwirrung durch den Begriff "BCD". Damit hat das 
Thema dieses Threads nun wirklich nichts zu tun?
Hier geht es um einen Hex-Schalter, der ganz einfach 4 Bit binär kodiert 
abliefert.
Gast #2142288
Lesenswert?

Thomas Eckmann schrieb:
> Bei einer 3 wird GND an PINC2 und PINC3 gelegt. Wenn man das jetzt so
> einliest: char nIn = ~((PINC >> 2) & 0x0F); steht in nIn eine 3.

Nicht wirklich:
1
                          76543210
2
   PINC               = 0b11110011 // bei Schalter auf 0x03
3
  (PINC >> 2)         = 0b00111100
4
  (PINC >> 2) & 0x0F  = 0b00001100 // LowNibble ausmaskieren
5
~((PINC >> 2) & 0x0F) = 0b11110011 // keine 0x03, sondern 0xF3

Das Register PINC muss zuerst invertiert werden:
1
char nIn = ((~PINC) >> 2) & 0x0F;
2

3
                          76543210
4
   PINC               = 0b11110011 // bei Schalter auf 0x03
5
 (~PINC)              = 0b00001100 // invertieren
6
((~PINC) >> 2)        = 0b00000011
7
((~PINC) >> 2) & 0x0F = 0b00000011 // = 0x03

Grüße
Gast #2142305
Lesenswert?

Tip schrieb:

>> Sagt dir BCD etwas?
>
> Warum dann noch mehr Verwirrung durch den Begriff "BCD". Damit hat das
> Thema dieses Threads nun wirklich nichts zu tun?

Ja, früher haben die Kinder das ABC gelernt. Da man ja heute weiter
ist, lernen sie gleich das BCD. :-)
Gruss
Harald
OP #2145215
Lesenswert?

Johannes F. schrieb:
> ~((PINC >> 2) & 0x0F)

Ich habe mich nun ausgiebig mit dem Thema beschäftigt und bin jeden 
Schritt einzeln durchgegangen um den Vorgang zu verstehen.

Ich denke ich weiss nun wo das Problem liegt.

Es müsste
nIn = ~(PINC >> 2) & 0x0F;
heissen und nicht
~((PINC >> 2) & 0x0F);

Die Negierung des gesammten Ausdrucks scheint hier nicht richtig zu 
sein. Wenn ich am Kodierschalter eine 1 einstelle(wobei PC2 an diesem 
Pin hängt), dann würde folgendes rauskommen...

~((PINC >> 2) & 0x0F) ergibt 11110001 -> 241
~(PINC >> 2) & 0x0F ergibt 00000001 -> 1
Gast #2145350
Lesenswert?

El Nino schrieb:
> Es müsste
> nIn = ~(PINC >> 2) & 0x0F;
> heissen und nicht
> ~((PINC >> 2) & 0x0F);

Das habe ich schon in meinem ersten Beitrag zu diesem Thread 
geschrieben:

Johannes F. schrieb:
> Oder etwas einfacher:
> schalterzustand = ~(PINC >> 2) & 0x0F;

;)

El Nino schrieb:
> Die Negierung des gesammten Ausdrucks scheint hier nicht richtig zu
> sein.

Genau das habe ich in meinem zweiten Beitrag ausführlich erläutert.
Ich würde folgende Variante vorziehen:

Johannes F. schrieb:
> char nIn = ((~PINC) >> 2) & 0x0F;

Wenn man wie oben zuerst den Rechtsshift durchführt, sind Bit 6 und 7 
zunächst gelöscht, da beim Shiften in der Regel Nullen nachgeschoben 
werden.
Anschließend werden sie aber durch die Negation gesetzt.
Das ist hier aufgrund der anschließenden Ausmaskierung des LowNibbles 
zwar egal, aber ich finde es logischer und übersichtlicher, PINC zuerst 
zu negieren und erst danach zu shiften.

Grüße

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren