Wie steuere ich einen 16-Channel-Analog-Multiplexer mit einem Arduino über 74HC595 an?

Gast #4968676
Lesenswert?

Hallo,
da ich es satt habe die ganze Zeit nur auszuprobieren, um Misserfolge zu 
verkraften. Frage ich mal nach.

Ich steuere einen 16:1 analog-Multiplexer mit meinem Aduino-Uno an. Dies 
ist der Schaltungs aufbau:

http://bildr.org/blog/wp-content/uploads/2011/01/CD74HC4067_Empty.png


Der Sketch:

int speicherPin = 10;
int taktPin     = 11;
int datenPin    = 9;
int analogPin   = 2;
int messErgebnis = 0;
long motherCode = 0;



void setup() {
  pinMode(speicherPin, OUTPUT);
  pinMode(taktPin, OUTPUT);
  pinMode(datenPin, OUTPUT);
  pinMode(analogPin, INPUT);
  Serial.begin(9600);

}

void loop() {
/*
  Serial.println("=====================================");
  Serial.print("MotherCode: ");
  Serial.println(motherCode, BIN);
  Serial.println("=====================================");

    */for(int regalCodeCounter = 0; regalCodeCounter < 16; 
regalCodeCounter++) {

    long fullCode = (0B1001 << 4) + motherCode;
    fullCode = fullCode << 8;
    fullCode += getRegalCode(regalCodeCounter);
    sendBytes(0B1001000100001101);
    messErgebnis = analogRead(analogPin);
    Serial.println(0B1001000100000001, BIN);
    delay(250);
    Serial.println(messErgebnis);
    delay(250);


  }

  delay(1000);

  motherCode++;

  if(motherCode == 16)     motherCode = 0;

}

int getRegalCode(long regalCodeCounter) {

  long sendRegalCode = 0B00000000;

  sendRegalCode = regalCodeCounter << 4;
  sendRegalCode += regalCodeCounter;

  return sendRegalCode;

}

void sendBytes(long data) {

  digitalWrite(speicherPin, LOW);
  shiftOut(datenPin, taktPin, MSBFIRST, data >> 8);
  shiftOut(datenPin, taktPin, MSBFIRST, data & 255);
  digitalWrite(speicherPin, HIGH);

}


Ich lasse die Bit-Komibi, die der MUX erhält, durch zwei Schieberegister 
74HC595 generieren, die ihre Signale direkt an die Eingänge des 
MUX(S0-S3)schicken

Wenn ich den Sketch hochlade funktioniert ales perfekt, doch wenn ich 
eine Spannung auslesen möchte, dann klappt dies auch, sofern bei den 15 
anderen Input Pins des MUX keine Spannung anlieegt. Liegt dort jedoch 
eine Spannung an, so wird mit dieser Spannung ein Mittelwert gebildet. 
Und dieser wird dann im Seriellen Monitor angezeigt.
Falls jemand eine hätte, woran das liegt, wäre ich sehr dankbar.
Gast #4968683
Lesenswert?

t800w schrieb:
> Ich steuere einen 16:1 analog-Multiplexer mit meinem Aduino-Uno an. Dies
> ist der Schaltungs aufbau:
>
> http://bildr.org/blog/wp-content/uploads/2011/01/CD74HC4067_Empty.png

t800w schrieb:
> Ich lasse die Bit-Komibi, die der MUX erhält, durch zwei Schieberegister
> 74HC595 generieren, die ihre Signale direkt an die Eingänge des
> *MUX(S0-S3)* schicken

Dann stimmt doch aber Dein verlinkter Schaltungsaufbau gar nicht, oder 
verstehe ich Dich falsch? Mach doch bitte mal eine richtigen Schaltplan, 
gern per Hand gezeichnet.
Gast #4968696
Lesenswert?

Weil ich den MUX im ersten Post nicht kannte ;).
Aber laut Datenblatt ist das so korrekt.

Bitte weitere Infos:
1) welche Spannungsquellen liegen an den Eingängen? Spannungsteiler? 
DACs? ...?
2) wie sieht die Eingangsbeschaltung des ADC aus? direkt an den ADC?

Ich vermute, dass die Leckströme eines jeden Kanals zu deinem Nutzsignal 
hinzu kommen. Ein Pulldown am ADC-Eingang könnte (je nach Quelle an den 
Mux-Eingängen) helfen. Größe hängt von diesen Quellen ab.

Bitte 1) für genauere Angaben beantworten.
Gast #4968706
Lesenswert?

Das mag ja sein, aber sowas führt immer in die Irre und sorgt für 
Diskussionen zu Bereichen, die vielleicht doch korrekt sind. oder auch 
nicht.

So wie das EN. Es müsste /EN oder nEN heißen, damit klar ist, dass es 
low-aktiv ist.
Gast #4968710
Lesenswert?

Felix Adam schrieb:
> Das mag ja sein, aber sowas führt immer in die Irre und sorgt für
> Diskussionen zu Bereichen, die vielleicht doch korrekt sind. oder auch
> nicht.
>
> So wie das EN. Es müsste /EN oder nEN heißen, damit klar ist, dass es
> low-aktiv ist.

Wo und wie müsste ich das Anschließen, da ich gerade sehr verwirrt bin.
Gast #4968733
Lesenswert?

@Felix Adam

Als Spannungsteiler benutze ich einen LDR (Bereich 0-10 KOhm), der mit 
High verbunden ist. Auf der anderen Seite ist ein 10KOhm Wiederstand, 
der mit Low verbunden ist.

Felix Adam schrieb:
> Und was ist mit dem ADC-Eingang? Gibt es einen Pulldown? und/oder einen
> Stützkondensator?

Nein
Gast #4968775
Lesenswert?

Wolfgang schrieb:
> Ein 74LS595 ist da arg fehl am Platze. Damit erreichst du nicht sicher
> den H-Pegel vom 74HC...
>
> Und Steuereingänge in der Luft hängen zu lassen, ist - unabhängig von
> der IC-Familie - zumindest kein guter Stil, bei CMOS sogar verboten.

Danke, es ging um das Prinzip. Aber für Dich suche ich gern noch einen 
74HC595 raus ... /Sarkasmus off
Gast #4968873
Lesenswert?

Ich denke, du hast ein Problem mit den leckströmen durch die 15 nicht 
aktivierten Kanäle. Im Datenblatt findest du diese unter "OFF-state 
leakage current". Je kanal können (so ich das richtig interpretiere) bis 
zu ca. 1µA zusammen kommen.
Dieser Strom fließt duch den 10kOhm-Widerstand an deinem aktivierten 
Kanal gen Masse und verursacht so einen Messfehler.

Du könntest das prüfen und nachmessen, indem du an einen Kanal mal 
100kOhm nach Masse ohne einen LDR nach 5V anschließt und diesen Kanal 
mal aktivierst. Die anderen belasse so wie sie sind mit ihren LDRs und 
10kOhm-Widerständen. Mit einem Multimeter sollte sich jetzt eine 
Spannung messen lassen, die diesem Wert ungefähr entspricht.

Hast du kein Multimeter, dann schalte dem 100kOhm-Widerstand noch einen 
Kondensator mit mindestens 100nF parallel. So beeinflusst die Messung 
des ADC den Messwert nahezu nicht und du bekommst dir den Wert von 
deiner Schaltung geliefert.

Ferner solltest du nach dem Umschalten deines Mux ein paar Millisekunden 
warten, bevor dein ADC zu messen beginnt. So sollten die Spannungen alle 
auf ihrem Endwert sein.
Gast #4979653
Lesenswert?

Hallo, ich will mehrere 16-Cahnnel-Analog-Multiplexer (Typ: CD74HC4067) 
mit einem Arduino auslesen. Die Multiplexer steuere ich ebenfalls mit 
dem Arduino via 74HC595 an. Die 74HC595 funktionieren perfekt, jedoch 
zun die Multiplexer nicht das, was sie tun sollen, d.h jeder MUX bildet 
ein Mittelwert aus allen 16 Eingangssignalen, und gibt diesen dann an 
den Arduino weiter.


So lautet das Programm:
1
int speicherPin = 10;
2
int taktPin     = 11;
3
int datenPin    = 9;
4
long motherCode = 0;
5

6
void setup() {
7
  pinMode(speicherPin, OUTPUT);
8
  pinMode(taktPin, OUTPUT);
9
  pinMode(datenPin, OUTPUT);
10
  Serial.begin(9600);
11

12
}
13

14
void loop() {
15

16
    for(int regalCodeCounter = 0; regalCodeCounter < 16; regalCodeCounter++) {
17

18
    long fullCode = (0B1001 << 4) + motherCode;  // 1001 + motherCode
19
    fullCode = fullCode << 8;                   // 1001 + motherCode + 0000 0000
20
    fullCode += getRegalCode(regalCodeCounter); // 1001 + motherCode + regalCode
21
   
22
   
23
    sendBytes(fullCode);
24
    Serial.println(fullCode,BIN);
25
    delay(100);
26
    
27

28
  }
29

30
  delay(10);   // Eine Sekunde Verzögerung für jeden neuen MotherCode
31

32
  motherCode++; // MotherCode hochzählen
33

34
  if(motherCode == 16) // MotherCode zurücksetzen
35
    motherCode = 0;
36

37
}
38

39
// Generiere den RegalCode, welcher aus zwei identischen Zahlen besteht
40
int getRegalCode(long regalCodeCounter) {
41

42
  long sendRegalCode = 0B00000000;
43

44
  sendRegalCode = regalCodeCounter << 4;
45
  sendRegalCode += regalCodeCounter;
46

47
  return sendRegalCode;
48

49
}
50

51
void sendBytes(long data) {
52

53
  digitalWrite(speicherPin, LOW);
54
  shiftOut(datenPin, taktPin, MSBFIRST, data >> 8);
55
  shiftOut(datenPin, taktPin, MSBFIRST, data & 255);
56
  digitalWrite(speicherPin, HIGH);
57

58
}


Dieses Programm ist so generiert, sodass es einen Binär-Code 
"hochzählt", ist das Maximum des möglichen 16 stelligen erreicht, so 
wird wieder bei 0 begonnen.
Angehängte Dateien:
#4979670
Lesenswert?

t800w schrieb:

> Hallo, ich will mehrere 16-Cahnnel-Analog-Multiplexer (Typ: CD74HC4067)
> mit einem Arduino auslesen.

Was meinst du mit "auslesen"?

> Die Multiplexer steuere ich ebenfalls mit
> dem Arduino via 74HC595 an. Die 74HC595 funktionieren perfekt, jedoch
> zun die Multiplexer nicht das, was sie tun sollen, d.h jeder MUX bildet
> ein Mittelwert aus allen 16 Eingangssignalen, und gibt diesen dann an
> den Arduino weiter.

Wie kommst du auf diese Schlußfolgerung?

> So lautet das Programm:

Ich sehe da an keiner Stelle, daß du den analogen(?) Wert, den der 
Multiplexer ausgibt, irgendwie erfassen würdest.
Gast #4979687
Lesenswert?

> Was meinst du mit "auslesen"?

Das Signal vom MUX über einen analogen Pin am Arduino-Bord i Seriellen 
Monitor anzeigen lassen


> Wie kommst du auf diese Schlußfolgerung?

Ich habe an die 74HC595 LEDs angeschlossen, die sind dann mit dem Code 
an und aus gegenagen. Somt ziehe ich die Schlussvolgerung, dass es nicht 
an den 74HC595 liegen kann. Der Mittelwert ist ebenfalls bestätigt. Ich 
zeige dies an einem Beispiel:

Ich lese Pin C5 am MUX aus. Lege ich bei C9 eine andere Spannung an, so 
wird ebenfalls der Wert des Pins C5 beeinflusst. Warum der MUX dies tut 
ist mir ein Rätsel, deswegen frag ich ja.



> Ich sehe da an keiner Stelle, daß du den analogen(?) Wert, den der
> Multiplexer ausgibt, irgendwie erfassen würdest.

Ich hab ausversehn das falsche Programm hochgeladen, hier ist das 
Richtige:
1
int speicherPin = 10;
2
int taktPin     = 11;
3
int datenPin    = 9;
4
int analogPin   = 2;
5
int messErgebnis = 0;
6
long motherCode = 0;
7

8

9
  
10
void setup() {
11
  pinMode(speicherPin, OUTPUT);
12
  pinMode(taktPin, OUTPUT);
13
  pinMode(datenPin, OUTPUT);
14
  pinMode(analogPin, INPUT);
15
  Serial.begin(9600);
16

17
}
18

19
void loop() {
20
/*
21
  Serial.println("=====================================");
22
  Serial.print("MotherCode: ");
23
  Serial.println(motherCode, BIN);
24
  Serial.println("=====================================");
25
  
26
    */for(int regalCodeCounter = 0; regalCodeCounter < 16; regalCodeCounter++) {
27

28
    long fullCode = (0B1001 << 4) + motherCode;  // 1001 + motherCode
29
    fullCode = fullCode << 8;                   // 1001 + motherCode + 0000 0000
30
    fullCode += getRegalCode(regalCodeCounter); // 1001 + motherCode + regalCode
31
   
32
   
33
    sendBytes(0B1001000100001101);
34
    messErgebnis = analogRead(analogPin); 
35
   // Serial.println(0B1001000100000001, BIN);
36
   // delay(250);
37
    Serial.println(messErgebnis);
38
    delay(250);
39

40
    
41
  }
42

43
  //delay(1000);   // Eine Sekunde Verzögerung für jeden neuen MotherCode
44

45
  motherCode++; // MotherCode hochzählen
46

47
  if(motherCode == 16) // MotherCode zurücksetzen
48
    motherCode = 0;
49

50
}
51

52
// Generiere den RegalCode, welcher aus zwei identischen Zahlen besteht
53
int getRegalCode(long regalCodeCounter) {
54

55
  long sendRegalCode = 0B00000000;
56

57
  sendRegalCode = regalCodeCounter << 4;
58
  sendRegalCode += regalCodeCounter;
59

60
  return sendRegalCode;
61

62
}
63

64
void sendBytes(long data) {
65

66
  digitalWrite(speicherPin, LOW);
67
  shiftOut(datenPin, taktPin, MSBFIRST, data >> 8);
68
  shiftOut(datenPin, taktPin, MSBFIRST, data & 255);
69
  digitalWrite(speicherPin, HIGH);
70

71
}
Gast #4979707
Lesenswert?

Dein Problem sind wahrscheinlich seit deinem ersten Beitrag die 
Leckströme.
Dafür sehe ich derzeit nur zwei Lösungen:

1) deine Spannungsquellen (LDR + Widerstand als Spannungsteiler, 
richtig?) sind zu hochohmig. Hinter jeden davon einen Impedanzwandler 
mit OP und erst dann auf den MUX.
2) anderen MUX mit deutlich kleineren Leckströmen einsetzen.
Beitrag #4979738 wurde von einem Moderator gelöscht.
Moderator (Firma: Titel) Persönliche Seite #4979761
Lesenswert?

t800w schrieb:
> So lautet das Programm:
Du darfst gerne um deinen C-Code die [c] Tags herum machen. So wie es in 
der kurzen Anleitung über jeder Eingabebox bei "Antwort schreiben - 
Wichtige Regeln - erst lesen, dann posten!" steht. Und es nicht nur beim 
Lesen belassen, sondern es auch tun...

t800w schrieb:
> Habe die Lösungen aus dem ersten Thread ausprobiert, doch es hat immer
> noch keinen Erfolg gebracht. Außerdem kostet fragen ja nix
Du hättest aber wenigstens erwähnen können, dass an der selben Baustelle 
schon mal was los war.

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