Pages: [1] 2   Go Down
Author Topic: Grundlagen zu einer 8x8 LED Matrix  (Read 2243 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Arduino-Community,
ein Freund und ich sind dabei auf einer 8x8 LED Matrix das berühmte Spiel "Snake" zu programmieren.
Wir benutzen 16 74HC595 Schieberegister, 64 zweifarbige LEDS(grün und rot) und einen Arduino Mega (ATmega1280).
Nun haben wir die Matrix fertig gebaut und ich wollte anfangen einzelne Leds anzusprechen, was jedoch nicht so funktioniert wie ich mir das vorstelle.
Ich hatte mir das so gedacht, dass man mit einem byte Matrix[8]; array jede einzelne Zeile der Matrix ansprechen kann und das die Bits
der einzelnen Bytes jeweils die LEDS "wiederspiegeln". Sprich das meine erste LED Reihe folgendermaßen funktionieren würde:

Code:
Matrix[1] = 85 //0b01010101
, wodurch jeweils die 2. LED immer leuchten soll, was Sie aber nicht tun.
Es werden jeweils die einzelnen Reihen der Matrix damit angesprochen und nun wollte ich wissen wie ich jeweils die einzelnen LEDS der einzelnen Reihen ansteuern kann.
Hier der Quellcode:
Code:
Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

byte Matrix[8];

void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  Matrix[1] = 85;
}


void loop() {

    digitalWrite(latchPin, LOW);

    shiftOut(dataPin, clockPin, MSBFIRST, Matrix[1]); //0b01010101
   
    digitalWrite(latchPin, HIGH);
}
und hier ein bild der Matrix, wenn der Arduino diese mit dem Quellcode ansteuert:


Die LED in der 3 Reihe spinnt manchmal, hat nix mit dem Progg zutun.

Wenn Ihr noch weitere Informationen benötigt, lasst es mich wissen. Bin hier relativ neu und freue mich über Tipps und Tricks rund ums programmieren.
Wenn es irgendwelche Tutorial's gibt könnt ihr mir die auch gerne senden smiley.
Danke schonmal im Vorraus,
idl0r
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 78
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

1. In C++ fanngen Arrays mit Index 0 an
2. hast du wahrscheinlich bei der Verdrahtung Zeilen und Spalten vertauscht
3. würde ein Plan der Beschaltung helfen
4. Wenn du die Schieberegister über die seriellen Ausgänge in Reihe geschaltet hast, dann musst du die Zeilen alle hintereinander herausshiften. Wenn alles parallel geschaltet ist, hast du die Sache falsch verdrahtet. Clock und Latch schon parallel, aber Data nicht.
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 250
Posts: 21201
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie ich das verstehe hast Du je ein LED auf einen Ausgang des 595 geschalten und alle 16 Schieberegister in Serie ( Dout auf Din).

Um ein Bild darzustellen mußt Du jedesmal alle Daten der 64 LED hinausschiften also jedesmal 16 Byte.
So wie ich das sehe stimmt es wie die LED leuchten außer Reihe 3 da scheint ein Verdrahtungsfehler zu sein. Ein 595 steuert jeweils eine Kolonne an.

Grüße Uwe

 
« Last Edit: October 25, 2011, 01:41:23 pm by uwefed » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo ,
hier ist der Plan wie unsere Matrix geschaltet wird: http://imageshack.us/photo/my-images/109/8x8duoledmatrixfritzing.jpg/
es wurde nach diesem prinzip verdrahtet: http://www.arduino.cc/en/Tutorial/ShiftOut
also eine reihe aus 8 shiftregistern für rot nach "shiftout" (außer das unsere reihen untereinander sind und nicht nebeneinander)
und eine reihe aus 8 shiftregistern für grün nach "shiftout"
Ich lade noch die Fritzing-Datei hoch dann kannste dir vllt einen besseren Überblick verschaffen.
MfG: idl0r

* Untitled_Sketch.zip (95.44 KB - downloaded 11 times.)
« Last Edit: October 25, 2011, 01:44:56 pm by idl0r » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@ Uwe, könnten Sie mir vllt ein Programmierbeispiel geben um z.B. die LED ganz unten links nur zum leuchten zubringen? wäre Ihnen sehr dankbar dafür
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 250
Posts: 21201
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dann ist ja alles richtig außer daß Du das eine LED kontrollieren mußt.
Du mußt also immer 8 Byte übertrragen auch wenn Du nur 1 LED ändern willst.


Code:
Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

byte Matrix1[] = {85, 170,85, 170,85, 170,85, 170};
byte Matrix2[] = {170, 85, 170,85, 170,85, 170,85};



void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  }


void loop() {

    digitalWrite(latchPin, LOW);
  for (int i = 0;i<8;i++)
{
    shiftOut(dataPin, clockPin, MSBFIRST, Matrix1[i]);
}  
    digitalWrite(latchPin, HIGH);

delay (1000);

   digitalWrite(latchPin, LOW);


  for (int i = 0;i<8;i++)
{
    shiftOut(dataPin, clockPin, MSBFIRST, Matrix2[i]);
}  
    digitalWrite(latchPin, HIGH);
delay (1000);
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey,
also erstmal ein großes Dankeschön an uwefed, funktioniert das programm.
Jetzt habe ich aber nochmal eine frage bezüglich des "refreshens" der Matrix.
Ich will jetzt von oben links "2 Punkte" nach oben rechts laufen lassen,
sprich ich könnte dem Array ja für die erste Stelle den Wert 128 geben(10000000) und nur oben links die LED würde leuchten.
Dann im nächsten durchlauf wird ja i zu 2 und ich würde der 2 Stelle des Arrays auch 128 geben(Oben links und der 2. von oben links wären an).
Dann im 3. Durchlauf würdeich der ersten Arraystelle (sprich i-2, da i=3) eine 0 zuweisen wodurch sich diese beiden Punkte immer weiter nach rechts verschieben würden,
jedoch wird die Matrix immer erst ganz am ende refresht wenn das Array bereit alle werte übergeben bekommen hat.
WIe könnte ich also die einzelnen Schritte für mich "sichtbar" machen? Ich hatte mir das so in codeform gedacht:

Code:
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

byte Matrix1[] = {0, 0, 0, 0, 0, 0, 0, 0};
byte Matrix2[] = {170, 85, 170,85, 170,85, 170,85};



void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  }


void loop() {
  int Zaehler = 0;
  digitalWrite(latchPin, LOW);
  for (int i = 0;i<8;i++)
{
  if (Zaehler == 1){
    Matrix1[i-2] = 0;
    Matrix1[i]   = 128;
    shiftOut(dataPin, clockPin, MSBFIRST, Matrix1[i]);
    digitalWrite(latchPin, HIGH);
    delay (1000);
  }
  else
    Matrix1[i] = 128;
    shiftOut(dataPin, clockPin, MSBFIRST, Matrix1[i]);
    digitalWrite(latchPin, HIGH);
    delay (1000);
    Zaehler++;
}

Wenn ich diesen Code ausführe wird jedoch nur nach einiger Zeit die gesamte obere Reihe an LEDS ausgegeben.
Habe ich einen Denkfehler im Code? oder wie "refresh" man eine Matrix richtig?
MfG: idl0r
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 250
Posts: 21201
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mach innerhalb der loop() Schleife eine Kontrolle mit millis() um eine Triggerung der Update des Displays zu haben und die einzelnen Schritte des Spiels zu berechnen. Da das Display nicht flackert kannst Du die Zeit beliebig wählen.
Grüße Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Leute,
erstmal danke an uwefed für die info mit dem refreshen, hab das mal umgesetzt und funktioniert soweit smiley
Jetzt wollte ich nochmal etwas nachfragen und zwar habe ich das gefühl dass die einzelnen bits, welche die
LEDS ja repräsentieren immer weiter "durchgepusht" werden.
Ich wollte jetzt einfach mal ein Programm schreiben welches schrittweise die LEDS von Oben links nach unten Links
anschaltet und das habe ich mir so gedacht, dass ich einfach sage ich habe ein Array of byte mit 8 stellen.
Die erste Stelle ist 128, sprich die oberste LED ist an, die restlichen Stellen des Arrays sind 0, was bewirken soll
dass nur oben links die LED leuchten soll.
Dann halbiere ich diese 128 zu 64, damit die untere LED angeschaltet wird und die obere ausgeschaltet.
Nun funktioniert das auch halbwegs, aber aus irgendeinem grund bleibt im 2 Durchlauf die LED in der oberen Reihe an
und rückt einen platz weiter, sprich die erste LED ist nichtmehr an, sondern die 2., dann im 3 durchlauf ist die LED der 1. Reihe auf der 3 LED und
die der 2. Reihe auf der 2 LED und der der 3 Reihe auf der 1 LED usw.
Dadurch ergibt sich eine Diagonale beim 8 durchlauf, was ich jedoch nicht nachvollziehen kann, da ich ja nur die erste Stelle des arrays jeweils rausshifte.
Hier mein Quellcode dazu:


Code:
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

byte Matrix1[] = {0, 0, 0, 0, 0, 0, 0, 0};
byte Matrix2[] = {0, 0, 0, 0, 0, 0, 0, 0};

int Zaehler = 0;
int Rows = 8;
int RunterZaehlen = 128;

long time[8];
void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
 
for(int i = 0; i<8; i++){
 time[i] = millis() + i*i*i;
}
}

void LeereArray(){
  digitalWrite(latchPin, LOW);
  for(int i = 0; i<8; i++){
      Matrix1[i] = 0;
      shiftOut(dataPin, clockPin, MSBFIRST, Matrix1[i]);
  }
  digitalWrite(latchPin, HIGH);
  delay(1000);



void Snake(){
  int RunterZaehlen = 128;
  for(int i = 0; i< 8;i++){
      digitalWrite(latchPin, LOW);
      Matrix1[1] = RunterZaehlen;
      RunterZaehlen = RunterZaehlen / 2;
      if(millis()>time[i]){
      shiftOut(dataPin, clockPin, MSBFIRST, Matrix1[1]);
      digitalWrite(latchPin, HIGH);
      delay(1000);
      }
     
  }
  }


void loop() {
  Snake();
  /*if(Zaehler == 1){
  LeereArray();
  }*/
}



Hier hab ich das ganze zur besseren Übersicht nochmal fotografiert:

1:





2:





3:


Danke schonmal für die Hilfe smiley
MfG: idl0r

P.S: das ganze geht immer bis unten rechts smiley-wink und fängt ab der Hälfte von oben links wieder neu an, deshalb
sieht man da auch immer die Hälfte der "alten" bits

Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 250
Posts: 21201
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

long time[8]; das muß eine unsigned long Variable sein!!

Du mußt die einzelnen Bits des Matrixarrays setzen und dann alle 8 Werte des Arrays IMMER gemeinsam auf einen Rutsch verschicken.

Grüße Uwe
Logged

AREA COLOGNE
Offline Offline
Edison Member
*
Karma: 21
Posts: 1125
I am 1 of 10 who understands binary
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Um die ganze Sache mit dem Shiftout zu beschleunugen kann man auch die SPI Schnittstelle nehmen die ist mindestens um Faktor 5 schneller als das "normale Shifout". Das alles in eine Funktion geschrieben und dann wird das alles auch noch übersichtlicher
Logged

So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 250
Posts: 21201
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Um die ganze Sache mit dem Shiftout zu beschleunugen kann man auch die SPI Schnittstelle nehmen die ist mindestens um Faktor 5 schneller als das "normale Shifout". Das alles in eine Funktion geschrieben und dann wird das alles auch noch übersichtlicher

Da idl0r jedes LED einzeln über den Ausgang der Schieberegister ansteuert und nicht multiplext ist die Übertragungsgeschwindigkeit kein Problem.
Grüße Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Du mußt die einzelnen Bits des Matrixarrays setzen und dann alle 8 Werte des Arrays IMMER gemeinsam auf einen Rutsch verschicken.

Grüße Uwe


Verstehe ich das jetzt richtig, dass ich ein bit array mit 64 stellen machen soll, sprich für jede LED ein bit, oder soll ich weiterhin mit dem 8 byte array arbeiten? Weil dann verstehe ich nicht ganz was du meinst mit "einzelne bits setzen",weil das tue ich doch indem ich bytes reinschiebe oder?
Und wie kann ich denn ein gesamtes Array auf einen "Rutsch" verschicken/ausgeben? Das geht doch nur über eine Schleife, was dann wieder nicht auf einen rutsch wäre, sondern durchgang für durchgang oder?
MfG: idl0r
« Last Edit: October 27, 2011, 08:36:30 am by idl0r » Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 250
Posts: 21201
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void Snake(){
  int RunterZaehlen = 128;
  for(int i = 0; i< 8;i++){
      digitalWrite(latchPin, LOW);
      Matrix1[1] = RunterZaehlen;
      RunterZaehlen = RunterZaehlen / 2;
      if(millis()>time[i]){
      shiftOut(dataPin, clockPin, MSBFIRST, Matrix1[1]);
      digitalWrite(latchPin, HIGH);
      delay(1000);
      }
     
  }
Hier änderst Du ein Bit und überträgst 1 Byte nicht die ganzen 8 Byte der Matrix.
Die Schieberegister stellen immer die letzten 8 übertraggenen Byte dar!!!!
Grüße Uwe 
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo uwefed,
ich verstehe jetzt aber nicht ganz wie Sie das meinen mit dem Übertragen des ganzen Arrays. Ich kann doch immernur pro durchlauf einen Byte übertragen oder gibt es hier einen Befehl/"trick", welcher das gesamte
Array überträgt?
Wäre Ihnen für ein Codebeispiel sehr dankbar, da dies meist verständlicher und anschaulicher ist.
Herzlichen dank schonmal für die Hilfe,
idl0r
Logged

Pages: [1] 2   Go Up
Jump to: