Forum: Mikrocontroller und Digitale Elektronik Wie Kodierschalter auswerten?


von Nino K. (lnino)


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.

von Denis (Gast)


Lesenswert?

Stichwort Tastenmatrix

von Ingo D. (ingo2011)


Lesenswert?

... sieh mal lieber nach BCD-Switch, BCD-CODE
Gruß Ingo

von Tim R. (vref)


Lesenswert?


von Duck und weg (Gast)


Lesenswert?

Datenblatt lesen kann ja jeder.
Wozu gibt's das Forum
;-)

von Harald Wilhelms (Gast)


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

von Nino K. (lnino)


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?

von Elektroniker (Gast)


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.

von Thomas E. (thomase)


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.

von Vlad T. (vlad_tepesch)


Lesenswert?

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

bitweise negation nicht vergessen da low-Aktiv, wenn gegen GND

von Tim R. (vref)


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.

von Nino K. (lnino)


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.

von U.R. Schmitt (Gast)


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)

von spess53 (Gast)


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

von Johannes F. (Gast)


Lesenswert?

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

Ja.
1
zahl = ~PINC & ((1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5))

Gruß

von Thomas E. (thomase)


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.

von Tim R. (vref)


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

von Johannes F. (Gast)


Lesenswert?

Oder etwas einfacher:
1
schalterzustand = ~(PINC >> 2) & 0x0F;

Grüße

von Nino K. (lnino)


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.

von Hannes L. (hannes)


Lesenswert?

El Nino schrieb:
> Ich versteh nicht warum dann in nIn die aktuelle Zahl steht.

Der Schalter ist binär codiert. Häng zum Test 4 LEDs (mit 
Vorwiderständen) dran und schalte ihn mal langsam durch. Versuche dabei 
zu verstehen, was Du da siehst...

...

von Michael_ (Gast)


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?

von Karl H. (kbuchegg)


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

von Nino K. (lnino)


Lesenswert?

Hannes Lux schrieb:
> Der Schalter ist binär codiert. Häng zum Test 4 LEDs (mit
>
> Vorwiderständen) dran und schalte ihn mal langsam durch. Versuche dabei
>
> zu verstehen, was Du da siehst...

Danke für den netten Tipp. Werde den Test durchführen um den Vorgang 
besser verstehen zu können.

von Thomas E. (thomase)


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.

von Nino K. (lnino)


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.

von Hannes L. (hannes)


Lesenswert?

El Nino schrieb:
> Jetzt kommt
> langsam Licht ins Dunkel.

Du hast wohl den hundertsten Schritt vor dem ersten gemacht. Ohne das 
Wissen über Bits und Bytes hat es keinen Sinn, mit Mikrocontrollern zu 
arbeiten.

Es rächt sich, wenn man meint, ohne Basics auszukommen... 8-(
Also ran, an die Grundlagen.

...

von Stephan (Gast)


Lesenswert?

El Nino schrieb:
> Danke für die Aufstellung der Bitweisen Verschiebung. Jetzt kommt
> langsam Licht ins Dunkel.

und das schon nach dem 25.Eintrag. Respekt.

von Tip (Gast)


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.

von Johannes F. (Gast)


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

von Harald Wilhelms (Gast)


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

von Nino K. (lnino)


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

von Tip (Gast)


Lesenswert?

El Nino schrieb:
> 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.

Da stand ja auch drüber "Nicht wirklich:"
;-)

von Johannes F. (Gast)


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

von Nino K. (lnino)


Lesenswert?

Johannes F. schrieb:
> Das habe ich schon in meinem ersten Beitrag zu diesem Thread
> geschrieben:

Du hast vollkommen recht. Ich denke ich habe einfach zu schnell darüber 
gelesen und angenommen, dass der Befehl in deinem Post der gleiche ist 
wie in denen der anderen. Mein Fehler.

Danke für die Unterstützung. Jetzt habe ich den Dreh raus.

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.