Pages: [1]   Go Down
Author Topic: BCD codierte Ausgänge  (Read 972 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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. smiley


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);
    }
   

Logged

Central Europe
Offline Offline
Edison Member
*
Karma: 7
Posts: 1220
Use the Source, Luke.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 (>smiley-cool 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 smiley-wink


Grüße
« Last Edit: February 08, 2011, 03:09:25 pm by intelo » Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1550
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

AREA COLOGNE
Offline Offline
Edison Member
*
Karma: 21
Posts: 1148
I am 1 of 10 who understands binary
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ;-)
Logged

So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 271
Posts: 21936
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: