Hallo zusammen ich habe ein Problem bei meinem aktuellen Projekt.
Ich möchte 60 LED's im Sekundentakt nacheinander einschalten (JA wieder
eine LED UHR :) )
Als Hardware nutze ich 8 hintereinander geschaltete Schieberegister
74HCT595 mit dahinter geschaltetem LED Treiber ULM2803.
Als uC nutze ich den ArduinoMega
Der Code:
1
//*** zuweisung der PIN's
2
3
intoe=2;
4
intmr=3;
5
intleatch=4;
6
intclock=5;
7
intdata=6;
8
//*********************
9
10
inttemp=0;
11
longsekuunden=0;
12
13
14
voidsetup(){
15
pinMode(oe,OUTPUT);
16
pinMode(mr,OUTPUT);
17
pinMode(latch,OUTPUT);
18
pinMode(clock,OUTPUT);
19
pinMode(data,OUTPUT);
20
}
21
22
voidloop(){
23
24
digitalWrite(mr,HIGH);
25
digitalWrite(oe;LOW);
26
27
digitalWrite(latch,LOW);
28
shiftOut(data,clock,LSBFIRST,sekunden>>56);
29
shiftOut(data,clock,LSBFIRST,sekunden>>48);
30
shiftOut(data,clock,LSBFIRST,sekunden>>40);
31
shiftOut(data,clock,LSBFIRST,sekunden>>32);
32
shiftOut(data,clock,LSBFIRST,sekunden>>24);
33
shiftOut(data,clock,LSBFIRST,sekunden>>16);
34
shiftOut(data,clock,LSBFIRST,sekunden>>8);
35
shiftOut(data,clock,LSBFIRST,sekunden);
36
digitalWrite(latch,HIGH);
37
38
temp=temp+1;
39
40
41
sekunden=(sekunden<<1)+1;
42
delay(1000);
43
44
if(temp>61)
45
{
46
temp=0;
47
sekunden=0;
48
}
49
}
Nun zu meinem Problem:
Das Programm läuft bis zur 32. Sekunde klappt alles, es wird im
Sekundentakt eine LED hinzu geschaltet. Aber ab der 33. Sekunde macht
die Uhr nicht mehr das was sie soll. Das liegt vermutlich am Typ der
Variable Sekunden, da long max. 2^32 schafft. (hab die Variable im
Monitor angezeigt ab der 33 Sekunde ist der Wert -1)
Meine Frage ist jetzt kennt jemand ne Alternative?? Oder habe ich was
Übersehen?
Da alle Schieberegister mit dem gleichen LATCH und CLOCK arbeiten wird
ein Aufteilen in 2*4 Register auch schwer.
Danke für eure Hilfe
Florian Beckmann schrieb:> delay(1000);
Vorneweg: das ist keine Uhr, sondern ein ganz ganz grobes Schätzeisen...
> da long max. 2^32 schafft.
2^32 in Sekunden reicht locker bis an dein Lebensende und darüber
hinaus. Aber du willst den long als 32 Bit breites Schieberegister
verwenden, da ist bedeutend früher Schluss.
> Meine Frage ist jetzt kennt jemand ne Alternative??
Ja, du kannst deine Sekunden einfach zählen und die Bitmaske zur Ausgabe
an die LEDs einfach ausrechnen. Mit Divisionen und Modulo geht das
ganz einfach...
>> delay(1000);>Vorneweg: das ist keine Uhr, sondern ein ganz ganz grobes Schätzeisen...
Ohja, hab ich selbst mal unterschätzt wie groß die Abweichung sich
aufsummiert!
>if (temp > 61)
Da muss man zurück in die erste Klasse und nochmal Uhrzeit lesen üben!
Nimm eine RTC (oft intern), sonst wird das nichts.
Ich habe versucht die Abweichung des Quarzes über Software fix zu
kompensieren. Bei drei Aufbauten waren die Abweichungen jeweils
verschieden.
Kleiner Hinweis: das sind keine fertigen Kopiervorlagen, sondern nur
Denkanstöße. Und das mit dem delay(1000) ist immer noch Murks. Du hast
doch millis(). Mit ein wenig Nachdenken lässt sich damit eine ganggenaue
Uhr basteln...
Extrem einfach wäre es, wenn du nicht eine byteweise shiftOut() Funktion
verwenden würdest, sondern die Pins selber ansteuerst:
1
unsignedcharsekunden,i;
2
3
digitalWrite(latch,LOW);
4
for(i=0;i<60;i++){
5
if(i<sekunden)digitalWrite(data,HIGH);// die nötigen LEDs anschalten
6
elsedigitalWrite(data,LOW);// die anderen ausschalten
Peter Dannegger schrieb:> Noch etwas einfacher:
Hatte ich auch schon, finde aber die Default-Einstellung "LED an" mit
einmaliger Umschaltung auf "LED aus" für Anfänger schlechter
verständlich. Immerhin ist schon die "Nichtverwendung" der shiftOut()
Funktion sicher eine mentale Herausforderung... ;-)
So danke für guten Beiträge.
Habe das Problem jetzt lösen können.
Hab einfach die variable sekunden als long long definiert. So habe ich
64 Bit zur Verfügung.
Florian Beckmann schrieb:> Habe das Problem jetzt lösen können.
"Hingewurschtelt" würde ich das nennen.
Du hast ein wahnsinniges Glück, dass die Minute nur 60s hat.
Lothar Miller schrieb:> Florian Beckmann schrieb:>> delay(1000);> Vorneweg: das ist keine Uhr, sondern ein ganz ganz grobes Schätzeisen...
Bei Arduino habe ich alle Beispiele so gelöst gesehen, hab mich schon
gewundert, aber bei denen kam es auch nicht so drauf an.
Gibt es denn eine einfache Möglichkeit, dies genau zu lösen? Interrupt?
Kenne C fast nicht und kann höchstens ein paar Anpassungen machen.
Gruss Chregu