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.
...oder einfach Datenblatt lesen. http://www.produktinfo.conrad.com/datenblaetter/700000-724999/705462-da-01-de-Miniatur_Codierschalter.pdf letzte Seite.
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
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?
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.
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.
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
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.
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.
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)
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
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ß
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.
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
Oder etwas einfacher:
1 | schalterzustand = ~(PINC >> 2) & 0x0F; |
Grüße
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.
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... ...
>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?
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
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.
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.
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.
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. ...
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.
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.
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
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
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
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:" ;-)
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.