36 Photodioden "gleichzeitig" auslesen, Schieberegister

Hallo,

ich würde gerne wissen ob mein erstes wirkliches Arduino-Projekt machbar ist.

Zielstellung ist es 36 Photodioden "gleichzeitig" (oder sehr schnell hintereinander) auszulesen und die Werte/Daten in einer Matrix zu speichern.

Grundsätzlich möchte ich über Schieberegister immer nur eine Photodiode mit Spannung belegen und deren Wiederstand dann am analogen Eingang des Arduino messen, somit benötige ich nur einen analogen Eingang um alle Photodioden nacheinander auszulesen.

Ich habe mir überlegt 6 Schieberegister hintereinander zu schalten. An jedem Ausgang eines jeden Schieberegisters hängt jeweils eine Photodiode, welche dann in den analogen Eingang des Arduino (A1) und über einen 10kOhm Wiederstand zur Erde des Arduino geht.

Die Schieberegister (74HC595) sind wie folgt verkabelt:

Ausgänge 1-6 -> jeweils eine Photodiode
Ausgänge 7-8 -> nicht belegt
GND & OE -> Erde Arduino
VCC & MR -> 5V Arduino (dauerhaft)
ST_CP -> Arduino Ausgang (5)
SH_CP -> Arduino Ausgang (6)
DS -> Arduino Ausgang (7)
Q7' -> DS des nächsten Schieberegisters

Das heisst wenn ich zum Beispiel die Photodiode am 1. Ausgang des 2. Schieberegisters messen will gibt der Arduino (000000001000000000000.....) an die Schieberegister. Die Bits werden dann durch alle Schieberegister durchgegeben und sobald ich von Low auf High setzte liegen nur an dieser Photodiode 5V an, somit kann ich den Wert am analogen Eingang des Arduinos dieser Photodiode zuordnen.

Funktioniert dieser Aufbau prinzipiell?

Weitere Fragen:

  1. Genügt es einen 10kOhm Wiederstand zu verwenden, vor welchem alle Photodioden ja zusammenlaufen oder muss hiner jeder Photodiode ein einzelner Wiederstand sein?

  2. Wenn ich mit dieser Schaltung alle 36 Photodiodenwiederstände messe, wie lange wird das ungefähr dauern? (wie viele ms? und wie kann ich sowas selbst berechnen/abschätzen?)

  3. Alle ST_CP Eingänge der Register hängen an einem Arduino-Pin, genauso alle ST_CP. Funktioniert das so?

Der Schaltplan ist im Anhang!

Über Antworten würde ich mich freuen, steige gerade noch neu ein und kenne mich noch nicht sehr gut aus mit der Materie.

Viele Grüße
Mo

Frage nach Sichtung des Schaltplans: reden wir über Photodioden oder LDRs?

Ach ja: willkommen im Forum ;D

Das funktioniert so nicht. Die Schieberegister haben als Ausgang entwerder H oder L. Dadurch hast Du alle anderen 35 LDRs gegen Masse geschaltet und also paralell zum 100k Spannungsteilerwiderstand. Du kannst nichts genaues messen.

Du kannst für jeden LDR eine Spannungsteilerwiderstand und 0,1µF Kondensator montieren und die Spannung über Analogmultiplexer vom typ 74HC4067 mit einem oder mehreren dem Analogeingang/Gängen verbinden.

http://www.nxp.com/documents/data_sheet/74HC_HCT4067.pdf

Grüße Uwe

Vielen Dank für die schnellen Antworten erstmal.

Klaus_ww:
Frage nach Sichtung des Schaltplans: reden wir über Photodioden oder LDRs?

Ich verwende LDRs, also Fotowiederstände.

uwefed:
Das funktioniert so nicht. Die Schieberegister haben als Ausgang entwerder H oder L. Dadurch hast Du alle anderen 35 LDRs gegen Masse geschaltet und also paralell zum 100k Spannungsteilerwiderstand. Du kannst nichts genaues messen.

Achso, ich habe total vergessen das LOW nicht 0V/bzw. keine Spannung sondern 3Volt entspricht. Du hast natürlich vollkommen recht, da messe ich Unsinn.

uwefed:
Du kannst für jeden LDR eine Spannungsteilerwiderstand und 0,1µF Kondensator montieren und die Spannung über Analogmultiplexer vom typ 74HC4067 mit einem oder mehreren dem Analogeingang/Gängen verbinden.

Benötige ich dann überhaupt noch meine Schieberegister 74HC595?
Oder kann ich einfach an alle LDRs 5 Volt anlegen und ich messe immer nur den LDR dessen Ausgang am Analogmultiplexer gerade geschalten ist?

Das heisst aber ich benötige für jeden LDR einen eigenen Wiederstand.

Da ich 3 analoge Multiplexer mit jeweils 16 Eingängen (und 4 Ansteuerungen) verwenden werde benötige ich 4x3 = 12 Ausgänge vom Arduino um die 3 Multiplexer anzusteuern, das heisst ich kann einfach zwei der 74HC595 Schieberegister für die Ansteuerung der Multiplexer verwenden?

Ich werde mich mal in die Analogmultiplexer einarbeiten und dann einen 2. Anlauf drunter posten.
Nochmal vielen Dank für die Hilfe.

Grüße
Mo

PS: Ein Test (der falschen 1. Lösung) gestern Abend mit 6 LDRs hat übrigens trotz der Fehler sehr gut funktioniert. Anscheinend sind die 3V für die LDRs deutlich zu wenig und deshalb messe ich anscheinend halbwegs ordentlich Werte. Da ich genaue Werte benötige werde ich das Projekt trotzdem neu aufrollen.

Arduino-Mo:
Da ich 3 analoge Multiplexer mit jeweils 16 Eingängen (und 4 Ansteuerungen) verwenden werde benötige ich 4x3 = 12 Ausgänge vom Arduino um die 3 Multiplexer anzusteuern,

Nein! Du brauchst 4 + 3. Die Adress-Leitungen gehen auf alle Multiplexer gleichzeitig und der aktuelle MUX wird über den Enable-Eingang ausgewählt.

Ausgehend von Deiner ursprünglichen Schaltung

  1. brauchst Du einen analogen Eingang oder reicht Dir die digitale Information? Das hat auch Einfluß auf die notwendige Zeit.
  2. Du könntest in Reihe zum LDR eine Diode vorsehen, damit nur bei HIGH ein Strom fließt.

Arduino-Mo:
Achso, ich habe total vergessen das LOW nicht 0V/bzw. keine Spannung sondern 3Volt entspricht. Du hast natürlich vollkommen recht, da messe ich Unsinn.

Hochohmig wäre das, was Du benötigst. Mit einem I/O Expander (PCF8574 oder MCP23017) könntest Du Anschlüsse als Ausgang aber auch als hochohmigen Eingang definieren.

Serenifly:
Nein! Du brauchst 4 + 3. Die Adress-Leitungen gehen auf alle Multiplexer gleichzeitig und der aktuelle MUX wird über den Enable-Eingang ausgewählt.

Verstanden, Danke.

agmue:

  1. brauchst Du einen analogen Eingang oder reicht Dir die digitale Information? Das hat auch Einfluß auf die notwendige Zeit.

Digital würde auch reichen, ich benötige auf einer 6x6 Matrix nur auf jedem Feld zu jeder Zeit die Information wie Hell es ist, d.h. die Matrix im Code soll laufend mit Helligkeitswerten belegt werden.
Da im Arduino-CookBook der LDR über den analogen Eingang "ausgelesen" wurde habe ich das einfach so übernommen.

Momentan sieht meine Schaltung so aus:

Ziel: Die Helligkeit von 36 Feldern in einer Matrix ablegen (mindestens alle 200ms) mit 36 LRDs.

Der Arduino steuert mit 7 digitalen Ausgängen 3 Multiplexer vom Typ: CD74HC4067E.

Am Eingang eines jeden Multiplexers liegen die 5V des Arduino an.
An den 48 Ausgängen der Multiplexer hängen direkt jeweils eine LDR, dann in Reihe ein Wiederstand (1kOhm) der an der Erde hängt. Zwischen dem Wiederstand und der LDR führt ein Kabel zum A0 Eingang des Arduino.

Nun steuert der Arduino z.B. Multiplexer 1, 4. Ausgang auf 1, das heisst am 4. Ausgang des Multiplexers 1 liegen 5 Volt an, an allen anderen 47 Ausgänge liegt nichts an (offener Stromkreis).

Also kann ich das jetzt gemessene Signal (A0) der LDR Multiplexer 1, Ausgang 4 direkt zuordnen.

Irgendwelche Denkfehler? =)
Hätte ich mal doch lieber Elektrotechnik statt Maschinenbau studiert :wink:

Im Anhang der Schaltplan, allerdings nur für 2 Multiplexer und 32 Ausgänge/Felder.

Vielen Dank für die Hilfe.

Mo

A0 muß an den Multiplexer-Ausgang, sonst kannst Du nicht messen.

agmue:
A0 muß an den Multiplexer-Ausgang, sonst kannst Du nicht messen.

Hmm, das versteh ich nicht ganz.
Ich messe Spannung eigentlich am Arduino immer so: "Bild-Anhang"
Der Arduino lösst das Signal in A0 dann auf 0-1023 (weil 8Bit) auf.

Am Multiplexer-Ausgang hängt der LDR der dann mit A0 verbunden und über den 1kOhm Wiederstand an die Erde geht.

Was stimmt da denn nicht bzw. bis jetzt hat bei mir die Spannungsmessung immer geklappt.

Grüße
Mo

SIG (Ausgang siehe Bild) müßte an A0.

agmue:
SIG müßte an A0.

Okay, mir ist noch nicht klar wo der Unterschied ist aber das heisst die Schaltung sieht so aus:

5V Arduino -> Alle LDRs -> Jede LDR an einen Eingang des Multiplexers -> Ausgang Multiplexer an A0 Arduino, vom Ausgang Multiplexer nochmal über einen Wiederstand an die Erde des Arduino?

Sry das ich hier so ein Chaos hereinbringe.

So, wie Du das ursprünglich gemacht hast, leitest Du 5V durch den Multiplexer. Das entspricht der Idee mit den Schieberegistern. Wenn Du aber einen Analogmultiplexer verwendest, sollte auch die zu messende analoge Spannung durch diesen fließen. Finde ich zumindest. Jetzt gefällt mir der Schaltplan. Allerdings solltest Du D0 und D1 meiden, das ist USB vom UNO.

Wenn Du die drei SIGs mit A0, A1 und A2 verbindest, mißt Du drei Werte "gleichzeitig". Möglicherweise kannst Du dann sogar auf die EN verzichten.

Serenifly:
Nein! Du brauchst 4 + 3. Die Adress-Leitungen gehen auf alle Multiplexer gleichzeitig und der aktuelle MUX wird über den Enable-Eingang ausgewählt.

Nein das sind dann entweder 8 oder 7 Pins:
4 zur Auswahl des Eingangs (alle 3 Multiplexer paralell
3 zum Enabel
1 Analoger Eingang

oder
4 zur Auswahl des Eingangs
3 analoge Eingänge je einen pro multiplexer.
Grüße Uwe

Ich meinte nur zur Kanalauswahl! Ohne die analogen Eingänge

So, letzte und hoffentlich endgültige Version des Schaltplans,

-> 64 LDRs messen
-> 4 Analoge Multiplexer
-> 4 Analoge Eingänge am Arduino benutzt
-> 5 digitale Ausgänge am Arduino benutzt

4 Messwerte werden gleichzeitig über analogRead() erfasst.
Die S0, S1, S2, S3 Variablen aller Multiplexer werden parallel angesteuert.
Jeder Multiplexer sendet an einen Ausgang.

2 letzte Fragen:

  1. Muss ich ein delay() vor oder hinter analogRead() einbauen damit der Messwert genau ist oder nimmt sicher der Arduino selbst genug Zeit. Zum Beispiel in einer for-Schleife wo analogRead oft nacheinander aufgerufen wird?

  2. Ist der Schaltplan so in Ordnung?

Vielen Dank und Grüße
Mo

Zu 2. So gefällt er mir! Schönheit: Mux1 an A0, Mux2 an A1, Mux3 an A2, Mux4 an A3. Damit Du nicht in Tüdel kommst.

Zu 1. Vor meinem geistigen Auge sehe ich eine blockierende Schleife, die alle Messungen auf eine Schlag durchführt. Da schlage ich doch Messung-Loop-Messung-Loop ... vor. Willst Du direkt an die Ports oder mit digitalWrite arbeiten (Vergleich der Zeiten)?

agmue:
Zu 2. So gefällt er mir! Schönheit: Mux1 an A0, Mux2 an A1, Mux3 an A2, Mux4 an A3. Damit Du nicht in Tüdel kommst.

Zu 1. Vor meinem geistigen Auge sehe ich eine blockierende Schleife, die alle Messungen auf eine Schlag durchführt. Da schlage ich doch Messung-Loop-Messung-Loop ... vor. Willst Du direkt an die Ports oder mit digitalWrite arbeiten (Vergleich der Zeiten)?

Im Code sind die Multiplexer und die Analog Eingänge sortiert, wollte im Schaltplan nur weniger kreuzende Linien. =)

Ich arbeite mit Port Manipulation.

Grundsätzlich wird in einer großen for-Schleife zuerst S0-S3 gesetzt, dann die Multiplexer angeschaltet, 4x hintereinander analogRead aufgerufen, die 4 verschiedenen Eingänge eben, Multiplexer wieder aus und neuer Loop. Habe angenommen das 4 analogRead Messungen gleichzeitig passieren können :-(.

Werde heute Abend mal den kommentierten Code posten, dann wird es vielleicht etwas anschaulicher.
Danke und Grüße
Mo

:slight_smile: Alle meine Befürchtungen sind gegenstandslos, mein geistuges Auge sieht ein wundervolles Programm :slight_smile:

Ob eine Verzögerung zwischen den analogRead sein muß, weiß ich nicht, da können ja andere Forumsmitglieder was zu sagen.

Arduino-Mo:
Habe angenommen das 4 analogRead Messungen gleichzeitig passieren können

Der µC hat nur einen ADC. Die Eingänge werden auch nur über einen Multiplexer auf den ADC geschaltet.

Wie kann ich denn am einfachsten einen Multiplexer von Eingang 0-15 der Reihe nach durchgehen?
Ich habe das so gelöst, wobei ich mir sicher bin das es da einfachere Wege gibt?
Die PortManipulation mache ich am Ende wenn der Code stimmt und funktioniert, ausserdam kann so vielleicht jeder etwas damit anfangen :wink:

a zählt von 0 bis 15;

if (a < 8)                                                                                               //8x LOW, 8x HIGH
{digitalWrite(S3, LOW);}
else 
{digitalWrite(S3, HIGH);}

if ((a < 4) || (a > 7 && a < 12))                                                            //4x LOW, 4x HIGH.. 
digitalWrite(S2, LOW);}
else 
{digitalWrite(S2, HIGH);}

if ( (((a+2)%2) = 0) && (((a+4)%4)=0) || (((a+2)%2) != 0) && (((a+3)%4)=0) ) //2x LOW, 2x HIGH...
{digitalWrite(S1, LOW);}
else 
{digitalWrite(S1, HIGH);}

if (((a+2)%2) == 0)                                                                                  //LOW, HIGH, LOW...
{digitalWrite(S0, LOW);}
else 
{digitalWrite(S0, HIGH);}

Hat jemand einen Tipp für mich?
Im Anhang noch die Tabelle.