TLC5940 Mux Library & 74HC595 (Final Status)

Auf dieser Website gibt es eine Tlc5940Mux Library.
http://code.google.com/p/tlc5940arduino/

Nun habe ich ein paar Fragen zu dieser Library !

Wie muss man den 74LS138 für die Benutzung mit dieser Bibliothek an den Arduino anschliessen ?
Wird der TLC bei der TLC5940Mux Library genauso an den Arduino angeschlossen wie bei der TLC5940 Library, die sich ebenfalls auf dieser Website befindet ?

Meine Fragen beziehen sich hierbei auf den Arduino 2009 !

Vielleicht hat von euch ja jemand Erfahrung mit dieser Library !

Ich hab die andere benutzt, ich kam mit der nicht klar (auch weil die genannte im Alfastabium stecken geblieben ist)
http://www.thebox.myzen.co.uk/Hardware/Mini_Monome_files/Arduino_Firmware.zip auf
Mini Monome
Ich habe die beiden Files TLC5940Multiplex_pins.h und TLC5940Multiplex_defines.h für meine Zwecke geändert um eine Matrix 6 X 5 RGB LEDs ansteuern zu können und der Bibiothek einen neuen Namen gegeben. Dies auch weil Definitionen der PINs nicht in den genannten Files waren sondern in den .h bzw.cpp files der Bibiothek. Die Bibiothek ist umgeschrieben für nur 1 TLC; mehr ist möglich. Der LED-Farben-Buffer muß nur größer gemacht werden und pro Reihe die Daten für mehrere TLC hinausgeschoben werden.
Einige Funktionen sind auskommentiert weil ich sie nicht brauche. Die Bibiothek sieht das Einlesen einer 6 x 5 Taster Matrix vor. Wenn Du die nicht brauchst kannst Du noch weitere Funktionen auskommentieren.
Der Anschluß des TLC am Arudino findest Du in TLC5940Multiplex_pins.h bzw tlcmux_pins.h.
Ich benutze als Anodentreiber keinen 74xx138 sondern einen A2983 (sourcer darlington array) Der 138 spart Ausgänge da 3 PINs genügen aber dennoch braucht es einen Treiber da der 138 den Strom für 8/24 LED nicht aufbringen kann

Meine Versionen unten.
Grüße Uwe

tlcmux.zip (30.2 KB)

foto.zip (287 KB)

Hallo Uwefed,

werde mir die Daten mal genauer anschauen.

Gruss Megaionstorm

Nachtrag: Was ist auf der grünen Platine ?

Benötige ich ausser einem Arduino und 3 TLC5940 noch etwas anderes ?

Die grüne Platine ist der RTC DS1307. Das ist eine TIX-Uhr -Nachbau http://www.tixledclock.com/

Dann ein Arduino NANO, ein A2983 und ein TLC5940 und 3 Stücke der Button Pad Platine nebst Gummitasten von Sparkfun: Button Pad 4x4 - Breakout PCB - COM-08033 - SparkFun Electronics bzw Button Pad 4x4 - LED Compatible - COM-07835 - SparkFun Electronics

Außer den 3 TLCs brauchst Du noch einen A2983 und einen 74HC138 (falls Du die Anodenansteuerung multiplexen willst) und einige Widerstände und 0,1µF Entstörkondensatoren.

Grüße Uwe

Statt einem 74HC138 hätte ich einen 74LS138, statt dem A2983 einen UDN2981.

Geht das auch ?

Müßte auch mit Deinen ICs funktionieren.
Der Unterschied ist:
LS138 bzw HC138 haben leicht unterschiedliche Pegel für L und H bzw Leistungsaufnahme.
Der A2983 bzw ULN2981 haben eine unterschiedliche max Spannung an den Ausgängen. Für die Anwendung bei 5V ist dies irrilevant.

Grüße Uwe

Habe also erst einmal folgende TLC5940Mux Library versucht:
http://code.google.com/p/tlc5940arduino/

Durch die freundliche und tatkräftige Unterstützung von Alex Leone, dem Erschaffer der Library, ist es mir gelungen dies erfolgreich zu konstruieren.

Die 3 TLC5940 sind am Arduino genauso angeschlossen wie es auch bei der TLC5940 Library gemacht wird.

Der 74HC595 ist folgendermassen an den Arduino angeschlossen:
Arduino -> 74HC595
analog 0 -> Pin 14
analog 1 -> Pin 11
digital 9 -> Pin 12

Die Anoden der RGB Matrix sind direkt an dem 74HC595 angeschlossen, ohne Fets oder so !

Den Code zur Ansteuerung der Matrix durch den 74HC595 hat mir Alex Leone persönlich zugeschickt !

// SHIFT_DATA_PIN (PC0 is analog 0) = '595 SER pin (Pin 14)
#define SHIFT_DATA_PORT PORTC
#define SHIFT_DATA_PIN  PC0
#define SHIFT_DATA_DDR  DDRC
// SHIFT_CLK_PIN (PC1 is analog 1) = '595 SRCLK (Pin 11)
#define SHIFT_CLK_PORT  PORTC
#define SHIFT_CLK_PIN   PC1
#define SHIFT_CLK_DDR   DDRC
// '595 RCLK is hooked to tlc XLAT pin (Arduino digital Pin 9, 74HC595 Pin 12)


static inline void
shift8_595_row(uint8_t row)
{
  // the output of the '595 for the selected row should be high, all others
  // low
  uint8_t output = (1 << row);
  for (uint8_t bit = 0x80; bit; bit >>= 1) {
    if (bit & output) {
      SHIFT_DATA_PORT |= _BV(SHIFT_DATA_PIN);
    } else {
      SHIFT_DATA_PORT &= ~_BV(SHIFT_DATA_PIN);
    }    
    // pulse the '595 sclk
    SHIFT_CLK_PORT |= _BV(SHIFT_CLK_PIN);
    SHIFT_CLK_PORT &= ~_BV(SHIFT_CLK_PIN);
  }
}

ISR(TIMER1_OVF_vect)
{
  if (!isShifting) {
    disable_XLAT_pulses();
    isShifting = 1;
    sei();
    TlcMux_shiftRow(shiftRow);
    shift8_595_row(shiftRow);
    shiftRow++;
    if (shiftRow == NUM_ROWS) {
      shiftRow = 0;
    }
    enable_XLAT_pulses();
    isShifting = 0;
  }
}

void setup()
{
  SHIFT_DATA_DDR |= _BV(SHIFT_DATA_PIN);
  SHIFT_CLK_DDR  |= _BV(SHIFT_CLK_PIN);
  TlcMux_init();
}

Dies ist ein kleines Beispielprogramm:

#define  NUM_TLCS  3
#define  NUM_ROWS  8
#define  NUM_COLUMNS 8
#include "Tlc5940Mux.h"

volatile uint8_t isShifting;
uint8_t shiftRow;

byte red[8 * 8] = {255, 255, 255, 255, 255, 255, 255, 255,
                     0,   0,   0,   0,   0,   0,   0,   0,
                     0,   0,   0,   0,   0,   0,   0,   0,
                   255, 255, 255, 255, 255, 255, 255, 255,
                   255, 255, 255, 255, 255, 255, 255, 255,
                     0,   0,   0,   0,   0,   0,   0,   0,
                     0,   0,   0,   0,   0,   0,   0,   0,                                                                                                         
                   255, 255, 255, 255, 255, 255, 255, 255};
                  
byte green[8 * 8] = {  0,   0,   0,   0,   0,   0,   0,   0,
                     255, 255, 255, 255, 255, 255, 255, 255,
                       0,   0,   0,   0,   0,   0,   0,   0,
                       0,   0, 255, 255, 255, 255,   0,   0,
                       0,   0, 255, 255, 255, 255,   0,   0,
                       0,   0,   0,   0,   0,   0,   0,   0,
                     255, 255, 255, 255, 255, 255, 255, 255,
                       0,   0,   0,   0,   0,   0,   0,   0};
                       
byte blue[8 * 8] = {  0,   0,   0,   0,   0,   0,   0,   0,
                      0,   0,   0,   0,   0,   0,   0,   0,
                    255, 255, 255, 255, 255, 255, 255, 255,
                    255, 255,   0, 255,   0, 255, 255, 255,
                    255, 255, 255,   0, 255,   0, 255, 255,
                    255, 255, 255, 255, 255, 255, 255, 255,
                      0,   0,   0,   0,   0,   0,   0,   0,      
                      0,   0,   0,   0,   0,   0,   0,   0};
                      
byte blue2[8 * 8] = {  0,   0,   0,   0,   0,   0,   0,   0,
                       0,   0,   0,   0,   0,   0,   0,   0,
                     255, 255, 255, 255, 255, 255, 255, 255,
                     255, 255, 255,   0, 255,   0, 255, 255,
                     255, 255,   0, 255,   0, 255, 255, 255,
                     255, 255, 255, 255, 255, 255, 255, 255,
                       0,   0,   0,   0,   0,   0,   0,   0,      
                       0,   0,   0,   0,   0,   0,   0,   0};

// SHIFT_DATA_PIN (PC0 is analog 0) = '595 SER pin (Pin 14)
#define SHIFT_DATA_PORT PORTC
#define SHIFT_DATA_PIN  PC0
#define SHIFT_DATA_DDR  DDRC
// SHIFT_CLK_PIN (PC1 is analog 1) = '595 SRCLK (Pin 11)
#define SHIFT_CLK_PORT  PORTC
#define SHIFT_CLK_PIN   PC1
#define SHIFT_CLK_DDR   DDRC
// '595 RCLK is hooked to tlc XLAT pin (Arduino digital Pin 9, 74HC595 Pin 12)

int led_red;
int led_green;
int led_blue;

static inline void
shift8_595_row(uint8_t row)
{
  // the output of the '595 for the selected row should be low, all others
  // high
  uint8_t output = (1 << row);
  for (uint8_t bit = 0x80; bit; bit >>= 1) {
    if (bit & output) {
      SHIFT_DATA_PORT |= _BV(SHIFT_DATA_PIN);
    } else {
      SHIFT_DATA_PORT &= ~_BV(SHIFT_DATA_PIN);
    }    
    // pulse the '595 sclk
    SHIFT_CLK_PORT |= _BV(SHIFT_CLK_PIN);
    SHIFT_CLK_PORT &= ~_BV(SHIFT_CLK_PIN);
  }
}

ISR(TIMER1_OVF_vect)
{
  if (!isShifting) {
    disable_XLAT_pulses();
    isShifting = 1;
    sei();
    TlcMux_shiftRow(shiftRow);
    shift8_595_row(shiftRow);
    shiftRow++;
    if (shiftRow == NUM_ROWS) {
      shiftRow = 0;
    }
    enable_XLAT_pulses();
    isShifting = 0;
  }
}

void setup()
{
  SHIFT_DATA_DDR |= _BV(SHIFT_DATA_PIN);
  SHIFT_CLK_DDR  |= _BV(SHIFT_CLK_PIN);
  TlcMux_init();
}

void loop()
{
   for (byte Wiederholung = 0; Wiederholung <= 50; Wiederholung++)
   {
     for (uint8_t row = 0; row < NUM_ROWS; row++) 
     {
        for (uint8_t col = 0; col < NUM_COLUMNS; col++) 
        {
           Matrix_Pixel(row, col, red[(row * 8) + col], green[(row * 8) + col], blue[(row * 8) + col]);
        }
     }
     delay(500);
     for (uint8_t row = 0; row < NUM_ROWS; row++) 
     {
        for (uint8_t col = 0; col < NUM_COLUMNS; col++) 
        {
           Matrix_Pixel(row, col, red[(row * 8) + col], green[(row * 8) + col], blue2[(row * 8) + col]);
        }
     }
     delay(500);
   }
   RandomLight(NUM_ROWS, NUM_COLUMNS, 100, 250);
}

void RandomLight(byte NumRow, byte NumColumn, int Wiederholung, int Geschw)
{
  for (int Nr = 1; Nr <= Wiederholung; Nr += 1)
  {
     for (int Reihe = 0; Reihe < NumRow ; Reihe += 1)
     {
        for (int Zeile = 0; Zeile <= NumColumn; Zeile += 1)
        {
           Matrix_Pixel(Reihe, Zeile, random(255), random(255), random(255));
        }
     }
     delay(Geschw);
  }
}

void Matrix_Pixel(uint8_t row, uint8_t column, byte red, byte green, byte blue)
{
   led_red = map(red, 0, 255, 0, 4095);
   led_green = map(green, 0, 255, 0, 4095);
   led_blue = map(blue, 0, 255, 0, 4095);
   TlcMux_set(row, column, led_red / 1.8);
   TlcMux_set(row, column + 16, led_green);
   TlcMux_set(row, column + 32, led_blue);
}

Wenn zwischen den Ausgängen des 74HC595 und den Anoden der Matrix MOSFET's eingesetzt werden muss folgende Zeile

  // the output of the '595 for the selected row should be high, all others low
    uint8_t output = (1 << row);

in

  // the output of the '595 for the selected row should be low, all others high
  uint8_t output = ~(1 << row);

geändert werden !

http://tlc5940arduino.googlecode.com/svn/trunk/Tlc5940Mux/tlc5940mux_circuit_example.png

Benutzt habe ich folgende RGB Matrix:

60mm square 8*8 LED Matrix - super bright RGB (circle)
http://iteadstudio.com/store/index.php?main_page=product_info&cPath=35_37&products_id=189

RGB Matrix -> 74HC595
17 -> 15
18 -> 1
19 -> 2
20 -> 3
29 -> 4
30 -> 5
31 -> 6
32 -> 7

Hoffe das diese Bibliothek auch mit dem Atmega1284 funktioniert.
Muss die MCU wechseln da der Variabelnspeicher des Atmega328 zu klein ist !

hallo Megaionstorm colles projekt war gstern gleich mal darnn eine matrix mit 8x7 RGB Led´s zusammen zubauen die 3 Tlc habe ich hin bekommen

die anoten der RGB`s habe ich auch mit dem 74hc595 verbunden wie du es beschrieben hast .

also wenn ich dein code beispiel teste bekomme ich immer fehler meldung im diseble_XLAT_pulses´was not declared in this scope .
und ist es auch möglich diese matrix mit dmx anzusteuren . ???
gruss danke Tronig

Welche IDE Version ?

Welcher Arduino wird benutzt ?

TLCMux Library korrekt installiert ?

habe die 1.0.1 ich möchte das ganze mit einem arduino denke schon habe alles in die libraries ordener gepackt .

Falls eine der Library Dateien von der IDE nicht gefunden wird kannst Du Sie mit der Funktion 'Sketch/Datei hinzufügen', 'Sketch/Add file" hinzufügen !

Dies für den Fall das Du auch die Meldung '... Tlc5940Mux.h: No such file or directory'
erhälst !

Der Installationspfad der TLCMux Library sollte
'arduino-1.0.1/libraries/Tlc5940Mux'
sein !

In diesem Verzeichnis befinden sich dann die Unterverzeichnise 'examples' und 'pinouts' !

also soweit so gut die fehler meldung ist nun weg .
muss 2 rgb´s auswechseln Danke dir und ich habe auch nur 7 ROW ebenen
hast du da schon irgendwie nee idee wie ich diese nun per DMX oder lauf schrift zb durchlaufen lasse .

Du definierst den Lauftext in einem Array, einmal jeweils für Rot, Grün unf Blau.
Hier kommt dann der Viewport zum einsatz.

Das mit dem Viewport ist folgendermassen.

Dies ist das was Du darstellen willst, als Beispiel.
In diesem Fall 'HI'.

000000000000000000000000000000000000000000
011001100000001100000000000000000000000000
011001100000001100000000000000000000000000
011111100000001100000000000000000000000000
011111100000001100000000000000000000000000
011001100000001100000000000000000000000000
000000000000000000000000000000000000000000

Der Lauftext und damit das Array ist aber grösser als das Display selber.
Du kannst ja nur 8X7 Punkte auf der Matrix darstellen.
Das was Du davon zur Zeit darstellst ist der Viewport.
In diesem Fall ein grosses H.

000000000000000000000000000000000000000000
011001100000001100000000000000000000000000
011001100000001100000000000000000000000000
011111100000001100000000000000000000000000
011111100000001100000000000000000000000000
011001100000001100000000000000000000000000
000000000000000000000000000000000000000000

Wenn Du jetzt Schritt für Schritt den Viewport nach rechts verschiebst erhält Du eine Laufschrift nach links.

000000000000000000000000000000000000000000
011001100000001100000000000000000000000000
011001100000001100000000000000000000000000
011111100000001100000000000000000000000000
011111100000001100000000000000000000000000
011001100000001100000000000000000000000000
000000000000000000000000000000000000000000

In diesem Beispiel währe der Viewport elf mal um jeweils eine Spalte nach rechts weiterbewegt worden. Was auf der Matrix wie ein linkscrollender Text aussieht.