Forum: Mikrocontroller und Digitale Elektronik Wie steuere ich einen 16-Channel-Analog-Multiplexer mit einem Arduino über 74HC595 an?


von t800w (Gast)


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.

von Felix Adam (Gast)


Lesenswert?

Dann teile uns doch mal mit, welchen Mux du benutzt.

Und EN auf Masse ziehen, wo das Signal nicht invertiert scheint, scheint 
auch erstmal falsch zu sein.

von Felix Adam (Gast)


Lesenswert?

Ah, der 74HC4067? So wie im Link benannt?

von STM8-C-Anfänger (Gast)


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.

von Einer K. (Gast)


Lesenswert?

> int analogPin   = 2;
const byte analogPin   = A2;

von t800w (Gast)


Lesenswert?

Ja genau der, Sie haben gesagt, dass man EN nicht auf GND ziehen darf, 
warum nicht?

von Felix Adam (Gast)


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.

von t800w (Gast)


Lesenswert?

@ STM8-C-Anfänger

STM8-C-Anfänger schrieb:
> 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.

Der Link war nur für die Veranschaulichung für die Anschlüsse des Mux 
gedacht.

von Felix Adam (Gast)


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.

von t800w (Gast)


Lesenswert?

@Felix Adam

Ich benutze Spannungsteiler als Signaleingänge.

Ich schalte Sig direkt mit dem Arduino zusammen

von t800w (Gast)


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.

von Felix Adam (Gast)


Lesenswert?

Bei einem nicht-invertierten EN muss das EN auflogisch high. Bei einem 
/EN wie bei dem 74HC4067 auf low (GND).

Wie geschrieben: deine Zeichnung ist für andere verwirrend.

von Felix Adam (Gast)


Lesenswert?

Und welche Werte haben die Spannungsteiler? Gib uns doch bitte mal die 
Widerstandswerte.

Und was ist mit dem ADC-Eingang? Gibt es einen Pulldown? und/oder einen 
Stützkondensator?

von Harald W. (wilhelms)


Lesenswert?

t800w schrieb:

> wenn ich eine Spannung auslesen möchte, dann klappt dies auch,
> sofern bei den 15 anderen Input Pins des MUX keine Spannung anlieegt.

Liegen denn die gemultiplexten Spannungen innerhalb des
Arbeitsbereichs des Multiplexers? So ein IC-Multiplexer
bietet keine galvanische Trennung.

von t800w (Gast)


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

von t800w (Gast)


Lesenswert?

Harald W. schrieb:
> Liegen denn die gemultiplexten Spannungen innerhalb des
> Arbeitsbereichs des Multiplexers?

Ja, sie liegen im Bereich von 0 - maximal 5V.



> So ein IC-Multiplexer
> bietet keine galvanische Trennung.


Wie sollte ich das Problem dann Elektronisch lösen?

von Einer K. (Gast)


Lesenswert?

2 Schieberegister, für einen Multiplexer, scheint mir leicht 
übertrieben.

Wie auch immer, ein Schaltplan würde Klarheit schaffen.

von Wolfgang (Gast)


Lesenswert?

t800w schrieb:
> Serial.println("=====================================");
>
>     */for(int regalCodeCounter = 0; regalCodeCounter < 16;
> regalCodeCounter++) {

Formatiere deinen Code mal anständig. Wer soll das denn lesen?

C-Code bitte als C-Code taggen!

von STM8-C-Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

Also hast Du das in etwa so verschaltet?

von STM8-C-Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

Sorry, das war zu eilig. So, wie jetzt angehangen?

von Wolfgang (Gast)


Lesenswert?

STM8-C-Anfänger schrieb:
> Also hast Du das in etwa so verschaltet?

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.

von STM8-C-Anfänger (Gast)


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

von STM8-C-Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

Ich hoffe, der gefällt besser ...

von Felix Adam (Gast)


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.

von Felix Adam (Gast)


Lesenswert?

Falsch, für alle inaktiven Kanäle zusammen bis zu ca. 1µA.

von T800w (Gast)


Lesenswert?

@STM8-C-Anfänger

Der Schaltplan stimmt so.

von t800w (Gast)


Angehängte Dateien:

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.

: Bearbeitet durch Moderator
von Axel S. (a-za-z0-9)


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.

von t800w (Gast)


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
}

: Bearbeitet durch Moderator
von Einer K. (Gast)


Lesenswert?

Warum 2 Threads zum selben Thema?
https://www.mikrocontroller.net/topic/424627

von Harald W. (wilhelms)


Lesenswert?

Arduino F. schrieb:

> Warum 2 Threads zum selben Thema?
> https://www.mikrocontroller.net/topic/424627

Wahrscheinlich gefielen ihm die Antworten im ersten Thread nicht.
Jetzt hofft er auf Antworten die ihm besser gefallen. :-(

von t800w (Gast)


Lesenswert?

@wilhelms

Habe die Lösungen aus dem ersten Thread ausprobiert, doch es hat immer 
noch keinen Erfolg gebracht. Außerdem kostet fragen ja nix

von Felix Adam (Gast)


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.

von Harald W. (wilhelms)


Lesenswert?

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

Normalerweise lassen sich solche Fehler durch systematisches Messen
leicht einkreisen. Solche Messungen können wir aus der Entfernung
nicht durchführen.

von Einer K. (Gast)


Lesenswert?

t800w schrieb:
> Außerdem kostet fragen ja nix
Nicht den Frager, aber die Zeit der kostenlosen Helfer.

Hat man dir schon gesagt, dass du etwas egomanisch drauf bist?
Wenn nicht, dann jetzt!
Aber ich glaube nicht, dass ich da der Erste bin.....

Beitrag #4979738 wurde von einem Moderator gelöscht.
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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.

: Bearbeitet durch Moderator
von Jörg (Gast)


Lesenswert?

Vor allem würde ich mal den Multiplexer mit minimaler Beschaltung (ohne 
den Arduino) auf einem Breadboard aufbauen und mal messen.

Ich habe den Eindruck, bei Dir steht der Sketch im Vordergrund...

von Harald W. (wilhelms)


Lesenswert?

Jörg schrieb:

> Ich habe den Eindruck, bei Dir steht der Sketch im Vordergrund...

Wo ist denn da die Stelle, wo man lachen kann?

https://de.wikipedia.org/wiki/Sketch

von T800w (Gast)


Lesenswert?

Das Problem hat sich erledigt, funktioniert jetzt perfekt, es lag doch 
an dem pull-down wiederstand.
Vielen Dank

von Einer K. (Gast)


Lesenswert?

T800w schrieb:
> es lag doch
> an dem pull-down wiederstand.

Ich sehe keinen Pulldown.

von Christian M. (Gast)


Lesenswert?

Von dem hören wir bis zum nächsten Problem nichts mehr! Der hat gar 
nicht zugehört! Ich glaube, das ist ein Troll!

Gruss Chregu

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.