hi Forum, ich habe einen Zähler gebaut, der mittels einer Lichtschranke zählt. Die Entfernung von der IR-Diode und Fotodiode ist ca. 30 cm. bei der Entfernung empfängt die Fotodiode aber nichts (kaum zu verarbeiten). jetzt habe ich mit einem OP (LT1013) das Signal verstärkt(Schaltung im Anhang). Signal verstärkt alles gut. Jetzt das Problem : am Arduino ist ein analoges Signal von 822 bei offener Lichtschranke und 0 wenn sie unterbrochen ist. Das erste Signal was ich lese nachdem die Schranke wieder offen ist wenn sie unterbrochen war variiert zwischen 0-30 obwohl das Signal ja wieder 822 sein müsste. Deshalb zählt nachdem sie unterbrochen war nochmal obwohl die Lichtschranke offen ist. Jetzt kommt meine Vermutung ich habe am Ausgang vom OP bisschen gemessen und die Spannung während die Lichtschranke von unterbrochen zu offen geht springt nicht direkt von 0V (unterbrochen) und 5V (nicht unterbrochen) sondern nachdem sie direkt wieder offen ist so ca. 100-500mV. Dadurch kommen denke ich die niedrigen Signale. Ich habe es mit einem Pulldown Widerstand versucht aber das bringt nicht und jetzt bin ich ratlos. Hat jemand eine Idee was ich machen könnt oder ob meine Vermutung richtig ist? danke schon mal im voraus :) (ps. bin im 2 Lehrjahr bei Elektroniker für Geräte und Systeme, deswegen verzeiht mir wenn ich nicht sooo die Ahnung hab)
:
Verschoben durch Moderator
Hallo und was passiert, wenn Du einen Widerstand von 100 kOhm von Kathode der Fotodiode zur positiven Betriebsspannung einbaust? MfG
Cano O. schrieb: > ob meine Vermutung richtig ist? Welche Vermutung? Was stört dich denn prinzipiell an dem Verhalten? Natürlich muss der AD-Wert 100...500mV durchlaufen, wenn er von 0V nach 5V geht. Allein die Frage, wie schnell das geht, beantwortet sich z.B. aus der Bauteilauswahl. > Jetzt kommt meine Vermutung ich habe am Ausgang vom OP bisschen gemessen > und die Spannung während die Lichtschranke von unterbrochen zu offen > geht springt nicht direkt von 0V (unterbrochen) und 5V (nicht > unterbrochen) sondern nachdem sie direkt wieder offen ist so ca. 100-500mV. Du solltest dieses Verhalten mal mit einem Oszilloskop beobachten. "Normalerweise" arbeiten Lichtschranken übrigens mit moduliertem Licht, denn sonst sind sie extrem anfällig auf Sonneneinstrahlung und Fremdlicht...
:
Bearbeitet durch Moderator
Christian S. schrieb: > und was passiert, wenn Du einen Widerstand von 100 kOhm von Kathode der > Fotodiode zur positiven Betriebsspannung einbaust? Das ist bei einem Transimpedanzverstärker nicht nötig. Der TO kann noch einen 1n Kondensator parallel zum Widerstand schalten, aber ich glaube fast, das ist nicht die Lösung für das angesprochene Problem.
Beitrag #5319832 wurde von einem Moderator gelöscht.
> Was stört dich denn prinzipiell an dem Verhalten?
Ja diese 100 - 500 mV geben halt dieses kleine Signal von 0 - 30 am
arduino und das kann ich nicht gebrauchen. Ich könnte jetzt theoretisch
sagen das die lichtschranke unterbrochen ist wenn der analoge Wert
kleiner als 1 ist, da aber der Wert ab und zu 0 ist wenn die schranke
wieder offen ist hilft mir das nicht viel. Dewegen bin ich bisschen am
verzweifeln
Nur am Rande bemerkt. Man sollte beim Studium des Datenblatt darauf achten ob die Photo Diode für "Photo Voltaic" Gebrauch bestimmt ist oder "Photo Conductive". Im zweiten Fall schließt man an der Anode über ein RC eine Hilfspannung von -10 und mehr Volt an. In diesem Fall wirkt die Diode als veränderlicher Widerstand anstatt als Photo Spannungsquelle.
Gerhard O. schrieb: > Nur am Rande bemerkt. Man sollte beim Studium des Datenblatt darauf > achten ob die Photo Diode für "Photo Voltaic" Gebrauch bestimmt ist oder > "Photo Conductive". Im zweiten Fall schließt man an der Anode über ein > RC eine Hilfspannung von -10 und mehr Volt an. In diesem Fall wirkt die > Diode als veränderlicher Widerstand anstatt als Photo Spannungsquelle. also Die Fotodiode erzeugt einen kleinen Strom von ca. 50µA wenn sie Licht bekommt.
Gerhard O. schrieb: > In diesem Fall wirkt die Diode als veränderlicher Widerstand anstatt > als Photo Spannungsquelle. Beim Betrieb mit einem TIA arbeitet die Photodiode doch wohl als Stromquelle, und zwar im Kurzschlussbetrieb.
> Beim Betrieb mit einem TIA arbeitet die Photodiode doch wohl als > Stromquelle, und zwar im Kurzschlussbetrieb. hab ich das jetzt falsch gemacht oder wie ? bin grad bisschen überfordert...
Achi M. schrieb: > Ja diese 100 - 500 mV geben halt dieses kleine Signal von 0 - 30 am > arduino und das kann ich nicht gebrauchen. Dann schreib dein Programm doch so, dass es dich nicht mehr so arg stört... > Dewegen bin ich bisschen am verzweifeln Ich würde da einfach den Wert mit der Software ein wenig aufbereiten und filtern.
:
Bearbeitet durch Moderator
> Dann schreib dein Programm doch so, dass es dich nicht mehr so arg > stört... > Ich würde da einfach den Wert mit der Software ein wenig aufbereiten und > filtern. Ja das Problem dabei ist, dass ich jetzt sagen könnte das wenn der wert auf 0 ist das die Lichtschranke unterbrochen ist, aber das der Wert ja ab und zu auf 0 ist wenn sie wieder frei ist weil der ja zwischen 0-30 schwankt und ich den wert ja nicht unter 0 wählen kann. Deswegen dachte ich, ich kann das Problem am OP lösen.
Bleibt die Spannung denn bei 100-500mv, oder steigt sie dann doch wieder? Und dauert es zu lange bis sie wieder steigt? Meine sonst brauchst du im Mikrokontroler eifnach nur den Schwell wert deutlich anzuheben! Mit einem Wert von 1 als Schwellwert bei 1024 möglichen Werten (oder sind es gar noch mehr) zu arbeiten ist sowieso eher quatsch. Mit Pech wird etwas in die Leitung induziert, oder orgendeine Spiegelung aktiviert ungewollt die Schranke. Des weiteren könntest/solltest du das ganze auch "Entprellen". Also einen Mittelwert über einen kurzem zeitraum bilden, und anhand davon entscheiden. EDIT: Das kann man mittels Kondensator auch in Hardware machen.
:
Bearbeitet durch User
Alex G. schrieb: > Bleibt die Spannung denn bei 100-500mv, oder steigt sie dann doch > wieder? > Und dauert es zu lange bis sie wieder steigt? nein sie steigt dann wieder relativ schnell > Meine sonst brauchst du im Mikrokontroler eifnach nur den Schwell wert > deutlich anzuheben! ne also ich muss ja sagen, dass der UNTER einem bestimmten wert sein muss um unterbrochen zu sein und dieser kleine wert der kommt nachdem sie wieder frei wird liegt halt manchmal bei 0 und ich kann ja nicht unter 0 gehen > Des weiteren könntest/solltest du das ganze auch "Entprellen". Also > einen Mittelwert über einen kurzem zeitraum bilden, und anhand davon > entscheiden. Das hat mir mein Ausbilder auch vorgeschlagen aber ich bin noch relativer Anfänger beim Arduino und er hat gerade nicht so viel Zeit und ich hab keine Ahnung wie das geht
Achi M. schrieb: > Alex G. schrieb: >> Bleibt die Spannung denn bei 100-500mv, oder steigt sie dann doch >> wieder? >> Und dauert es zu lange bis sie wieder steigt? > > nein sie steigt dann wieder relativ schnell >> Meine sonst brauchst du im Mikrokontroler eifnach nur den Schwell wert >> deutlich anzuheben! > ne also ich muss ja sagen, dass der UNTER einem bestimmten wert sein > muss um unterbrochen zu sein und dieser kleine wert der kommt nachdem > sie wieder frei wird liegt halt manchmal bei 0 und ich kann ja nicht > unter 0 gehen Glaube du stehst ein wenig auf dem Schlauch. Als soweit ich das verstehe, steigt der Wert, sobald das Licht wieder auf den Sensor trifft, innerhalb einer kurzen Zeit an. Sie erreicht z.B. 800. Durch das wie auch imemr geartete Problem, hast du ungewollte Schwankungen zwischen 0 und 30 zud em Zeitpunkt wenn wieder Licht drauf scheint. Dann stell die Schwell auf z.B. 150. Ist der Wert UNTER 150 gilt die Schranke als unterbrochen. Ist er darüber, ist die Schranke in Takt. > Das hat mir mein Ausbilder auch vorgeschlagen aber ich bin noch > relativer Anfänger beim Arduino und er hat gerade nicht so viel Zeit und > ich hab keine Ahnung wie das geht Ist nicht extrem schwer. Du hat sicherlich einen Timer, der Prüft ob die Schranke offen/unterbrochen ist, ja? Sagen wir mal z.B. alle 50ms Dann initialisiere einen Array ('data[]') der Größe 10 ('limit'), sowie eine Zähl-Variable ('pos'). In dem Timer kommt dann etwa ein code wie dieser (hab jetzt grad Java Syntax im Kopf, aber C ist hier ähnlich):
1 | data[pos] = WERTVOMSENSOR; // Speichere den neuen Wert |
2 | pos++; // Incrementiere den Zähler |
3 | if(pos == limit) // Wenn der Zähler am Ende ist |
4 | {
|
5 | pos = 0; // Resette Zähler |
6 | int result = 0; |
7 | for(int i = 0; i < limit; i++) // Iteriere durch alle gespeicherten Werte |
8 | {
|
9 | result += data[i]; // summiere alle Daten |
10 | }
|
11 | result /= limit; // Teile die Daten durch deren Anzahl -> Durchschnittsberechnung |
12 | |
13 | if (result > SCHWELLE) |
14 | // SCHRANKE IN TAKT
|
15 | ELSE
|
16 | // SCHRANKE UNTERBROCHEN
|
17 | }
|
Das Resultat dieses Codes ist, dass 2 mal pro Sekunde, die Schranke auf Basis der letzten 10 Werte innerhalb der vergangenen 500ms evaluiert wird.
:
Bearbeitet durch User
> Glaube du stehst ein wenig auf dem Schlauch. > Als soweit ich das verstehe, steigt der Wert, sobald das Licht wieder > auf den Sensor trifft, innerhalb einer kurzen Zeit an. Sie erreicht z.B. > 800. > Durch das wie auch imemr geartete Problem, hast du ungewollte > Schwankungen zwischen 0 und 30 zud em Zeitpunkt wenn wieder Licht drauf > scheint. > Dann stell die Schwell auf z.B. 150. > Ist der Wert UNTER 150 gilt die Schranke als unterbrochen. Ist er > darüber, ist die Schranke in Takt. Ich glaube ich habe das nicht ganz so deutlich erklärt ich Versuchs nochmal. der Wert den ich bekomme wenn die Lichtschranke nicht unterbrochen ist liegt bei ca. 800 und wenn sie unterbrochen ist bei 0. Jetzt unterbreche ich die Schranke und der wert sinkt sofort von 800 auf 0. dann mache ich die Schranke frei und der wert springt nicht sofort wieder auf 800 sondern erst 0-30 und dann 800. Das heißt jetzt die Schranke ist frei und sollte bei 800 sein ist aber erst bei 0-30. Wenn ich den Schwellwert auf 150 lege und die Schranke wieder frei wird liegt der Wert bei 0-30 und das liegt unter 150 und somit denkt er, er ist unterbrochen und zählt nochmal. das ist mein Problem. Hoffe das war bisschen verständlicher.
Der Wert springt nach dem Unterbrechen aber nicht auf 800 und dann wieder auf 0-30, oder? Wieso zählt dann deine Schranke "nochmal"? Mit dem höheren Schwellwert würde die Schranke einfach nur SPÄTER reagiren, aber dafür immer korekt. Erklär mal bitte deine ganze aufgabe. Wie schnell muss die Schranke reagieren? Muss sie schneller reagieren, als es dauert bis der Wert von 800 erreicht wird? Wenn das der Fall ist, ist höchstwahrscheinlich der Sensor einfach ungeeignet (denn dann hilft auch Durschnittsberechnung natürlich nichts). Für sehr hohe Reaktionszeiten (wie z.B. für Spalten-Zählsysteme) sind sklche Spannungserzeugenden Sensoren ungeeignet. Btw. um die Frage im Titel zu beantworten: Ja, weil es sowas wie unendliche Steigung eines Werte in der Realität nicht gibt. D.h. du wirst immer eine steigende Kurve haben. Selbst im Inneren von Mikrocontrolern/CPUs wo nur Werte von 0 und 1, Relevanz haben, gibt ss in der Realität viele Zwischenwerte in den Übergängen. Das legt die Physik so vor.
:
Bearbeitet durch User
Alex G. schrieb: > Der Wert springt nach dem Unterbrechen aber nicht auf 800 und dann > wieder auf 0-30, oder? > Wieso zählt dann deine Schranke "nochmal"? Mit dem höheren Schwellwert > würde die Schranke einfach nur SPÄTER reagiren, aber dafür immer korekt. Ich glaube wir reden bisschen an einander vorbei. Die genauen Werte die die Fotodiode ausgibt sind im Programm nicht integriert. Im Programm sage ich einfach nur wenn der Wert unter 100 ist gilt die Schranke als unterbrochen und er Zählt einmal hoch. also wenn sie jetzt unterbrochen wird ist der Wert 0 und der Zähler auf 1. Ist die Schranke wieder frei "sollte" der Wert bei 800 sein und die Schranke ist über den angegebenen Wert 100 und somit nicht unterbrochen. Jetzt ist der Wert aber wegen dem OP ( meine Vermutung ) nicht bei den 800 die sein sollten weil die Schranke wieder frei ist sondern bei 0-30 und das ist unter 100 das Programm denkt die Schranke ist wieder unterbrochen und er Zählt einmal hoch und ist jetzt bei 2 wo aber 1 sein sollte.
Ist diese Abfrage in einem Timer, also so dass du dauernd abfragst und die "Schranke-Unterbrochen-Variable" erhöhst? Oder ist das eine Art event? Wenn es ein event ist, sollte dieses nicht ausgelöst werden, wenn der Schwellwert auf 100 oder höher ist. EDIT: Oder moment, hast du etwa eine Funktion/Event welches immer dann auslöst, wenn sich der Sensor-Wert ändert? Dann darfst du in dieser Funktion nicht einfach annehmen, dass die Schranke grade offen oder geschlossen war, sondern du musst mittels eine weiteren Variablen festhalten, wie der letzte Zustand war. Also die Variable: "UNTERBROCHEN". Angenommen das system startet mit geschlossener Schranke, dann initialisierst du UNTERBROCHEN mit false. Im Event schreibst du dann
1 | if ((!UNTERBROCHEN) && (WERT < SCHWELLE)) |
2 | {
|
3 | UNTERBROCHEN = true; |
4 | // was auch immer beim UNTERBRECHEN der Schranke geschehen soll
|
5 | }
|
6 | else
|
7 | if ((UNTERBROCHEN) && (WERT > SCHWELLE)) |
8 | {
|
9 | UNTERBROCHEN = false; |
10 | // was auch immer beim WIEDERHERSTELLEN der Schranke geschehen soll
|
11 | }
|
Wenn das nicht hilft, poste einfach dein Programm bitte und wie die Aufgabenstellung ist. Sonst kommen wir einfach nicht weiter. Bin mir zu 90% sicher dass ein kapitaler Denkfehler/Konzeptfehler vorliegt...
:
Bearbeitet durch User
Wie wäre es, wenn mal Zeiten in µs oder ms angegeben würden, ich lese hier immer nur 0-30 und geht erst später auf 800. Was bedeutet später. Oben hat jemand die Benutzung eines Oszis angeraten, dem schliesse ich mich an.
1 | int Taster1 = A1;// + |
2 | int Taster2 = A2; // - |
3 | int Taster_Reset = 12; // Zaehler reset |
4 | |
5 | int CD4511_1_A = 6; // Zahl 1 |
6 | int CD4511_1_B = 3; |
7 | int CD4511_1_C = 4; |
8 | int CD4511_1_D = 5; |
9 | |
10 | int CD4511_2_A = 7; // Zahl 2 |
11 | int CD4511_2_B = 2; |
12 | int CD4511_2_C = 9; |
13 | int CD4511_2_D = 8; |
14 | |
15 | int Sollwert = 10; // Standartwert beim Einschalten |
16 | |
17 | int Led_rot = 11 ; // LED für erreichten Sollwert |
18 | int Led_gruen = 10; // LED für noch nicht erreichten Sollwert |
19 | int buzzer = 13 ; // Signalgeber für erreichten Sollwert |
20 | |
21 | int Lichtschranke = A0; // Photodiode |
22 | |
23 | int counter = 0 ; // Variable für gezaehlte Vorgaenge |
24 | |
25 | boolean LS_offen_Last; // Letzter Wert der Lichtschranke |
26 | |
27 | |
28 | /* Eigene Funktionen */
|
29 | |
30 | int Aktualisiere_Display(int Zahl)//7 Segmentanzeige |
31 | {
|
32 | |
33 | |
34 | |
35 | switch (Zahl) |
36 | |
37 | {
|
38 | case 0: |
39 | {
|
40 | digitalWrite(CD4511_1_D, LOW); |
41 | digitalWrite(CD4511_1_C, LOW); |
42 | digitalWrite(CD4511_1_B, LOW); |
43 | digitalWrite(CD4511_1_A, LOW); |
44 | }
|
45 | break; |
46 | |
47 | case 1: |
48 | {
|
49 | digitalWrite(CD4511_1_D, LOW); |
50 | digitalWrite(CD4511_1_C, LOW); |
51 | digitalWrite(CD4511_1_B, LOW); |
52 | digitalWrite(CD4511_1_A, HIGH); |
53 | |
54 | }
|
55 | break; |
56 | |
57 | case 2: |
58 | {
|
59 | digitalWrite(CD4511_1_D, LOW); |
60 | digitalWrite(CD4511_1_C, LOW); |
61 | digitalWrite(CD4511_1_B, HIGH); |
62 | digitalWrite(CD4511_1_A, LOW); |
63 | |
64 | }
|
65 | break; |
66 | |
67 | case 3: |
68 | {
|
69 | digitalWrite(CD4511_1_D, LOW); |
70 | digitalWrite(CD4511_1_C, LOW); |
71 | digitalWrite(CD4511_1_B, HIGH); |
72 | digitalWrite(CD4511_1_A, HIGH); |
73 | |
74 | }
|
75 | break; |
76 | |
77 | case 4: |
78 | {
|
79 | digitalWrite(CD4511_1_D, LOW); |
80 | digitalWrite(CD4511_1_C, HIGH); |
81 | digitalWrite(CD4511_1_B, LOW); |
82 | digitalWrite(CD4511_1_A, LOW); |
83 | |
84 | }
|
85 | break; |
86 | |
87 | case 5: |
88 | {
|
89 | digitalWrite(CD4511_1_D, LOW); |
90 | digitalWrite(CD4511_1_C, HIGH); |
91 | digitalWrite(CD4511_1_B, LOW); |
92 | digitalWrite(CD4511_1_A, HIGH); |
93 | |
94 | }
|
95 | break; |
96 | |
97 | case 6: |
98 | {
|
99 | digitalWrite(CD4511_1_D, LOW); |
100 | digitalWrite(CD4511_1_C, HIGH); |
101 | digitalWrite(CD4511_1_B, HIGH); |
102 | digitalWrite(CD4511_1_A, LOW); |
103 | |
104 | }
|
105 | break; |
106 | |
107 | case 7: |
108 | {
|
109 | digitalWrite(CD4511_1_D, LOW); |
110 | digitalWrite(CD4511_1_C, HIGH); |
111 | digitalWrite(CD4511_1_B, HIGH); |
112 | digitalWrite(CD4511_1_A, HIGH); |
113 | |
114 | }
|
115 | break; |
116 | |
117 | case 8: |
118 | {
|
119 | digitalWrite(CD4511_1_D, HIGH); |
120 | digitalWrite(CD4511_1_C, LOW); |
121 | digitalWrite(CD4511_1_B, LOW); |
122 | digitalWrite(CD4511_1_A, LOW); |
123 | |
124 | }
|
125 | break; |
126 | |
127 | case 9: |
128 | {
|
129 | digitalWrite(CD4511_1_D, HIGH); |
130 | digitalWrite(CD4511_1_C, LOW); |
131 | digitalWrite(CD4511_1_B, LOW); |
132 | digitalWrite(CD4511_1_A, HIGH); |
133 | }
|
134 | break; |
135 | }
|
136 | }
|
137 | |
138 | int Aktualisiere_Display2(int Zahl) |
139 | {
|
140 | switch (Zahl) |
141 | |
142 | {
|
143 | case 0: |
144 | {
|
145 | digitalWrite(CD4511_2_D, LOW); |
146 | digitalWrite(CD4511_2_C, LOW); |
147 | digitalWrite(CD4511_2_B, LOW); |
148 | digitalWrite(CD4511_2_A, LOW); |
149 | }
|
150 | break; |
151 | |
152 | case 1: |
153 | {
|
154 | digitalWrite(CD4511_2_D, LOW); |
155 | digitalWrite(CD4511_2_C, LOW); |
156 | digitalWrite(CD4511_2_B, LOW); |
157 | digitalWrite(CD4511_2_A, HIGH); |
158 | |
159 | }
|
160 | break; |
161 | |
162 | case 2: |
163 | {
|
164 | digitalWrite(CD4511_2_D, LOW); |
165 | digitalWrite(CD4511_2_C, LOW); |
166 | digitalWrite(CD4511_2_B, HIGH); |
167 | digitalWrite(CD4511_2_A, LOW); |
168 | |
169 | }
|
170 | break; |
171 | |
172 | case 3: |
173 | {
|
174 | digitalWrite(CD4511_2_D, LOW); |
175 | digitalWrite(CD4511_2_C, LOW); |
176 | digitalWrite(CD4511_2_B, HIGH); |
177 | digitalWrite(CD4511_2_A, HIGH); |
178 | |
179 | }
|
180 | break; |
181 | |
182 | case 4: |
183 | {
|
184 | digitalWrite(CD4511_2_D, LOW); |
185 | digitalWrite(CD4511_2_C, HIGH); |
186 | digitalWrite(CD4511_2_B, LOW); |
187 | digitalWrite(CD4511_2_A, LOW); |
188 | |
189 | }
|
190 | break; |
191 | |
192 | case 5: |
193 | {
|
194 | digitalWrite(CD4511_2_D, LOW); |
195 | digitalWrite(CD4511_2_C, HIGH); |
196 | digitalWrite(CD4511_2_B, LOW); |
197 | digitalWrite(CD4511_2_A, HIGH); |
198 | |
199 | }
|
200 | break; |
201 | |
202 | case 6: |
203 | {
|
204 | digitalWrite(CD4511_2_D, LOW); |
205 | digitalWrite(CD4511_2_C, HIGH); |
206 | digitalWrite(CD4511_2_B, HIGH); |
207 | digitalWrite(CD4511_2_A, LOW); |
208 | |
209 | }
|
210 | break; |
211 | |
212 | case 7: |
213 | {
|
214 | digitalWrite(CD4511_2_D, LOW); |
215 | digitalWrite(CD4511_2_C, HIGH); |
216 | digitalWrite(CD4511_2_B, HIGH); |
217 | digitalWrite(CD4511_2_A, HIGH); |
218 | |
219 | }
|
220 | break; |
221 | |
222 | case 8: |
223 | {
|
224 | digitalWrite(CD4511_2_D, HIGH); |
225 | digitalWrite(CD4511_2_C, LOW); |
226 | digitalWrite(CD4511_2_B, LOW); |
227 | digitalWrite(CD4511_2_A, LOW); |
228 | |
229 | }
|
230 | break; |
231 | |
232 | case 9: |
233 | {
|
234 | digitalWrite(CD4511_2_D, HIGH); |
235 | digitalWrite(CD4511_2_C, LOW); |
236 | digitalWrite(CD4511_2_B, LOW); |
237 | digitalWrite(CD4511_2_A, HIGH); |
238 | |
239 | }
|
240 | break; |
241 | }
|
242 | }
|
243 | |
244 | /* Eigene Funktionen ende */
|
245 | |
246 | |
247 | void setup() { |
248 | |
249 | Serial.begin(9600); |
250 | |
251 | pinMode(CD4511_1_D, OUTPUT); |
252 | pinMode(CD4511_1_C, OUTPUT); |
253 | pinMode(CD4511_1_B, OUTPUT); |
254 | pinMode(CD4511_1_A, OUTPUT); |
255 | |
256 | |
257 | pinMode(CD4511_2_D, OUTPUT); |
258 | pinMode(CD4511_2_C, OUTPUT); |
259 | pinMode(CD4511_2_B, OUTPUT); |
260 | pinMode(CD4511_2_A, OUTPUT); |
261 | |
262 | pinMode(Taster1, INPUT); |
263 | pinMode(Taster2, INPUT); |
264 | pinMode(Taster_Reset, INPUT); |
265 | pinMode(Led_gruen, OUTPUT); |
266 | pinMode(Led_rot, OUTPUT); |
267 | pinMode(Lichtschranke, INPUT); |
268 | pinMode (buzzer, OUTPUT) ; |
269 | |
270 | digitalWrite(Taster1, HIGH); |
271 | digitalWrite(Taster2, HIGH); |
272 | digitalWrite(Led_gruen, HIGH); |
273 | digitalWrite(Taster_Reset, HIGH); |
274 | |
275 | }
|
276 | |
277 | void loop() |
278 | {
|
279 | |
280 | |
281 | |
282 | |
283 | int val = analogRead(Lichtschranke); // Wert der Fotodiode auslesen |
284 | |
285 | boolean LS_offen = val <100; // Lichtschranke offen |
286 | |
287 | Serial.println(val); |
288 | |
289 | |
290 | if (LS_offen == false) |
291 | {
|
292 | |
293 | if (LS_offen_Last == true) |
294 | {
|
295 | |
296 | digitalWrite (buzzer, HIGH) ; // Signal für ein Zählvorgang |
297 | delay (100) ; |
298 | digitalWrite (buzzer, LOW) ; |
299 | delay(100); |
300 | |
301 | counter++; |
302 | |
303 | Serial.print("\t Zaehler = "); |
304 | Serial.print(counter); |
305 | Serial.print("\t von "); |
306 | Serial.println(Sollwert); |
307 | }
|
308 | |
309 | }
|
310 | |
311 | LS_offen_Last = LS_offen; // Speichert letzen Zaehlvorgang damit nur einmal gezaehlt wird |
312 | |
313 | |
314 | if (counter >= Sollwert) // erreicht der Zaehler den Sollwert ertönt ein Signal und eine LED leuchtet von Gruen auf Rot |
315 | {
|
316 | |
317 | digitalWrite(Led_gruen, LOW); |
318 | digitalWrite(Led_rot, HIGH); |
319 | |
320 | digitalWrite (buzzer, HIGH) ; |
321 | delay (1000) ; |
322 | digitalWrite (buzzer, LOW) ; |
323 | delay(1000); |
324 | |
325 | }
|
326 | |
327 | if (digitalRead(Taster1) == LOW) // Taster um den Sollwert zu erhöhen |
328 | {
|
329 | while (digitalRead(Taster1) == LOW) |
330 | |
331 | Serial.print("\t Zaehler = "); |
332 | Serial.print(counter); |
333 | Serial.print("\t von "); |
334 | Serial.println(Sollwert); |
335 | if ( Sollwert < 99) |
336 | Sollwert++; |
337 | |
338 | }
|
339 | |
340 | |
341 | if (digitalRead(Taster2) == LOW) // Taster um den Sollwert zu verringern |
342 | {
|
343 | while (digitalRead(Taster2) == LOW) |
344 | |
345 | Serial.print("\t Zaehler = "); |
346 | Serial.print(counter); |
347 | Serial.print("\t von "); |
348 | Serial.println(Sollwert); |
349 | if (Sollwert > 1) |
350 | Sollwert--; |
351 | }
|
352 | |
353 | Aktualisiere_Display(Sollwert % 10); |
354 | Aktualisiere_Display2(Sollwert / 10); |
355 | |
356 | |
357 | if (digitalRead(Taster_Reset) == LOW) // Taster um den Zaehler zurueck zu setzten |
358 | |
359 | {
|
360 | while (digitalRead(Taster_Reset) == LOW) |
361 | |
362 | Serial.println(" Zaehler zurückgesetzt "); |
363 | counter = 0; |
364 | |
365 | digitalWrite(Led_gruen, HIGH); |
366 | digitalWrite(Led_rot, LOW); |
367 | |
368 | }
|
369 | }
|
Aufgabe ist ein Zähler soll mittels einer Lichtschranke die aus einer Fotodiode und einer IR-Diode besteht Gegenstände zu einer zuvor mit 2 Taster definierten zahl hochzählen. Bei erreichen der definierten zahl soll ein Signal ertönen und eine Led von Grün auf Rot umschalten. Die definierte zahl soll auf einer 7-Segmentanzeige gezeigt werden. Der Zähler soll mit einem weiteren Taster zurückgesetzt werden können. hoffe du kannst den halbwegs lesen
Hmmmm... Sieht eigentlich gut aus. Musste eigentlich funktioneiren und eine einfache sofware-entprellung ist damit drin. Der Fehelr dürfte nur geschehen wenn dein Sensor irgendwie kurrzeitig hoch UND runter springt. Was gibt eigentlich "Serial.println(val);" in dem Moment und kurz nachdem, die Schranke wieder freigegeben wird, aus? Kannst auch trotzdem mal versuchen die Variante aus meinem letzten Post zu übernehmen. Der Loop ist mit dem Event gleich zu setzen, in dem Fall.
:
Bearbeitet durch User
Achi M. schrieb: > ich habe einen Zähler gebaut, der mittels einer Lichtschranke zählt. Die > Entfernung von der IR-Diode und Fotodiode ist ca. 30 cm. bei der > Entfernung empfängt die Fotodiode aber nichts (kaum zu verarbeiten). Wenn Du Umgebungslicht nicht abschirmst durch z.B innen schwarz gefärbte Röhrchen, dann wird das nichts...
Achi M. schrieb: > Das hat mir mein Ausbilder auch vorgeschlagen Und/oder eine Hysterese einbauen. Achi M. schrieb: > aber ich bin noch > relativer Anfänger beim Arduino und er hat gerade nicht so viel Zeit und > ich hab keine Ahnung wie das geht Beides überfordert den Fragesteller - was soll man da antworten? Wer ko der ko, oder halt net. Georg
In einem solchen Fall lohnt es sich, den Arduino mal weg zu legen und sich grundsätzliche Gedanken zu machen. In der Skizze sehen wir ein analoges Signal, wie es vom OP kommen könnte. Bei einer einzelnen Schwelle erhalten wir zusätzliche Pulse. Wir könnten zwei Schwellen nehmen und den Bereich dazwischen ignorieren. Ist der Pegel höher als die Ein_Schwelle haben wir EIN. Unterhalb der Aus_Schwelle AUS. => Hysterese Am besten einige Pulse aufzeichnen und überlegen, wie man diese mit den beiden Schwellen zählen könnte. Welchen Zustand muss man sich merken? Wenn die Lösung klar ist, dann mit Arduino umsetzen.
Wenn das tatsächlich so aussieht, ja. So ein Verhalten wäre genau meine Erklärung dafür dass es mit dem obigen Code nicht klappt. In dem Schaubild würde allerdings reichen wenn man nur die obere Schwelle verwenden würde.
> So ein Verhalten wäre genau meine Erklärung dafür dass es mit dem obigen > Code nicht klappt. Ich glaube wir sind bisschen von der eigentlichen frage abgekommen. Der Code funktioniert Super. nur das Schwanken wo OP ist mir im Weg.
> Wir könnten zwei Schwellen nehmen und den Bereich dazwischen ignorieren. > Ist der Pegel höher als die Ein_Schwelle haben wir EIN. Unterhalb der > Aus_Schwelle AUS. => Hysterese > Am besten einige Pulse aufzeichnen und überlegen, wie man diese mit den > beiden Schwellen zählen könnte. Welchen Zustand muss man sich merken? > Wenn die Lösung klar ist, dann mit Arduino umsetzen. Hab ich nicht verstanden.
Achi M. schrieb: >> So ein Verhalten wäre genau meine Erklärung dafür dass es mit dem obigen >> Code nicht klappt. > > > Ich glaube wir sind bisschen von der eigentlichen frage abgekommen. Der > Code funktioniert Super. nur das Schwanken wo OP ist mir im Weg. Wie schwankt der OP denn genau? So wie du das erklärt hast, müsste der Code funktionieren, denn es gibt keinen Grund weshalb bei hoher Schwelle, trotzdem den Zähler mehrfach erhöhen sollte. Ist der Verlauf etwa so wie auf der Grafik von Limi (das wäre anders als dus erklärt hast)? Bitte zeichne einen möglichst genauen Zeit-Verlauf des Wertes auf Papier oder mach ein Bild vom Oszilloskop, falls du das zur Verfügung hast.
:
Bearbeitet durch User
> Bitte zeichne einen möglichst genauen Zeit-Verlauf des Wertes auf Papier > oder mach ein Bild vom Oszilloskop, falls du das zur Verfügung hast. Hoffe die ist verständlich.
Okey, also zur Rekapitulation: Während die Schranke unterbrochen ist, ist der Wert auf 0. SOBALD die Schranke frei wird, ist der Wert ERSTMAL sofort bei 800, fällt DANN auf 0, steigt DANN auf 30 langsam am und DANN wieder auf 800?! Okey, wenn das so ist, zeigt in der Tat entweder sensor, oder der OV ein eher ungewöhnliches Verhalten. Zwei Möglichkeiten: 1. Anderer Sensor-Aufbau 2. Durchschnittsbildung über einen Zeitraum der deutlich länger als dieser 0-30 Bereich ist. Wie das geht hab ich oben ja gezeigt. Willst du aber Unterbrechungen der Lichtschranke feststellen, die Kürzer sind, als dieser 0-30 Abfall, dann kommst du nicht um einen anderen Sensor oder OV herum.
:
Bearbeitet durch User
Achi M. schrieb: > Der Code funktioniert Super. Das hört sich hier aber nicht so an: Achi M. schrieb: > ist jetzt bei 2 wo aber 1 sein sollte Dein Programm passt auch nicht so ganz zu deiner Beschreibung: Achi M. schrieb: > Im Programm > sage ich einfach nur wenn der Wert unter 100 ist gilt die > Schranke als unterbrochen und er Zählt einmal hoch.
1 | boolean LS_offen = val <100; // Lichtschranke offen |
Müsste das nicht "LS_offen = val >=100" sein? Hysterese: Dazu brauchst du zwei Abfragen: 1. Wenn val>700 dann LS_offen=True 2. Wenn val<100 dann LS_offen=False Liegt val im Bereich von 100...700 dann erfolgt keine Änderung des letzten Zustandes.
Achi M. schrieb: > Das hat mir mein Ausbilder auch vorgeschlagen aber ich bin noch > relativer Anfänger beim Arduino und er hat gerade nicht so viel Zeit und > ich hab keine Ahnung wie das geht Achi M. schrieb: > Unbenannt.png Probiere es mal mit einem Kondensator parallel zu R. Das beruhigt das Signal schon mal. Eine Hysterese kann man dann per Software einbauen. Wie kräftig man das Signal filtern darf, hängt davon ab, wie schnell die Lichtschranke reagieren muss.
> Okey, also zur Rekapitulation: > Während die Schranke unterbrochen ist, ist der Wert auf 0. Richtig > SOBALD die Schranke frei wird, ist der Wert ERSTMAL sofort bei 800, > fällt DANN auf 0, steigt DANN auf 30 langsam am und DANN wieder auf > 800?! genau andersrum sie wird frei ist dann erst bei 0-30 dann nach ca. 0,5 Sekunden sofort bei 800. Und das brauch ich nicht
Ja richtig, ein Kondensator ist die Dritte Möglichkeit. Das ist im Grunde eine primitive Durchschnittsbildung in Hardware :)
Achi M. schrieb: > genau andersrum > > sie wird frei ist dann erst bei 0-30 dann nach ca. 0,5 Sekunden sofort > bei 800. > > Und das brauch ich nicht The Fuu, wieso denn nicht?! Wie ist der Wert denn davor? Also wenn die Schranke unterbrochen ist, ist der Wert doch bei 0, oder? D.h. wenn die Scranke frei wird, steigt er einfach nur. Dann müsste der Code funktionieren,
Achi M. schrieb: > Alex G. schrieb: >> Ja richtig, ein Kondensator ist die Dritte Möglichkeit. > > Wie Groß? Nein, vergiss den Kodnensator. Wenn es nicht diese SPitze gibt die ich beschrieben hab, dann bringt der nichts. Des weiteren ist dein Diagramm dann verdammt verwirrend >_> Gab es in dem zeitverlauf ind einem Diagramm nur eine unendlich kurze Unterbrechung der Lcihtschranke? Denn es gibt keinen längeren Zeitpunkt wo der Wert auf 0 ist.
:
Bearbeitet durch User
> Nein, vergiss den Kodnensator. Wenn es nicht diese SPitze gibt die ich > beschrieben hab, dann bringt der nichts. Gibt es ne andere Möglichkeit?
Geh mit dem Debugger dran und lass dir anzeigen was laut print-Befehl wirklich beim Gerät ankommt. Dort liegt irgendwo das Problem, denn bei einer Schwelle von 100 die richtig implementiert ist, müsste es gehen! Das Langsame ansteigen von 0 auf 30 ignorierert die Schwelle ja! Würde dir auch nochmal raten, meinen anderen Code hier umzusetzen: Alex G. schrieb: >
1 | > if ((!UNTERBROCHEN) && (WERT < SCHWELLE)) |
2 | > { |
3 | > UNTERBROCHEN = true; |
4 | > // was auch immer beim UNTERBRECHEN der Schranke geschehen soll |
5 | > } |
6 | > else |
7 | > if ((UNTERBROCHEN) && (WERT > SCHWELLE)) |
8 | > { |
9 | > UNTERBROCHEN = false; |
10 | > // was auch immer beim WIEDERHERSTELLEN der Schranke geschehen soll |
11 | > } |
12 | >
|
P.S. Lass keinesfalls den teil hinter dem ELSE weg, auch wenn du nichts beim widerherstellen der Schranke ausführen willst!
:
Bearbeitet durch User
> Würde dir auch nochmal raten, meinen anderen Code hier umzusetzen:
Alles Klar ich versuchs mal danke:)
> Würde dir auch nochmal raten, meinen anderen Code hier umzusetzen:
Funktioniert super Dankeschön :))
Achi M. schrieb: >> Würde dir auch nochmal raten, meinen anderen Code hier umzusetzen: > > Funktioniert super Dankeschön :)) Klasse! Hmpf, wünschte ich würde grad verstehen wieso genau dein eigener Code, nicht das selbe/richtige tut :D
Alex G. schrieb: > Achi M. schrieb: > wünschte ich würde grad verstehen wieso genau dein eigener Code, > nicht das selbe/richtige tut Vielleicht ist ein Fehler in seinem Code. Beitrag "Re: Baut Op signal langsam ab?"
Achi M. schrieb: > dann mache ich die Schranke frei und der wert springt nicht sofort > wieder auf 800 sondern erst 0-30 und dann 800. Wie lange ist "nicht sofort"? Wie groß ist der Widerstand? Man kann Schaltpläne auch lesbar posten und nicht als Briefmarke.
Habe mal einen Transimpedanzverstärker aufgebaut. Mit der empfindlichen Fotodiode PD333-3C reicht als Lichtschranke eine Glühbirne in 1m Entfernung. Für punktförmige LED-Strahler in größeren Entfernungen kann die Verstärkung noch deutlich angehoben werden (100k oder 1M statt 10k und den 10µF Elko entsprechend verkleinern). Eine zusätzliche Optik würde eine weitere Verbesserung erzeugen. In der zweiten OP-Hälfte stecken auch noch Verstärkungsreserven drin (jetzt nur Faktor 1 bis 3). Durch den Tiefpass können nur lange Impulse gezählt werden (langsam gehende Menschen). Ein schneller Vogel wird nicht gezählt, auch nicht zwei direkt hintereinander.
Elon M. schrieb: > Keine Ahnung :D Das wissen wir. Elon M. schrieb: > Da bin ich raus. Du warst nie drin. Achso, du bist bloss mit deiner Vielzahl an Pseudonymnamen durcheinanderkommen, unter denen du hier so auftrittst.
Hallo Ich hab bezüglich zum oben erwähnten Schaltplan eine Frage. Benötigt der OP eines Transimpedanzwandlers eine negative Versorgungsspannung ? Die Ausgangsspannung ist ja Ua = -I*R. mfg Mike
Mike schrieb: > Benötigt der OP eines Transimpedanzwandlers eine negative > Versorgungsspannung ? Nein.
Mike schrieb: > Die Ausgangsspannung ist ja Ua = -I*R. Da die Fotodiode "richtigrum" montiert ist, ist die Polarität des Stroms grade so, dass sich ein positiver Wert für Ua ergibt. Ohne negative Versorgung muss es aber zumindest ein OPV-Typ sein, der am Eingang bis an die negative Versorgung herunter arbeiten kann. Also einer mit "Rail to Rail Input" oder zumindest mit "Input common mode range includes Ground".
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.