Forum: FPGA, VHDL & Co. Matrix LED Steuerung funktioniert nicht


von GS (chromosoma)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe genz normale 32x16 RGB LED Matrix von adafruit.

Diese will ich mit FPGA ansteuern.
Die Sache ist recht einfach, cih schiebe 32 Werte, setzte Latch-Signal 
kurz auf '1'  und gehe zur nächste  Zeile.
Das Bild wird von einem BRAM gelesen. Zuerst wollte ich nur das untere 
Teil der Matrix ausprobieren.
Doch  leider funktioniert es nicht so ganz wie es soll.  Das im BRAM 
gespeicherte Muster wird verschoben ausgegeben (s. Bild).
Wenn ich die Zeilen  und/oder die Adressen manuelle  auswähle, 
funktioniert alles sauber. Die Zeilen werden einzeln richtig 
eingeschaltet und  beleuchtet.
Nur wenn ich versuche das Bild als ganzes  anzeigen, geht es nicht:
 Wie  man auf dem Bild sieht, sind die Zeilen um eins nach oben 
verschoben.Die richtigen Zeilen leuchten zwar auch, aber nur  stark 
gedimmt.
 Ich verstehe nicht was falsch ist, an sich sind das bloß vier Zähler,
in der Simulation und SignalTap sieht alles richtig aus....



Hier ist mein Code:
1
process(clock_50)
2
begin
3
 if rising_edge(clock_50)then
4
   ramwe<='0'; 
5
  matrix_oe_n<='0';
6
  if(counter<50)then-------clock for matrix
7
  counter<=counter+1;
8
   clock_en<='0';
9
  else 
10
    counter<=0;
11
   clock_en<='1';
12
  end if;
13
 end if;
14
end process;
15
    gpio_1(3 downto 1)<=std_logic_vector(to_unsigned(lines,3));
16
17
process(clock_50)
18
begin
19
if rising_edge(clock_50) then  
20
21
22
   if(clock_en='1')then
23
     matrix_clk<='1';
24
   if(shiftcounter<31)then
25
    matrix_latch<='0';
26
    else
27
    matrix_latch<='1';
28
   end if;
29
     if(ramaddr<255)then
30
       ramaddr<=ramaddr+1;
31
      else
32
       ramaddr<=0;
33
    end if;
34
    
35
         if(to_integer(unsigned(ramq))>matrix_frame)then-----pwm generation
36
          matrix_r1<='1';
37
          else
38
          matrix_r1<='0';
39
           end if;
40
    if(shiftcounter<31)then----pixelcounter
41
42
      shiftcounter<=shiftcounter+1;
43
     else
44
      shiftcounter<=0;
45
       if(lines<7)then----linecounter
46
         lines<=lines+1;
47
       else  
48
           lines<=0;
49
             if(matrix_frame<255)then----framecounter
50
             matrix_frame<=matrix_frame+1;
51
          else
52
            matrix_frame<=0;
53
          end if;
54
           end if;
55
    end if;
56
  else
57
  matrix_clk<='0';
58
  end if;
59
end if;
60
end process;
61
end main;

von Duke Scarring (Gast)


Lesenswert?

Hast Du noch einen Link zum Schaltplan der Matrix?
Und wie sieht Deine entity aus?

von GS (chromosoma)


Lesenswert?

Duke Scarring schrieb:
> Hast Du noch einen Link zum Schaltplan der Matrix?
> Und wie sieht Deine entity aus?

Hi.
Hier ist die Matrix
http://www.adafruit.com/product/420

Entity zeige ich, sobald ich zuhause bin.

von GS (chromosoma)


Lesenswert?

Bitte, helft mir. Ich habe schon alles versucht,aber die benachbarten 
Zeilen leuchten auch einwenig.(wie im Bild)
Ich schalte OE immer aus, bevor ich die Zeilen ändere, verdammt, was tue 
ich denn falsch?

Hier ist  mein übersichtlicher Code:
1
process(clock_50)
2
begin
3
if rising_edge(clock_50) then  
4
5
   if(clock_en='1')then  
6
7
8
      case matrixst is
9
    when st0 =>      
10
11
         matrixst<=st1;
12
    when st1 =>------shift pixeldata           
13
14
         matrix_r1<=test((shiftcounter+lines*4));--------testdata
15
         matrix_clk<='1';-------clock the data into register
16
      if(shiftcounter<31)then    
17
        shiftcounter<=shiftcounter+1;
18
      else  
19
          shiftcounter<=0;  
20
                       matrix_oe_n<='1';---disable output
21
          matrix_latch<='0';
22
        matrixst<=st2;
23
24
      end if;
25
      when st2=>       -----------latch data, on falling egde,set new address
26
             matrix_latch<='1';----latch data
27
             gpio_1(3 downto 1)<=std_logic_vector(to_unsigned(lines,3));-----set new adress
28
                    matrixst<=st3;
29
30
      when st3=>              
31
             if(lines<7)then  ------move to next line
32
          lines<=lines+1;
33
         else
34
          lines<=0;
35
            end if;
36
37
           matrix_latch<='0';
38
        matrixst<=st4;
39
40
    when st4=>  
41
            matrix_oe_n<='0';------enable output
42
            matrixst<=st5;
43
    when st5=>
44
             
45
                 ----------small delay--------
46
             if(delay<20)then
47
         delay<=delay+1;
48
         else
49
         delay<=0;
50
51
         matrixst<=st0;
52
         end if;
53
    when others=>NULL;
54
    end case;
55
  else
56
  matrix_clk<='0';
57
  end if;
58
end if;
59
end process;

: Bearbeitet durch User
von GS (chromosoma)


Angehängte Dateien:

Lesenswert?

Hier ist noch ein Bild.wie man sieht leuchten die benachbarte LED auch 
einwenig.Istes vllt normal für  eine LED Matrix,eine Art crosstalking...

von Achim S. (Gast)


Lesenswert?

Böser Kommunist schrieb:
> verdammt, was tue
> ich denn falsch?

1) du zeigst uns kein Datenblatt zur Matrix (unter dem Link oben habe 
ich zumindest keinen gefunden, und stundenlag suchen möchte ich nicht).
2) du zeigst uns keinen Schaltplan
3) du zeigst uns nicht deine Entity (bzw. wie deine internen Signale auf 
das Interface gemapt sind).

Sollen wir erraten, wie die Matrix korrekt angesteuert werden müsste, 
damit wir den Fehler in deinem Code suchen können?

Ok, dann mache ich mal einen Versuch zu raten (und du wirst mir 
wahrscheinlich gleich darauf erklären, dass ich falsch liege, weil die 
Matrix das genau so sehen will): In st1 setzt du matrix_clk 32 
Taktzyklen lang fest auf 1. Ich würde bei einem CLK-Signal darauf 
tippen, dass es die 32 Zyklen lang toggeln muss (also 32 mal von 0 auf 1 
schalten).

Ansonsten gilt der selbe Ratschlag wie immer: simuliere dein Design und 
prüfe nach, dass am Interface zur Matrix die gewünschte Signalfolge 
erzeugt wird.

Böser Kommunist schrieb:
> Hier ist noch ein Bild.wie man sieht leuchten die benachbarte LED auch
> einwenig.Istes vllt normal für  eine LED Matrix,eine Art crosstalking...

Wenn die MUX-Transistoren zu langsam abschalten (z.B. weil ein Bipolarer 
Transistor nicht schnell genug aus der Sättigung kommt), dann kann es zu 
solchem Nachleuchten kommen. Mit einem Schaltplan könnte man mehr 
sagen...

von MaWin (Gast)


Lesenswert?

Böser Kommunist schrieb:
> Ich verstehe nicht was falsch ist

Es sieht so aus, als ob du die Zeile änderst, und erst dann den Inhalt 
der Schieberegister mit dem neuen Bitmuster lädst, so daß einige Zeit 
das alte Bitmuster in der Folgezeile stehen bleibt.

Du musst ERST alle LEDs ausschalten in dem das Schieberegister genullt 
wird oder OE inaktiv wird.
DANN die Zeile wechseln.
DANN das Schieberegister mit den neuen Werten laden und an die Ausgänge 
durchschalten (LAT) und einschalten (OE).

Die Pause, in der die LEDs aus sind, muss ausreichend sein für
"I’m guessing this is caused by frequency-invariant delays in the LED 
driver shift registers."

von GS (chromosoma)


Angehängte Dateien:

Lesenswert?

Hallo, hier is noch der "Schaltplan".
Die Sache ist, es gibt keine doku  dazu.
Ich könnte die Verbindungen verfolgen, und könnte feststellen, dass alle 
signale zuerst durch den 75hc245 tranceiver durchgehen, und dann die 
MBI5025 clones  (16 constant-current output channels)  steuern.
Hier ist ein Link zur Interfacebeschreibung.
Es sollte eigentlich ganz einfach funktionieren, tut es aber nicht...


https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/new-wiring

: Bearbeitet durch User
von GS (chromosoma)


Lesenswert?

Ich tue es wirkliuch so, wie oben beschrieben:

OE_N  auf 1 setzten, LEDs ausschalten.
delay (einige µs)
Neue Zeile auswählen.
delay
neue Daten in den Register schieben.
delay
Latch aktivieren.
delay
OE_N auf '0', LED einschalten.


Trotzdem überlagern sich die benachbarten Zeilen.

Vllt ist der 74hc245 tranceiver  defekt?

Meine FPGA Ausgänge haben 3,3LVTTL , und der 74HC  benutzt LSTTL, sollte 
aber egal  sein, oder?


PS
Der nächste Schritt wäre jetzt  direkt  den Signal am Transceiver mit 
dem LogicAnalyzer anzusehen...

: Bearbeitet durch User
von GS (chromosoma)


Angehängte Dateien:

Lesenswert?

Hallo noch einmal:)

Ich habe mir die echte Signale mit dem LogicAnalyser angeschaut.
Das erste Bild(links) zeigt die Signale am FPGA Ausgang.
Das zweite Bild zeigt die Signale am 75HC Ausgang
Das dritte Bild(am FPGA gemessen) zeigt noch die Daten, die ich  in den 
Register schiebe. Wie man sieht jede Zeile bekommt immer selbe Daten.

Bis jetzt sieht alles in Ordnung aus.
Keine Ahnung was  falsch sein kann...


PS
In diesem Fall nehme ich nur zwei Zeilen.
Wenn Line=0, wird die erste  Zeile gemein,  für Line=1 die Zweite.

: Bearbeitet durch User
von Achim S. (Gast)


Lesenswert?

die kritische Zeit für das Nachleuchten von Pixeln auf der falschen 
Zeile ist die Zeit vom Umschalten der Zeile (bei dir Line bzw. Addr) zum 
Wiedereinschalten der Stromtreiber (OE). In der Zeit muss der 
MUX-Transistor der bisherigen Zeile sicher ausschalten. Das sieht in 
deinen Messungen grob nach ~2µs aus (lässt sich im Screenshot nicht so 
ganz genau bestimmen) und das könnte für gesättigte MUX-Transistoren zu 
kurz sein. Verlängere diese Zeit mal und schau, ob das Nachleuchten 
besser wird.

Dafür darfst du das OE dann auch wieder während des Eintaktens aktiv 
lassen - solange das LE auf low ist sollte es den Ausgängen des MBI5025 
egal sein, was sich in seinem Shiftregister tut.

Ansonsten würde ich mal genau nachschauen, ob die Pulsbreiten der CLK 
sicher groß genug sind (20ns min), wobei Probleme an der Stelle eher zu 
funktionalen Problemen als zu Nachleuchten führen würde.

In deinem zuletzt gezeigten Code war die Nutzung des Clock-Enable 
unschön, weil sich das folgende Konstrukt nicht per Clock-Enable an 
einem Register realisiseren lässt:

Böser Kommunist schrieb:
> if(clock_en='1')then
....
> else
>   matrix_clk<='0';

Im Code zu den Messungen ist das aber evtl. schon umgestellt, oder?

von GS (chromosoma)


Angehängte Dateien:

Lesenswert?

Morgen.
Danke für die Antwort.
Ich sitze noch an den Messungen.
Hier ist noch eine Messung direkt an dem Transistor, der die Zeilen 
ansteuert.
Ich habe noch die OE einwenig in die Mitte geschoben, trotzdem ist das 
Nachleuchten da...
 Zwischen dem Umschalten und OE vergehen gute 12 µs....sollte doch 
ausreichen, oder?

PS
Die Sache mit dem Clock Enable ist immer noch unschön, das werde ich 
korrigieren, soweit das Nachleuchten weg ist.

: Bearbeitet durch User
von Achim S. (Gast)


Lesenswert?

Böser Kommunist schrieb:
> Ich habe noch die OE einwenig in die Mitte geschoben, trotzdem ist das
> Nachleuchten da...

Ist es wenigstens ein bisschen schwächer geworden ;-) ?

Böser Kommunist schrieb:
> Zwischen dem Umschalten und OE vergehen gute 12 µs....sollte doch
> ausreichen, oder?

12µs ist in der Tat schon ganz schon lang. Bei einer halbwegs passablen 
Schaltung sollte das reichen, damit der Transistor wieder sperrt. Kannst 
du versuchen an der Schaltung abzulesen, wie der Transistor angesteuert 
wird und was für ein Transistor für die Zeile verwendet wird? Evtl. 
wären Oszi-Messungen (anstelle des Logic-Analyzers) geschickter, um dem 
Ausschaltverhalten anzusehen, ob es wirklich >12 µs dauert.

Was ansonsten noch ginge: um ganz sicher zu gehen, dass es sich um ein 
Nachleuchten (und nicht um ein optisches Übersprechen) handelt, könntest 
du mal die Zählreihenfolge der Zeilen umstellen und schauen, ob das 
Nachleuchten dann in der oberen Zeile (statt der unteren) kommt.

von MaWin (Gast)


Lesenswert?

Böser Kommunist schrieb:
> Hier ist noch eine Messung direkt an dem Transistor, der die Zeilen
> ansteuert.

Wie ich solche Software hasse, die die Ticks nicht an runden Werten 
anbringt.

Dein OE_N ist gerade mal 5 Ticks an, das sind 6.75us.

Meinst du nicht, 6.75ms wären besser ?

Die 12us sollten trotz Output staggering des MBI5025 ausreichend sein, 
er schaltet auch den langsamsten Ausgang in 135us um.

Aber wie lange brauchen die Zeilen-MOSFETs ? Wie werden die angesteuert 
? Gate-Vorwiderstand ?

von MaWin (Gast)


Lesenswert?

MaWin schrieb:

Natürlich:

Die 12us sollten trotz Output staggering des MBI5025 ausreichend sein,
er schaltet auch den langsamsten Ausgang in 135ns um.

von GS (chromosoma)


Lesenswert?

So, ich habe jetzt Delay zwischen Umschalten der Zeilen und OE erhöht, 
und  tatsächlich  lässt das Nachleuchten  langsam nach.
Erst ab 500µs Verzögerung ist fast nichts zu sehen!
Aber 500 µs  für Zeilen FET ist doch...viel?

Das  reicht gerade noch  für eine 8 Bit PWM Steuerung

Die Zeilensteuerung sieht so aus:
Die Binäre Adresse  geht durch den 74HC245  in den 74hc138 line 
decoder/multiplexer.

Aus dem 74hc138 gehe die einzelne Zeilensteuersignale in eine 8 PIN IC.
Diese übernimmt jeweils 2 Zeilen.
Auf der IC steht 4953 412601

: Bearbeitet durch User
von Achim S. (Gast)


Lesenswert?

Böser Kommunist schrieb:
> Auf der IC steht 4953 412601

Also sowas wie der hier:
https://www.fairchildsemi.com/datasheets/FD/FDS4953.pdf

Böser Kommunist schrieb:
> Erst ab 500µs Verzögerung ist fast nichts zu sehen!
> Aber 500 µs  für Zeilen FET ist doch...viel?

Das ist wirklich lahm, selbst wenn der 74HC138 nur ein paar mA treibt.

Kannst du Oszi-Messungen des Abchaltvorgangs (steigende Flanke am Gate) 
von Gate und Drain machen?

von GS (chromosoma)


Lesenswert?

das würde ich sehr gerne machen, leider habe ich kein Oszi :(



Vor den Transistoren  gibt es zwei relative grösse Kondensatoren.
Drauf steht 220 10 V.
220 µF, ist das nicht zu viel?

Vllt.  deswegen schaltet alles so langsam

von Achim S. (Gast)


Lesenswert?

Böser Kommunist schrieb:
> Vor den Transistoren  gibt es zwei relative grösse Kondensatoren.
> Drauf steht 220 10 V.
> 220 µF, ist das nicht zu viel?

Wenn Sie am Gate oder am Drain hängen würden, dann wären Sie tatsächlich 
viel zu viel ;-)

Hoffentlich hängen sie einfach an der Versorgung (also zwischen Source 
und GND). Dort kann es dann fast nicht gar zu viel sein.

von GS (chromosoma)


Lesenswert?

Ja,  die Caps sind  an der Versorgung, schade.

Trotzdem vielen dank an allen  für die Hilfe:))

: Bearbeitet durch User
von MaWin (Gast)


Lesenswert?

Böser Kommunist schrieb:
> Aus dem 74hc138 gehe die einzelne Zeilensteuersignale in eine 8 PIN IC.
> Diese übernimmt jeweils 2 Zeilen.
> Auf der IC steht 4953 412601

D.h. es wird ein MOSFET-Treiber verwendet.
Der sollte die MOSFET rasend schnell umschalten können, also genau das 
Gegenteil von auf über 500us verschliffenen Flanken bewirken.

Allerdings merkwürig, daß ein 128 verwendet wird, bei dem der aktive 
Ausgang los ist. Normalerweise wollen MSFET Treiber aktiv high (238).

von Inscheniör (Gast)


Lesenswert?

Hast Du die Verzögerung der BRAMs berücksichtigt?

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.