Forum: Mikrocontroller und Digitale Elektronik Kann man das besser schreiben?


von Nils W. (darky9312)


Angehängte Dateien:

Lesenswert?

Hallo erstmal
Ich bastel im Moment an einem Board mit 32 einzeln ansteuerbaren Leds 
und einem DIsplay mit Laufschrift.Die Leds werden über 2 Multiplexer 
(4067) angesteuert. Beim letzten Mal hatte ich das Problem, dass mein 
Programm nicht richtig auf die Tasterdrücke reagiert hat, wonach wir zu 
dem Schluss gekommen sidn, dass ich erstmal ein übersichtliches Programm 
schreiben sol ;) (Bin noch C Anfänger) Dabei habe ich mir auch direkt 
ein schöneres Konzept ausgedacht um die Leds anzusprechen. Ursprünglich 
wurde einfach eine Variable genommen ud diese dann +1 oder +2 oder so 
genommen und das dann soundsooft udnd as dann einfach an den Port für 
die Leds ausgegeben. Nun ahbe ich mir gedacht, ich speicher einfach den 
"Code" für jede Led ab und gebe dann nacheinander alle aus. Dadurch kan 
man viel schönere Muster machen. das Problem ist nun, das diese Methode 
ziemlich speicheraufwändig ist udn ich das ganze mit ne AtMega8 mache^^. 
Nun meine Frage: Hat Jemand einen Vorschlag, wie man das ganze nun so 
realisieren könnte, sodass ähnlich wie ich das vorhatte Muster erzeugt 
werden können aber weniger Speicher verbraucht wird? Das Beispielmuster 
lässt alle Leds gleicheitig leuchte und dann geht eine nach der anderen 
aus und bleibt aus. Dieses Muster verbraucht allerdings schon 70% meines 
Programspeichers (laut AvrSTudio) Aber eigentlch sollte das Programm 
noch so weitergehen, dass eine anch der anderen wieder angeht.
Bitte helft mir :)

von Nils W. (darky9312)


Lesenswert?

Hat keiner eine Idee??

von Dummy (Gast)


Lesenswert?

Nils Wiechert schrieb:
> Hat keiner eine Idee??

Hinweis: Reihen und Folgen.

von Dirk (Gast)


Lesenswert?

Speichere die Abfolge der LEDs in einem Array ab. Dann holst Du Dir in 
einer Schleife die Werte nacheinander aus dem Array und weist sie in 
jedem Schritt Led_Port zu.

von Nils W. (darky9312)


Lesenswert?

@ Dummy:
Hinweis leider nicht verstanden :)
@ Dirk:
werde ich mal versuchen. Danke
Melde mich wieder
Liebe Grüße
Nils

von Dummy (Gast)


Lesenswert?

Nils Wiechert schrieb:
> Hinweis leider nicht verstanden :)

Was hast Du nicht verstanden?

http://de.wikipedia.org/wiki/Folge_%28Mathematik%29#Bildungsgesetz_einer_Folge

von Nils W. (darky9312)


Lesenswert?

@ Dummy
Hm das gucke ich mir morgen nochmal an dafür ist es jetzt zu spät :D

von Nils W. (darky9312)


Lesenswert?

Wenn ich jetzt ein array mit
1
char Muster1 [32];
mache dann kostet das doch wieder genausoviel SPeicher oder? Gibt es 
"binäre" arrays?

von Floh (Gast)


Lesenswert?

Nils Wiechert schrieb:
> Gibt es
> "binäre" arrays?

ja, z.B ein Byte für 8 Bits :-)

von Nils W. (darky9312)


Lesenswert?

Ich Idiot :D
Alles klar danke ^^

von Dummy (Gast)


Lesenswert?

Mal so als kleine Hinführung auf meinen Hinweis mit den Folgen:

Schau Dir mal Deine Sequenz
1
char Led1  =  (0b00100000);
2
char Led2  =  (0b00100001);
3
char Led3  =  (0b00100010);
4
char Led4  =  (0b00100011);
5
char Led5  =  (0b00100100);
6
char Led6  =  (0b00100101);
7
char Led7  =  (0b00100110);
8
char Led8  =  (0b00100111);
9
char Led9  =  (0b00101000);
10
char Led10  =  (0b00101001);
11
char Led11  =  (0b00101010);
12
char Led12  =  (0b00101011);
13
char Led13  =  (0b00101100);
14
char Led14  =  (0b00101101);
15
char Led15  =  (0b00101110);
16
char Led16  =  (0b00101111);
17
char Led17  =  (0b00010000);
18
char Led18  =  (0b00010001);
19
char Led19  =  (0b00010010);
20
char Led20  =  (0b00010011);
21
char Led21  =  (0b00010100);
22
char Led22  =  (0b00010101);
23
char Led23  =  (0b00010110);
24
char Led24  =  (0b00010111);
25
char Led25  =  (0b00011000);
26
char Led26  =  (0b00011001);
27
char Led27  =  (0b00011010);
28
char Led28  =  (0b00011011);
29
char Led29  =  (0b00011100);
30
char Led30  =  (0b00011101);
31
char Led31  =  (0b00011110);
32
char Led32  =  (0b00011111);

Du wirst mir sicher zustimmen, dass man aus der LED-Zahl 1 - 32 den 
links stehenden Wert berechnen kann. Das vereinfacht eine Menge, 
jedenfalls aber das schreiben von Code.

Sei n die Led-Nummer, so ergibt sich der links stehende Wert, nennen wir 
ihn k gemäß folgenden Ausdrücken:
1
if (n < 17) k = 32 + n - 1; else k = n - 1;
Grundsätzlich muss n dabei zwischen einschliesslich 0 und 32 liegen.

Das ganze immer wieder neu zu schreiben

LED1 ...
LED2 ...
LED3 ...
...

kannst Du Dir also sparen.

Genauso bei Deiner ursprünglichen Fragestellung:
Versuche herauszufinden, ob die Abfolge, die Du erreichen willst einer 
Regel gehorcht, die Du als mathematische Formel ausdrücken kannst. Evtl. 
mache Fallunterscheidungen.

von Nils W. (darky9312)


Lesenswert?

Danke für deine Antwort dummy.
Aber ich bin anscheinend zu doof dafür... will auch nicht dass mir 
irgendeiner das ganze vorkaut^^ dabei verliere ich dann auch den spaß. 
Ich denke mal dass du meinst dass man den rechten Wert berechnen kann. 
Wie die If-Abfrage funktioniert ist mir auch klar aber wie sie die Chars 
beschreiben soll verstehe ich nicht. Entweder ist es echt zu Spät oder 
ich bin echt zu doof...

von DrD (Gast)


Lesenswert?

Guck dir doch mal 
http://oldwiki.blinkenarea.org/bin/view/Blinkenarea/BlinkenLEDs an. 
Evtl. findest du dort etwas. Was ich aber gerade sehe, du solltest dir 
doch noch mal ein paar Tutorials antun, z.B. über Bitmanipulation oder 
das AVR GCC Tutorial.
Eine kleine Hilfe:
Du nimmst ein 32Bit-Array, das deine Sequenz enthält und noch ein paar 
Steuerinformationen. Um es einfach zu halten, enthält Index 0 die Anzahl 
der einzelnen Schritte deiner Sequenz und Index 1 die 
Laufgeschwindigkeit (hier x * 10ms), danach  sind die einzelnen Schritte 
deiner Sequenz gespeichert.
Deine Countdownsequenz würde z.B. so aussehen:
Guck dir doch mal 
http://oldwiki.blinkenarea.org/bin/view/Blinkenarea/BlinkenLEDs an. 
Evtl. findest du dort etwas. Was ich aber gerade sehe, du solltest dir 
doch noch mal ein paar Tutorials antun, z.B. über Bitmanipulation oder 
das AVR GCC Tutorial.
Eine kleine Hilfe:
Du nimmst ein 32Bit-Array, das deine Sequenz enthält und noch ein paar 
Steuerinformationen. Um es einfach zu halten, enthält Index 0 die Anzahl 
der einzelnen Schritte deiner Sequenz und Index 1 die 
Laufgeschwindigkeit, danach  sind die einzelnen Schritte deiner Sequenz 
gespeichert.
Deine Countdownsequenz würde z.B. so aussehen:
1
unsigned char sequenz[34]={32, 1000,
2
0b11111111111111111111111111111111,
3
0b11111111111111111111111111111110,
4
0b11111111111111111111111111111100,
5
0b11111111111111111111111111111000,
6
0b11111111111111111111111111110000,
7
0b11111111111111111111111111100000,
8
usw.
9
}
Der Programmteil würde ungefähr so aussehen:
1
for (k=2;k<sequenz[0]+2;k++){
2
  for (delay=0;delay<sequenz[2];delay++){
3
    for (i=0;i<32;i++){
4
      if (sequenz[k]&(1<i)) Led_Port=Led[i]
5
      delay_us(10)
6
    }
7
  }
8
}
Die delay-Schleife musst du für deine CPU-Frequenz und 
Schritgeschwindigkeit anpassen. Ausserdem sollte die Led-Definition in 
ein Array.
dies ist kein getesteter Code, sondern nur eine schnelle und grobe 
Vorstellung, wie es gehen könnte.

von Dummy (Gast)


Lesenswert?

OK. Noch ein Beispiel. Deine Funktion led_minuseins ist geradezu ein 
Paradebeispiel.
Du iterierst immer wieder...
1
int umrechnung (int n) {
2
  if (n < 17)
3
    return (32 + n - 1);
4
  else
5
    return(n - 1);
6
}
7
8
//  Alle sind an udn eine anch der anderen geht aus
9
void led_minuseins (void)
10
{
11
  int n;
12
  for (char k = 0; k<200;k++) {
13
    for (n = 1; n <=32; n++) {
14
      Led_Port = umrechnung (n);
15
      _delay_us (10);
16
    }
17
  }
18
  for (char k = 0; k<200;k++){
19
    for (n = 2; n <=32; n++) {
20
      Led_Port = umrechnung (n);
21
      _delay_us (10);
22
    }
23
  }
24
  for (char k = 0; k<200;k++){
25
    for (n = 3; n <=32; n++) {
26
      Led_Port = umrechnung (n);
27
      _delay_us (10);
28
    }
29
  }
30
31
  for (char k = 0; k<200;k++){
32
    for (n = 4; n <=32; n++) {
33
      Led_Port = umrechnung (n);
34
      _delay_us (10);
35
    }
36
37
  }
38
  // uswusf.
39
  for (char k = 0; k<200;k++){
40
    Led_Port = Led32;
41
    _delay_us (320);
42
  }
43
}
Schon sehr viel kürzer, oder?

Aber fällt Dir was auf?
Der Start-Index der inneren Schleife folgt wiederrum einer Regel. Er 
läuft von 1 bis 32.
Also noch eine Möglichkeit zur Vereinfachung.
1
void led_minuseins (void)
2
{
3
  int n;
4
  int l;
5
  for (l = 1; l <= 32; l++) {
6
    for (char k = 0; k<200;k++) {
7
      for (n = l; n <=32; n++) {
8
        Led_Port = umrechnung (n);
9
        _delay_us (10);
10
      }
11
    }
12
  }
13
}

Aber schreib bitte nicht, das sei genial.
Das ist so ziemlich das simpelste Beispiel dafür warum programmierbare 
Rechner überhaupt einen Sinn machen.

von DrD (Gast)


Lesenswert?

@ Dummy:
müsste es nicht
1
if (n < 17) k = 32 + n - 1; else k = 16 + n - 1;
heißen?
Wenn die Verdrahtung so bleibt, ist es ja ok. Falls die sich ändern 
sollte, ist eine explizite Definition doch besser, oder?

von Dummy (Gast)


Lesenswert?

DrD schrieb:
> @ Dummy:
> müsste es nichtif (n < 17) k = 32 + n - 1; else k = 16 + n - 1;
> heißen?

Das kannst Du Dir selbst ausrechnen. Was kommt raus wenn n = 32 ist und 
was soll heraus kommen?

DrD schrieb:
> Wenn die Verdrahtung so bleibt, ist es ja ok. Falls die sich ändern
> sollte, ist eine explizite Definition doch besser, oder?

Das kommt darauf an...

An sich macht es keinen Sinn die Verdrahtung immer wieder zu ändern.
Aber wenn, dann würde ich eher eine Zwischenschicht (z.B. ein Makro) 
einführen, die es erlaubt die physischen LED-Positionen als Binaerzahl 
so zu interpretieren, das die am meisten rechte den niedrigsten und jede 
links folgende einen jeweils um den Faktor 2 höheren Stellenwert hat.
Andernfalls wäre es sicherlich unübersichtlicher eine Musterfolge in 
eine mathematische Formel umzusetzen.

von Dummy (Gast)


Lesenswert?

Übrigens, wie Karl-Heinz B. immer wieder und mit einer gewissen 
Berechtigung anmerkt, ist es übel für eine Variable die nur als Zahl 
interpretiert wird den Typ char zu verwenden. Nimm int. Das ist ein 
Zahlenwert. char nimmt man für Zeichen.

von Floh (Gast)


Lesenswert?

Dummy schrieb:
> Nimm int. Das ist ein
> Zahlenwert. char nimmt man für Zeichen.

Am besten sogar noch die inttypes:
uint8_t , uint16_t ...
Da weis jeder mit/ohne Vorzeichen und die gewollte Datenbreite.

von DrD (Gast)


Lesenswert?

Hast recht. Da habe ich nicht lange genug draufgesehen.

von DrD (Gast)


Lesenswert?

unsigned char geht natürlich auch nicht für 32bit-Zahlen.

von test (Gast)


Lesenswert?

und noch so ein "char-Fall":

>  for (char k = 0; k<200;k++) {

Wenn der jemals wieder als der Schleife rauskommt, dann würde mich das 
wundern.

von Peter D. (peda)


Lesenswert?

Nils Wiechert schrieb:
> Dieses Muster verbraucht allerdings schon 70% meines
> Programspeichers (laut AvrSTudio)

Ne, ne, so wird das nix.
Du must schon das Gehirn einschalten, denn dazu ist es ja da und das ist 
es auch, was am Programmieren Spaß macht.

Schalte den PC aus, nimm Papier und Stift und beschreibe in Worten in 
welcher Folge die LEDs schalten sollen.
Und danach kannst Du dann daraus eine Regel ableiten und diese Regel in 
Programmcode umsetzen.

Eine Regel kann leicht 1000 Zustände beschreiben.
Was ist wohl einfacher:
Eine Regel hinzuschreiben und die 1000-mal durchlaufen zu lassen oder 
ganz stumpfsinnig 1000 Zustände hintereinander zu klatschen?


Falls man aber wirklich völlig ungeordnete Zustände ausgeben will, kann 
man ne Tabelle nehmen oder ne Pseudozufallsfunktion.


Peter

von Dummy (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Und danach kannst Du dann daraus eine Regel ableiten und diese Regel in
> Programmcode umsetzen.

Also weisst Du, Du hast ja ne Menge Ahnung und so aber kannst Du bitte 
höflicherweise die Threads mal vollständig lesen ehe Du Tips gibst die 
hier schon lang und breit mit Beispiel genannt worden sind? Das wäre 
nett.
Das Verhalten ist mir bei Dir schon öfter aufgefallen.
Ist ja nicht wirklich übel gemeint von mir, aber es nervt allmählich.

von Simon K. (simon) Benutzerseite


Lesenswert?

Dummy schrieb:
> Peter Dannegger schrieb:
>> Und danach kannst Du dann daraus eine Regel ableiten und diese Regel in
>> Programmcode umsetzen.
>
> Also weisst Du, Du hast ja ne Menge Ahnung und so aber kannst Du bitte
> höflicherweise die Threads mal vollständig lesen ehe Du Tips gibst die
> hier schon lang und breit mit Beispiel genannt worden sind? Das wäre
> nett.
> Das Verhalten ist mir bei Dir schon öfter aufgefallen.
> Ist ja nicht wirklich übel gemeint von mir, aber es nervt allmählich.

Freu dich doch bitte überhaupt, dass jemand wie Peter hier antwortet. 
Auch wenn es möglicherweise nichts neues bringt.

von Peter D. (peda)


Lesenswert?

Dummy schrieb:
> Ist ja nicht wirklich übel gemeint von mir, aber es nervt allmählich.

Ist ja auch nicht für Dich gedacht, der die richtige Vorgehensweise 
schon kennt.

Der Mensch ist ja keine Maschine.
Daher ist es durchaus nicht vergebens, etwas mehrmals zu sagen und auch 
in etwas abgewandelter Form. Dadurch prägt es sich leichter ein.

Ansonsten wären ja Seminare völlig nutzlos, in denen der Stoff der 
Vorlesung vertieft wird.


Peter

von Nils W. (darky9312)


Lesenswert?

Probiere grade die Varianten von DRD umzuetzten weil die von Dummy zwar 
auch sehr schön ist, aber mehr Speicher braucht.
Ich habe den Code etwas umegwandelt, damit er auch funktioniert, anaj 
tut er eigentlich nicht aber egal... Auf jedenfall sieht r jezt so aus:
1
void led_minuseins (void)
2
{
3
  int k;
4
  int i;
5
  int delay;
6
  for (k=2;k<sequenz[0]+2;k++){
7
    //for (delay=0;delay<sequenz[2];delay++){
8
      for (i=0;i<32;i++){
9
        if (sequenz[k]&(1<i)){
10
        Led_Port=Led[i];
11
      }
12
        _delay_us(10);
13
      }
14
    //}
15
  }
16
}

Die Speicherung des Muster folgendermaßen :
1
uint32_t sequenz[34]={32, 1000,
2
0b11111111111111111111111111111111,
3
0b11111111111111111111111111111110,
4
0b11111111111111111111111111111100,
5
0b11111111111111111111111111111000,
6
0b11111111111111111111111111110000,
7
0b11111111111111111111111111100000,
8
0b11111111111111111111111111000000,
9
0b11111111111111111111111110000000,
10
0b11111111111111111111111100000000,
11
0b11111111111111111111111000000000,
12
0b11111111111111111111110000000000,
13
0b11111111111111111111100000000000,
14
0b11111111111111111111000000000000,
15
0b11111111111111111110000000000000,
16
0b11111111111111111100000000000000,
17
0b11111111111111111000000000000000,
18
0b11111111111111110000000000000000,
19
0b11111111111111100000000000000000,
20
0b11111111111111000000000000000000,
21
0b11111111111110000000000000000000,
22
0b11111111111100000000000000000000,
23
0b11111111111000000000000000000000,
24
0b11111111110000000000000000000000,
25
0b11111111100000000000000000000000,
26
0b11111111000000000000000000000000,
27
0b11111110000000000000000000000000,
28
0b11111100000000000000000000000000,
29
0b11111000000000000000000000000000,
30
0b11110000000000000000000000000000,
31
0b11100000000000000000000000000000,
32
0b11000000000000000000000000000000,
33
0b10000000000000000000000000000000,
34
};
Aber das Schreiben des Ledarrays habe ich so gemacht wie Dummy es 
vorgeschlagen hat (mit ner Funktion). Das funktioniert auch (dank Hilfe 
meines Bruders).
Mein Problem ist nun, dass beim Ausgeben des Arrays auf die Leds ja 
eigentlich ein Bit nach dem anderen abgefragt werden sollte. Aber 
stattdessen leuchtet die vorletzte Led hell und die erste und die letzte 
Led garnicht. Die anderen leuchten so dunkel, dass man es kaum sieht 
aber das liegt daran, dass ich die Delay Schleife zu Testzwecken 
rausgenommen habe. Weiß einer warum das nicht funktioniert?
Danke schonmal für eure bisherige Hilfe :)
Liebe Grüße
Nils

von Dummy (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Der Mensch ist ja keine Maschine.
> Daher ist es durchaus nicht vergebens, etwas mehrmals zu sagen und auch
> in etwas abgewandelter Form. Dadurch prägt es sich leichter ein.

Hmm. Naja. Auch ein Gesichtspunkt. Ist anscheinend auch nötig. Angenehm, 
das Du so cool auf mein Posting reagiert hast.

Nils Wiechert schrieb:
> Probiere grade die Varianten von DRD umzuetzten weil die von Dummy zwar
> auch sehr schön ist, aber mehr Speicher braucht.

Was vergleichst Du denn da? Meine Version braucht für das Muster 0 Bytes 
Speicher (abgesehn von den Laufindizes) und die von DrD braucht 33 * 32 
Bit = 132 Bytes.

Das Muster, das Du im letzten Post geschrieben hast, ist auch wieder 
regelmäßig. Es läuft von 0xFFFFFFFF bis 0x80000000

von DrD (Gast)


Lesenswert?

Poste mal deinen ganzen Code.
Dummy hat dir den Weg erklärt, die Sequenzen zu programmieren, ich habe 
den Vorschlag gemacht, die Sequenzen zu speichern und einfach 
auszugeben. Sequenzen als Bitfolgen zu speichern benötigt mehr Speicher, 
als die Algorithmen der Sequenz zu programmieren.
1. Möglichkeit benötigt weniger Speicher
2. Möglichkeit ist einfacher umzusetzen bezüglich verschiedener 
Sequenzen, da diese nicht als Algorithmus beschrieben werden müssen, 
sondern nur als Ablauf
Welchen Weg man nimmt, ist Geschmackssache.

von Nils W. (darky9312)


Lesenswert?

Ich poste morgen mal meinen ganzen Code bin grade bei nem Kollegen...
Melde mich also morgen nochmal...
Bis dann
Liebe Grüße
Nils

von Nils W. (darky9312)


Angehängte Dateien:

Lesenswert?

So hier nochmal der ganze Code.

von Lukas K. (carrotindustries)


Lesenswert?

Nils Wiechert schrieb:
> Probiere grade die Varianten von DRD umzuetzten weil die von Dummy zwar
> auch sehr schön ist, aber mehr Speicher braucht.
> Ich habe den Code etwas umegwandelt, damit er auch funktioniert, anaj
> tut er eigentlich nicht aber egal... Auf jedenfall sieht r jezt so aus:
> ....
Die Tabelle kannst du dir sparen.
Du fängst mit 0xffffffff an und für jeden Schritt wird um 1 nach links 
geschoben, sowie das letzte bit gelöscht.

von Nils W. (darky9312)


Lesenswert?

Das stimmt zwar, allerdings würde ic gerneauch das Muster so 
abspeichern, der Vollständigkeit halber, da ja später noch andere Muster 
dazukommen.

von Floh (Gast)


Lesenswert?

Nils Wiechert schrieb:
> Das stimmt zwar, allerdings würde ic gerneauch das Muster so
> abspeichern, der Vollständigkeit halber, da ja später noch andere Muster
> dazukommen.

Ich würd pro Musterablauf ne Funktion machen, damit die Schnittstelle 
einheitlich ist.
Je nach Muster kann die Funktion ja dann rechnen oder in einer Tabelle 
nachschlagen.

von Nils W. (darky9312)


Lesenswert?

Wäre auch eine Idee.

von Nils W. (darky9312)


Lesenswert?

Aber das ist ja im Moment garicht mehr das Problem. Mein Problem ist, 
dass die FUnktion, welche das Array auslesen soll nicht das macht was 
sie soll und ich nicht weiß warum^^

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Das stimmt zwar, allerdings würde ic gerneauch das Muster so
> abspeichern, der Vollständigkeit halber, da ja später noch andere Muster
> dazukommen.

Du sagst es: später.
Ich würde vorschlagen, du konzentrierst dich erst mal auf einfache Dinge 
und siehst zu, dass du die beherrscht und verstehst.

Auch wenn hier im Forum gerne in die Richtung 'allgemeine Lösungen' 
gegangen wird: Für einen Einsteiger ist das oftmals tödlich, wenn man in 
zu früh in Richtung total allgemeine Lösungen drängt. Dazu muss man 
schon über relativ viel Grundlagenwissen verfügen und auch verstehen, 
welche Techniken bei allgemeinen Lösungen angebracht sind.

Solange es dir Schwierigkeiten macht, aus einer Aufzählung von 
angestrebten Zuständen, deren Bitmuster sich relativ trivial in Form von 
Formeln und Regeln beschreiben lässt, ebendiese Regel und Formeln zu 
sehen und zu programmieren, solltest du da mehr Aufwand reinstecken.

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Aber das ist ja im Moment garicht mehr das Problem. Mein Problem ist,
> dass die FUnktion, welche das Array auslesen soll nicht das macht was
> sie soll und ich nicht weiß warum^^

Anstatt da jetzt großartig zu künsteln, mach eine gaaaaanz einfache 
Tabellenabarbeitung.

von Floh (Gast)


Lesenswert?

Nils Wiechert schrieb:
> void led_minuseins (void)
> {
>   int k;
>   int i;
>   int delay;
>   for (k=2;k<sequenz[0]+2;k++){
>     //for (delay=0;delay<sequenz[2];delay++){
>       for (i=0;i<32;i++){
>         if (sequenz[k]&(1<i)){
>         Led_Port=Led[i];
>       }
>         _delay_us(10);
>       }
>     //}
>   }
> }

Meinst du das?
Würd ich eher in der Richtung schreiben (nur als Vorgehensweise):

uint32_t  temp = sequenz[4];  //als Beispiel einlesen
PORTA = (temp & 0xFF);
PORTB = (temp>>8) & 0xFF);
PORTC = (temp>>16) & 0xFF);
PORTD = (temp>>24) & 0xFF);

so setzt du alle LEDs entsprechend der Bitstellen, vorausgesetzt sie 
sind an PORTA,B,C,D angeschlossen.
Kannst ja mal deine Pinbelegung erwähnen :-)

von Nils W. (darky9312)


Lesenswert?

Karl heinz Buchegger schrieb:
>Solange es dir Schwierigkeiten macht, aus einer Aufzählung von
>angestrebten Zuständen, deren Bitmuster sich relativ trivial in Form von
>Formeln und Regeln beschreiben lässt, ebendiese Regel und Formeln zu
>sehen und zu programmieren, solltest du da mehr Aufwand reinstecken.

Das sehe ich ein :)

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:
> Nils Wiechert schrieb:
>> Aber das ist ja im Moment garicht mehr das Problem. Mein Problem ist,
>> dass die FUnktion, welche das Array auslesen soll nicht das macht was
>> sie soll und ich nicht weiß warum^^
>
> Anstatt da jetzt großartig zu künsteln, mach eine gaaaaanz einfache
> Tabellenabarbeitung.

Du hast eine Tabelle
Led, die 34 Elemente umfasst.

Element 0 und Element 1 lässt du für erste links liegen, und die 
restlichen Elemente 2 bis 31 gibst du der Reihe nach aus. Jeweils eine 
Wartezeit dazwischen.
1
void led_minuseins (void)
2
{
3
  int k;
4
  int i;
5
  int delay;
6
  for (k=2;k<sequenz[0]+2;k++){
7
    //for (delay=0;delay<sequenz[2];delay++){
8
      for (i=0;i<32;i++){
9
        if (sequenz[k]&(1<i)){
10
        Led_Port=Led[i];
11
      }
12
        _delay_us(10);
13
      }
14
    //}
15
  }
16
}
Das muss dir doch selbst auffallen, dass das für die beschriebene 
Funktionalität viel zu kompliziert ist. Da gibt es ein k, ein i, ein 
sequenz und ein Led
Was machen diese Variablen alle?

Schmeiss das wegt und schreibs neu. Aber diesmal nicht einfach nur 
abschreiben, sondern selber überlegen.

Und nenn die Funktion nicht "led_minuseins", denn das tut sie nicht. Die 
Funktion gibt einfach nur eine Tabelle an einen Port aus. Mehr tut sie 
nicht (und soll sie auch nicht tun).

von Nils W. (darky9312)


Lesenswert?

Wie schon am Anfang vom Thread erwähn, liegen die Leds an 2 16er 
Multiplexern, sonst wäre das alles kein Problem :D. Sind an PortD die 
Datenleitungen sind die gleichen. "Ausgewählt" wird über die Inhibit 
Eingänge der Multiplexer.

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Wie schon am Anfang vom Thread erwähn, liegen die Leds an 2 16er
> Multiplexern, sonst wäre das alles kein Problem :D.

2 Dinge
a) wie ist der verschaltet
b) was um alles in der Welt hat dich geritten, gleich mit
   Multilexern anzufangen.

Mit gemultiplexten LED muss man völlig anders arbeiten. Und nachdem was 
ich bisher von dir an Code gesehen habe, fehlen dir da massive 
Grundlagen.

von Nils W. (darky9312)


Angehängte Dateien:

Lesenswert?

DAs ist der Schaltplan. AUf die Idee mit den Multiplexern hat mich ein 
Freund gebracht... Dann habe ich mir die DInegr mal egnauer angegckt u 
habs auch für eine gute Idee gehalten. Wie viel zu hoch ist das denn für 
den Anfang?

von Nils W. (darky9312)


Lesenswert?

naja multiplexen würde ich as was ich da gemacht habe nicht nennen :D

von Karl H. (kbuchegg)


Lesenswert?

Das ganze Aufbau ist Schwachsinn.
Wozu soll das gut sein einen Analog-Multiplexer/Demultiplexer zu nehmen 
um 16 LED anzusteuern?

von Nils W. (darky9312)


Lesenswert?

der kann sowohl analog als auch digital. Kommt auf die Betriebsspannung 
an. Mir wurde der so verkauft, dass ich dann mit einem IC 16 Leds 
ansteuern kann. mir ist schon klar, dass richtiges Multiplexen anders 
geht aber so war es... "einfacher"

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> der kann sowohl analog als auch digital. Kommt auf die Betriebsspannung
> an. Mir wurde der so verkauft, dass ich dann mit einem IC 16 Leds
> ansteuern kann. mir ist schon klar, dass richtiges Multiplexen anders
> geht aber so war es... "einfacher"


Der IC ist unsinnig für den Job.

Mit einem stink normalen 595 Schieberegister wärst du besser bedient 
gewesen. Bzw. wenn schon multiplexen, dann richtig: Aufbau als Matrix 
mit einem Spaltentreiber und einem Zeilentreiber

von Nils W. (darky9312)


Lesenswert?

Das is ja ach der Grund warum ich das Array nun Bitweise abfragen muss. 
um dann zu sehen ob an der stelle ne 1 oder eine 0 steht und dann 
entweder die Led die der stelle im Array entspricht ansteuert oder 
nicht.

von Karl H. (kbuchegg)


Lesenswert?

Ich weiß jetzt nicht recht, was ich dir raten soll.

* Dein Hardwareaufbau ist nicht besonders glücklich
* Du stehst mit Bitoperatioenn auf Kriegsfuss
* Um sinnvoll Multiplexen zu können, müsstest du eigentlich mit
  Timern auf Du-und-du stehen

Da sind so viele Detailprobleme und du hast dich leichtsinnig in einen 
Mehrfrontenkrieg eingelassen, das es nicht einfach ist, da jetzt eine 
sinnvolle Schritt-für-Schritt Strategie für die weitere Vorgehensweise 
vorzuschlagen.

Natürlich kann 'man' mit diesem Aufbau 32 LED betreiben. Aber dazu muss 
'man' schon über ein nicht unbeträchtliches Grundwissen verfügen. Und 
dein Eröffnungsposting zeigt mir, dass du das nicht hast.

von Nils W. (darky9312)


Lesenswert?

Scheiße :D (Tschuldigung).
Das sieht so aus als wäre es für mich undmöglich as ganze bis samstag 
fertigzubekommen... Naja danke für eure Hilfe :)

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Scheiße :D (Tschuldigung).
> Das sieht so aus als wäre es für mich undmöglich as ganze bis samstag
> fertigzubekommen...

Das kommt drauf an, was es werden soll.

Wenn es nur darum geht, einzelne LED nacheinander tabellengesteuert 
ein/aus zu schalten, wobei jede LED eine bestimmte Zeitdauer brennen 
soll, dann ist das relativ simpel möglich.

Wenn du aber mehrere LED "gleichzeitig" brennen haben musst, dann führt 
kein Weg an einem "aufwändigem" Multiplexen vorbei. Wobei ... ein 1:32 
Multiplex ... das könnte haarig werden.

von Nils W. (darky9312)


Lesenswert?

Bisher bei TEsts bin ich für mehrere Leds gleichzeitig einfach 
hingegangen und habe alle möglichen pausen rausgenommen. Dann ging das 
schnell genug um das einzene leuchten nicht sehen zu können. Wäre 
soetwas ähnliches nicht auch mit der Arraymethode möglich?

von Lukas K. (carrotindustries)


Lesenswert?

>
1
        if (sequenz[k]&(1<i)){
müsst das nich 1<<i heißen?

von Nils W. (darky9312)


Lesenswert?

bin sofort wieder da muss nur mal eben mit den Hunden gassi gehen

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Bisher bei TEsts bin ich für mehrere Leds gleichzeitig einfach
> hingegangen und habe alle möglichen pausen rausgenommen. Dann ging das
> schnell genug um das einzene leuchten nicht sehen zu können. Wäre
> soetwas ähnliches nicht auch mit der Arraymethode möglich?


Bis zu einem gewissen Grad ja. Wird aber kompliziert.

von Grrrr (Gast)


Lesenswert?

Ob Du die Arraymethode anwendest oder die Formelmethode ist nicht Dein 
eigentliches Problem. Vielmehr die Kontrolle des Zeitablaufs, die ohne 
Hilfe von Timern (das solltest Du Dir bis nächsten Samstag nicht 
versuchen anzutun) um einiges komplexer wird.

Zunächst wäre es gut, wenn Du Dir das Ganze anhand eines Ablaufdiagramms 
(Flussdiagramms) klarmachst. Ich meine nicht so sehr das Du eine 
bestimmte formale Form einhalten sollst, sondern Dir klarmachst, welche 
Operationen in welcher Reihenfolge ablaufen, wo die Wiederholpunkte sind 
und wo genau die Delays zum tragen kommen und wie die Kombination aus 
dem Delay für das Multiplexen und dem Delay für den visuellen Ablauf 
zusammenwirkt. Die Auswahl der konkreten LEDs aus dem Muster ist dabei 
nebensächlich und kann erstmal nur durch einen groben Namen 
gekennzeichnet werden. Die Auswahl der LED für das Multiplexing aus dem 
jeweils momentanen Muster ist wichtiger.

Dann hast Du vielleicht eine Chance, aber das wird ein hartes Stück 
Arbeit für Dich. Viel Glück.

von Nils W. (darky9312)


Lesenswert?

So wieder da. Hatte unterwegs eine Idee. Wenn ich jetzt für jedes Muster 
eine eigene FUnktion schreiben würde (ich weiß... Umständlich, könnte 
man auch mit einer machen) dann könnte ich ja bei den zusätlichen Werten 
im Array nich nur Pause abspeichern sonern auch wie oft jede einele 
Variable aus dem Arary ausgegeben werden soll oder? und das könnte cih 
ja dann ohne Pause machen und danach die Pause einfügen. Ist nur so ne 
Idee... Aber würde diese Idee funktionieren?

von Nils W. (darky9312)


Lesenswert?

@ GRRRR
danke :)

von Nils W. (darky9312)


Lesenswert?

Also ich meinte nicht eine FUnktion die das Muster beschreibt sondern 
eine Funktion Pro Array^^

von Peter D. (peda)


Lesenswert?

Das mit den Multiplexern ist ein voller Schuß ins Knie, sobald mehr als 
eine LED gleichzeitig leuchten soll.
Sollen alle leuchten, ist das ein Tastverhältnis 1/32, d.h. die glimmen 
nur noch leicht.
Multiplexen ohne Timerinterrupt ist programmtechnisch gesehen ein 
Albtraum und ergibt in der Regel ein elendes Geflackere.

Schmeiß sie runter und nimm 4 Stück 74HC595 kaskadiert, die Ansteuerung 
findest Du im Tutorial.


Peter

von Nils W. (darky9312)


Angehängte Dateien:

Lesenswert?

@ Peter : Geht leider nichtmehr... hab wohl nicht ordentlcih geplant und 
auch schon alles verlötet... s. Bild

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> @ Peter : Geht leider nichtmehr... hab wohl nicht ordentlcih geplant und
> auch schon alles verlötet... s. Bild

Ist aber deine beste Option.

Ich zermatere mir auch schon eine Weile das Hirn, wie man diesen 
verkorksten Aufbau retten könnte. Hab schon in Richtung 5-er Multiplex 
oder 8-er (also 5 aus 32, bzw 8 aus 32) gedacht. Das also nur maximal 5 
bzw. 8 LED gleichzeitig brennen können. Mit einem Timerinterrupt wäre 
das gar nicht mal so schlimm. Aufwändig ist nur der Ansteuerteil, der 
aus dem Muster die jeweiligen 5 LEd rausholt, bzw. die Beschreibung des 
Musters.

Wenn du morgen die Multiplexer gegen 595 austauschen würdest, würden 
sich eine Menge Probleme im Nichts auflösen. So wild ist dieser 
Austausch auch wieder nicht.

PS: Wieviele LED willst du den maximal gleichzeitig brennen lassen?

von Nils W. (darky9312)


Angehängte Dateien:

Lesenswert?

DOch :D ist er wohl... mach ich aber trotzdem... für die schieberegister 
brauche ich jeweils 3 Bit zum ansteuern oder? könnte knapp werden am 
atmega8... selbst wenn ich die noch mit an die Programmierschnittstelle 
dranhänge würde es leider nicht passen da ich dann doch 3*4 = 12 Pins 
brauche oder sehe ichd as falsch? ;(
aber dann muss ich auch erst zu meinem Vater oder den vorher fragen ob 
der noch 4 595 rumliegen hat. (ich hofe  mal dass die Antwort JA lautet)

von Nils W. (darky9312)


Lesenswert?

Muss zugeben es ist nicht die schönste Art der VErdrahtung aber mit 
brücken und Silberdraht gin schlecht und Hab leider keine Vorrichtung 
zum Ätzen

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> DOch :D ist er wohl... mach ich aber trotzdem... für die schieberegister
> brauche ich jeweils 3 Bit zum ansteuern oder?

Nicht jeweils.
Du benötigst genau und einmalig 3 Bit. Punkt.

von Lukas K. (carrotindustries)


Lesenswert?

Nils Wiechert schrieb:
> oder sehe ichd as falsch? ;(
Ich befürchte ja, die 74HC595 kann man Kaskadieren.
s. http://www.mikrocontroller.net/wikifiles/a/ac/Mega8-595-2.gif
und 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister
Du brauchst also nur 4 Pins.

von Nils W. (darky9312)


Lesenswert?

Ah ok dann hauts ja besser hin als mit den Multiplexern... Scheißteile

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Ah ok dann hauts ja besser hin als mit den Multiplexern... Scheißteile

Die sind ja auch für ganz andere Anwendungszwecke gedacht.

von Nils W. (darky9312)


Lesenswert?

jo^^ ICh glaueb so wie ich hat noch niemand versucht die dinger zu 
zweckentfremden. dann fahr ich morgen mal zu meinem vater und such mal 
nach ein paar 595

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> DOch :D ist er wohl...

Du musst doch nur die ganzen Drähte von den LED zu den Multiplexern 
aufmachen. Der Rest kann ja bleiben.

Du weißt aber schon, dass es für solche Sachen:
* Fädeldraht gibt
* man 'Bahnen' auch dadurch erzeugen kann, dass man mit Lötzinn
 nebeneinanderliegende Pads verbindet und so mit einer Lötzinnwurst
 eine Leiterbahn aufbaut

von Nils W. (darky9312)


Lesenswert?

von Fädeldraht hab ich noch nie gehört hört sich aber super an... wie 
geht das denn dan genau? (nur antworten wennde bock has eigentlich eghts 
hier ja um was anderes :P) und statt mit ner Lötzinnwurst hätt ich dann 
ach direkt Silberdraht nehmen können abre is ja kein Platz aufer Platine

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:

> hier ja um was anderes :P) und statt mit ner Lötzinnwurst hätt ich dann
> ach direkt Silberdraht nehmen können abre is ja kein Platz aufer Platine

Weil alles voller Drähte ist und du dir vorher nicht überlegt hast, wie 
du zumindest die IC und das LCD so anordnen könntest, dass du möglichst 
geradelinie Leitungen zum Verbinden dieser Komponenten hast, du du dann 
mit Lötzinnleitungen (oder Silberdraht wenn du schon auf Draht stehst) 
simpelst realisieren kannst.

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> von Fädeldraht hab ich noch nie gehört hört sich aber super an... wie
> geht das denn dan genau?

So sieht das dann aus
http://de.wikipedia.org/wiki/F%C3%A4deltechnik

von Nils W. (darky9312)


Lesenswert?

Stimmt... die Planung ist wirklich zu kurz gekommen^^ aber ich habds 
halt dummerweise auch zum Großteil darauf angelegt dass alles optisch 
gut aussieht

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:
> Nils Wiechert schrieb:
>> von Fädeldraht hab ich noch nie gehört hört sich aber super an... wie
>> geht das denn dan genau?
>
> So sieht das dann aus
> http://de.wikipedia.org/wiki/F%C3%A4deltechnik

Der Draht ist im Stift auf einer Spule aufgewickelt und schaut beim 
Stift unten an der Spitze raus.
Ich machs so:
Drahtende in das Loch reinstecken und ein paar mal um den IC Pin 
wickeln. Das in das Loch reinstecken hat den Grund, dass der Draht dann 
fixiert wird und ich den Draht dann auch wirklich ein paar mal rund um 
das Beinchen wickeln kann.
Dann mit dem Stift zum Zielbeinchen fahren, wobei sich der Draht 
abwickelt.
Dort wieder ein paar mal rund ums Beinchen wickeln.
Stift zur Seite legen und Lötkolben her.
Normal löten, eventuell einen kleinen Tick länger als normal, damit die 
Isolierung vom Draht auch sicher im flüssigen Lötzinn schmilzt.
An beiden Enden löten und dann noch am Ziel den Draht an der Lötstelle 
mit einem kleinen Messer direkt am Zinn abschneiden.

Und schon kann die nächste Verbindung gemacht werden.
Nachdem die gezogene Verbindung im Schaltplan abgehakt wurde, 
selbstverständlich. Tut man das nicht, verliert man bei komplexeren 
Schaltungen ganz schnell den Überblick.

Mit ein bischen Übung geht das ganz schnell.

Hab ich mich verhaut, dann wird der Draht an beiden Enden mit dem 
Messerchen abgeschnitten und wenn möglich herausgezogen. Wenn das nicht 
leicht geht, dann bleibt er eben drinnen.

von Nils W. (darky9312)


Lesenswert?

Hm das mit der Fädeltechnik sieht super asu... werd ich auch mal 
demnächst ausprobieren

von Nils W. (darky9312)


Lesenswert?

machst du das wie bei Wikipedia mit diesen Bänkchen wo der Draht dann 
zwischenliegt?

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> machst du das wie bei Wikipedia mit diesen Bänkchen wo der Draht dann
> zwischenliegt?

Bei komplexeren IC-Gräbern: ja

MIch störts, wenn die Einzeldrähte da so kreuz und quer über die ganze 
Platine laufen.
Aber eigentlich war das sogar besser, weil die Einzeldrähte dann nicht 
parallel laufen und sich gegenseitig Signale einkoppeln. Ich hatte damit 
allerdings noch nie wirkliche Probleme.

So gehts halt von jedem IC-Bein in die IC-Mitte zum Kamm und von dort 
läuft dann das Bündel vom IC weg und verteilt sich bis es beim Ziel-IC 
wieder aus dem Bündel und dem Kamm herauskommt und zum Zielbeinchen 
führt.

von Nils W. (darky9312)


Lesenswert?

Jetzt sag nur noch dass man alles entweder bei Pollin, Reichelt oder 
Cnrad bekommt dann bekommste nen Knutscher :)

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Jetzt sag nur noch dass man alles entweder bei Pollin, Reichelt oder
> Cnrad bekommt dann bekommste nen Knutscher :)

Und warum soll man das dort nicht bekommen?

von Nils W. (darky9312)


Lesenswert?

KNUTSCH^^ nein jetzt mal zuück zum ernst^^ ICh hab schon öfter erlebt 
dass Teile die ich haben wollte bei keinem vond en dreien zu besorgen 
sind

von Karl H. (kbuchegg)


Lesenswert?

http://www.conrad.de/ce/de/product/532665/DRAHTSPULEN-SET
http://www.conrad.de/ce/de/product/532630/VERDRAHTUNGS-STIFT

Bedenke aber, das C die Apotheke unter den Vermarktern ist. D.h. bei den 
anderen gibts die wahrscheinlich billiger.
Auch wenn das Zeugs (insbesondere die Stifte) unverschämt teuer sind, es 
lohnt sich.

von Nils W. (darky9312)


Lesenswert?

Karl heinz Buchegger schrieb:

> Auch wenn das Zeugs (insbesondere die Stifte) unverschämt teuer sind, es
> lohnt sich.

ja denk ich mir. Mal sehen ob ich mir so ein set noch diesen Monat oder 
erst nächsten anschaffe. Praktisch ist es ja.

von Nils W. (darky9312)


Angehängte Dateien:

Lesenswert?

SO das ist der neue Schaltplan mit den Schieberegistern. Wollte nur mal 
nachfragen ob ich das so richtig gemacht habe.

von Karl H. (kbuchegg)


Lesenswert?

SCL brauchst du nicht wirklich. Kann man auch auf fixen Pegel legen.

von Nils W. (darky9312)


Lesenswert?

SO die Ics sind bei reichelt bstellt hoffe mal die kommen schnell an. 
Das mit SCL werd ich dann noch ändern. Wenn ich das im Datenblatt 
richtig gesehen habe dann muss der auf High weil der bei Low alle 
Ausgänge auf 0 setzt richtig? Alels klar dann hoff ich mal das Reichelt 
schnell liefert und mache mich schonmal an den Umbau des Boards. Wenn 
ich auf Probleme stoße melde ich mich wieder ok? Wenn der Umbau fertig 
ist fang ich schonmal mit dem Programm an.  Wenn ich auf Probleme stoße 
melde ich mich wieder ok?
Liebe Grüße und danke für die viele bisherige Hilfe.
Nils

von eklige Tunke (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Bedenke aber, das C die Apotheke unter den Vermarktern ist. D.h. bei den
> anderen gibts die wahrscheinlich billiger.
Bei Reichelt heißen die Fädelstifte und kosten nicht den halben 
Conrad-Preis, aber fast. ;-)
Seit wann gibt es denn reicheltpedia? 
http://www.reicheltpedia.de/index.php/F%C3%A4delstift
Da ist mir ja was entgangen und das ist allemal besser als diese üblen 
eingescannten Peudo-Datenblätter von Conrad...

von Nils W. (darky9312)


Lesenswert?

Stimmt Reicheltpedia kannte ich bis du es gepostet hast auch noch 
nicht^^. ichsuche immer bei google nach datenblättern. funktioniert 
eigentlich immer ganz gut.

von Nils W. (darky9312)


Lesenswert?

So mit löten bin ich fertig. Hat deshalb so lange gedauert weil ich 
gestern meine Tablete nicht genommen hab. Habe AdHS und mich gestern 
deshalb immer wieder mit anderen Sachen abgelenkt... So ne Scheiße ich 
hassen das, aber ich schweife ab... Ich wollte mich jetzt ans 
programmieren machen. Aber ich habe immer noch nicht verstanden wie das 
mit dem bitweisen Auslesen von Arrays funktioniert. Kann mir das bitte 
nocheinmal einer erklären? habe im Forum schon danach gesucht aber 
nichts gefunden.
Liebe Grüße
Nils

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:

> programmieren machen. Aber ich habe immer noch nicht verstanden wie das
> mit dem bitweisen Auslesen von Arrays funktioniert.

Vergiss das bitte für erste (noch dazu wenn du unter Zeitdruck stehst)

Mach ein Array mit 32 Elementen. Jedes Element steht für eine LED. Ist 
es 0 dann soll die LED nicht brennen, ist es 1 soll die LED brennen.

Und diese 32 Elemente ackerst du in einer Schleife durch und gibst ein 1 
Bit bzw. ein 0 Bit an die Schieberegisterkette aus.

Speichersparender wäre es natürlich, wenn man die 32 LED in einem 
uint32_t unterbringen würde. Aber wenn du mit Bitoperationen sowieso 
noch auf Kriegsfuss stehst, musst du nicht sparen.

PS: Vergiss nicht SCL auf 1 zu halten! Ansonsten werden dir die 
Schieberegister was husten.

von Nils W. (darky9312)


Lesenswert?

Das hatte cih ja vor, aber muss ich dazu nicht das Arary bit für bit 
(bitweise) auslesen undann ausgeben? Das Schieberegister hat doch nur 
einen serielen Eingang. Oder meintest du das so:
1
uint8_t Led [32] = {
2
Led[1] 1,
3
Led[2] 0,
4
.
5
.
6
.
7
}
?

von Nils W. (darky9312)


Lesenswert?

Karl heinz Buchegger schrieb:

> Speichersparender wäre es natürlich, wenn man die 32 LED in einem
> uint32_t unterbringen würde. Aber wenn du mit Bitoperationen sowieso
> noch auf Kriegsfuss stehst, musst du nicht sparen.

So hatte ic das eigentlich vor, und das ganze dann in einem Array mit 32 
uint32_t damit ich das komplette Muster in einem Arary habe.

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Das hatte cih ja vor, aber muss ich dazu nicht das Arary bit für bit
> (bitweise) auslesen undann ausgeben?

Wozu?
1
   for( i = 0; i < 32; ++i ) {
2
     if( Led[i] == 0 )
3
       // LEd i soll nicht brennen  ( 0 ausgeben )
4
     else
5
       // Led i soll brennen ( 1 ausgeben )
6
   }

> Das Schieberegister hat doch nur
> einen serielen Eingang.

Ja und?
Das hat ja mit dem Led Array nur indirekt zu tun.
Wenn da in einem Array Eintrag eine 0 drinnen steht, gibst du eine 0 
aus. STeht keine 0 drinnen, gibst du eine 1 aus. Deswegen musst du doch 
den Led Eintrag nicht bitweise zerpfriemeln

> Oder meintest du das so:
>
1
> uint8_t Led [32] = {
2
> Led[1] 1,
3
> Led[2] 0,
4
> .
5
> .
6
> .
7
> }
8
>

genau so

von Nils W. (darky9312)


Lesenswert?

Aber wenn ich das mit
1
uint8_t Led [32] = {
2
Led[1] 1,
3
Led[2] 0,
4
.
5
.
6
.
7
}
mache, dan brauche ich für ein muster 8*32*32 = 8192 Byte... dann ist 
mein Atmega8 mit einem Muster schon übervoll... könnte amn das nicht 
kleiner als mit uint8_t machen? Gibt es einen Datenyp der nur 1 und 0 
ist?

von Karl H. (kbuchegg)


Lesenswert?

1
#define SR_PORT    PORTD
2
#define SR_DDR     DDRD
3
4
#define SER_PIN    PD0
5
#define SCK_PIN    PD1
6
#define SCL_PIN    PD2
7
#define RCK_PIN    PD3
8
9
uint8_t Led[32] = { 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
11
12
void Output()
13
{
14
  uint8_t i;
15
16
  for( i = 0; i < 32; ++i ) {
17
    if( Led[i] == 0 )
18
      SR_PORT &= ~( 1 << SER_PIN );    // 0 auf den Dateneinganf vom SR
19
    else
20
      SR_PORT |=  ( 1 << SER_PIN );    // 1 auf den Dateneingan vom SR
21
22
    SR_PORT |=  ( 1 << SCK_PIN );      // an SCK einen Puls erzeugen
23
    SR_PORT &= ~( 1 << SCK_PIN );
24
  }
25
26
  // alle 32 Bits sind draussen
27
  // Die SR-Latches durchschalten
28
  SR_PORT |=  ( 1 << RCK_PIN );
29
  SR_PORT &= ~( 1 << RCK_PIN );
30
}
31
32
int main()
33
{
34
  uint8_t tmp, i;
35
36
  //
37
  // Schieberegister Anschlüsse auf Ausgang
38
  //
39
  SR_DDR = ( 1 << SER_PIN ) | ( 1 << SCK_PIN ) |
40
           ( 1 << SCL_PIN ) | ( 1 << RCK_PIN );
41
42
  // SR löschen
43
  SR_PORT &= ~( 1 << SCL_PIN );
44
  SR_PORT |=  ( 1 << SCL_PIN );
45
  // ab jetzt den SCL nicht mehr angreifen
46
47
  while( 1 ) {
48
    Output();    // das 32-Array komplett ausgeben
49
50
    // nur zur Demo
51
    // alle Stellen um 1 Stelle verschieben
52
    tmp = Led[0];
53
    for( i = 0; i < 31; ++i )
54
      Led[i] = Led[i+1];
55
    Led[31] = tmp;
56
57
    _delay_ms( 500 );
58
  }
59
}

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:

> mache, dan brauche ich für ein muster 8*32*32 = 8192 Byte...

Wenn ein Muster aus 32 Stufen besteht.
OK. Hast du recht.
Hab ich nicht bedacht.

Machs trotzdem fürs erste. Ich hab dir ein Testprogramm gepostet. Nur um 
mal zu sehen, ob deine Hardware überhaupt funktioniert.

Das Umschreiben der Ausgabefunktion ist ja kein Problem

von Karl H. (kbuchegg)


Lesenswert?

Hier ist deine neue Ausgabefunktion, die einen uint32_t bitweise ausgibt
1
void Output( uint32_t value )
2
{
3
  uint8_t i;
4
5
  for( i = 0; i < 32; ++i ) {
6
    if( ( value & 0x01 ) == 0 )
7
      SR_PORT &= ~( 1 << SER_PIN );    // 0 auf den Dateneinganf vom SR
8
    else
9
      SR_PORT |=  ( 1 << SER_PIN );    // 1 auf den Dateneingan vom SR
10
11
    SR_PORT |=  ( 1 << SCK_PIN );      // an SCK einen Puls erzeugen
12
    value >>= 1;
13
    SR_PORT &= ~( 1 << SCK_PIN );
14
  }
15
16
  // alle 32 Bits sind draussen
17
  // Die SR-Latches durchschalten
18
  SR_PORT |=  ( 1 << RCK_PIN );
19
  SR_PORT &= ~( 1 << RCK_PIN );
20
}


1
int main()
2
{
3
   ....
4
  uint32_t step = 0b00000000000000000000000000000001;
5
6
  while( 1 ) {
7
    Output( step );
8
9
    step <<= 1;
10
    _delay_ms( 500 );
11
  }
12
}

von Nils W. (darky9312)


Lesenswert?

Das Problem ist ja,dass ich die Ics noch nicht habe, ahbe aber alles so 
angeschlossen wie es im Tutorial stand, bis auf die Tatsache , dass ich 
SCL auf +5V gelegt habe, da du gesagt hast , dass ichs nciht brauche.
Supergroßes danke für deine Riesige Mühe mir zu Helfen,ich haecht keine 
Ahnung was ich ohne dich machen würde, doch eigentlich schon 
wahrscheinlich heir sitzen und denken "warum geht das nicht, warum geht 
das nicht???". Dass du mal eben ein passendes Programm geschrieben hats 
istauch supernet, aber wie gesagt ich kanns im Moment leider noch nicht 
ausprobieren. Dann heist es wohl erstmal warten -.-

von Nils W. (darky9312)


Lesenswert?

hey Super danke :). Mann ich bin echt froh dass es dieses Forum gibt :D

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Das Problem ist ja,dass ich die Ics noch nicht habe, ahbe aber alles so
> angeschlossen wie es im Tutorial stand,

OK.
Ich hab dir im Code #define für die tatsächliche Belegung gemacht. Das 
ist also kein Problem an deine tatsächliche Schaltung anzupassen

> bis auf die Tatsache , dass ich
> SCL auf +5V gelegt habe,

Das war vernünftig.
Dann kann der Teil in main() mit dem Löschen der SR ersatzlos entfallen.

von Nils W. (darky9312)


Lesenswert?

wenn  ich das richtig verstanden habe dann Lässt das Programm eine 
leuchtende Led einmal durchwandern oder?

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> wenn  ich das richtig verstanden habe dann Lässt das Programm eine
> leuchtende Led einmal durchwandern oder?

Mehr als das.
Das Programm mit dem Array lässt die aktuelle LED-Belegung rundum 
wandern. Egal welche und wieviele LED brennen. Du kannst ja einmal 
einfach ein paar mehr Einträge auf 1 setzen :-)

Das mit dem uint32_t ist einfacher. Da wird tatsächlich nur 1 LED einmal 
rundum geschickt. Mit der Betonung auf einmal. Du kannst noch andere 
Bits auf 1 setzten, die wandern genauso bis zum ENde der Leds.

1
int main()
2
{
3
   ....
4
  uint32_t step = 0b00000000000000000000000000000001;
5
  uint8_t tmp;
6
7
  while( 1 ) {
8
    Output( step );
9
10
    tmp = step & 0x80000000;
11
    step <<= 1;
12
    if( tmp )
13
      step |= 0x00000001;
14
15
    _delay_ms( 500 );
16
  }
17
}

Jetzt wandert auch hier das Muster im Kreis.


Sofern sich da überhaupt etwas tut!
Drumm wäre es wichtig die Funktion der Hardware zu testen, ehe da jetzt 
kompliziertere Schemata aufgebaut werden!

von Nils W. (darky9312)


Lesenswert?

Supersache :) ich freu mich schon auf die Ics (und hofe nebenbei dass 
die überhaupt noch rechtzeitig kommen^^)

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:

> das nicht???". Dass du mal eben ein passendes Programm geschrieben hats
> istauch supernet,

Ist aber die Ausnahme, da du das bis Samstag fertig haben willst (und 
ich ab Do nicht mehr im Forum bin). Und da das ganze offenbar ein 
Geschenk werden soll, wäre es ganz gut, wenn du rechtzeitig ein paar 
Tage vorher etwas grundsätzlich lauffähiges hast.

von Nils W. (darky9312)


Lesenswert?

Hm vielleicht kann ich in der Zeit schonmal die Rückplatte machen (die 
wird geschraubt also wenn was falsch dran ist ist das kein Problem)
Soll hinterher mit Batterien betrieben werden 7805 ist auch mti drauf.

von Nils W. (darky9312)


Lesenswert?

Karl heinz Buchegger schrieb:

> Ist aber die Ausnahme, da du das bis Samstag fertig haben willst (und
> ich ab Do nicht mehr im Forum bin). Und da das ganze offenbar ein
> Geschenk werden soll, wäre es ganz gut, wenn du rechtzeitig ein paar
> Tage vorher etwas grundsätzlich lauffähiges hast.

Mir ist klar dass es nicht der Normalfall ist, dass man in dieser Art 
hilfe bekommt :) deswegen bedanke ich mich ja sosehr. Mir fällt grade 
auf, dass ich weniger Schreibfehler mache wenn ich garnicht auf die 
Tastatur gucke beim Tippen (gehört hier zwar nicht hin aber mich würde 
mal interessieren ob das bei anderen Leuten auch so ist)

von Nils W. (darky9312)


Angehängte Dateien:

Lesenswert?

Hm dann erstmal zu etwas anderem. ich habe auf dem board auch Taster, 
mit denen ich unter andrem den Text auf dem lcd ändern wollte. Im Anhang 
ist ersteinmal das Programm das ich hinterher mit einfügen möchte. So 
wie ich das sehe, ist es bei nicht gedrücktem völlig unmöglich, dass 
sich der Text ändert, und doch tut er es. Woran liegt das? Die Schleife 
bei der Tasterabfage sol bewirken, dass bei nicht gedrücktem Taster 
sofort aus der Schleife gesprungen wird. wenn der Taster allerdings 
gedrückt wird, wird in der while schleife darauf gewartet, dass der 
Taster wieder losgelassen wird, was durch die ifabfrage spofort dazu 
führt, dass der Text geändert wird... Naja zumindest SOLL es das tun. 
Weiß einer wieso NICHT?

von Karl H. (kbuchegg)


Lesenswert?

Hatten wir das nicht vor kurzem schon mal?

1
void Tasterabfrage (void)
2
{
3
  if (!(PINB&(1<<PINB0)));
4
  {
5
    while (!(PINB&(1<<PINB0)));
6
    {
7
      if (PINB&(1<<PINB0));
8
      {
9
        Textaendern();
10
      }
11
    }
12
  }
13
}

Was machen die ganzen ; an den Zeilenenden?

von Peter D. (peda)


Lesenswert?

Nils Wiechert schrieb:
> Hm dann erstmal zu etwas anderem.

Dann solltest Du besser auch nen anderen Thread aufmachen.
Zum Thema Taster haben viele schon Fusseln vorm Mund.
Mein Geheimtip, nimm ne fertige und bewährte Lösung.


Peter

von Nils W. (darky9312)


Lesenswert?

Mann ich versuch echt drauf zu achten udn trotzdem überseh ichs immer 
wieder -.-

von Nils W. (darky9312)


Lesenswert?

jetzt funktionierts :) Ich idiot danke dass du mich drauf aufmerksam 
gemacht hättest  :)

von Karl H. (kbuchegg)


Lesenswert?

Du solltest trotzdem Peters Rat beherzigen und eine richtige, 
funktionierende Entprellung benutzen.

von Peter D. (peda)


Lesenswert?

Man kann Lichteffekte aber auch mit ner Statemachine statt einer Tabelle 
machen.
Hier mal ein Beispiel:
1
#define  F_CPU  1e6
2
3
#include <util/delay.h>
4
#include <avr/io.h>
5
6
7
#define  LEDS    32
8
9
10
int main( void )
11
{
12
  uint16_t state = 0;
13
  uint32_t val = 0;
14
15
  for(;;){
16
    Output( val );
17
    _delay_ms( 50 );
18
    switch( ++state ){
19
      default:
20
        state = 1;
21
        val = 1;                                // 1. LED an
22
        break;
23
24
      case 2 ... LEDS:                          // Lichtpunkt nach links
25
        val <<= 1;
26
        break;
27
28
      case LEDS + 1 ... 2 * LEDS - 1:           // Lichtpunkt nach rechts
29
        val >>= 1;
30
        break;
31
32
      case 2 * LEDS ... 3 * LEDS - 2:           // Lichtstrahl nach links
33
        val += val + 1;
34
        break;
35
36
      case 3 * LEDS - 1 ... 4 * LEDS - 2:       // Lichtstrahl kleiner
37
        val >>= 1;
38
        break;
39
40
      case 4 * LEDS - 1 ... 5 * LEDS - 2:       // Lichtstrahl nach rechts
41
        val = (val >> 1) + (1 << (LEDS-1));
42
        break;
43
44
      case 5 * LEDS - 1 ... 6 * LEDS - 2:       // Lichtstrahl kleiner
45
        val <<= 1;
46
        break;
47
48
      case 6 * LEDS - 1 ... 7 * LEDS - 2:       // Lichtstrahl nach links durchlaufend
49
        val += val + 1;
50
        break;
51
52
      case 7 * LEDS - 1 ... 8 * LEDS - 2:
53
        val <<= 1;
54
        break;
55
56
      case 8 * LEDS - 1 ... 9 * LEDS - 2:       // Lichtstrahl nach rechts durchlaufend
57
        val = (val >> 1) + (1 << (LEDS-1));
58
        break;
59
60
      case 9 * LEDS - 1 ... 10 * LEDS - 2:
61
        val >>= 1;
62
        break;
63
    }
64
  }
65
}

Die Routine "Output" von Karl Heinz und die Pin-Direktion setzen gehört 
noch dazu.


Peter

von Nils W. (darky9312)


Lesenswert?

Das sieht auch super aus, aber ich werde erstmal zum probieren die 
VErion von karl benutzen. Was amcht den die Zeile
#define  F_CPU  1e6
?
Ist die für die CPU Frequenz? denn die definiere ich doch schon in 
manchen routinen (unter anderem in den Lcd routinen) und ausserdem ist 
die doch im Makefile schon drin.

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:

> Ist die für die CPU Frequenz? denn die definiere ich doch schon in
> manchen routinen (unter anderem in den Lcd routinen) und ausserdem ist
> die doch im Makefile schon drin.

Wenn du sie im Makefile hast (was gut ist), dann nimm sie überall anders 
raus. Das vermeidet, dass du dir selbst ein Ei damit legst, indem du 
vergisst sie an allen Stellen zu ändern, wenn sich die Taktfrequenz 
ändert.

von Peter D. (peda)


Lesenswert?

Karl heinz Buchegger schrieb:
> Das vermeidet, dass du dir selbst ein Ei damit legst, indem du
> vergisst sie an allen Stellen zu ändern

Sowas macht man garnicht erst. Man ändert nicht alle Stellen, weil es 
immer nur eine Stelle im Projekt gibt.
Da ich kein Make benutze, ist diese eine Stelle bei mir im "Main.h" 
(außer das Projekt besteht nur aus einem einzigen File).


Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter Dannegger schrieb:

> Sowas macht man garnicht erst. Man ändert nicht alle Stellen, weil es
> immer nur eine Stelle im Projekt gibt.

Manchmal denk ich mir:
Es gibt eine Reihe von 'Unsauberkeiten' (um nicht das Wort 'Fehler' in 
den Mund zu nehmen), bei denen muss jeder Programmierer mindestens 
einmal, mit anschliessender stundenlanger Fehlersuche, selbst 
hineinfallen bis er erkennt, wo das Problem liegt.

von Nils W. (darky9312)


Lesenswert?

Hm Avrstudio  macht doch automatisch ein makefile warum sollte ich das 
also nciht nutzen^^? Werde die CPU Frequenz dann an den anderen STellen 
rausnehmen. Ihc habe immer gedacht dass C ein makefile braucht??? Stimmt 
das garnicht?

von Karl H. (kbuchegg)


Lesenswert?

Nils Wiechert schrieb:
> Hm Avrstudio  macht doch automatisch ein makefile warum sollte ich das
> also nciht nutzen^^?

Ist ja auch ok

> Werde die CPU Frequenz dann an den anderen STellen
> rausnehmen.

Darum gehts.
So eine Einstellung macht man immer nur an 1 Stelle
Im Idealfall dort, wo man sie leicht findet. Auch 2 Jahre später.

> Ihc habe immer gedacht dass C ein makefile braucht??? Stimmt
> das garnicht?

Nö.
Ein makefile ist nur eine Möglichkeit, wie man sich den Vorgang des 
Bauens einer Applikation vereinfachen und automatisieren kann. Aber 
nichts und niemand hindert einen daran, den Compiler händisch aus einer 
Commandline für jedes C-File aufzurufen und die Einzelteile händisch zum 
Programm zusammenzulinken. Und so hat man das auch gemacht, bevor sich 
jemand den Mechanismus von 'make' hat einfallen lassen.
Letzten Endes geht es nur darum, dass Änderungen in einem C-File auch 
compiliert werden und ein neues Programm entsteht. Ob du das händisch 
machst, oder ob das ein Werkzeug namens 'make' aufgrund einer 
Beschreibung der Zusammenhänge und Uhrzeitvergleich von Dateien macht 
ist letzten Endes egal (letzteres ist komfortabler). Dem Compiler ist es 
egal, wer ihn aufruft :-)

von Karl H. (kbuchegg)


Lesenswert?

Wie arbeitet make, bzw was hat es mit dem Makefile auf sich?

Im Makefile ist einfach nur beschrieben, welche Datei von welchen 
anderen Dateien abhängen und mit welchem Kommando man diese Datei 
erzeugen kann.

Da steht also drinnen:
Im eine Datei (zb) test.hex zu erzeugen (die du dann auf den Prozessor 
brennen kannst), müssen die Einzelteile test.o und (zb) uart.o 
vorliegen. Sind die da, dann werden die beiden zusammengelinkt und man 
bekommt das hex-File.

Jetzt gehts aber weiter:
test.o hängt von test.c und uart.h ab und man erhält test.o indem man 
test.c durch den Compiler schickt
uart.o hängt von uart.c und uart.h ab und man erhält sie, indem man 
uart.c durch den Compiler jagt
1
test.hex: test.o uart.o
2
      Linker aufrufen um test.hex zu erhalten
3
4
test.o: test.c uart.h
5
      Compiler aufrufen um test.o zu erhalten
6
7
uart.o: uart.c uart.h
8
      Compiler aufrufen um uart.o zu erhalten
das ist der grundsätzliche Aufbau (in seiner simpelsten Form) eines 
Makefiles.
Das Tool make schnappt sich diese Beschreibung und überprüft ganz 
einfach die File-Timestamps. Editierst du zb uart.c, dann hat uart.c ein 
neueres Datum als uart.o
Daher wird das zugehörige Kommando (Compiler aufrufen um uart.o zu 
erhalten) ausgeführt und man bekommt ein neues uart.o.
Dadurch ist jetzt aber auch uart.o neuer als test.hex und folgerichtig 
wird auch das dort vermerkte Kommando ausgeführt.

Folge: Du editierst uart.c und make macht alle Schritte die notwendig 
sind um daraus ein neues test.hex zu erzeugen. Beachte: test.c hängt 
nicht von uart.c ab, daher ist es nicht neu compiliert worden. Hättest 
du uart.h editiert, so würde make auch diese Abhängigkeit feststellen, 
feststellen dass uart.h neuer ist als test.o und das zugehörige Compiler 
Kommando ausführen.

Das ist alles was make macht: Die Zeiteinträge von Dateien vergleichen 
und bei Bedarf die zugehörigen Kommandos ausführen.
Aktuelle Makefiles sind ein wenig komplizierter aufgebaut, aber das 
Prinzip ist immer noch dasselbe.

von Nils W. (darky9312)


Lesenswert?

Ah danke für die super erklärung. Dann ist das wahrscheinlich auch der 
Grund, warum ich nur einmal auf compilieren klicken kann und der beim 
zweiten mal nichts mehr macht, wenn ich nichts ändere.

von Nils W. (darky9312)


Lesenswert?

m in meinen Lcd routinen steht jetzt
1
#ifndef F_CPU
2
#define F_CPU 12000000
3
#endif
Das kann man doch drin lassen oder? Weil das doch nur dann die cpu 
Frequenz definiert wenn sie noch nicht definiert ist oder?

von Peter D. (peda)


Lesenswert?

Nils Wiechert schrieb:
> Das kann man doch drin lassen oder?

Besser nicht.
Wenn wichtige Eingaben vergessen wurden, sollte der Compiler nen Fehler 
ausgeben.


> Weil das doch nur dann die cpu
> Frequenz definiert wenn sie noch nicht definiert ist oder?

Und warum soll die dann immer richtig sein?

Besser:
1
#ifndef F_CPU
2
#error Ey Mann, du hast die Frequenz nicht angegeben !!!
3
#endif


Peter

von Nils W. (darky9312)


Lesenswert?

Ah okay werde ich ändern danke ^^

von Nils W. (darky9312)


Lesenswert?

Habe übrigens eie versandbestätigung von Reichelt von heute morgen so um 
7 Uhr sollten also morgen da sein :)

von Nils W. (darky9312)


Angehängte Dateien:

Lesenswert?

Ich ahbe die Ics jetzt bekommen. Aber leider leuchten alle Leds auf 
einmal und nicht nur die bei denen in der Variable eine 1 steht. Im 
ANhang ist der Code. ICh habe alles nach Plan verlötet. weiß jemand 
warum es trotzdem nciht funktioniert?
Liebe Grüße
Nils

von Nils W. (darky9312)


Lesenswert?

HM da bisher keiner getworet hat stelle ich die Frage mal anders, meint 
ihr ich habe mich verlötet oder das Programm ist falsch?

von Nils W. (darky9312)


Lesenswert?

Fehler gefunden... das DDR vom SR Port wurde nirgends beschrieben.

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
Noch kein Account? Hier anmelden.