Ich brauche dringend Hilfe bei der Schaltung meiner Lichtschranke. Ich
habe gerade einen Bau aufgebaut und diesen getestet. Jedoch war das
Ergebnis dass es nicht funktioniert. Ich habe meine led an digital write
high geschalten dann die led über einen vorwiderstand benutzt und dann
wieder mit einem kabel zurück zu Ground an den Arduino geführt. Den
Fototransistor habe ich an 5V geschalten davor einen 820 ohm widerstand
dann ein kabel zu analog0 um einen ausgabewert zu erhalten und dann
wieder zu ground. Der Quellcode hier:
1
#define led 22
2
#define lichtschranke A0
3
4
voidsetup(){
5
pinMode(led,OUTPUT);
6
7
Serial.begin(9600);
8
9
}
10
11
voidloop(){
12
digitalWrite(led,HIGH);
13
14
intsensorValue=analogRead(lichtschranke);
15
Serial.println(sensorValue,DEC);// Daten der Lichtschranke auf dem Computer ausgeben => darüber Schwellenwert festlegen
16
17
}
Was ist hier falsch gelaufen? Muss ich drauf achten in welcher
Reihenfolge ich meine Teile schalte? Wenn ja wie?
> Den Fototransistor habe ich an 5V geschalten davor einen> 820 ohm widerstand dann ein kabel zu analog0
Halt!
Wie genau ist das verschaltet?
Beschreib nicht deinen Aufbau, zeichne ihn auf! Dann gibt es keine
Missverständnisse.
Das sollte so sein
1
+------------------------ +5V
2
|
3
R
4
|
5
+----------> zum Arduino
6
|
7
Phototranistor
8
|
9
+------------------------ GND
Der Phototranistor bildet mit dem R einen Spannungsteiler. Fällt kein
Licht drauf, dann sperrt der Transistor und am Ausgang kannst du 5V
messen. Fällt Licht drauf, dann schaltet der Tranistor durch und du
misst 0V am Arduino. Theoretisch brauchst du dazu noch nicht mal den
ADC, miss aber sicherheitshalber mit einem Voltmeter die Spannung noch
nach.
Also meine Schaltung ist so:
+--------------------------------- +5V
|
Phototransistor
|
R
|
-----------> zum Arduino
|
GND
Der Ausgabewert lag immer bei 0. Ich habe gerade deine Idee getestet da
kam immer 1023 raus wie schaffe ich jetzt aber das ich den Wert auch
noch verändern kann?
Maximilian Ruderer schrieb:> Also meine Schaltung ist so:>> +--------------------------------- +5V> |> Phototransistor> |> R> |> -----------> zum Arduino> |> GND>> Der Ausgabewert lag immer bei 0.
logisch.
Wie soll der auch jemals anders werden?
> Ich habe gerade deine Idee getestet da> kam immer 1023 raus wie schaffe ich jetzt aber das ich den Wert auch> noch verändern kann?
Indem du den Widerstand passend zum Phototransistor variierst.
Und natürlich wäre es auch eine gute Idee, den Phototranistor auch
richtig rum anzuschliessen.
Des weiteren wäre es gut, wenn der Phototransistor und die Lichtquelle
in der Wellenlänge zusammenpassen. Und für erste Tests wärs
wahrscheinlich auch nicht schlecht mal mit was ordentlichem auf den
Transistor draufzuleuchten.
Maximilian Ruderer schrieb:> was für Widerstände sollte ich bei meinem SFH 300> http://www.alldatasheet.com/datasheet-pdf/pdf/45635/SIEMENS/SFH300.html> benutzen?
Laut Datenblatt hat deiner bei 5V C-E SPannung ca. 5mA Photostrom.
R = U/I
Das sind dann ca 1kOhm.
D.h. der Vorwiderstand ungefähr in der gleichen Größenordnung
(Fautregel). Deine 820Ohm sollten schon reichen, auch wenn ich
persönlich höher gehen würde.
Wahrscheinlich hast du ihn nur verkehrt rum angeschlossen oder du
leuchtest nicht ordentlich in den Phototransistor rein, ev. mit dem
falschen Leuchtmittel. Der hat nur einen Öffnungswinkel von ca. 25°!
Maximilian Ruderer schrieb:> Warum ändert sich der wert nicht?
- Hast Du die Schaltung vom 14.10.2013 15:41 auch korrigiert?
- Wie ist die Schaltung jetzt?
- Ist LED und Transistor richtig herum angeschlossen?
- Hast Du den "Wert" auch mal mit einem Multimeter gemessen?
- Wo hast Du gemessen?
- Wie ist gemessene Wert?
Die LED CQY99 und der Transistor SFH300 müssten im Prinzip zusammen
funktionieren, auch wenn die Wellenlängen nicht optimal zusammenpassen.
Gruß Dietrich
sonderlich hell scheint mir die IR-Diode aber nicht zu leuchten.
Vergleich doch mal die Helligkeit mit der IR-Diode in einer
Fenseher-Fenbedienung. (Handykameras können IR-Licht normalerweise
sichtbar machen). Die Vorschau der Kamera genügt, du musst kein Bild
machen. Einfach mal mit der Handy-Kamera von vorne in deine LED
reinschauen und dann als Vergleich in die LED einer FB und eine Taste
drücken.
Auch würde ich für erste Tests das ganze mal abseits vom Arduino testen.
Zumindest würde ich die Versorgung der Komponenten nicht über
Ausgabepins machen.
1
+5V --------+ +-------------- 5V
2
| |
3
R R
4
| +-----> Voltmeter
5
IR-LED |
6
| Transistor
7
| |
8
GND -------+ +--------------- GND
Ob du den Transistor richtig rum angeschlossen hast oder nicht, kann man
an den Bilder nicht erkennen. Sollte aber nicht kritisch sein, wenn du
den einfach mal umdrehst.
Hab den Transistor auch mal umgedreht Wert ist immer 1023
Dietrich L. schrieb:> Maximilian Ruderer schrieb:>> Warum ändert sich der wert nicht?>> - Hast Du die Schaltung vom 14.10.2013 15:41 auch korrigiert?> - Wie ist die Schaltung jetzt?> - Ist LED und Transistor richtig herum angeschlossen?> - Hast Du den "Wert" auch mal mit einem Multimeter gemessen?> - Wo hast Du gemessen?> - Wie ist gemessene Wert?>> Die LED CQY99 und der Transistor SFH300 müssten im Prinzip zusammen> funktionieren, auch wenn die Wellenlängen nicht optimal zusammenpassen.>> Gruß Dietrich
Also Schaltung ist korrigiert. Schaltung ist wie vorgeschlagen. LED
leuchtet leicht auf einem BILD. Was ist ein Multimeter? Am PC gemessen
Karl Heinz Buchegger schrieb:> sonderlich hell scheint mir die IR-Diode aber nicht zu leuchten.> Vergleich doch mal die Helligkeit mit der IR-Diode in einer> Fenseher-Fenbedienung. (Handykameras können IR-Licht normalerweise> sichtbar machen). Die Vorschau der Kamera genügt, du musst kein Bild> machen. Einfach mal mit der Handy-Kamera von vorne in deine LED> reinschauen und dann als Vergleich in die LED einer FB und eine Taste> drücken.
da hast du deutlich recht wie kann ich meine heller machen?
Maximilian Ruderer schrieb:> Was ist ein Multimeter?
Ein Messgerät, das viele ("Multi") verschiedene elektrische Signale
messen ("Meter") kann. In dem Fall brauchst Du nur ein Voltmeter =
Spannungsmesser.
Wenn Du so misst, dann umgehst Du mögliche Fehler im Programm.
Gruß Dietrich
Maximilian Ruderer schrieb:> wie kann ich meine heller machen?
Wie groß ist denn der Vorwiderstand?
Maximilian Ruderer schrieb:> ok sowas habe ich daheim wo muss ich dann messenwie mache ich das am> besten mit meinen Teilen?
zwischen Widerstand und Transistor gegen Masse
Maximilian Ruderer schrieb:> ok sowas habe ich daheim wo muss ich dann messenwie mache ich das am> besten mit meinen Teilen?
Hast Du die Schaltung von Karl Heinz nicht gesehen?
Hier nochmal:
1
+5V --------+ +-------------- 5V
2
| |
3
R R
4
| +-----> Voltmeter
5
IR-LED |
6
| Transistor
7
| |
8
GND -------+ +--------------- GND
Das Voltmeter kommt zwischen dem angegebenen Punkt und GND, d.h.
parallel zum Transistor.
Die beiden GND und die beiden +5V dürfen auch zusammengeschaltet werden
;-)
Gruß Dietrich
Hab jetzt das ganze nochmal an arduino getestet nur das ich die Diode an
5V (VCC) geschalten habe. Dort hat sie viel heller gescheint. Und kurz
und vereinzelt waren andere werte zu sehen allerdings wird die led dabei
sehr heiß :( Da ist doch was falsch oder habe 27 ohm widerstand
Es sieht auf dem Foto aus als ob du die Widerstände nicht in Reihe
geschaltet hast.
In Bild 1, bei der IR-LED Beschaltung sieht es aus als ob GND, beide
Beinchen vom Widerstand und die LED auf dem selben Anschluss des
Breadbords stecken.
Damit wäre der Widerstand nicht in Reihe geschaltet und es würde
erklären warum die IR-Led warm wird.
Zur Kontrolle des Widerstandes ohne Multimeter könntest du es mit dieser
Seite versuchen :
http://www.umrechnung.org/elektrischer-widerstand-farbcode/widerstand-farbcode-rechner-tabelle.htm
So wie auf der Zeichnung.
Darum hab ich sie gemacht.
Von 5V geht eine Leitung zum einen Ende des Widerstands. Vom anderen
Ende des Widerstands geht eine Verbindung zur Led. Vom anderen Ende der
Led geht es nach Masse.
Achtung. Bei deinem Steckbrett sind wahrscheinlich jeweils 5 Anschlüsse
in einer Zeile miteinander verbunden.
D.h. so
1
+-----------------------+
2
| +-+-+-+-+ +-+-+-+-+ |
3
| |
4
| +-+-+-+-+ +-+-+-+-+ |
5
| |
6
......
d.h. du gehst mit den 5V zb hier hin
1
#
2
#
3
#
4
+-#---------------------+
5
| #-+-+-+-+ +-+-+-+-+ |
6
| |
7
| +-+-+-+-+ +-+-+-+-+ |
8
| |
9
......
steckst dann den Widerstand so dass er diese 5V Schiene mit einer der
nächsten Zeilen verbindet
um dann vom anderen Ende der LED nach Masse zu gehen
1
+5V GND
2
# #
3
# #
4
# #
5
+-#---------------------+ #
6
| #-#-+-+-+ +-+-+-+-+ | #
7
| R | #
8
| +-#-+-+-#LED#-+-+-+-#####
9
| |
10
......
wenn du jetzt mit der Zeichnung vergleichst, dann entspricht das von den
vorgesehenen Verbindungen her, genau dem Aufgezeichneten.
1
+5V --------+ +-------------- 5V
2
| |
3
R R
4
| +-----> Voltmeter
5
IR-LED |
6
| Transistor
7
| |
8
GND -------+ +--------------- GND
von 5V gibt es eine Verbindung zum Widerstand, vom Widerstand zur LED,
von der LED nach Masse
Für den Transistor machst du genau das gleiche. Du steckst so, dass die
vorgesehenen Verbindungen enstehen.
Und besorg dir um nächsten Baumarkt um 8 Euro ein Multimeter! Das ist
doch Unsinn, Elektronik-Basteln zu wollen ohne wenigstens ein
allereinfachstes Messgerät zu haben.
Und halte dich ein wenig an die Farbcodes für Kabel.
Rot == positive Spannungsversorgung (+5V)
Schwarz == Massse (GND)
Ich hab schon so ein Messgerät, aber wusste nicht wie es zu benutzen
habe. Danke für eure Hilfe seit echt klasse. Ich werde des ganze testen
wenn ich heimkomme und mein Ergebnis wieder berichten :)
Also habe jetzt getestet hat super geklappt erstmal. Am Arduino wurde
ohne Unterbrechung immer der Wert 1021 angezeigt und mit Unterbrechung
1023 :D Ich habe auch die Spannung mit einem Multimesser gemessen. Bei
Led war die Spannung 1,33 und bei Phototransistor 4,73. Reicht das jetzt
schon für Messungen? oder sollte ich weitere Sachen verbessern?
Also ich möchte jetzt gerne die Lichtschranke weiter bearbeiten. Kann
ich für die Zeitmessung einfache if Bereiche von 0-x und x-1023 setzen?
Kann ich das Steckbrett auseinanderschneiden um die teile weiter zu
entfernen?(hab nur eins) und wie schalte ich die beiden 5V und GND
zusammen?
Maximilian Ruderer schrieb:> Also ich möchte jetzt gerne die Lichtschranke weiter bearbeiten. Kann> ich für die Zeitmessung einfache if Bereiche von 0-x und x-1023 setzen?
?
Da kannst programmieren was immer du möchtest.
Niemand hindert dich daran
Praktisch wirst du das aber so machen:
Durch Versuch und Irrtum hast du herausgefunden, dass der ADC einen WErt
von 150 liefert, wenn der Strahl nicht unterbrochen ist und einen Wert
von 876 wenn der Strahl unterbrochen ist.
Die MItte dazwischen ist also bei ca. 500
d.h. du definierst ganz einfach: wenn der Messwert vom ADC kleiner als
500 ist, dann gilt das als nicht unterbrochener Strahl, ist er größer,
dann ist der Strahl unterbrochen.
> Kann ich das Steckbrett auseinanderschneiden um die teile weiter zu> entfernen?(hab nur eins)
Können tust du schon. Die Frage ist, wie sinnvoll das ganze ist, und ob
du nicht mit einer kleinen Streifenraster oder Lochraster-Platine besser
bedient wärst.
Bei so einer kleinen Schaltung, wie der hier, könnte man auch ins Auge
fassen anstatt einer richtigen Platine, die ganze Sache auf Karton
aufzubauen. So wie zb hier
http://www.ledhilfe.de/viewtopic.php?f=35&t=7056> und wie schalte ich die beiden 5V und GND> zusammen?
Ist das eine Fangfrage?
Mit Draht?
Karl Heinz Buchegger schrieb:> d.h. du definierst ganz einfach: wenn der Messwert vom ADC kleiner als> 500 ist, dann gilt das als nicht unterbrochener Strahl, ist er größer,> dann ist der Strahl unterbrochen.
Wobei.
Bei den Spannungspegeln, die du jetzt hast, brauchst du im Grunde
genommen gar keinen ADC.
Du legst den Ausgang einfach auf einen digitalen Eingang und im Programm
kriegst du dann 0 und 1 (bzw. HIGH und LOW) je nachdem, ob der Strahl
unterbrochen ist oder nicht.
Wenn ich jetzt größere Abstände mach wie z. B. 10 cm bekomme ich als
wert nur ca. 1000 bzw. ca 4,5V. Gibt es hierfür einen Trick oder ein
bestimmtes Teil dass die Werte wieder kleiner werden? Reichen Werte wie
1000 auch aus um ohne Probleme die Geschwindigkeit zu messen?
Maximilian Ruderer schrieb:> Gibt es hierfür einen Trick oder ein> bestimmtes Teil dass die Werte wieder kleiner werden?
Ja, nennt sich "Sammellinse".
Oder du vergrößerst den Arbeitswiderstand. Das gibt aber Probleme bei
Einfall von Umgebungslicht.
Maximilian Ruderer schrieb:> Wo gibt es die zu kaufen bei amazon und ebay kam nichts konkretes oder> kann man die selbst bauen?
Und was sagt dir der erste Treffer bei ebay (310405195397) oder der
zweite (221299692295)?
Du bist jetzt an einem Punkt angelangt, an dem es nicht mehr ausbleibt,
dass du dir ein wenig über Physik Gedanken machst.
Denn was du jetzt im Grunde hast, ist ein einfaches Messgerät. Dein
Zahlenwert ist proportianal einer Messgröße. Nämlich welcher?
Dem Lichteinfall auf dem Phototransistor.
Je höher der Zahlenwert, desto geringer ist der Lichteinfall, oder
anders ausgedrückt, desto weniger IR-Licht kann der Transistor
wahrnehmen.
Je kleiner der Zahlenwert, desto mehr IR-Licht merkt der Transistor.
Wobei mit 'Lichtmenge' eigentlich gemeint ist 'mehr oder weniger
Energie, übertragen in Form von Infrarot-Licht'.
D.h. wenn du deine Lichtschranke verbessern willst, dann musst du dir
physikalische Methoden überlegen, wie du die Energieübertragung von der
Lichtquelle zur Empfänger verbessern kannst. Da gibt es 3
grundsätzliche Ansatzpunkte
* den Sender verbessern
* den Empfänger verbessern
* die Übertragungsstrecke verbessern
Wen ich davon ausgehe, dass die an Sender und Empfänger mit deinen
einfachen Mitteln zunächst nicht allzuviel verbessern kannst, dann ist
die Übertragsungsstrecke ein erster Ansatzpunkt.
Du fragst: was bringt denn eine Lupe?
Hast du schon mal den Versuch gemacht, mit einer Lupe und Sonnenlicht
ein getrocknetes Blatt (vom Baum) in Brand zu setzen? Was machst du da?
Warum funktioniert das? Schon mal mit einer Taschenlampe gespielt? Was
passiert, wenn du vorne an der Linse drehst? Wie verändert sich der
Lichtfleck, den du damit auf eine Wand kriegst. Was sagt uns das über
die Energieverteilung aus, und über ihren Zusammenhang mit der
Linsenstellung?
Ein anderer Ansatzpunkt könnte es zb sein, den Sender in eine Röhre zu
setzen. Genauso mit dem Empfänger. Warum bringt das etwas?
Ganz einfach. Weil die Messwerte, wie du selbst schon gemerkt hast, sich
aufgrund der Distanz immer weniger unterscheiden. Woran liegt das
wiederrum? Das liegt, wenn man sich mal das Datenblatt ansieht, auch
daran, dass der Transistor nicht nur auf die eine Wellenlänge der Diode
empfindlich ist, sondern auf einen weiten Bereich reagiert. D.h. der
Phototransistor reagiert auch auf die Umgebung, also Licht, welches
nicht von der LED kommt. Je weiter die LED entfernt ist, desto weniger
Anteil hat aber die LED an dieser Gesamtsicht des Transistors. Desto
geringer fallen daher auch die Variationen aus. Ändern lässt sich das
unter anderem dadurch, dass man dem Empfänger Scheuklappen verpasst. Ihn
in eine Röhre steckt, so dass er hauptsächlich nur noch den eigentlichen
Sender sieht und nicht mehr abgelenkt wird.
Sorry, aber du bist an einem Punkt angelangt, an dem du vom reinen
Nachbauen übergehen musst zu: ich fang an selber nachzudenken. Ich fang
an zu beobachten, was ich in der Natur sehe. Ich fange an zu beobachten
und in Beziehung zu setzen, was ich aus der Bedienung anderer Geräte
gelernt habe. Es wird Zeit, dass du anfängst, deine Welt mit offenen
Augen zu sehen und nicht nur die Natur an dir vorbeiziehen zu lassen.
Maximilian Ruderer schrieb:> Hier Bilder
Irgendwie scheinst du das Steckbrett noch nicht begriffen zu haben oder
ich sehe das nicht richtig.
Du steckst da alles in eine Reihe. Somit "steckt" der Widerstand nur da
drin, wird aber durch das Steckbrett überbrückt.
Du musst die Sachen schon um eine Reihe versetzt anordnen.
Ich möchte gerne meine Lichtschranke progrmamiren (Sammellinsen sind
gerade bestellt kann es nicht optimal testen bis freitag). Habt ihr paar
Tipps zu meinem aktuellen Programtext?
Maximilian Ruderer schrieb:> Ich möchte gerne meine Lichtschranke progrmamiren (Sammellinsen sind> gerade bestellt kann es nicht optimal testen bis freitag). Habt ihr paar> Tipps zu meinem aktuellen Programtext?
Gibt es ein spezifisches Problem?
> if ( sensorValue1 >= 500)
größer 500 bedeutet physikalisch was?
Ist die Lchtschranke dann unterbrochen oder ist sie 'geschlossen'
> {> start=millis();> }> if ( sensorValue2 >= 500)> {> ende=millis();> Geschwindigkeit=(ende-start)/3;> }> }
Ich denke du hast da eine Asymetrie drinnen.
Dein Messzeitraum beginnt, wenn das Objekt die erste Lichtschranke
wieder freigibt und es endet, wenn das Objekt die zweite Lichtschranke
das erste mal unterbricht. D.h. im Klartext die Länge deines Objektes
geht in die Messdauer ein. Bei gleicher Geschwindigkeit aber längerem
Objekt kommt bei dir eine kürzere Zeit raus.
es gibt kein spezielles Problem wollte nur mal fragen. Ja die Grenze 500
ist nur grob ausgesucht und wie ich des mit der länge verhinder wusste
ich nicht denn ein delay ist auch schlecht zu nutzen. Gibt es da noch
andere Mögglichkeiten?
Maximilian Ruderer schrieb:> es gibt kein spezielles Problem wollte nur mal fragen. Ja die Grenze 500> ist nur grob ausgesucht und wie ich des mit der länge verhinder wusste> ich nicht denn ein delay ist auch schlecht zu nutzen. Gibt es da noch> andere Mögglichkeiten?
Wie wärs mit einer Variablen (auch Flag genannt), in der man sich merkt,
dass die Lichtschranke am Start schon mal unterbrochen wurde und daher
jede weitere UNterbrechung nix mehr gilt, weil die Messzeit schon läuft?
Dann kann das Objekt so lang sein wie es will. Sobald es mit seiner
Vorderkante die erste Lichtschranke durchbricht, beginnt die Zeit zu
laufen und daran ändert sich auch nichts mehr, egal wie lange das Objekt
die erste Lichtschranke noch weiterhin blockiert ehe es dann durch diese
Linie komplett durch ist.
Ich würde anstelle der IR-LEDs und Sammellinsen billige Laserpointer als
Lichtquelle nehmen. Damit erledigen sich die meisten deiner Probleme.
Die Analogauswertung kannst du dir dann auch sparen. Die Reaktionszeit
deiner Messung kann dadurch nur besser werden.
Olaf B. schrieb:> Ich würde anstelle der IR-LEDs und Sammellinsen billige Laserpointer als> Lichtquelle nehmen. Damit erledigen sich die meisten deiner Probleme.> Die Analogauswertung kannst du dir dann auch sparen. Die Reaktionszeit> deiner Messung kann dadurch nur besser werden.
ich teste jetzt erstmal meins gescheid wenn es nicht klappen sollte
erwäge ich deine Idee umzusetzen
Maximilian Ruderer schrieb:> und wie kann man das machen, dass man eine Variable speichert?
Diese Frage versteh ich nicht.
Du benutzt ja schon Variablen.
1
#define lichtschranke1 A1
2
#define lichtschranke2 A2
3
intstart=0;
4
intende=0;
5
intGeschwindigkeit;
6
7
uint8_tstartSeen=0;// <-----
8
9
10
voidsetup(){
11
pinMode(led,OUTPUT);
12
13
Serial.begin(9600);
14
15
}
16
17
voidloop(){
18
digitalWrite(led,HIGH);
19
20
intsensorValue1=analogRead(lichtschranke1);
21
intsensorValue2=analogRead(lichtschranke2);
22
Serial.println(Geschwindigkeit,DEC);
23
24
if(sensorValue1>=500)
25
{
26
if(startSeen==0)// <--- wurde die Startschranke schon einmal unterbrochen?
27
{
28
// Nein, noch nicht
29
start=millis();
30
startSeen=1;// merken, dass die startschranke schon ausgelöst wurde.
31
// D.h. start hat jetzt schon den korrekten Wert der ersten Unterbrechung.
32
// Jede weitere festgestellte Unterbrechung gilt nix mehr.
33
}
34
}
35
else
36
startSeen=0;// die Lichtschranke ist wieder frei. Die nächste
37
// Unterbrechung gilt also wieder
38
39
40
if(sensorValue2>=500)
41
{
42
ende=millis();
43
Geschwindigkeit=3/(ende-start);
44
}
45
}
Das Problem ist ja, dass dein Programm, während der Körper sich durch
die Lichtschranke bewegt, ja viele male die Lichtschranke abfragt. D.h.
dein Programm wird zb 20 mal hintereinander die Lichtschranke als
unterbrochen feststellen. Dich interessiert aber nur der Zeitpunkt an
dem das das ERSTE mal der Fall war!
Un dgenau da kommt jetzt die Variable 'startSeen' ins Spiel. Sie ist 0,
solange die Lichtschranke nix feststellt. Wird die Lichtschranke das
erste mal unterbrochen detektiert, ist sie immer noch 0. Die Zeit wird
festgestellt und die Variable auf 1 gestellt. Beim nächsten Durchgang
durch loop() wird zwar festgestellt, dass die Lichtschranke durchbrochen
ist, ABER die Variable startSeen ist jetzt 1 (heißt, diese Unterbrechung
wurde schon in eine Startzeit umgesetzt). Und jetzt unterbleibt das
feststellen der Zeit, denn die wurde ja schon festgestellt. Erst wenn
dann das Objekt durch die Lichtschranke durch ist, die Lichtschranke
also nicht mehr unterbrochen ist, wird startSeen wieder auf 0 zurück
gesetzt, damit bei der nächsten Unterbrechung dann die nächste
Messperiode beginnen kann.
> .... 3/(ende-start);
Ich denke nicht, dass du das willst.
Aber das wirst du dann schon sehen, wenn du die ersten realen Messungen
machst.
Du kriegst hier Als Ergebnis nur 0, 1, 2 oder ganz selten auch mal 3
raus.
FAQ
Der Punkt: "Datentypen in Operationen"
// Daten der Lichtschranke auf dem Computer ausgeben => darüber Schwellenwert festlegen
17
18
if(sensorValue>=500)
19
{
20
start=1;
21
}
22
23
else
24
{
25
start=0;
26
}
27
28
if(start=1)
29
{
30
millis();
31
}
32
intzeit=millis();
33
Serial.println(zeit,DEC);
34
}
ähm ja kann mir jemand erklären wie ich des jetzt verändern muss? Sp is
des genau gleich wie zuvor. Ich hab da grad nicht die zündente Idee wie
ich das hier^^ reinzuschreiben habe.
if(startSeen==0)// <--- wurde die Startschranke schon einmal unterbrochen?
25
{
26
// Nein, noch nicht
27
start=millis();
28
startSeen=1;// merken, dass die startschranke schon ausgelöst wurde.
29
// D.h. start hat jetzt schon den korrekten Wert der ersten Unterbrechung.
30
// Jede weitere festgestellte Unterbrechung gilt nix mehr.
31
}
32
}
33
else
34
startSeen=0;// die Lichtschranke ist wieder frei. Die nächste
35
// Unterbrechung gilt also wieder
36
37
if(sensorValue2>=1000)
38
{
39
40
if(endeSeen==0)// <--- wurde die Startschranke schon einmal unterbrochen?
41
{
42
// Nein, noch nicht
43
ende=millis();
44
endeSeen=1;// merken, dass die startschranke schon ausgelöst wurde.
45
// D.h. start hat jetzt schon den korrekten Wert der ersten Unterbrechung.
46
// Jede weitere festgestellte Unterbrechung gilt nix mehr.
47
}
48
}
49
else
50
endeSeen=0;// die Lichtschranke ist wieder frei. Die nächste
51
// Unterbrechung gilt also wieder
52
53
54
Geschwindigkeit=0,1/((start-ende)/1000);
55
Serial.println(Geschwindigkeit,DEC);
56
}
Ok also alles sollte eigentlich gehen bei sensor Value1 &2 passt alles
mehrmals überprüft bei. Ende und Start klappt auch vorzüglich nur bei
Geschwindigkeit kommt nur 0,00000000 die ganze Zeit! Warum?
ghost schrieb:> Da kommt jetzt oft"inf" was bedeuted dass? Ab und zu kommen auch> Zahlenwerte
inf ... infinity ... unendlich.
Du dividierst durch 0.
Lass dir halt mal die werte für start und ende auch ausgeben.
Dann kannst du die Berechnung auch nachvollziehen!
Es gibt kein Gesetz, welches besagt, dass du nur das Endergebnis während
der Programmentwicklungsphase ausgeben darfst.
Es gibt auch kein Gesetz, welches dir verbieten würde, hier
1
if(sensorValue1>=1000)
2
{
3
if(startSeen==0)
4
{
5
start=millis();
6
startSeen=1;
7
8
Serial.write('#"); // <--------------
9
}
10
}
ein Zeichen auszugeben, so dass du am PC siehst, wann die Lichtschranke
'anschlägt' und ob das evntuell wegen eines schlechten Grenzwertes
mehrmals passiert. (Selbiges natürlich auch für die andere
Lichtschranke)
Ja OK. Jedoch kommt jetzt bei serial monitor kurz ein neuer wert und
dann wieder 0.00000000698 durchgängig. Durch breche ich die
Lichtschranken neu kurz neuer wert dann wieder ^^ das ist sich sinnlos
oder? Wie kann das sein??
Ja, doch. Das kann sein.
Das ist genau das was du programmiert hast :-)
Dein Progammaufbau
1
voidloop()
2
{
3
schranke1behandeln
4
5
schranke2behandeln
6
7
8
ergebnisausgeben
9
}
die Ausgabe des Ergebnisses hängt von nichts ab und wird daher bei jedem
Durchlauf durch loop gemacht. Schau dir deinen Code an!
Es wäre vielleicht ganz gut, das Ergebnis nur dann ausgeben zu lassen,
wenn auch eine Messung zu Ende ist. Das ist zb. dann der Fall, wenn die
Lichtschranke 2 durchbrochen wurde.
Im übrigen würde ich mir auch mal die Werte für sensorValue1 bzw.
sensorValue2 ausgeben lassen. Nur um sicher zu gehen, dass die auch so
sind, dass der Code nicht jedes mal in
1
if(sensorValue1>=1000)
2
{
3
if(startSeen==0)
4
{
5
start=millis();
6
startSeen=1;
hinein geht.
Wie gesagt: du darfst dir ruhig Zwischenwerte und Variablen ausgeben
lassen. Alles was du brauchst um nachvollziehen zu können, warum dein
Code welchen Zweig durch all die ifs nimmt.
@Karl Heinz
Auch wenn du mich hier letztens mal blöd angeranzt hast, trotzdem bleib
ich dein Fan.
Das ist einfach nur geil wie du die Dinge erklärst und Denkanstöße
gibst.
Hab jetzt nichts mit Lichtschranken gemacht, aber das bereite mich schon
mal gut vor.
Man muss auf jeden Fall genau überlegen was wann passiert und warum das
so ist. Dazu ist es auch, wie ich immer wieder feststelle, elementar
wichtig zu wissen wie so ein µC arbeitet.
War sehr interessant.
F. Fo schrieb:> ... und Denkanstöße gibst.
Das war nicht immer so.
Ich hab aber festgestellt, dass das wenig bis nichts bringt, wenn ich
den Leuten den Code bis ins Detail vorkaue.
Da ist die 'Arschtrittmethode' besser, auch wenn sie unhöflicher wirkt.
Denn letzten Endes ist es besser wenn er das Programm schreibt (und
nicht ich), auch wenn es dabei so manches mal in eine Sackgasse geht aus
der man ihn wieder rauslotsen muss.
Die Erfahrung war nämlich, dass sich ein nicht geringer Anteil zurück
gelehnt hat und nur noch darauf gewartet hat, dass die Leute hier im
Forum ihnen alles mehr oder weniger schlüsselfertig servieren. Gelernt
haben sie dabei nichts und das hat man auch deutlich gemerkt.
Man muss nämlich auch sehen, dass das Begehen von Fehlern Teil des
Lernprozesses ist. Es gehört genauso dazu, wie Stürzen zum
Radfahren-Lernen dazugehört. Nimmst du jemandem diese Möglichkeit, dann
lernt er es auch nicht richtig.
Es gibt natürlich immer wieder Fälle, in denen man Codestücke
ausformulieren muss, weil es sich ganz schlecht erklären lässt. Aber
auch da gehe ich immer mehr davon weg, kompletten Code zu liefern,
sondern mehr nur die relevanten Stückchen.
if(startSeen==0)// <--- wurde die Startschranke schon einmal unterbrochen?
180
{
181
start_Zeitmessung=millis();// Nein, noch nicht
182
startSeen=1;// merken, dass die startschranke schon ausgelöst wurde.
183
// D.h. start hat jetzt schon den korrekten Wert der ersten Unterbrechung.
184
// Jede weitere festgestellte Unterbrechung gilt nix mehr.
185
}
186
}
187
else
188
startSeen=0;// die Lichtschranke ist wieder frei. Die nächste Unterbrechung gilt also wieder
189
if(sensorValue2>=Grenze2)
190
{
191
if(endeSeen==0)// <--- wurde die Startschranke schon einmal unterbrochen?
192
{
193
ende_Zeitmessung=millis();// Nein, noch nicht
194
endeSeen=1;// merken, dass die startschranke schon ausgelöst wurde. D.h. start hat jetzt schon den korrekten Wert der ersten Unterbrechung. Jede weitere festgestellte Unterbrechung gilt nix mehr
Also ich dachte mir mal ich schicke mal den vollständigen Programcode
damit mir gut geholfen werden kann und Probleme bzw. Verbesserungen mir
schnell aufgezeigt werden können.
Zwei Probleme habe ich auf jeden Fall noch die ich beheben möchte 1. die
Geschwindigkeit wird wieder nicht richtig angezeigt, ich bin mir sicher
dass der Fehler nicht groß ist aber ich mag ihn einfach nicht finden :(
2. Ich möchte dass Werte wie Geschwindigkeit nur einmal angezeigt werden
auf dem lcd mit set Cursor oder ähnlichen habe ich es schon versucht,
aber nicht passend hinbekommen. Ich mache da irgendetwas falsch.
Ich weiß, dass ganze ist sehr viel und vielleicht verlange ich zu viel
dass mir jetzt hier weiter geholfen wird, allerdings möchte ich jetzt so
kurz vor dem Ende schnell weiter kommen. Deshalb hoffe ich das jemand
mir gleich schnell und einfach weiterhelfen kann wie auch bisher
(besonderes Dankeschön an karlHeinz). Ich habe versucht mich erst im web
zu informieren aber da findet man sehr schwer genau das passende ohne
sich durch 100 Sachen durch zu lesen :(
so ganz hast du das aber auch nicht durchschaut, wie ein switch-case in
C funktioniert. Da wärst du ja mit einer if-else if Leiter noch besser
bedient gewesen.
C-Buch!
i/100
i ist ein int, 100 ist ein int.
Damit ist das eine Integerdivision und wird auch als solche ausgeführt.
3 / 100 ergibt 0. Eine glatte 0.
FAQ den Punkt über Datentypen in Operationen
> Ich möchte dass Werte wie Geschwindigkeit nur einmal angezeigt werden auf dem
lcd mit set Cursor oder ähnlichen habe ich es schon versucht, aber nicht passend
hinbekommen.
setcursor ist schon mal ein Ansatz.
Damit steht die Zahl schon mal immer an der gleichen Stelle.
Mit 'nicht passend hinbekommen' kann niemand was anfangen.
if(startSeen==0)// <--- wurde die Startschranke schon einmal unterbrochen?
195
{
196
start_Zeitmessung=millis();// Nein, noch nicht
197
startSeen=1;// merken, dass die startschranke schon ausgelöst wurde.
198
// D.h. start hat jetzt schon den korrekten Wert der ersten Unterbrechung.
199
// Jede weitere festgestellte Unterbrechung gilt nix mehr.
200
}
201
}
202
else
203
startSeen=0;// die Lichtschranke ist wieder frei. Die nächste Unterbrechung gilt also wieder
204
if(sensorValue2>=Grenze2)
205
{
206
if(endeSeen==0)// <--- wurde die Startschranke schon einmal unterbrochen?
207
{
208
ende_Zeitmessung=millis();// Nein, noch nicht
209
endeSeen=1;// merken, dass die startschranke schon ausgelöst wurde. D.h. start hat jetzt schon den korrekten Wert der ersten Unterbrechung. Jede weitere festgestellte Unterbrechung gilt nix mehr
Also hier wieder der volle Text.
Das Problem mit dem Werte anzeigen habe ich jetzt passend gelöst. Und
auch i habe ich zu float gemacht.
So wenn ich jetzt bei Grenze1 am LCD 1000 einstelle funktioniert, dies
klasse. Wenn ich danach die Lichtschranke1 unterbreche wird der Wert von
start_Zeitmessung unterbrochen. Also da ist alles super!
Aber bei Grenze 2 funtioniert etwas nicht drücke ich hier auf Select
zeigt mir das LCD nicht nur einmal den Wert von Grenze1 an sondern ich
muss ein zweitesmal select drücken um wieder in das Menü kommen zu
kommen. Des weiteren verändert sich nach Veränderung des Wertes Grenze2
kommt keine Änderung bei ende_Zeitmessung wenn ich die Lichtschranke
unterbreche.
Hier ist glaub ich mein letztes Problem (bitte sei das letzte ;) )
Also das Problem von oben besteht zwar immer noch allerdings ist es mir
gelungen Messungen zu machen und ich habe auch werte bekommen allerdings
waren diese nie größer als 0,36 km/h
Dann wird dir das folgende auch nicht gefallen.
Dein Code, so wie er gepostet wurde, ist schon viel zu lang, viel zu
unübersichtlich und viel zu schlecht strukturiert. Deshalb verlierst du
die Übersicht.
Der erste und einer der wichtigsten Punkte ist: Code muss sauber
strukturiert und eingerückt werden! Es darf keinen Zweifel geben, auf
welcher Einrücktiefe sich welcher Code befindet.
Mit jeder öffnenden { wird um 2 Zeichen eingerückt, mit jeder
schliessenden } wird um 2 Zeichen ausgerückt. Die 2 sind jetzt nur
beispielhaft zu sehen und sind ein populärer Wert. Wichtig ist, dass
dieses Konsequent gemacht werden muss! Denn nur so, kriegt man ein
optisches Bild, welche Codeteile zb von welchem if abhängen.
Das andere ist: Nimm Codeteile, die für sich alleine eine Funktion
erfüllen und steck sie in Funktionen. Damit erreichst du, dass die
Einzelteile übersichtlicher werden!
und ps:
ein switch-case funktioniert so
1
switch(select)
2
{
3
case500:
4
machwas;
5
break;
6
7
case501:
8
machwasanderes;
9
break;
10
11
case502:
12
machirgendwasganzanderes;
13
break;
14
}
die switch case, so wie du sie gemacht hast, sind zwar nicht in dem
Sinne falsch, aber sie ziehen den Code enorm in die Länge. Und genau das
willst du nicht, denn ein in die Länge gezogener Code kostet dir
Übersicht! So wie du die sitch-case gesetzt hast, bringen die dir
nichts, auch wenn sie im eigentlichen Sinne nicht falsch sind. Denn
anstelle von
1
switch(select)
2
{
3
case500:
4
lcd.clear();
5
lcd.print(Grenze2);
6
lcd.setCursor(5,0);
7
}
8
switch(select)
9
{
10
case501:
11
Grenze2=500;
12
}
13
switch(select)
14
{
15
case502:
16
Grenze2=750;
17
}
18
switch(select)
19
{
20
case503:
21
Grenze2=1000;
22
}
könnte man das auch als
1
if(select==500)
2
{
3
lcd.clear();
4
lcd.print(Grenze2);
5
lcd.setCursor(5,0);
6
}
7
8
if(select==501)
9
Grenze2=500;
10
11
if(select==502)
12
Grenze2=750;
13
14
if(select==503)
15
Grenze2=1000;
schreiben und hat genau dasselbe in der Hälfte Codezeilen ausgedrückt.
Deine Version fügt einfach nur einen Haufen optischen Schnickschnack
hinzu, für den du nichts kriegst, für den du aber bezahlst - mit Verlust
der optischen Übersicht.
Noch besser ist es aber, zum Beispiel diesen Teil in eine eigene
Funktion zu stecken
1
voidHandleMenu500(intMenuSelect)
2
{
3
if(MenuSelect==500)
4
lcd.clear();
5
6
elseif(MenuSelect==501)
7
Grenze2=500;
8
9
elseif(MenuSelect==502)
10
Grenze2=750;
11
12
elseif(MenuSelect==503)
13
Grenze2=1000;
14
15
lcd.setCursor(5,0);
16
lcd.print(Grenze2);
17
}
und dann von loop() aus auszurufen, wenn die Select-Zahl in diesem
Bereich ist
1
....
2
3
4
if(select>=500&&select<=600)
5
HandleMenu500(select);
6
7
....
dadurch wird loop kürzer, was wiedderrum der Übersicht zu gute kommt,
wenn es darum geht, was in loop eigentlich passiert.
Man könnte auch die Bereichsabfrage auf den Menüpunkt mit in die
Funktion hineinziehen, um so loop() noch mehr zu entlasten.
Der ganze Themenkreis rund um deine Buttonabfrage und Verteilung auf die
diversen Funktionsgruppen ist zb so ein Fall.
Beachte auch, wie ich die Funktion HandleMenu500 umgestaltet habe. Denn
natürlich willst du die neue Grenze ja auch auf dem LCD ausgeben, wenn
dein Benutzer den Menüpunkt 501 selektiert. Du hast nichts davon, wenn
du nur den Wert neu setzt. Du musst ihn schon auch noch ausgeben.
Dadurch, dass sich diese Funktion nur und ausschliesslich damit
beschäftigt, die 500-er Menüpunkte zu handhaben, kann man das aber in
der Funktion sehen, weil sich die Funktion nur damit beschäftigt. In
deinem riesen Code-Wust in loop() sieht man das alles nicht vernünftig -
der Überblick fehlt, weil alles schon zu groß und zu unübersichtlich und
zu wenig auf bestimmte Aufgabenbereiche fokusiert ist.
Kurz und gut:
deinen Code müsste man jetzt erst mal sauber und konsequent einrücken um
überhaupt nur rausfinden zu können, was da eigentlich schief geht. NOch
besser wäre es den Code komplett neu zu strukturieren. Irgendwann ist
eben immer ein Punkt erreicht, an dem die Fähigkeiten des Programmierers
nicht mehr ausreichen, ihn zu überblicken. Und dann ist auch der Punkt
erreicht, an dem man seltsame Fehler hat, denen man nicht auf die Spur
kommt.
IMHO ist jetzt erst mal Hausaufgaben machen angesagt. Man kann erste
Tests und Funktionsüberprüfungen mit schnell hingeschustertem Code
machen. Kann mann. Dabei lernt man Grundtechniken, wie sich Systeme
verhalten, sammelt Erfahrung darüber wie ein bestimmter Teilbereich
grundsätzlich funktioniert.
Aber das richtige Programm wird dann sauber aufgebaut und gut
strukturiert. Alles andere ist letzten Endes für die Tonne.
ich muss noch ergänzen, dass bei einem heutigen test dass ganze schon
nicht schlecht gearbeitet hat nur: waren die werte nie größer wie 17,53
war das Objekt eindeutig schneller kam sofort auf dem Display 90000 km/h
Das heisst, wenn die Lichtschranken so schnell ansprechen, dass sie im
gleichen Zyklus kommen, hast du denUnterschied zwischen den 2 micros()
- Aufrufen und Berechnungen.
Die Auflösung von micros() sind 4 µs.
Geschwindigkeit = (i*3.6 *10000) / 4 = i * 9000 km/h
(komplett unabhängig von der tatsächlichen Geschwindigkeit)
Das sollte den einen Punkt erklären?
Mich interessiert jetzt selbst, wie lang ein micros() - Aufruf dauert
...
Wenn ein Umlauf 1 ms dauert, und zwischen start und stop ein loop()
Umlauf liegt, ergibt sich
Geschwindigkeit = (i*3.6 *10000) / (1050) = ca. i * 36 km/h
Bei 2 Umläufen ca. (i*3.6 *10000) / (2000) = ca. i * 18 km/h
... (usw)
Wenn ein Umlauf länger dauert, ergeben sich natürlich gröbere
Stufungen...
Das ist als verständliches Beispiel gedacht, und daher meine Frage nach
den loop - Zykluszeiten ...
Edit: meine ursprüngliche Annahme von ca 50 µs zwischen start- und
stop-micros()
war wohl etwas pessimistisch. Werte im Bereich von 4, 8, ... µs sind
wohl eher das was du siehst.
Könnte es daran liegen^^?