Projekt: Der Bau und die Programmierung einer LED Matrix

Anleitungen für "hausgemachte" LED Projekte

Moderator: T.Hoffmann

MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Mo, 10.10.11, 18:35

Hi,

Zuerst bedanke ich mich bei der Firma LUMITRONIX® LED-Technik GmbH ( http://www.leds.de/ ) die mich bei meinem Schul-Projekt unterstützt.

Nun möchte ich gerne mein Projekt vorstellen. Das ganze wird wie schon im Titel gesagt eine LED Matrix auf der ein Spiel laufen soll. Das ganze wird mit Hilfe des Mikrocomputers Arduino programmiert. In diesem Forum werde ich immer meine Fortschritte teilen und somit eine Schritt für Schritt Anleitung schaffen die Ideal für jeden zum Nachbauen oder auch Nachlesen ist. Des Weiteren nehme ich auch gerne eure Vorschläge und Verbesserungen entgegen und bin auch, soweit
verfügbar, offen für eure Fragen.

Nun zum Aufbau der LED Matrix:
Ich werde eine 16*16 LED Matrix bauen, die ich in 4 8*8 Matrizen aufteile.

Für eine 16*16 Matrix braucht man folgendes (in Klammern befindet sich immer die von mir georderten Materialien).
So die Materialien sind alle bestellt und ich warte schon auf das Paket um loszulegen. Dann erkläre ich auch den genauen Aufbau der LED Matrix anhand von Fotos.


Inhaltsverzeichnis
Zuletzt geändert von MeineKekse am Di, 17.04.12, 15:54, insgesamt 12-mal geändert.
O.Mueller
Moderator
Beiträge: 4089
Registriert: Do, 23.02.06, 15:08
Wohnort: Südbaden
Kontaktdaten:

Di, 11.10.11, 10:35

Na, da sind wir sehr gespannt. Gutes Gelingen auf jedem Fall schon einmal von uns !
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Mi, 12.10.11, 19:51

Während die Materialien auf den Weg zu mir sind, erkläre ich mal hier die Berechnung der Vorwiderstände.
Wichtig zur Berechnung sind folgende Angaben:

Betriebsspannung: 5V – da der Mikrocomputer den ich zum Programmieren benutze auch mit 5 Volt angetrieben wird ist es sehr sinnvoll, die LEDs ebenfalls mit 5 Volt anzutreiben. So braucht man nur ein Netzgerät.
Betriebsspannung der LEDs: 2,2V( bei den LEDs die ich gewählt habe) – ist aus dem Datenblatt entnehmbar.
Stromstärke: 6 mA – reichen aus damit die LEDs, die ich gewählt habe hell genug leuchten. Den Wert der maximalen Stromstärke einer LED kann man aus dem Datenblatt entnehmen. Ich werde allerdings nur 6mA zur Verfügung stellen(Warum folgt später).

Nun zur Rechnung:

Laut Ohm’schen Gesetz gilt:
R = U / I

U = U(Betriebsspannung) – U(Betriebsspannung der LEDs) - dieses ist die Spannung die "vernichtet" werden muss.

Also ist U= 5V – 2,2V ; allerdings ändert sich die an den LEDs verfügbare Betriebsspannung durch verwendete Bauteile, die der Steuerung der LED - Matrix dienen(dazu später mehr).Die neue Betriebsspannung beträgt 3,8 Volt.

Es folgt U= 3,8 V – 2,2 V =1,6V

R = 1,6V / 0,006 A = 266,7 Ohm; wir beachten = V/A also nicht mA.

Wir nehmen also den nächst größeren Normwert, also 270 Ohm.

Ich hoffe es hat euch geholfen bei Fragen einfach melden.
Zuletzt geändert von MeineKekse am Mi, 12.10.11, 21:04, insgesamt 2-mal geändert.
Benutzeravatar
Achim H
Star-Admin
Star-Admin
Beiträge: 13067
Registriert: Mi, 14.11.07, 02:14
Wohnort: Herdecke (NRW)
Kontaktdaten:

Mi, 12.10.11, 20:55

wir beachten = V/A also nicht mA.

Die Grundeinheit für den elektrischen Strom ist und war schon immer Ampere.
Teile oder ein Vielfaches davon müssen immer in die Grundeinheit (also in Ampere) umgerechnet werden.
Sowas lernt man normalerweise im Physikunterricht.


Was Formatierungen angeht:
Bitte wähle stets eine Farbe, die man auf allen Hintergründen (hell oder dunkel) erkennen kann. Da eine formatierte Schrift (warum weiß der Geier) kleiner als normale Schrift dargestellt wird, solltest Du diese durch eine geeignete Formatierung wieder auf eine gleiche Buchstabengröße bringen. Dazu muss die Schrift nur mit size=120 vergrößert werden. Formatierungen können anschließend verschachtelt werden (die Schriftgröße muss immer als erstes formatiert werden).

Beispiel (gleiche Buchstabengröße, dunkelrot):
[color=#BF0000][size=120]mA[/size][/color]

Ergebnis:
V/mA


Beispiel (gleiche Buchstabengröße, dunkelrot und fett):
[b][color=#BF0000][size=120]mA[/size][/color][/b]

Ergebnis:
V/mA


Wir nehmen also den nächst größeren Normwert, also 270 Ohm.

Das wäre der nächstgrößere Normwert aus der E12-Reihe.
Der nächstgrößere Normwert aus der E96-Reihe wäre 267 Ohm.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Mi, 12.10.11, 22:36

Sowas lernt man normalerweise im Physikunterricht.
Ich bin im Lk und du wirst erstaut sein wie viele das falsch machen.
Dazu muss die Schrift nur mit size=120 vergrößert werden.
Besser wäre eigentlich size=130
Siehe HHH
Das erste H hat size=130 das letzte size=120
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Sa, 15.10.11, 12:10

Hi,

ich empfehle besonders Anfängern diesen Schritt durchzuführen, alle andern können ihn machen oder auch gleich zum nächsten Schritt springen. Dieser erste Schritt dient der Vertiefung des Verständnisses einer LED Schaltung. Zusätzlich werden dabei die Anfänge der Programmiersprach erklärt.

Eine Testschaltung ist meist temporär aufgebaut. Sie kann folgenden Zwecke dienen:
  • Der Überprüfung von theoretischem Verständnis
    Ob die Schaltung funktioniert
    Ob alle verwendeten Materialien unbeschädigt sind
    Wie sich die Schaltung verhält wenn sie leicht verändert wird.
    Das Testen von Programmen auf dem Mikrocontroller
benötigte Materialien
  • -für den Aufbau
    • Breadboard(optional – aber sehr hilfreich und empfehlenswert)
      Bild
      Erspart einem das Löten durch bereits bestehende Verbindungen und dem einfachen Zusammenstecken neuer Verbindungen mit Überbrückungsdrähten
      Bild
      Silberdraht
      Draht kann man verschiedenen gebrauchen. Unisolierten(blank) oder isolierten(den kann man ja bei Bedarf abisolieren). Wenn man mit Breadboard arbeitet, sollte er von der Dicke passen. Auch verschiedene Farben sind sinnvoll, wenn man sie sinnvoll nutzt, kann man sich die Fehlersuche erleichtern.
      Es ist übriges auch gut Litze(Also Draht der aus vielen Adern besteht) zu haben. Für Zuleitungen, z.b. für alles was flexibel bleiben soll.
      Der meiste "Silberdraht" den man so kaufen kann ist übrigens versilberter Kupferdraht. Also beim Preisvergleich darauf achten welche Qualität es ist. Versilberter Kupferdraht ist billiger.
      Widerstände
      LEDs
    -für die Programmierung
    • Arduino
      Bild
      Bild
      A-male to B-male USB Kabel
      Bild
      Bild

So die erste Testschaltung dient einfach dem generällen Verständnis, wie man ein LED anschließt. Auch wenn sie sehr einfach ist dient sie später ins besondere dazu, die Grundlagen der Programmiersprache zu erläutern.
Bild

Eine LED ist über einen Widerstand am Arduino angeschlossen. Ground ist dabei der Minuspol.

Bild
Die zweite Testschaltung ist eine Art Simulation einer Spalte/Reihe einer 8*8 LED MAtrix. Sie verdeutlicht den Aufbau einer LEd-Matrix und hilft ebenfalls weitergehende Erläuterungen der Programmiersprache zu machen. In dieser Schaltung haben alle einen gemeinsamen Minuspol. Allerdings hat jede LED ihren eigenen Pluspol, so ist es möglich jede LED anzusteuern. Das Problem: Alle LED teilen sich einen Widerstand. Das bedeutet wenn alle LEDs gleichzeitig leuchten, teilen sie sich den Strom.Dadurch leuchten sie dunkler.

Bild
Die dritte Testschaltung löst das Problem der Ersten, indem vor jeder LED ein Widerstand eingesetzt wurde.Der Widerstand ist hier also am Pluspol angeschlossen und nicht mehr am Minuspol.

So sehen dei drei Schaltungen auf dem Breadboard aus.
Bild
Bild
Bild
Zuletzt geändert von MeineKekse am So, 23.10.11, 17:55, insgesamt 9-mal geändert.
Suntrader
Mega-User
Mega-User
Beiträge: 167
Registriert: Mi, 05.10.11, 00:51

Sa, 15.10.11, 12:37

MeineKekse hat geschrieben: • Prototype Platine(optional – aber sehr hilfreich und empfehlenswert)
Du meinst vermutlich ein Breadboard. Diese rechteckigen Flächen, meist weiß, mit vielen Kontakten.
die gibt es übrigens in verschiedenen Größen mit unterschiedlichen vielen Kontakten, .. und zu sehr unterschiedlichen Preisen.
2-3 Stück sind auf jeden Fall sinnvoll.
Silberdraht
Draht kann man verschiedenen gebrauchen. Unisolieren(blank) oder isolierten(den kann man ja bei Bedarf abisolieren). Wenn man mit Breadboard arbeitet, sollte er von der Dicke passen. Auch verschiedenen Farben sind sinnvoll, wenn man sie sinnvoll nutzt, kann man sich die Fehlersuche erleichtern.
Es ist übriges auch gut Litze(Also Draht der aus vielen Adern besteht) zu haben. Für Zuleitungen, z.b. für alles was flexibel bleiben soll.
Der meiste "Silberdraht" den man so kaufen kann ist übrigens versilberter Kupferdraht. Also beim Preisvergleich darauf achten welche Qualität es ist. Versilberter Kupferdraht ist billiger.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Sa, 15.10.11, 13:09

Draht kann man verschiedenen gebrauchen.
Danke habe ich oben in meinem Post mit aufgenommen.
Suntrader
Mega-User
Mega-User
Beiträge: 167
Registriert: Mi, 05.10.11, 00:51

Sa, 15.10.11, 15:36

Bei Deiner Testschaltung 2 ist folgendes Problem:
Du hast einen Widerstand in der GND Leitung. das bewirkt, das alle LEDs ihn sich teilen müssen. Was bewirkt wenn eine LED leuchtet bekommt sie den ganzen Strom, wenn 8 leuchten, bekommt jede nur ca. 1/8 des Stroms. Sie leuchten also dunkler (Aber noch etwas heller als sie nachher beim multiplexen leuchten).
Außerdem eine Parallelschaltung von den Dioden solltest du nicht machen, immer nen Widerstand zum entkoppeln einfügen. Was automatisch passiert , wenn du in auf die andere Seite packst, aso je einen an PIN6..13 in diesem Fall.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Sa, 15.10.11, 15:48

Bei Deiner Testschaltung 2 ist folgendes Problem:
Du hast einen Widerstand in der GND Leitung. das bewirkt, das alle LEDs ihn sich teilen müssen. Was bewirkt wenn eine LED leuchtet bekommt sie den ganzen Strom, wenn 8 leuchten, bekommt jede nur ca. 1/8 des Stroms. Sie leuchten also dunkler
Okay ich sehe jetzt was du meinst werde mich gleich drum kümmern.
Suntrader
Mega-User
Mega-User
Beiträge: 167
Registriert: Mi, 05.10.11, 00:51

Sa, 15.10.11, 15:55

Okay in diesem Fall schon, aber bei einer 8*8 Matrix ist es doch sowieso genau dies der Fall oder nicht(also wenn ich pro Reihe einen Widerstand anbringe)?
Nein, jeder Reihe bekommt einen eigenen Widerstand, von jeder Reihe leuchtet nur maximal eine LED, d.h. ein Widerstand "versorgt" nur maximal eine leuchtende LED. Der Spaltentreiber, versorgt jedoch 0-8 LEDs, darum muß er ja auch 8 Mal soviel Strom liefern können wie die Reihentreiber, damit es nicht zu helligkeitsunterschieden kommt.
Würdest du dort die Widerstände in den Spalten reinbauen hättest du auch das Problem.
Zuletzt geändert von Suntrader am Sa, 15.10.11, 16:02, insgesamt 1-mal geändert.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Sa, 15.10.11, 15:56

jop habe ich eben auch gerade eingesehen. Danke
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

So, 16.10.11, 21:08

Hi,

in diesem Post erkläre ich ein paar Grundlagen der Arduino-Programmiersprache. Wer Schritt1 durchgeführt hat, kann sie gleich praktisch anwenden. Für alle anderen ist dies ein wenig Theorie.
Als erstes sollte man die Entwicklungsumgebung downloaden und installieren.
Troubleshooting: http://arduino.cc/en/Guide/Troubleshooting

Da die Arduino-Programmierspreche auf C/C++ basiert, ist es von Vorteil wenn man diese kennt. Viele Befehle sind identisch.
So nun zur ersten Testschaltung. Öffnet die Entwicklungsumgebung und klickt auf File < Examples < Basics < Blink.
Ihr solltet folgendes sehen:

Bild

Nun zu den Befehlen /* */ leitet einen mehrzeiligen Kommentar ein.
// Leitet einen einzeiligen Kommentar ein.

Die beiden Funktionen void setup () und void loop () müssen in jedem Programm vorhanden sein.
void setup () wird nur einmal am Anfang des Programmes ausgeführt. Es dient zur Deklaration von Variablen und PIN-Zuständen sowie dem Einbinden von Klassen.
Die zweite Funktion void loop () wird wie der Name schon sagt, immer wiederholt.
In dieser Funktion dienen die Befehle dem aktiven kontrollieren des Mikrocomputers.

Beachte, dass hinter jedem Befehl ein Semikolon steht.

In der ersten Funktion werden hier folgende Befehle benutzt:
pinMode(13, output); - Pin 13 wird mit diesem Befehl als Ausgabe deklariert.
pinMode(12, input); - würde Pin 12 als Eingang deklarieren(z.B. zum Einlesen von Tastendrücken)

In der zweiten Funktion werden diese Befehle benutzt:
digtalWrite(13, HIGH); - Pin 13 wird auf den Zustand High gestellt -> der Strom fließt -> die LED leuchtet;
delay(1000); - der Prozessor wartet 1000 Millisekunde, also eine Sekunde in dieser Zeit kann der Prozessor also nichts anders machen
digtalWrite(13, LOW); - Pin 13 wird auf den Zustand Low gestellt -> der Strom fließt nicht mehr -> die LED ist aus;

Klickt nun auf Tools < Board und wählt euer Board aus (ich benutze den Arduino Uno).
Nun klickt auf Tools < Serial Port und wählt den USB Port aus in dem euer Mikrocontroller angeschlossen ist. Kennt ihr den Port nicht zieht euer USB Kabel vom Computer. Der Port der nicht mehr angezeigt wird, ist der den ihr momentan benutzt. Verbindet danach euren Computer wieder mit dem Mikrocontroller.
Klickt nun auf den Upload-Button.
Bild
Eure LED sollte nun blinken.

Eure Fragen einfach Posten. :D
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

So, 23.10.11, 12:38

Hi,

in diesem Post erkläre ich weitere Grundlagen der Arduino-Programmiersprache. Schritt2: Programmierung der Testschaltung 1 sollte dabei verstanden sein. Wenn nicht einfach fragen.

Mit 8 LEDs kann man zwar schon kleinere Animationen basteln, allerdings ist es zur Erklärung der Programmierung mit Schleifen sinvoll wieder jede LED zum blinken zu brigen. Dies hat den Vorteil, dass die Befehel der ersten Testschaltung nur erweitert und nicht verändert werden müssen.

Nun zur Programmierung:

Die erste Variante kann bereits ohne neues Wissen programmiert werden.

Bild

Dieser Code hat jedoch Nachteile. Zwar ist er schnell mit Copy und Past erstellt und kann ohne neu erlerntes Wissen geschrieben werden, trozdem ist es sinvoll ihn anders zu realisieren da:

  • -nach jedem Einfügen muss per Hand die Pinnummer geändert werden
    -der Code ist sehr lang
    -die Folge: der Code ist sehr unleserlich
    -die nächste Folge: Änderungen und die Fehlersuche werden erschwert

Um den Code nun zu verkürzen muss man ihn so aufbereiten, dass sich die Befehle automatisch wiederholen, sich die Pinnummer aber jedesmal ändet.

Der "neue" Code sieht so aus:

Bild


Dazu benutzt man Variablen, Schleifen, Vergleichsoperatoren und Rechenoperatoren.

Definition:
Rechenoperatoren sind im Grunde Operatoren zum Rechnen (also addieren, multiplitzieren, subtrahieren usw.)

Erklärung:
Rechenoperatoren werden benutz um Werte oder Variablen miteinander zu verrechnen.

Beispiel:
5 + 10;
30 - 2;
// Das ganze kann in einer Variablen abgespeichert werden (sie unten)
int Variable1 = 6;
Variable1 = Variable1 + 10; // Der neue Wert der Variable wäre 16

// Das geht auch kürzer
int Variable2 = 3;
Variable2; += 6; // Der neue Wert der Variable wäre 9

// oder noch kürzer wenn man mit 1 addiert oder subtrahiert
int Variable3 = 5;
Variable3++; // Der neue Wert der Variable wäre 4( --für die Subtraktion)
------------------------------------------------------------------------------------------------------------------------

Definition:
Vergleichsoperatoren sind im Grunde Operatoren zum Vergleichen (also gleich, größer, größer gleich usw.)

Erklärung:
Sie werden in einer Programmiersprache benutzt um Variablen mit einem Wert oder mehrer Variablen miteinander zu vergleichen.

Beispiel:
i == 15; // Ist i gleich 15?
i <= 3; // Ist i kleiner gleich 3?

------------------------------------------------------------------------------------------------------------------------

Definition:
Eine Variable bezeichnet einen Platzhalter für einen Wert, beispielsweise eine Zahl.

Erklärung:
In diesem Fall ist es eine ganzzahlige Variable. Die wird mit int eingeleitet. Eine Gleit- oder Fließkommerzahl wird mit float eingeleitet.
Der Variablen wird ein Wert zugewiesen, indem hinter ihrem Namen ein Gleichheitszeichen steht.

Beispiel:
int Variable1; //wobei Variable 1 der Name der Variablen ist
Variable1 = 6;

oder

float Variable2 = 7.23; //Beachte, dass die Nachkommastelle mit einem Punkt getrennt wird

------------------------------------------------------------------------------------------------------------------------

Definition:
Eine Schleife ist eine Kontrollstruktur in Programmiersprachen. Sie wiederholt einen Anweisungs-Block – den so genannten Schleifenrumpf oder Schleifenkörper – so lange, wie eine Laufbedingung gültig ist

Erklärung:
In diesem Fall ist es eine for Schleife.
Sie ist folgendermaßen aufgebaut:

for ( Initialisierungsteil ; Bedingungsteil ; Anweisungsteil)
{Schleifenrumpf}

Der Initialisierungsteil: In ihm findet die Dekleration sowie die Zuweisung einer Variablen statt. //z.B. int i = 13; ( Die Variabele heißt i und hat den Wert 13)

Der Bedigungsteil: Hier steht die Bedingung, die erfüllt werden muss, damit der Schleifenrumpf ausgeführt wird // z.B. int i == 5; ( wenn i gleich 5 ist)

Der Anweisungsteil: Hier steht eine Rechenperation, die mit der Variablen durchgeführt wird, die zur Veränderung dieser führt // z.B. i++; ( i wird um 1 erhöht)
!ACHTUNG! Der Anweisungsteil wird nach jedem Schleifendurchgang jedoch vor dem nächsten Bedingungsteil ausgeführt.

Beispiel:
for ( int i = 13; i > 5; i--){
digitalWrite(i, HIGH);
delay(1000);
digitalWrite(i, LOW);
delay(1000);
}

So ihr könnt beide Codes abtippen und sie auf euren Arduino laden und euch davon überzeugen, dass beides funktioniert.

Wenn etwas unverständlich ist wie immer einfach Fragen
Zuletzt geändert von MeineKekse am So, 23.10.11, 15:27, insgesamt 1-mal geändert.
Suntrader
Mega-User
Mega-User
Beiträge: 167
Registriert: Mi, 05.10.11, 00:51

So, 23.10.11, 13:39

MeineKekse hat geschrieben:Hi,

// Das ganze muss in einer Variablen abgespeichert werden (sie unten)
Nein, es muß nicht, aber man kann. Man muß damit gar nichts machen, man kann Ausdrücke auch als Feldindex nehmen, oder Parameter
// Das geht auch kürzer
int Variable2 = 3
Variable2 =+ 6 // Der neue Wert der Variable wäre 9
int Variable2 = 3;
Variable2 += 6; // ist richtiger ;) Oder will das Arduino C tatsächlich noch diese Form?
.. du hast die Semikolon vergessen .. auch an anderen stellen .. :)
// oder noch kürzer wenn man mit 1 addiert oder subtrahiert
int Variable3 = 5
Variable3++ // Der neue Wert der Variable wäre 4( --für die Subtraktion)
oder auch :
++Variable3 ; // je nachdem wie man es braucht
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

So, 23.10.11, 17:11

int Variable2 = 3;
Variable2 += 6; // ist richtiger ;) Oder will das Arduino C tatsächlich noch diese Form?
.. du hast die Semikolon vergessen .. auch an anderen stellen .. :)
hast recht bei langen Post und vielen Formatierungen wird es dann doch schon sehr unübersichtlich und Tippfehler schleichen sich ein.
// oder noch kürzer wenn man mit 1 addiert oder subtrahiert
int Variable3 = 5
Variable3++ // Der neue Wert der Variable wäre 4( --für die Subtraktion)
oder auch :
++Variable3 ; // je nachdem wie man es braucht
Vorsicht!

Man darf ++Variable verwenden und auch Variable++, es gibt nur einen wichtigen Unterschied.
Also nochmal hier für alle die es sehr genau wissen wollen:

var Variable1 = 7;
var Variable2= ++Variable1;
var Variable3= Variable1++;
var Variable4 = Variable1;

Welchen Wert hat Variable2, welchen Wert hat Variable3?

Die (vielleicht etwas überraschende) Antwort lautet: Variable2 hat den Wert 8, Variable3 hat auch den Wert 8. Betrachten man zunächst die zweite Zeile:

var Variable2= ++Variable1;

Der ++-Operator steht vor dem Variablennamen. Das bedeutet hier, dass zunächst diese Operation (Variable1 um eins erhöhen) ausgeführt und dann der neue Wert (8) der Variablen Variable2 zugewiesen wird.

Bei der dritten Zeile ist es genau andersherum:

var Variable3 = Variable1++;

Zuerst wird der Variablen Variable3 der (aktuelle) Wert von Variable1(momentan 8) zugewiesen, dann wird der Wert von AnzahlAuflagen um eins vergrößert

var Variable4 = Variable1;

Variable4 müsste dann 9 sein, da die Variable Variable1 den aktuellen Wert 9 besitzt.
Borax
Star-Admin
Star-Admin
Beiträge: 12020
Registriert: Mo, 10.09.07, 16:28

So, 23.10.11, 21:45

Ich weiß schon, warum ich C nicht mag :D
Man muss jedes mal erst 'um die Ecke' denken, nur um den Code zu verstehen. Da sind mir Sprachen ohne solche Kurzformen (Basic/Pascal/ASM) einfach lieber. Klar mit ausreichend Übung kann man bestimmt auch C 'runterlesen'.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

So, 23.10.11, 22:03

Da sind mir Sprachen ohne solche Kurzformen (Basic/Pascal/ASM) einfach lieber.
Klar aber du musst die Kurzform ja nicht benutzen.. :D
Suntrader
Mega-User
Mega-User
Beiträge: 167
Registriert: Mi, 05.10.11, 00:51

So, 23.10.11, 22:04

Man sollte die Sprache schon kennen und sich damit auseinandersetzten wenn man sie benutzen will. C ist ja nicht wirklich mächtig. Und wenn man das PostInkrement oder preinkrement nicht mag, läßt man es weg. Aber man sollte es lesen können, wenn man andere Sourcen liest, weil man es fast überall findet.
Mit C kann man sicher Sourcen erzeugen die nur extrem schwer lesbar sind, geht aber in anderen Sprachen auch. Man kann in C aber auch so programmieren das man es gut lesen kann. Für Anfänger ist C nicht geeignet, die sollten erst mal mit eine Sprache anfangen, die mehr Überprüfungen zuläßt.
Ich mag C und kann es auch problemlos lesen., aber ich nutzte sie auch schon recht lange. C gibt für fast alle Rechner, wenn man entsprechend programmiert, sind die Sourcen problemlos übertragbar, oder so zu Pflegen das sie auf ganz unterschiedlichen Maschinen laufen.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Di, 01.11.11, 22:07

Hi,

damit ich den Schaltplan der Matrix besser erklären erkläre ich hier schon mal was ein Schieberegister ist.
Ich beziehe mich hierbei auf den 74HC595. Andere arbeiten funktionieren fast identisch oder nur mit geringen Abweichungen.

Also ein Schieberegister ist ein logisches Schaltwerk. Dies bedeutet, dass es mehrere Eingangswerte zu einem Ausgangswert verarbeitet. Alle Eingabewerte sind dabei in boolischer Form also an oder aus / false or true / 1 oder 0.

Ein Schieberegister ist aus Flipflops aufgebaut, die in Reihe geschaltet sind.EIn Flipflop ist eine SChaltung, die 2 stabile Zustände annehmen kann, nämlich genau an oder aus / false or true / 1 oder 0. Dies ermöglichte es diesen booleschen Wert( 1 (Bit) über lange Zeit zu speichern. Im 74HC595 können 8 Bits gespeichert werden. 8 Bits nennt man auch ein Byte.

Beim Hereinschieben eines neuen Bits verschiebt sich jeder vorhandende in den nächsten Flipflop. Das letzte Bit wird herrausgeschoben. Allerdings kann man hier mehrere Schieberegister hintereinander schalten. Dies nennt ma nauch kaskadieren. So wird das letzte Bit des ersten Registers beim Hereinschieben eines neuen Bits in den zweiten Schieberegister geschoben.

So nun nun zu den Anschlüssen( wie gesagt ich beziehe mich hier auf den 74HC595 ).

Bild

Pin- Nummer.....Funktion
1...................Ausgang 2
2...................Ausgang 3
3...................Ausgang 4
4...................Ausgang 5
5...................Ausgang 6
6...................Ausgang 7
7...................Ausgang 8
8...................Masse/ Ground/ Minus-Pol
9...................Betriebsspannung 5V
10..................Ausgang 1
11..................Serieller Dateneingang
12..................Ausgangssteuerung
13..................Speichertakt
14..................Schiebetakt
15..................Reset
16..................Serieller Datenausgang

So nun noch ein paar mehr Daten zum 74HC595.
  • serial-in/serial-out - bei einer seriellen Schnitstelle/ Datenübertragung werden Bits nacheinander über eine Leitung übertragen

    parallel-out - mehrere Bits werden parallel übertragen, also gleichzeitig

    Ausgangsregister - Daten können zwischenzeitlich im Schieberegister gespeichert werden.

    asynchroner Reset - Daten können asynchron zurückgesetzt werden, also nicht gleichzeitig
So beim nächsten Mal gehts dann darum wie man so einen Schieberegister ansteuert.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Do, 03.11.11, 21:32

Nun zum zweiten Teil:

Der 74HC595 besteht im Großen und Ganze aus einem Schieberegister und einem Ausgangsregister.

Bild
Der obere Abschnitt, also der in dem Werte stehen ist der Schiberegister. Der untere Teil ist der Ausgangsregister.
Die drei Anschlüsse rechts mit den Pin-Nummer 11, 13 und 14 sind zum ansteuern des 74HC595.Pin 11, also DS, ist der Dateneingang. Pin 13 ist der Speichertakt und Pin 14 Schiebetakt.

Wenn man nun Daten an den Dateneingang(DS) sendet oder auch clock Pin genannt, werden die 8 zulezt gesendeten Bits gespeichert werden.In diesem beispiel sind Pin 0,2,6 und 7 auf LOW gesetzt und 1,3,4 und 6 Auf HIGH gesetzt.

Will man nun ein weiteres Bit in den Register hineinschieben( hier die 1 links vom DS Anschluss), muss man den SH_CP -Pin (auch clock Pin)ansteuern, was im nächsten Bild verdeutlicht wird. Dabei wird das letzt Bit aus Q7' herausgeschoben.

Bild

Mit jeder neuen positiven Taktflnke(Low --> High) am Pin SH_CP wird ein neues Bit in den Register geschoben.

Das nächste Bild beschreibt die Freigabe dieser dieser Daten
Bild

Bei jeder positiven Taktflanke am ST_CP Pin(auch latch Pin genannt) wird der Inhalt des Schieberegisters in den Ausgangsregister übernommen.

Mit dem OE Pin kann nun der Ausgang freigegeben werden.

Mit dem MR Pin kann ein Reset vorgenommen werden , also alle Bits werden auf 0 gestellt.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Mi, 16.11.11, 20:30

Hi, endlich habe ich wiede ein wenig Zeit gefunden mein Projekt fortzusetzen.

Dieser kurze Post zeigt euch wie eine LED- Matrix generell aufgebaut ist.

Bild

Wie sehr schön auf dem Bild zu sehen wir hier jeweils ein Pol jede LED in einer Reihe mit einander verbunden. Der andere Pol jeder LED wird dann entlang der Spalten verbunden. Dies erlaubt trotz verhältnissmäßig wenig Kabeln ( im Vergleich, wenn man jede LED einzeln anschließt) gezielt Ansteuerung jeder einzelnen LED.

Zuletzt verbindet man entwerder jede Reihe oder jede Spalte mit einem Widerstand und verbindet danach die Kabel mit einem Spalten - Treiber und einem Reihen - Treiber( Dies ist in meinem Fall der oben genannte IC (steht für intigrated circuits, also in meinem Fall dieser Baustein: 74HC595 )
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Mi, 16.11.11, 20:38

Und noch ein kleiner Post hinterher.

Die Verkabelung sollte eigentlich klar sein, das sie anhand dem erworbenem Wissen über den Schieberegister erstellt werden kann.
Also hier noch einmal die Verbindungen.

Bild

Die roten Kabel sind dabei die Reihen und die grünen Kabel die Spalten.

Falls trotzdem noch irgendwelche Fragen auftauchen bin ich gerne bereit zu antworten.
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Di, 27.12.11, 12:31

HI,

so nach etwas längerer Zeit bin ich wieder hier. Heute zeige ich euch wie man so eine Matrix den eigentlich richtig zusammenlötet.
Was man braucht sollte bekannt sein(Lötzinn, Silberdraht, LEDs, Platinen und Geduld...).
  • 1. Pletziere die erste Reihe der Leds aud der Platine.
    2. Überprüfe, dass die Polarität jeder LED richtig herum ist, da es extrem schwer sein wird dies nachträglich zu ändern.
    Bild
    3. Löte beid Beine der LED an das Board. Sie sollten im rechten WInkel zum Board stehen. Wer es nachher am einfachsten haben will schneidet gleich den Pin der Kathode ab. VORSICHT auf gar keinen Fall die Anode kürzen, die wird später noch gebraucht.
    Bild
    4. Nimm nun den Silberdraht und löte ihn an jede Kathode. Der Draht solte so dicht wie möglich an der Platine verlaufen.
    Bild
    5. Wiederhole Schritt 1-4 bis jede LED am richtigen Platz sitzt und verlötet ist.
    Bild
    6. Um nun die Anoden zu verbinden gibt es mehere Möglichkeiten.

    • 1. Variante) Löte an jeder Anode einer LED-Reihe einen Silberdraht. Der Draht darf auf gar keinen Fall die Kathodenverbindung berührern. Der Draht verläuft somit in der Luft.
      2. Variante) Biege die Anoden um 90 Grad, sodass sie sich gegenseitig berühren. Auch hier gilt, dass keinerlei Berührung mit der Kathodenverbindung bestehen darf.
      Bild

    7. Verlötet nun die eben gesetzte Verbindung. Und schneide überschüssigen Draht ab.
    Bild
    8. Wiederhole Schritt 6 und 7 bis alle Verbindungen verlötet sind.
    9. Zuletzt löte an ein Ende der Anode und an ein Ende der Kathode isolierten Draht an, der später zum Arduino führen wird.

Hier die fertige Matrix, der Silberdrht wird natürlich noch mit isoliertem ersetzt.
Bild
MeineKekse
Super-User
Super-User
Beiträge: 72
Registriert: Mi, 05.10.11, 17:31

Di, 17.04.12, 15:53

Da es ein enorm hoher Aufwand ist nachfolgenden benötigten Code vollständig zu erklären, sind nur die wichtigsten Bestandteile direkt als Kommentar im Quellcode angegeben erklärt. Bei Fragen daher einfach Posten ich werde sie dann schnellst möglich beantworten. Verbesserungen oder Erweiterungen des Codes nehme ich natürlich auch gerne entgegen.

Noch Kurz vorweg der Quellcode wird benötigt um überhaupt LEDs auf dem Display zum Leuchten zu bringen. Dabei wurden die vier 8x8-LED-Matrizen in jeweils ein Koordinatensystem eingeteilt(unten links ist LED (1,1) oben rechts ist die LED (8,8). Diese Angaben werden vom Programm in die richtigen Byte- Werte für die Schieberegister konvertiert. Zusätlich wird für eine korrekte Anzeige jedes Bildes auf der Matrix das Multiplexverfahren angewandt.

configuration.h - Datei

Code: Alles auswählen

/********************************************************/
/*                                                      */
/*      This file is used to adapt the following:       */
/*        -pins your matrices are connected to          */
/*        -total number of matrices                     */
/*                                                      */
/*      advanced option:                                */
/*        -how you matrices are conneted to the         */
/*         74HC595                                      */
/*                                                      */
/********************************************************/


//Pin connected to latch pin (ST_CP) of 74HC595
  const int latchPin = 6;
//Pin connected to clock pin (SH_CP) of 74HC595
  const int clockPin = 7;
//Pin connected to Data in (DS) of 74HC595
  const int dataPin = 5;

//Total number of matrices 
  const int totalNumberOfMatrices = 4;
  
//By changing byte - values you can adapt the way how your matrice is connected
//Bytes might need to be added or subtracted when more or less matrices are used
  const int bytesX[totalNumberOfMatrices][8] =  {  {127, 191, 223, 239, 247, 251, 253, 254}, 
                                                   {127, 191, 223, 239, 247, 251, 253, 254},
                                                   {254, 253, 251, 247, 239, 223, 191, 127},
                                                   {254, 253, 251, 247, 239, 223, 191, 127},
                                                };
  const int bytesY[totalNumberOfMatrices][8] =  {  {128,  64,  32,  16,   8,   4,   2,   1},
                                                   {  1,   2,   4,   8,  16,  32,  64, 128},
                                                   {128,  64,  32,  16,   8,   4,   2,   1},
                                                   {  1,   2,   4,   8,  16,  32,  64, 128},
                                                };
                          
/* Size of Matrices supported is momentary limited to 8*8 
  Please do not change these values as the programm may not work correctly afterwards  */
  
  const int height = 8;
  const int width  = 8;
  
die main-file

Code: Alles auswählen


// Start ligtUpLeds function

void lightUpLeds(int drawLeds[][height*width][2], int length){

 /***                                                                  ***/
 /***    no support for non quadratic matrices(momentary only 8*8)     ***/
 /***                                                                  ***/
  
  
/**** Variable to count number of y values ****/

int relativizelength = 0;

/**** Variable to save if the outshifting process has to be skiped or not ****/

int skip = 0;


/**** Variables to calculate  ****/

int dataX[totalNumberOfMatrices][width][height];   // x- Values per y value
for(int a=0; a < totalNumberOfMatrices; a++)
  for(int a2=0; a2 < 8; a2++)
    for(int a3= 0; a3 < 8; a3++)
      dataX[a][a2][a3] = 255;
    
int dataOutput[totalNumberOfMatrices][2][8] = {0};  // final 8 x- and y-values  
 

/**** Checking the array for values  ****/

for(int matrixNumber = 0; matrixNumber < totalNumberOfMatrices; matrixNumber++)
  for(int possibleLed = 0; possibleLed < width*height; possibleLed++)
    for(int row = 0; row < 8; row++){
      /**** iterate y values ****/
      if((drawLeds[matrixNumber][possibleLed][y]) == (row+1) )
        dataOutput[matrixNumber][y][row] = bytesY[matrixNumber][row];
      /**** iterate x values ****/
      if(drawLeds[matrixNumber][possibleLed][x] == (row+1) )
        dataX[matrixNumber][drawLeds[matrixNumber][possibleLed][y]-1][row] = bytesX[matrixNumber][row];
    }
  



/**** adapting the length of the action to the numbers of y values to light  up ****/

for(int b = 0; b < height; b++)
  for(int matrixNumber = 0; matrixNumber < totalNumberOfMatrices; matrixNumber++)
    if(dataOutput[matrixNumber][y][b] != 0 ){ relativizelength++; break;}

length /= relativizelength;

/**** Calculating final x-Output ****/

for(int matrixNumber = 0; matrixNumber < totalNumberOfMatrices; matrixNumber++)
  for(int u = 0; u < 8; u++ ){
     dataOutput[matrixNumber][x][u] = dataX[matrixNumber][u][7];
     for(int u2 = 0; u2 < width-1; u2++)
       dataOutput[matrixNumber][x][u] += dataX[matrixNumber][u][u2];
     dataOutput[matrixNumber][x][u] -= 255*(width-1);
  }
  
 

for(int repeat = 0; repeat < length - (length*relativizelength/1000)*40* totalNumberOfMatrices ; repeat++){  
  /****  - ((length*relativizelength)/1000)* (61* totalNumberOfMatrices)) : approximate conversion factor to get the right light on time when consindering computation time of Arduino****/
  for(int u = 0; u < 8; u++ ){     
    for(int matrixNumber = 0; matrixNumber < totalNumberOfMatrices; matrixNumber++)
      if(dataOutput[matrixNumber][y][u] != 0) skip++;
    if(skip != 0){   
      skip = 0;       
      /**** Making the LEDs shine after checking if they have to light up ****/
      digitalWrite(latchPin, LOW);
      for(int matrixToDisplay = (totalNumberOfMatrices-1); matrixToDisplay > -1; matrixToDisplay--){
        if(matrixToDisplay % 2 == 0){
          shiftOut(dataPin, clockPin, MSBFIRST, dataOutput[matrixToDisplay][x][u]);
          shiftOut(dataPin, clockPin, MSBFIRST, dataOutput[matrixToDisplay][y][u]);
        }else{
          shiftOut(dataPin, clockPin, MSBFIRST, dataOutput[matrixToDisplay][y][u]);
          shiftOut(dataPin, clockPin, MSBFIRST, dataOutput[matrixToDisplay][x][u]);
        }
      } 
      digitalWrite(latchPin, HIGH);
      delay(1);
      }
    }
  }
}

folgende Funktion erzeugt jeweils ein Viereck auf jeweils jeder Matrix an angebenem Punkt

Code: Alles auswählen

// Start createFigure function

void createFigure(int drawLeds[][height*width][2], int bottomLeftCornerX, int bottomLeftCornerY){  
  
  drawLeds[0][0][x] = bottomLeftCornerX;
  drawLeds[0][0][y] = bottomLeftCornerY;
  
  drawLeds[0][1][x] = bottomLeftCornerX;
  drawLeds[0][1][y] = bottomLeftCornerY+1;
  
  drawLeds[0][2][x] = bottomLeftCornerX+1;
  drawLeds[0][2][y] = bottomLeftCornerY;
  
  drawLeds[0][3][x] = bottomLeftCornerX+1;
  drawLeds[0][3][y] = bottomLeftCornerY+1;
  
  
  drawLeds[1][0][x] = bottomLeftCornerX;
  drawLeds[1][0][y] = bottomLeftCornerY;
  
  drawLeds[1][1][x] = bottomLeftCornerX;
  drawLeds[1][1][y] = bottomLeftCornerY+1;
  
  drawLeds[1][2][x] = bottomLeftCornerX+1;
  drawLeds[1][2][y] = bottomLeftCornerY;
  
  drawLeds[1][3][x] = bottomLeftCornerX+1;
  drawLeds[1][3][y] = bottomLeftCornerY+1;
  
  
  drawLeds[2][0][x] = bottomLeftCornerX;
  drawLeds[2][0][y] = bottomLeftCornerY;
  
  drawLeds[2][1][x] = bottomLeftCornerX;
  drawLeds[2][1][y] = bottomLeftCornerY+1;
  
  drawLeds[2][2][x] = bottomLeftCornerX+1;
  drawLeds[2][2][y] = bottomLeftCornerY;
  
  drawLeds[2][3][x] = bottomLeftCornerX+1;
  drawLeds[2][3][y] = bottomLeftCornerY+1;
  
  
  
  drawLeds[3][0][x] = bottomLeftCornerX;
  drawLeds[3][0][y] = bottomLeftCornerY;
  
  drawLeds[3][1][x] = bottomLeftCornerX;
  drawLeds[3][1][y] = bottomLeftCornerY+1;
  
  drawLeds[3][2][x] = bottomLeftCornerX+1;
  drawLeds[3][2][y] = bottomLeftCornerY;
  
  drawLeds[3][3][x] = bottomLeftCornerX+1;
  drawLeds[3][3][y] = bottomLeftCornerY+1;
  

  
  lightUpLeds(drawLeds, 2000);
  
}
und zuletzt die Datei mit der FUnktion, die genau das macht was ich ganz zu beginn beschrieben hat

Code: Alles auswählen

// Start ligtUpLeds function

void lightUpLeds(int drawLeds[][height*width][2], int length){

 /***                                                                  ***/
 /***    no support for non quadratic matrices(momentary only 8*8)     ***/
 /***                                                                  ***/
  
  
/**** Variable to count number of y values ****/

int relativizelength = 0;

/**** Variable to save if the outshifting process has to be skiped or not ****/

int skip = 0;


/**** Variables to calculate  ****/

int dataX[totalNumberOfMatrices][width][height];   // x- Values per y value
for(int a=0; a < totalNumberOfMatrices; a++)
  for(int a2=0; a2 < 8; a2++)
    for(int a3= 0; a3 < 8; a3++)
      dataX[a][a2][a3] = 255;
    
int dataOutput[totalNumberOfMatrices][2][8] = {0};  // final 8 x- and y-values  
 

/**** Checking the array for values  ****/

for(int matrixNumber = 0; matrixNumber < totalNumberOfMatrices; matrixNumber++)
  for(int possibleLed = 0; possibleLed < width*height; possibleLed++)
    for(int row = 0; row < 8; row++){
      /**** iterate y values ****/
      if((drawLeds[matrixNumber][possibleLed][y]) == (row+1) )
        dataOutput[matrixNumber][y][row] = bytesY[matrixNumber][row];
      /**** iterate x values ****/
      if(drawLeds[matrixNumber][possibleLed][x] == (row+1) )
        dataX[matrixNumber][drawLeds[matrixNumber][possibleLed][y]-1][row] = bytesX[matrixNumber][row];
    }
  



/**** adapting the length of the action to the numbers of y values to light  up ****/

for(int b = 0; b < height; b++)
  for(int matrixNumber = 0; matrixNumber < totalNumberOfMatrices; matrixNumber++)
    if(dataOutput[matrixNumber][y][b] != 0 ){ relativizelength++; break;}

length /= relativizelength;

/**** Calculating final x-Output ****/

for(int matrixNumber = 0; matrixNumber < totalNumberOfMatrices; matrixNumber++)
  for(int u = 0; u < 8; u++ ){
     dataOutput[matrixNumber][x][u] = dataX[matrixNumber][u][7];
     for(int u2 = 0; u2 < width-1; u2++)
       dataOutput[matrixNumber][x][u] += dataX[matrixNumber][u][u2];
     dataOutput[matrixNumber][x][u] -= 255*(width-1);
  }
  
 

for(int repeat = 0; repeat < length - (length*relativizelength/1000)*40* totalNumberOfMatrices ; repeat++){  
  /****  - ((length*relativizelength)/1000)* (61* totalNumberOfMatrices)) : approximate conversion factor to get the right light on time when consindering computation time of Arduino****/
  for(int u = 0; u < 8; u++ ){     
    for(int matrixNumber = 0; matrixNumber < totalNumberOfMatrices; matrixNumber++)
      if(dataOutput[matrixNumber][y][u] != 0) skip++;
    if(skip != 0){   
      skip = 0;       
      /**** Making the LEDs shine after checking if they have to light up ****/
      digitalWrite(latchPin, LOW);
      for(int matrixToDisplay = (totalNumberOfMatrices-1); matrixToDisplay > -1; matrixToDisplay--){
        if(matrixToDisplay % 2 == 0){
          shiftOut(dataPin, clockPin, MSBFIRST, dataOutput[matrixToDisplay][x][u]);
          shiftOut(dataPin, clockPin, MSBFIRST, dataOutput[matrixToDisplay][y][u]);
        }else{
          shiftOut(dataPin, clockPin, MSBFIRST, dataOutput[matrixToDisplay][y][u]);
          shiftOut(dataPin, clockPin, MSBFIRST, dataOutput[matrixToDisplay][x][u]);
        }
      } 
      digitalWrite(latchPin, HIGH);
      delay(1);
      }
    }
  }
}

Antworten