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:
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:
Genügt es einen 10kOhm Wiederstand zu verwenden, vor welchem alle Photodioden ja zusammenlaufen oder muss hiner jeder Photodiode ein einzelner Wiederstand sein?
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?)
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.
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.
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.
brauchst Du einen analogen Eingang oder reicht Dir die digitale Information? Das hat auch Einfluß auf die notwendige Zeit.
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:
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
Im Anhang der Schaltplan, allerdings nur für 2 Multiplexer und 32 Ausgänge/Felder.
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.
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?
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
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:
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?
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
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
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.