Go Down

Topic: BCD codierte Ausgänge (Read 1 time) previous topic - next topic

intelo

Hallo miteinander,

ich werde so langsam depressiv bei dem Problem.

Kurz dazu eine Einleitung:
Ich habe 8 Taster über ein Eingangsregister 4021 BE eingelesen.
Über das Arduino gebe ich die Binärwerte dem Ausgangsregister und dieses lässt parallel dazu acht LED's leuchten, in Abhängigkeit was für Taster gedrückt wurden!!!

Nun mein Problem. Ich möchte die Ausgänge (LED's) binär codieren. Um so 256 Taster anschließen zu können.

Gibt es vielleicht dazu eine elegantere Lösung? Zu beachten ist, das ich ein dauerhaftes paralleles Signal am Ausgangsregister haben muss und ich nicht mehr Ausgänge zur nutzen darf, da danach ein System kommt.

Beispiel:

Taster 1 gedrückt---> LSB LED leuchtet--> übergebener Strom von Eingangsregister 0000 0001

Taster 6 gedrückt---> LED 2, LED 3 leuchten---> übergebener Strom von ER 0000 0110

Taster 8 gedrückt---> LED 4 leuchten---> übergebener Strom von ER 0000 1000

Ich habe alles probiert switch case, und if Abfragen, doch nichts führte zum Ziel.

Gibt es Vielleicht dafür eine Bitoperation?

Weiß jemand wie man das Problem lösen kann?


Ich danke euch im Vorraus für eure Lösungen. :)


Hier das Listing:

//**********************************
//Pin connected to ST_CP of 74HC595
int latchPin_out = 7;
//Pin connected to SH_CP of 74HC595
int clockPin_out = 8;
//Pin connected to DS of 74HC595
int dataPin_out = 9;
// Pin connected

int latchPin_in = 10;
// Pinconnection to 74HC4021BE
int clockPin_in = 11;
// Pinconnection to 74HC4021BE
int dataPin_in = 12;
// Pinconnection to 74HC4021BE

//**********************************
void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin_out, OUTPUT);
  pinMode(clockPin_out, OUTPUT);
  pinMode(dataPin_out, OUTPUT);
 
  pinMode(dataPin_in, INPUT);
  pinMode(clockPin_in, OUTPUT);
  pinMode(latchPin_in, OUTPUT);
 
  Serial.begin(9600);
}
//**********************************
void loop() {

 
    int switchVar1 = 0;
    digitalWrite(latchPin_in,1);
    delayMicroseconds(10);
    digitalWrite(latchPin_in,0);
    switchVar1 = shiftIn(dataPin_in, clockPin_in);
    Serial.println(switchVar1, BIN);
    shift_Out (switchVar1, dataPin_out, clockPin_out, latchPin_in);

    //delay(500);
}
   
    byte shiftIn(int myDataPin, int myClockPin) {
    int i;
    int temp = 0;
    int pinState;
    byte myDataIn = 0;
 
    pinMode(myClockPin, OUTPUT);
    pinMode(myDataPin, INPUT);
    for (i=7; i>=0; i--)
   
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(0.2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
           pinState = 0;
         }
    digitalWrite(myClockPin, 1);
  }
 
    return myDataIn;

  }
   
    byte shift_Out(byte var, int Dpout, int Cpout, int Lpout){
     
    digitalWrite(Lpout, LOW);
    // shift out the bits:
    shiftOut(Dpout, Cpout, LSBFIRST, var); 

    //take the latch pin high so the LEDs will light up:
    digitalWrite(Lpout, HIGH);
    }
   


Korman

Ich verstehe das Problem nicht wirklich. In deinem Beispielen ist die Ausgabe immer der Wert der Eingabe, nur in Binärdarstellung. Was kannst du jetzt nicht?

Korman

intelo

#2
Feb 08, 2011, 09:05 pm Last Edit: Feb 08, 2011, 09:09 pm by intelo Reason: 1
Hallo Korman,

und zwar folgendes zu meinem Problem.

Ich möchte eine Anzahl Taster (ca.64) an das Arduino anschließen. In der Praxis sind das dann Reissdrähte, also einfache Drähte die bei einer Materialermüdung z.b. Brückenkonstruktionen ausdehnen und reissen... der Taster öffnet also.

Dazu habe ich die Shiftin Funktion genutzt. Mit Shift out bekomm ich genau den Reissdraht angezeigt, der getastet wurde. Soweit so gut.

Das Eingangsregister ist Binär unterteilt von LSB 2^0 bis MSB 2^7.Jedes der 8 Bits wird seriell ins Arduino geschoben und von dort aus seriell zum Ausgangsregister, danach parallel dargestellt. Jetzt liegen 8 bits parallel an z.b an den LEDS.


Aber jetzt kommts, ich habe nur 8 Ausgänge, nicht mehr, und ich, möchte mehr als 8 Reissdrähte anschließen und detektieren.
Das bedeutet ich muss die Ausgänge bcd codieren, also die Eingänge (>8) auf die Ausgänge binär abbilden!

Nochmal zum Beispiel nur für 8 Reissdrähte!:

Reissdrähte 1, 2 und 8 sprechen an---> der Eingang sieht so aus = 1 0 0 0 0 0 1 1 stimmts?

und jetzt am Ausgang binär codieren 1+2+8 = 11--> die 11 darstellen auf 8 Ausgangsleds--> 0 0 0 0 1 0 1 1 stimmts?

Der Vorteil ist dabei, dass ich 255 Reissdrähte codieren kann (Personalisieren). Doch wie setze ich das als Code um?

Gibt es für meine Problemstellung eine bessere, schnellere (Laufzeit) Lösung?

Ich freue mich über jede Hilfe deinerseits, eurerseits ;)


Grüße

olikraus

Hallo

Wenn ich es korrekt verstanden habe, dann soll folgendes passieren:

Taste 6 (Binär 0010 0000, Dezimal 32) soll 6 ergeben (Binär 0000 0110)
oder
Taste 1 (Binär 0000 0001, Dezimal 1) soll 1 ergeben (Binär 0000 0001)

der mathematische Zusammenhang ist dann mit
t = Tastennummer und o = Output wie folgt
  2^(o-1) = t
bzw nach o aufgelöst:
  o = 1+log2( t )
o ist nur dann keine irrationale Zahl, wenn t eine 2er Potenz ist. Praktisch bedeutet das, dass man nur eine Taste drücken darf. Wenn zwei oder mehr Tasten gleichzeitig gedrückt werden, dann ist nicht ganz klar, was angezeigt werden soll.

Wenn man sich dafür entscheidet nur die Taste mit der höchsten Nummer anzuzeigen, kann man o durch ausprobieren ermitteln (sinngemäß):
uint8_t bestimmeTastennummer(uint8_t t)
{
if ( t == 0 )
  return 0;
for ( o = 8; o > 0; o-- )
{
  tt = 1<<(o-1);
  if ( (t & tt) != 0 )
   break;
}
return o;
}
Mit 256 Tasten wird das etwas schwierig, weil es keinen Datentypen mit 256 Bits gibt. Da müsste man dann in einem Bit-Array nach dem höchsten Bit suchen. Das geht aber auch.

---

hmm Nachtrag, habe deine letzte Antwort gerade gesehen, als ich meine Antwort getippt habe. Jetzt bin ich auch ratlos, denn wenn beispielsweise Drähte 3 und 8 reissen, kommt ja auch 11 raus.
Mit anderen Worten, das ist ja nicht ganz eindeutig. Mit obiger Funktion könnte man das allerdings schon programmieren. Etwa so:
summe = 0
Solange t nicht 0 ist
   o = bestimmeTastennummer(t)
   lösche Bit o-1 in t
   summe += o

Oliver


volvodani

So ich versuche mich mal kurz zu halten :-)

Also du liest die einzelenen Eingänge ein

Du hast ja dein Eingangswerte(Digitaleingänge) ja in einem byte stehen du kannst jetzt
mit der Funktion BitRead http://arduino.cc/en/Reference/BitRead
kannst du dann in deinem Eingangsbyte einzelne Bit auslesen und dann damit rechnen
1Bit == HIGH dann Ergebnis +1
2Bit == HIGH dann Ergebnis +2
3Bit == HIGH dann Ergebnis +3

und in deinem "byte Ergebnis" hast du dann den letzlichen zahlenwert stehen das schiebst du dann in den 74HC595 und dann hast du dein Binärwert. Das packst du dann in eine for-Schleife damit du nicht soviel Schreiben musst


for (int i; i<=7,i++){
temp=BitRead(i,"hier kommt dein gelesenes Byte");
if (temp==High){
Ergebnis=Ergebnis+i;
}

Und dann müsst es schon gehen ;-)
So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

uwefed

Als Eingangsinterface hast Du 8 Schieberegister mit je 8 Eingängen.
Du schiebst 256 mal um alle Eingänge abzufragen. Du brauchst nur bei jedem schritt kontrollieren ob der Eingangswert LOW ist und die Anzahl der Schritte ist die Nummer des gerissenen Drahtes.

zaeler = 0
array [10]=0  // arraygröße auf max betätigte Reißdräte einstellen.

for (index = 0; index <256; index++)
clkpin = High
if (datapin == LOW)
{array[index ] = zaeler
zaeler ++
}
clkpin = low

clkpin und datapin sind die seriellen Ausgänge der Schieberegister.
Im array hast Du dann die gerissenen Drähte.

Grüße Uwe

Go Up