Hallo ich hab ein Programm geschrieben mit dem man mit einer 7
Segementanzeige von 0-9 hochzählt, dann will ich mit einem externen
resettaster wieder auf 0 zurücksetzen. Soweit funktioniert es auch. Nur
sobald ich dann wieder meine Lichtschranke betätige zählt die
Segmentanzeige nicht mehr weiter.
Ich hab eine arduino duemilanove
Kann mir jemand helfen?
Mach dir als erstes mal eine Funktion, der du eine Ziffer von 0 bis 9
übergibst, und die diese Ziffer dann auf der 7-Seg anzeigt.
Damit hast du dann diesen Teil aus der loop() draussen, so dass dir
dieses 'Detail' nicht mehr in die Quere kommt, wenn du dich um die Logik
kümmerst, wie sich der interne Zählerstand verändert, wenn irgendwas
passiert. Wichtig: dies ist die einzige Funktion, die die Erlaubnis hat,
an den Pins für die 7-Seg Anzeige rumzufummeln.
Dein Funktion loop() ist offensichtlich schon zu groß, so dass du die
implementierte Logik nicht mehr überblicken kannst.
biede1987 schrieb:> Ja dann muss er hier wieder von vorne anfangen mit zählen
Genau das meine ich.
'Von vorne anfangen mit zählen' bedeutet in erster Linie, dass der
Rundenzähler in Form der Variable 'Runde' auf 0 gesetzt wird. Es
bedeutet nicht, dass du dich in der Behandlung des Reset-Tasters um die
7-Seg Anzeige kümmern musst, in dem du die einzelnen Bits ansteuerst.
Deine loop sieht dann so aus
writeTo7Seg(Runde);// und hier, ganz zum Schluss wird dann dieser
11
// Wert, egal wie er jetzt ist, ausgegeben.
12
// Die Funktion writeToSeg weiß, wie das geht
13
}
14
15
voidwriteTo7Seg(uint8_tZiffer)
16
{
17
if(Ziffer==0)
18
{
19
...
20
}
21
elseif(Ziffer==1)
22
{
23
...
24
}
25
....
26
}
wenn du dann in deinem C++ Buch (oder C Buch) ein wenig geschmökert und
gelernt hast, dann wird dir auch eine Möglichkeit einfallen, wie du zb
mit Arrays dir die ganze Sache der Ausgabe auf die Anzeige massiv
vereinfachen kannst.
Aber erst mal ist wichtig, dass du den Anzeigeteil aus der loop soweit
raushältst, dass du dich dort Codemässig nur noch um die Manipulation
der Variable 'Runde' kümmerst und nicht aufgrund der Codelänge den
Überblick verlierst, wie deine Logik eigentlich aussieht.
wenn Runde den Wert 8 hat, dann KANN sie nicht den Wert 9 haben. Es ist
völlig sinnlos das noch zu testen. Es ist schlicht und ergreifend nicht
möglich.
1
if(Runde==0)
2
{
3
....
4
}
5
6
elseif(Runde==1)
7
{
8
....
9
}
10
11
elseif(Runde==2)
12
{
13
...
14
}
15
...
oder einfacher
1
switch(Runde)
2
{
3
case0:
4
.....
5
break;
6
7
case1:
8
.....
9
break;
10
11
case2:
12
.....
13
break;
14
15
default:
16
....
17
}
konsultiere bitte dein C++ (oder C) Buch, welche Möglichkeiten die
einfachen Basisdinge der Sprache dir bieten. Es gibt Grundlagen die
müssen einfach sitzen, ehe man das erste mal was 'richtiges'
programmiert. Wenn man von der Programmiersprache die man benutzt noch
nicht einmal 10% des Sprachumfangs kennt, dann ist man blutigster
Anfänger und sollte tunlichst noch ein paar Übungen durchspielen, ehe
man sich in die reale Welt rauswagt.
sagt sich so einfach nimm den,
ich hab jetzt schon mit dem angefangen!
Danke Karl Heinz, für die Info
dann mach ich einen neuen Tap auf und speicher dann meine Zahlen dort
rein und schreib dann meine Logik weiter.
Aber eigentlich müsste ich doch jetzt nur in dem Prommgrann
reinschreiben.
wenn die Reset taster gedrückt dann fange wieder an von vorne oder?
biede1987 schrieb:> sagt sich so einfach nimm den,> ich hab jetzt schon mit dem angefangen!>> Danke Karl Heinz, für die Info>> dann mach ich einen neuen Tap
Hä?
Was ist ein Tap?
> Aber eigentlich müsste ich doch jetzt nur in dem Prommgrann> reinschreiben.
Was ist so schwer an
1
...
2
voidsetup()
3
{
4
...
5
}
6
7
voidloop()
8
{
9
...
10
}
11
12
voidwriteTo7Seg(uint8_twert)
13
{
14
...
15
}
alles in einem 'Sketch'.
Es geht nur darum, dass du deine Funktion loop() ein wenig kürzer
kriegst, damit du sie wieder überblicken kannst (und damit du in loop()
auch nicht unmotiviert an irgendwelchen 7-Seg LEitungen rumfummelst,
obwohl du das dort gar nicht tun darfst)
> wenn die Reset taster gedrückt dann fange wieder an von vorne oder?
wenn der Reset Taster gedrückt wird, dann wird der Zähler auf 0 gesetzt.
Das ist es ja wohl, worauf es hinaus läuft, wenn du 'vor vorne anfangen'
sagst. Oder?
Ergo
1
....
2
if(digitalRead(reset))
3
Runde=0;
4
....
fertig.
In einem Programm haben Variablen durchaus eine Bedeutung, eine
Funktion.
In deinem Programm IST die Variable 'Runde' der Rundenzähler. Sie
repräsentiert die gezählten Runden. Wenn du also deine Runden
manipulierst, dann geschieht das, indem du die gwünschte Operation auf
DIESE Variable anwendest.
Der Rest, die Sache mit der 7_seg - das ist nur die ANzeige. Das
Sichtbarmachen des programminternen Rundenzählers. Hier in deinem
Programm
1
if(resetdruecken==LOW)
2
3
4
{
5
6
digitalWrite(a,0);
7
digitalWrite(b,0);
8
digitalWrite(c,0);
9
digitalWrite(d,0);
10
digitalWrite(e,0);
11
digitalWrite(f,0);
12
digitalWrite(g,1);
13
}
hast du das nicht berücksichtigt. Du hast zu kurz gedacht und deine
7-Segment Anzeige mit dem Rundenzähler verwechselt. Du bist nach dem
gegangen, was du siehst. Aber das ist Quatsch. Denn die 7_Seg Anzeige
ist ja nicht dein Rundenzähler. Die ist nur ANzeigeelement. Der
eigentliche Rundenzähler ist die Variable 'Runde'. Die wird manipuliert.
Und natürlich irgendwann zur Anzeige gebracht. Aber der Vorgang des
Anzeigens hat ja nichts mit dem Zählern von Runden bzw. der Verwaltung
dieser Zählung zu tun. Das ist nur eine Anzeige und nicht mehr.
Hallo Biede,
ich bin Modellbahner und habe das gleiche Problem.
Runden zählen und gleichzeitig die Geschwindigkeit zu ermitteln, um die
Geschwindikkeiten der Loks ein zu justieren.
Dein Aufwand mit einem µC ist viel zu aufwendig.
Ein Logikbaustein CD 4017 tut es genauso, mit viel weniger Aufwand.
Dieser ist ein Dezimalzähler nut 10 decodierten Ausgängen, der auch noch
kaskadieren kann.
Triggern kannst Du ihn mit einem Impuls von einem Reedkontakt oder einer
Lichtscharanke.
An den 10 Ausgängen hängst Du entweder ein 10-fach LED-Array oder einen
LCD-Dekoder zur Anzeige.
Das ganze hat den Vortei, das es viel weniger kostet als ein µC-Modul
und auch sehr viel schneller realisiert ist.
Grüße
Edgar
Stimmt du hattest recht, eigentlich ganz klar, ich muss ja meine Runde
auf 0 zurücksetzen und nicht die 7 Segementanzeige. oh man danke
ich schreib aber nicht Runde = 0 sonder -1
damit die 7 Segmentanzeige 0 anzeigt und Sie schaltet nur wenn ich dann
die Lichtschranke betätige. normaler weise muss doch dann die Anzeige
sofort 0 Anzeigen wenn ich den Reset-Taster drücke, liegt das an
biede1987 schrieb:> Stimmt du hattest recht, eigentlich ganz klar, ich muss ja meine Runde> auf 0 zurücksetzen und nicht die 7 Segementanzeige. oh man danke>> ich schreib aber nicht Runde = 0 sonder -1> damit die 7 Segmentanzeige 0 anzeigt und Sie schaltet nur wenn ich dann> die Lichtschranke betätige. normaler weise muss doch dann die Anzeige> sofort 0 Anzeigen wenn ich den Reset-Taster drücke, liegt das an
Was hast du sonst noch geändert?
Hast du dein Programm so umgeändert, wie ich es vorgeschlagen habe?
if(Lichtschrankeunterbrochen!=letzteRunde){// Der Zustand des Schalters hat sich verändert
8
9
if(Lichtschrankeunterbrochen==HIGH){// Ist der Schalter gedrückt?
10
Runde++;// Inkrementieren der Variablen Runde
11
12
Serial.print("Wir sind jetzt in der ");
13
Serial.print(Runde);
14
Serial.println(" Runde");
15
}
16
17
letzteRunde=Lichtschrankeunterbrochen;
18
}
19
20
writeTo7Seg(Runde);
21
}
22
23
voidwriteTo7Seg(uint8_twert)
24
{
25
if(wert==0)
26
{
27
digitalWrite(a,0);
28
digitalWrite(b,0);
29
digitalWrite(c,0);
30
digitalWrite(d,0);
31
digitalWrite(e,0);
32
digitalWrite(f,0);
33
digitalWrite(g,1);
34
}
35
36
elseif(wert==1)
37
{
38
digitalWrite(a,1);
39
digitalWrite(b,0);
40
digitalWrite(c,0);
41
digitalWrite(d,1);
42
digitalWrite(e,1);
43
digitalWrite(f,1);
44
digitalWrite(g,1);
45
}
46
47
elseif(wert==2)
48
{
49
...
50
}
51
...
52
}
Tu das bitte.
Denn jetzt können wir in loop() auch ohne seitenlanges Hin und Her
scrollen überblicken, dass nach der Erkennung des Reset-Tasters (und dem
damit verbundenen Rücksetzen von Runde auf 0) ganz zum Schluss die
Ausgabe von Runde auf die Anzeige erfolgt.
Denn natürlich reicht das ja nicht, den Rundenzähler auf 0 zu setzen. Du
willst das ja auch auf der Anzeige irgendwann mal sehen. Dazu muss aber
die Ausgabe mal gemacht werden. Ein Aufruf der Funktion writeTo7Seg mit
dem jeweils gültigen Wert von Runde leistet genau das.
Wird also der Reset Taster gedrückt vorgefunden dann wird Runde auf 0
gesetzt und als Abschluss in loop() wird auf jeden Fall der Wert von
Runde auf der Anzeige ausgegeben. loop() ist kurz genug, dass man das
problemlos erkennen kann. .....
.... In der jetzigen Version (mit Auslagerung des Anzeigecodes in eine
eigene Funktion). In der alten Version mit haufenweise Code in loop()
hast du den Überblick verloren, was wo passiert. DIe Lehre die du daraus
ziehen solltest: Es ist nicht egal, ob man sich eine Codewurscht
hinschmiert oder nicht. Denn in dem einen Fall reichen deine Fähigkeiten
den Code zu überblicken nicht aus. Im anderen Fall aber schon. Es ist
beide male der gleiche Code. Nur anders organsiert. Nämlich so, dass
deine Fähigkeiten reichen, mit dem Code zu arbeiten.
biede1987 schrieb:> ok ich habs jetzt umgeschrieben
Gut.
Du solltest alten Hasen ruhig etwas glauben, wenn sie Dinge ansprechen,
die du für unnötig hältst.
Genauso wie dir die alten Hasen sagen werden, dass eine konsistente und
saubere Code-Einrückung nicht einfach nur Selbstzweck ist, sondern
durchaus ein Instrument um Code und Logikfehler zu finden bzw. gar nicht
erst aufkommen zu lassen.
Es ist (auf lange Sicht) eben nicht egal, ob ....
1
...
2
elseif(wert==2)
3
{
4
digitalWrite(a,0);
5
digitalWrite(b,0);
6
digitalWrite(c,1);
7
digitalWrite(d,0);
8
digitalWrite(e,0);
9
digitalWrite(f,1);
10
digitalWrite(g,0);
11
}
12
elseif(wert==3)
13
{
das eine else nicht unter dem anderen steht, das eine abhängige
digitalWrite um 4 Zeichen eingerückt ist und die anderen um 6. Ob du
einmal die KLammern so anordnest
1
if(...){
2
...
3
}
und das andere mal so
1
if(...)
2
{
3
...
4
}
Ob es dir egal ist, dass die schliessende } einer Funktion wieder am
linken Rand steht, oder so wie hier
1
voidsetup(){
2
3
Serial.begin(9600);// Start der seriellen Kommunikation mit 9600bps
nicht.
Das alles sind rein formale Dinge. Aber ... sie haben einen Einfluss ob
ein Code leicht zu lesen ist, oder ob man zur Fehlersuche erst mal am
liebsten den Code reformatiert um die falsch gesetzten oder fehlenden
{-} Klammern zu finden.
biede1987 schrieb:> sagt sich so einfach nimm den,> ich hab jetzt schon mit dem angefangen!
Das ist ein Grund, aber kein Hindernis ;o)
Sorry, ich wollte Dir den Spaß an der lehrreichen Eigenentwicklung nicht
nehmen. Der olle 4026 macht halt genau das: Bis Zehn zählen, evtl. Reset
und hat gleich die Ausgänge speziell für Siebensegment-Anzeigen. Im
Prinzip macht er genau das was Du im ersten Post umrissen hast. Evtl.
müsste man noch eine Entprellung hinzufügen z.B. 555 monostabil.
Wenn bei Deinem Mikrocontroller mal die Pins knapp werden, kannst Du das
vielleicht kombinieren.
Auf jeden Fall noch viel Spaß und Erfolg bei Deinem Projekt!
Klaus
Guten Abend nochmal,
ich möchte jetzt als nächste 4 / Segmentanzeigen mit meinem Arduino
ansteuern. Jeweils 2 Anzeigen nutzen um die Runden von 0 bis 99 zu
zählen.
Ich habe als Eingänge 2 Lichtschranke die auch schon funktionieren und
als Ausgang hab ich diese 7 Segment anzeige.
http://www.ebay.de/itm/Rot-0-56-7-Segment-4-Digit-Super-LED-Display-Common-Anode-Time-12-pins-Anzeige-/400580687232?pt=Bauteile&hash=item5d44783580
Als Mikrokontroller hab ich mir den Arduino Mega gekauft.
Beigefügt hab ich mal mein Blockschaltbild.
was meint ihr ?
ich denke das Programm von oben, mit der Logik kann ich bei meienm neuen
anwenden?
Hallo nochmal, ich hab jetzt mein 4/ 7 Segmentanzeigen angeschlossen!
http://www.ebay.de/itm/Rot-0-56-7-Segment-4-Digit-Super-LED-Display-Common-Anode-Time-12-pins-Anzeige-/400580687232?pt=Bauteile&hash=item5d44783580
Das Programm von oben hab ich auf meinen Arduino Mega aufgespielt, der
Zähler funktionier auf der ersten Anzeige.
Wie kann ich jetzt programmieren das er nicht nur von 1 bi 9 zählt,
sondern von 1 - 99! So dass ich die zweite auch ansteuer!
Es ist nämlich so wenn ich dann meine 2 Ausgänge, dig 1 und 2 ansteuer
wird eine 11 , 22 usw. weiter angesteuert.
Würde es was bringen wenn ich mit einer libary arbeite?
Danke für die Anworten schonmal!
Gruß biede
biede1987 schrieb:> Wie kann ich jetzt programmieren das er nicht nur von 1 bi 9 zählt,> sondern von 1 - 99!
Das ist die falsche Frage.
Die richtige Frage lautet: wie steuere ich mehrere 7-Segment Anzeigen im
Multiplexverfahren an?
Denn dein Zähler für die Runden ist eine ganze normale uint8_t
Variablre, die bis 255 zählen kann. Das ist aber losgelöst von der
Fragestellung, wie man auf mehreren 7_Segment Anzeigen ausgibt. Der Weg
dorthin führt über die Erkentniss, dass man mehrstellige Anzeigen so
ansteuert, dass immer nur eine der Anzeigen angesteuert wird und kurz
drauf die nächste. Wenn das schnell genug gemacht wird, dann kommt dein
Auge bzw. Gehirn nicht mehr mit, dass du immer nur eine Anzeige
leuchtet. Voila: du siehst beide gleichzeitig leuchten (natürlich mit
anderem Inhalt)
> Würde es was bringen wenn ich mit einer libary arbeite?
Es würde was bringen, wenn du die Grundlagen lernen würdest.
Karl Heinz schrieb:> Denn dein Zähler für die Runden ist eine ganze normale uint8_t> Variablre, die bis 255 zählen kann. Das ist aber losgelöst von der> Fragestellung, wie man auf mehreren 7_Segment Anzeigen ausgibt. Der Weg> dorthin führt über die Erkentniss, dass man mehrstellige Anzeigen so> ansteuert, dass immer nur eine der Anzeigen angesteuert wird und kurz> drauf die nächste. Wenn das schnell genug gemacht wird, dann kommt dein> Auge bzw. Gehirn nicht mehr mit, dass du immer nur eine Anzeige> leuchtet. Voila: du siehst beide gleichzeitig leuchten (natürlich mit> anderem Inhalt)
Die einfachst mögliche Version (wenn auch nicht die schönste oder beste
oder einfach auch nur die Version wie man das normalerweise macht),
könnte zb so aussehen
1
uint8_tStelle;
2
3
voidloop()
4
{
5
...
6
7
8
// ... alle Anzeigen abschalten
9
....
10
// ... welches ist die nächste Stelle?
11
Stelle++;
12
if(Stelle==1)// momentan sind es nur 2 Stellen
13
Stelle=0;
14
15
// ... die jeweiligen Ausgangstreiber befüllen
16
if(Stelle==0)
17
writeTo7Seg(Runde%10);
18
elseif(Stelle==1)
19
writeTo7Seg(Runde/10);
20
21
// ... und die betreffende Anzeige einschalten
22
if(Stelle==0)
23
....
24
elseif(Stelle==1)
25
....
26
}
Schön ist das nicht gerade. Normalerweise macht man so einen Multiplex
mit einem Timer, der laufend und unabhähngig vom restlichen Programm die
Bitmuster für die einzelnen Stellen jeweils reihum an den einzelnen
Anzeigen ausgibt. Aber ich fürchte, das kriegst du noch nicht hin. D.h.
dein nächstes Ziel lautet: den Umgang mit einem Timer lernen.
Danke für die Antworten
das programm was ich gefunden hab ist müll weil es viel zu lang wird
oder?
das was du geschrieben hast arbeitet mit der 7 Seg libary?
biede1987 schrieb:> Danke für die Antworten>> das programm was ich gefunden hab ist müll weil es viel zu lang wird> oder?
Das Programm ist deswegen Müll, weil derjenige der es geschrieben hat,
selber nicht programmieren kann. Es ist auf genau dieselbe Art Müll, wie
wenn ein Grundschüler im zweiten Jahr, der gerade mal im Zahlenraum bis
100 addieren kann, dein Grundstück vermisst. Aus seiner Sicht mag es ihm
nicht schlecht vorkommen, aber objektiv gesehen ist es der Versuch mit
einem Sandkastenschäufelchen eine Baugrube auszuheben.
Du kannst es drehen und wenden wie du willst: Ehe man ein größeres
Programm schreiben kann, muss man erst mal die Grundlagen lernen. Wenn
man von seiner Programmiersprache noch nicht mal 10% des Umfangs
beherrscht, dann hat das alles keinen Sinn.
biede1987 schrieb:> http://www.instructables.com/files/orig/FDF/W8AY/G1BBDO34/FDFW8AYG1BBDO34.txt>> könnte mir dieses Programm helfen? So könnte ich doch meine Zahlen> darstelln oder?
Falls Du ein fertiges und alternatives Programm suchst, das auch mit
anderer Hardware (aber auch mit Arduino!) arbeiten darf, hätte ich da
was in der Schublade liegen.
Für:
- Arduino UNO oder kompatibles Board
- Anzeige: LCD-Keypad-Shield zum Aufstecken auf den Arduino
- Sensoren: Ein Reedkontakt pro Fahrspur unter der Fahrbahn montiert
Sag Bescheid, ob den fertigen Sketch für LCD-Keypad-Shield mal posten
soll!
biede1987 schrieb:> Ja das wäre toll wenn du das mal posten kannst, ich versuchs mal> trotzdem mit den 7 Segemnetanzeigen!
Das dürfte allerdings um einiges komplizierter werden als nur die
Umstellung auf die Verwendung Deiner Lichtschranken als Sensor zur
Erkennung, wann ein Fahrzeug die Ziellinie überquert.
Das hier habe ich mal für einen Bekannten gemacht, der mit seinem Enkel
auf einer Carrera-Bahn Rennen ausfährt, wenn der mal zu Besuch ist:
1
/*
2
Slotcar timing by "jurs" for mikrocontroller.net forum
Dieser Sketch ist so wie gepostet für die Erfassung von zwei Fahrzeugen
vorgesehen. Eine Erweiterung auf mehr Fahrzeuge (4 bis 6) wäre am
einfachsten möglich, indem man ein Board mit mehr als zwei
Hardware-Interrupts verwendet (z.B. "Arduino-MEGA").
Die Sensoren müssen an einem UNO-kompatiblen Board an den beiden Pins
angeschlossen werden, die Hardware-Interrupts erzeugen können, das sind
D2 und D3. Für die Auswertung der Reedkontakte werden die internen
PullUp-Widerstände in dieser Zeile aktiviert:
pinMode(reedPins[i],INPUT_PULLUP);
Wenn Deine Lichtschranken keine PullUps benötigen, dort einfach INPUT
statt INPUT_PULLUP einsetzen.
Und falls Du etwas an der Anzeige ändern möchtest: Das Programm
realisiert eine automatische Wechselanzeige, und zwar wird in einem
Rhythmus von 2 Sekunden umgeschaltet zwischen Anzeigen für
"Rundenzeiten" und "Rundenanzahl". Als Rundenzeiten werden sowohl die
Zeiten der letzten gestoppten Runde und die schnellste Rundenzeit "SR"
pro Fahrzeug angezeigt.
Falls Du die Anzeige ändern möchtest (vielleicht zunächst mal zur
Ausgabe auf dem Seriellen Monitor), diese Funktionen sind in diesen
beiden Funktionen zusammengefasst:
void RundenanzahlAnzeigen()
void RundenzeitenAnzeigen()
Rückstellung auf Null und Neustart des Sketches für das nächste Rennen
einfach durch Drücken des Reset-Buttons, dann startet der Controller
neu.
Vielleicht findest Du durch den Code, ansonsten kannst Du ja fragen.
biede1987 schrieb:> trotzdem mit den 7 Segemnetanzeigen!
LCD wär einfacher. Aber ich sehs wie du: 7-Segment sieht für den Zweck
einfach cooler aus.
Und? Wirds was?
Wie gesagt: der Trick ist, dass die beiden Anzeigen (bzw. dann 4 in
weiterer Folge) abwechselnd leuchten. Jede mit ihrer eigenen Ziffer bzw.
dem jeweils anzuzeigendem LED-Muster.
Da fällt mir noch was ein.
Wenn du an anderen Programmstellen keine exzessiven Delays benutzt, dann
kann man am Arduino auch mittels 'millis()'
http://arduino.cc/de/Reference/Millis
so was ähnliches machen, zu dem man normalerweise einen Timer einsetzt.
Shit:
Ich hab gerade versucht, dir da mal was zurecht zu machen.
Aber dieses digitalWrite wirft einem da dauerns Prügel zwischen die
Beine. Mit dem kann man das alles nicht vernünftig machen.
An welchen Portpins hast du deine 7-Segment Anzeige wie angeschlossen?
Das machen wir direkt am Arduino System vorbei. Das ist in Summe
einfacher, als sich da am digitalWrite vorbei zu mogeln. Bzw. falls du
nicht alle 7 Segnentleitungen an einem Port beisammen hast, kannst du
die noch hardwaremässig umlegen? Denn wenn mehrere Leitungen auf einen
Schlag gesetzt oder nicht gesetzt werden sollen, dann geht das deutlich
einfacher als mit dieser if-then-else und digitalWrite Orgie.
Voraussetzung ist aber, dass alle 7 Segmentleitungen an einem
physikalischen AVR Port liegen.
Danke Karl Heinz das du mir so hilfst,
die Libary hab ich mir vorgestern schon runter geladen, deswegen hab ich
auch gefragt ob man es besser ist mit einer libarty zu arbeiten. Bin da
aber nicht wirklich weiter gekommen.
ich hab hier mal mein Ein und Ausgänge
// Um die Runden der Fahrzeuge zu zählen, bedarf es einer Abfrage am
Startzielbogen
// um dem Mikrocontroller mitzuteilen ob das Fahrzeuge durchgefahren
ist oder nicht.
// Die Kontrolle, ob ein Fahrzeug durch den Startzielbogen gefahren
ist , geschieht durch
// eine selbst gebaute Infrarot - Lichtschranke, die am Bogen unten
angebracht ist.
// Ist die Lichtschranke belegt, dann sendet sie eine 1 an den
Mikrokontroller, sobald sich
// nicht belegt ist sendet sie eine 0. Durch einen Reset Taster
werden die Runden wieder auf zurückgesetzt
int Lichtschranke1 = 11; // Taster
int Lichtschranke2 = 13; // Taster
int Lichtschrankeunterbrochen1; // Variable für Pin Zustand Bahn 2
int Lichtschrankeunterbrochen2; // Variable für Pin Zustand Bahn 2
int letzteRunde1; // Variable für den letzten Schalterzustand
letzte Runde Bahn1
int letzteRunde2; // Variable für den letzten Schalterzustand
letzte Runde Bahn2
int Runde1 = 0; // Wie oft ist der Schalter gedrückt Bahn 1
int Runde2 = 0; // Wie oft ist der Schalter gedrückt Bahn 2
int reset = 12;
int resetdruecken; // Variable fuer Reset Taster
int a = 9;
int b = 3;
int c = 4;
int d = 5;
int e = 6;
int f = 7;
int g = 8;
int d1 =24;
int d2 =26;
int d3 =28;
int d4 =30;
void setup(){
Serial.begin(9600); // Start der seriellen Kommunikation mit
9600bps
pinMode(Lichtschranke1,INPUT);
pinMode(Lichtschranke2,INPUT);
pinMode(reset,INPUT);
pinMode(a,OUTPUT);
pinMode(b,OUTPUT);
pinMode(c,OUTPUT);
pinMode(d,OUTPUT);
pinMode(e,OUTPUT);
pinMode(f,OUTPUT);
pinMode(g,OUTPUT);
pinMode(d1,OUTPUT)
pinMode(d1,OUTPUT);
pinMode(d2,OUTPUT);
pinMode(d3,OUTPUT);
pinMode(d4,OUTPUT);
Hallo nochmal,
ich hab jetzt mal das Beispiel gemacht, hab meine Ausgänge dem Programm
angepasst. Die Zeit läuft auch ab!
Aber Warum leuchte die ersten zwei Ziffern heller wie die letzten zwei?
Hab über die gleichen Widerstände verwendet!
#include "SevSeg.h"
//Create an instance of the object.
SevSeg sevseg;
//Create global variables
unsigned long timer;
int CentSec=0;
void setup() {
//I am using a common anode display, with the digit pins connected
//from 2-5 and the segment pins connected from 6-13
sevseg.Begin(1,24,26,28,30,9,3,4,5,6,7,8,40);
//Set the desired brightness (0 to 100);
sevseg.Brightness(80);
timer=millis();
}
void loop() {
//Produce an output on the display
sevseg.PrintOutput();
//Check if 10ms has elapsed
unsigned long mils=millis();
if (mils-timer>=10) {
timer=mils;
CentSec++;
if (CentSec==10000) { // Reset to 0 after counting for 100 seconds.
CentSec=0;
}
//Update the number to be displayed, with a decimal
//place in the correct position.
sevseg.NewNum(CentSec,(byte) 2);
}
}
Ich habs jetzt hinbekommen das ich wenn ich meine Lichtschranke 1
betätige die Anzeig hochzählt von 1- 9999.
Wie bekomm ich jetzt hin, dass meine ersten zwei Ziffern für die erste
bahn sind und meine letzten zwei für die die zweite Bahn, sodass dann
beide bis 99 zählen.
Sorry, war unterwegs. Nach dem auspacken seh ich mir mal durch, was du
gebaut hast.
Nur soviel vorab, wenn deine Anzeige Zahlen von 0 bis 9999 anzeigen
kannst, dann kannst du ja aus 2 Rundenzählern, die jeder von 0 bis 99
gehen, die auszuegbende Zahl zusammensetzen:
auszugebende_Zahl = Runde1 * 100 + Runde2;
Karl Heinz schrieb:> Sorry, war unterwegs. Nach dem auspacken seh ich mir mal durch, was du> gebaut hast.>> Nur soviel vorab, wenn deine Anzeige Zahlen von 0 bis 9999 anzeigen> kannst, dann kannst du ja aus 2 Rundenzählern, die jeder von 0 bis 99> gehen, die auszuegbende Zahl zusammensetzen:>> auszugebende_Zahl = Runde1 * 100 + Runde2;
Damit das geht musst du aber die Unterdrückung der führenden 0-en in der
Lib entweder modifizieren oder aber ganz rauswerfen
Das ist in
1
voidSevSeg::FindNums()
der ganze Teil nach
1
//If there are zeros, set them to 20 which means a blank
biede1987 schrieb:> Wie kann ich die ändern muss ich die in ne text datei umwandlen und dann> rauslöschen?
Im Zip File hast du ja eine cpp-Datei und ein h-File vorgefunden.
Beides sind einfach nur Text-Dateien. Das cpp-File enthält den
Programmtext deiner 'Library'.
ich hab jetzt den teil rausgelöscht
//If there are zeros, set them to 20 which means a blank
//However, don't cut out significant zeros
if (negative==0) {
if (nums[0]==0 && DecPlace<3){
nums[0]=20;
if (nums[1]==0 && DecPlace<2) {
nums[1]=20;
if (nums[2]==0 && DecPlace==0) {
nums[2]=20;
}
}
}
}
else {
if (nums[1]==0 && DecPlace<2) {
nums[1]=20;
if (nums[2]==0 && DecPlace==0) {
nums[2]=20;
}
die dritte 0 kommt trotzdem noch
biede1987 schrieb:> die dritte 0 kommt trotzdem noch
'noch' oder 'nicht'?
Das angestrebte Ziel sieht so aus, dass deine 4-stellige 7_Segment
Anzeige an allen 4 Stellen eine 0 ausgibt, wenn du
jetzt ist es so dass ich am Anfang nichts sehe, und sobald ich meine
Lichtschranke betätige sind alle anzeigen an und bei der letzten steht
ne 1 wenn ich jetzt hochzähle bis 20 dann steht bei allen eine 0
Dein Code ist furchtbar. Rück den doch mal ordentlich ein!
Das ist kein Selbstzweck, das Code eine ordentliche Einrückung hat.
Anhand der Einrückung erkennt man die Struktur, inklusive welche
Anweisungen von welchen anderen Anweisungen abhängen. Je mehr Chaos du
da veranstaltest, desto unübersichtlicher wird das
1
// Um die Runden der Fahrzeuge zu zählen, bedarf es einer Abfrage am Startzielbogen
2
// um dem Mikrocontroller mitzuteilen ob das Fahrzeuge durchgefahren ist oder nicht.
3
// Die Kontrolle, ob ein Fahrzeug durch den Startzielbogen gefahren ist , geschieht durch
4
// eine selbst gebaute Infrarot - Lichtschranke, die am Bogen unten angebracht ist.
5
// Ist die Lichtschranke belegt, dann sendet sie eine 1 an den Mikrokontroller, sobald sich
6
// nicht belegt ist sendet sie eine 0. Durch einen Reset Taster werden die Runden wieder auf zurückgesetzt
7
8
#include"SevSeg.h"
9
10
SevSegsevseg;
11
intLichtschranke1=11;// Taster
12
intLichtschranke2=13;// Taster
13
intLichtschrankeunterbrochen1;// Variable für Pin Zustand Bahn 2
14
intLichtschrankeunterbrochen2;// Variable für Pin Zustand Bahn 2
15
intletzteRunde1;// Variable für den letzten Schalterzustand letzte Runde Bahn1
16
intletzteRunde2;// Variable für den letzten Schalterzustand letzte Runde Bahn2
17
intRunde1=0;// Wie oft ist der Schalter gedrückt Bahn 1
18
intRunde2=0;// Wie oft ist der Schalter gedrückt Bahn 1 2
19
20
intreset=12;
21
intresetdruecken;// Variable fuer Reset Taster
22
23
voidsetup(){
24
Serial.begin(9600);// Start der seriellen Kommunikation mit 9600bps
biede1987 schrieb:> Also wenn ich 0 eingebe dann kommen auch vier 0000
ja, soll auch (momentan) so sein.
Die Unterdrückung führender 0-en ist abgeschaltet!
Ich zähle jetzt auf beiden Seiten,
Problem ist jetzt nur noch wenn ich die Lichtschranke Bahn 1 betätige
zählt es zwar am Serial Monitor hoch, aber nicht auf meine Anzeige, erst
wenn ich Lichtschranke 2 betätige dann leuchte meine Anteige und ich
sehe beide Runden.
biede1987 schrieb:> Problem ist jetzt nur noch
Sorry. Ich greif den Chaoscode nicht mehr an, solange der so aussieht.
Wenn zureden nichts hilft, dann eben auf die harte Tour. Solange, bis du
merkst, dass ein vernünftig aussehender Code eine Hilfe dabei ist,
Logikfehler zu sehen und zu beseitigen.
// Um die Runden der Fahrzeuge zu zählen, bedarf es einer Abfrage am
Startzielbogen
// um dem Mikrocontroller mitzuteilen ob das Fahrzeuge durchgefahren
ist oder nicht.
// Die Kontrolle, ob ein Fahrzeug durch den Startzielbogen gefahren
ist , geschieht durch
// eine selbst gebaute Infrarot - Lichtschranke, die am Bogen unten
angebracht ist.
// Ist die Lichtschranke belegt, dann sendet sie eine 1 an den
Mikrokontroller, sobald sich
// nicht belegt ist sendet sie eine 0. Durch einen Reset Taster
werden die Runden wieder auf zurückgesetzt
#include "SevSeg.h"
SevSeg sevseg;
int Lichtschranke1 = 11; // Taster
int Lichtschranke2 = 13; // Taster
int Lichtschrankeunterbrochen1; // Variable für Pin Zustand Bahn 2
int Lichtschrankeunterbrochen2; // Variable für Pin Zustand Bahn 2
int letzteRunde1; // Variable für den letzten Schalterzustand
letzte Runde Bahn1
int letzteRunde2; // Variable für den letzten Schalterzustand
letzte Runde Bahn2
int Runde1 = 0; // Wie oft ist der Schalter gedrückt Bahn 1
int Runde2 = 0; // Wie oft ist der Schalter gedrückt Bahn 1 2
int reset = 12;
int resetdruecken; // Variable fuer Reset Taster
int auszugebende_Zahl;
void setup(){
Serial.begin(9600); // Start der seriellen Kommunikation mit
9600bps
pinMode(Lichtschranke1,INPUT);
pinMode(Lichtschranke2,INPUT);
letzteRunde1 = digitalRead(Lichtschranke1); // Anfangszustand
lesen
letzteRunde2 = digitalRead(Lichtschranke2); // Anfangszustand
lesen
resetdruecken =digitalRead(reset); // Anfangszustand lesen
sevseg.Begin(1,24,26,28,30,9,3,4,5,6,7,8,32);
//Set the desired brightness (0 to 100);
sevseg.Brightness(90);
}
void loop() {
sevseg.PrintOutput();
if (digitalRead(reset) == HIGH)
Runde1 = 0;
Lichtschrankeunterbrochen1 = digitalRead(Lichtschranke1);
if (Lichtschrankeunterbrochen1 != letzteRunde1) { // Der
Zustand des Schalters hat sich verändert
if (Lichtschrankeunterbrochen1 == HIGH) { // Ist der
Schalter gedrückt?
Runde1++; // Inkrementieren der Variablen Runde
if (Runde1==99) { // Reset von 99 auf 0
Runde1=0;}
Serial.print("Wir sind jetzt in der ");
Serial.print(Runde1);
Serial.println(" Runde Bahn1");
}
}
letzteRunde1 = Lichtschrankeunterbrochen1;
if (digitalRead(reset) == HIGH)
Runde2 = 0;
Lichtschrankeunterbrochen2 = digitalRead(Lichtschranke2);
if (Lichtschrankeunterbrochen2 != letzteRunde2) { // Der
Zustand des Schalters hat sich verändert
if (Lichtschrankeunterbrochen2 == HIGH) { // Ist der
Schalter gedrückt?
Runde2++; // Inkrementieren der Variablen Runde
if (Runde2==99) { // Reset von 99 auf 0
Runde2=0;}
Serial.print("Wir sind jetzt in der ");
Serial.print(Runde2);
Serial.println(" Runde Bahn2");
}
letzteRunde2 = Lichtschrankeunterbrochen2;
}
auszugebende_Zahl = Runde1 * 100 + Runde2;
sevseg.NewNum(auszugebende_Zahl,(byte) 2);
}
Hallo ich bins nochmal,
ich möchte mein Programm nochmals erweitertn:
4-stellige 7 Segmentanzeige bleibt,
zuätzlich soll über den Serial Monitor die Rundenzeit angezeigt werden!
Ich hab das Programm weiter geschrieben könnte es so funktionieren?
Vielen Dank schonmal für die Hinweise!
Danke
biede1987 schrieb:> Ich hab das Programm weiter geschrieben könnte es so funktionieren?
Du hast doch Dein Arduino-Board und eine Carrera-Bahn, probier's einfach
aus!
Übrigens habe ich hier auch mal im Arduino-Forum für jemanden mit
Carrera-Bahn eine Runden- und Zeitmessung gemacht und gepostet:
http://forum.arduino.cc/index.php?topic=158779.msg1189593#msg1189593
(Ich selbst habe keine Bahn.)
Als Sensoren werden da einfach nur zwei Reed-Kontakte verwendet, mit
Heißkleber unter die Bahn geklebt, und die Anzeige erfolgt auf einem
16x2 Text-LCD vom Typ "LCD Keypad Shield" zum Aufstecken für das
Arduino-Board.
Die Rundenzeiten werden in meinem Sketch per Interrupt-Routine
ermittelt, da ich mir nicht sicher war, ob die kleinen Flitzer nicht zu
schnell sind und den Reed-Kontakt für zu kurze Zeit schließen, um per
Polling zuverlässig abgefragt zu werden, insbesondere wenn zwei
Rennwagen "fast gleichzeitig" den kurzen Rundenimpuls erzeugen, weil sie
im Rennen gleichauf liegen.
Das LCD macht eine nette "Wechselanzeige", im Zweisekundentakt wechseln
sich ab:
- Rundenzahlen auf den Bahnen
- Rundenzeiten (letzte Runde und schnellste Rennrunde)
So ist nicht nur auf der Rennbahn "Action", sondern auch auf der
Anzeigentafel tut sich laufend etwas.
Vielleicht möchtest Du Dir auch diesen Code mal ansehen.
Was jetzt kommisch ist wenn die das programmierte Programm in mein altes
einfüge!
kommt am serial monitior die richtige Anzeige. Also Rundenzeit + Runde
Nur meine 4-stellige 7 Segmentanzeige funktioniert nicht, sie leuchtet
nur dann wenn die Lichtschranke unterbrochen ist!
Könnt mir erklären wieso,
Vielen Dank schon mal im Vorraus!
PS
Hallo Jürgen, danke für die INFO hab ich vorgestern Abend auch schon
gefunden, ich habs mir angeschaut und es war eine gute hilfe! möchte es
aber nciht mit einem LCD display machen sondern mit 7 Segmentanzeigen!
Hab auch alles schon aufgebaut und funktioniert! ich möchte jetzt nur
auf dem Serialmontitor die Rundenzeiten und die Geschwindigkeit
herrausgeben!
>if(digitalRead(Lichtschranke1)==HIGH){// Sobald die
18
>Tastegedrücktwurde
19
>Rundenanfang1=millis();
20
>while(digitalRead(Lichtschranke1)==HIGH);// Warten so
21
>langebisdieLichtschrankewiederbetätigtwird
22
>longRundenzeit1=millis()-Rundenanfang1;
23
>Serial.print("Das ist die Rundenzeit ");// Ausgaben
24
>zumSerialMonitor,nursichtbaramPC
25
>Serial.print(Rundenzeit1);
26
>Serial.println(" Bahn1");
27
>}
28
>}
29
>
So wird das nichts.
Du darfst nicht darauf warten, bis dein Auto die Runde beendet hat.
Du starrst ja auch nicht die ganze Zeit auf eine Stoppuhr, wenn du die
Rundenzeit messen willst.
Warum machst du denn nicht das naheliegenste.
Hier, an dieser Stelle ....
1
....
2
if(Lichtschrankeunterbrochen1==LOW){// Wenn Lichtschranke unterbrochen dann
3
Runde1++;// Runde1 hochzählen +1
... weißt du, dass genau zu diesem Zeitpunkt das AUto die Lichtschranke
durchfahren hat. Und genau zu diesem Zeitpunkt stellst du die aktuelle
Zeit fest, indem du sie von millis() erfragst.
Die vergleichst du mit der Zeit von der Runde zuvor (wenn es eine Runde
zuvor gab - das ist aber leicht festzustellen. Wenn die Rundenzahl 1
ist, dann gab es keine Runde zuvor) und die Differenz der beiden ist die
Rundenzeit. Die zu diesem Zeitpunkt festgestellte aktuelle Zeit aus
millis() merkst du dir noch, denn sie ist die Startzeit mit der dann bei
der nächsten Lichschrankenunterbrechung die nächste Rundenzeit ermittelt
wird.
1
....
2
if(Lichtschrankeunterbrochen1==LOW){// Wenn Lichtschranke unterbrochen dann
wenn ich das Programm in das Textfeld einfüge
kommt der immer ohne Einrückung gibt es da einen Trick,
deswegen hab ich auch jetzt das Programm angehängt!
ok danke
wenn ich jetzt bei dem Programm die Gesamtzeit nach 5 Runden anzeige
will
Dann schreib ich jetzt auch wieder:
[c]
if (Runde1 == 5 ) // Ende
nach 5 Runden
{
Gesamtzeit1 = (millis() - Start1)/1000; // Millis
von unten - Rundenanfang1
Serial.print("Gesamtzeit "); //
Ausgabe Serial Monitor
Serial.print(": " );
Serial.print(Gesamtzeit1);
Serial.println(" Sekunden");
[c/]
wie kann ich meine Start1 ( Startzeit) im Programm ermittlen?
klar wenn die Lichtschranke das erste mal auslöst
am besten so oder?
if (Runde1==1){ Start1 = millis();}
ok danke
wenn ich jetzt bei dem Programm die Gesamtzeit nach 5 Runden anzeige
will
Dann schreib ich jetzt auch wieder:
1
2
if(Runde1==1){
3
Start1=millis();}
4
5
if(Runde1==5)// Ende nach 5 Runden
6
{
7
Gesamtzeit1=(millis()-Start1)/1000;// Millis von unten - Rundenanfang1
8
Serial.print("Gesamtzeit ");// Ausgabe Serial Monitor
9
Serial.print(": ");
10
Serial.print(Gesamtzeit1);
11
Serial.println(" Sekunden");
wie kann ich meine Start1 ( Startzeit) im Programm ermittlen?
klar wenn die Lichtschranke das erste mal auslöst
am besten so oder?
if (Runde1==1){ Start1 = millis();}
Hallo nochmals ich möchte jetzt noch die beste Rundenzeit auswerten!
wie kann ich das machen?
wie kann ich es machen das sich der Atmega die Rundenzeiten sich merkt
und vergleicht?