Go Down

Topic: WS2801 LED Matrix funktioniert nichtmehr mit Arduino Mega (Read 1 time) previous topic - next topic

Witzman

Hallo zusammen,

ich habe mir in den letzten Wochen eine 16*20er LED Matrix aus WS2801 LEDs gebaut.
Angetrieben mit Arduino Nano, Glediator (und eigenen Scripten&FunkyClouds auszügen) - umschaltbar mittels TV Fernbedienung.


Das funktioniert soweit schon mal:
https://www.youtube.com/watch?v=sdc_4QS1G4I

Da ich Probleme habe, weitere Effekte auf den Nano zu bekommen, da zuwenig Speicherplatz, wollte ich jetzt auf den Mega umschwenken.

Soweit alles verkabelt, Sketch von Solderlabs besorgt, LED Zahl angepasst, auf den Mega kopiert und... Enttäuschung.

Ich bekomme es nicht zum laufen. Die Leds Leuchten nicht.

Ich hbae die Baudrate in Glediator auf 1M angepasst.

Anbei der Sketch von Solderlabs
Code: [Select]

//Arduino Mega Sketch to drive strands and matrices of WS2801 pixels with Glediator.
//(c)2012 by R. Heller
//wwww.solderlab.de

//Set Baudrate in Glediator to 1MBit !!!

//Change this to YOUR matrix size!!
#define Num_Pixels 16

//Serial Data Output (Arduino-Mega Pin 6)
#define SDO_Port          PORTH
#define SDO_DDR           DDRH
#define SDO_Pin           3

//Serial Data Clock (Arduino-Mega Pin 7)
#define CLK_Port          PORTH
#define CLK_DDR           DDRH
#define CLK_Pin           4

//############################################################################################################################################################
// Don't change anything upon here!                                                                                                                          #
//############################################################################################################################################################

#define Set_CLK_Low       CLK_Port     &=     ~(1 << CLK_Pin)
#define Set_CLK_High      CLK_Port     |=      (1 << CLK_Pin)
#define Set_CLK_Output    CLK_DDR      |=      (1 << CLK_Pin)

#define Set_SDO_Low       SDO_Port     &=     ~(1 << SDO_Pin)
#define Set_SDO_High      SDO_Port     |=      (1 << SDO_Pin)
#define Set_SDO_Output    SDO_DDR      |=      (1 << SDO_Pin)

#define CMD_NEW_DATA 1

unsigned char display_buffer[Num_Pixels * 3];

static unsigned char *ptr;
static unsigned int pos = 0;

volatile unsigned char go = 0;

void setup()
{
  Set_SDO_Output;
  Set_CLK_Output;
 
  //Disable global interrupts
  cli();
 
  //UART Initialisation
  UCSR0A |= (1<<U2X0);                               
  UCSR0B |= (1<<RXEN0)  | (1<<TXEN0) | (1<<RXCIE0);   
  UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00)             ;
  UBRR0H = 0;
  UBRR0L = 1; //Baud Rate 1 MBit
 
  ptr=display_buffer;
   
  //Enable global interrupts
  sei();
}

void loop()
{
  if (go==1) {shift_out_data(); go=0;}
}

//############################################################################################################################################################
// USART-Interrupt-Prozedur (called every time one byte is compeltely received)                                                                               #
//############################################################################################################################################################

ISR(USART0_RX_vect)
{
  unsigned char b;
 
  b=UDR0;
 
  if (b == CMD_NEW_DATA)  {pos=0; ptr=display_buffer; return;}   
  if (pos == (Num_Pixels*3)) {} else {*ptr=b; ptr++; pos++;} 
  if (pos == ((Num_Pixels*3)-1)) {go=1;}
}


//############################################################################################################################################################
// Shift out Data                                                                                                                                            #
//############################################################################################################################################################

void shift_out_data()
{

  for (int i=0; i<Num_Pixels; i++)
  {
    byte r = display_buffer[i*3+0];
    byte g = display_buffer[i*3+1];
    byte b = display_buffer[i*3+2];
       
    for (byte j=0; j<8; j++)
    {
       Set_CLK_Low;
       if (r & (1<<(7-j))) {Set_SDO_High;} else {Set_SDO_Low;}     
       Set_CLK_High;
    }
   
    for (byte j=0; j<8; j++)
    {
       Set_CLK_Low;
       if (g & (1<<(7-j))) {Set_SDO_High;} else {Set_SDO_Low;}     
       Set_CLK_High;
    }
   
     for (byte j=0; j<8; j++)
    {
       Set_CLK_Low;
       if (b & (byte)(1<<(7-j))) {Set_SDO_High;} else {Set_SDO_Low;}     
       Set_CLK_High;
    }
  }
 
  Set_CLK_Low;
  delayMicroseconds(800); //Latch Data
 
}

//############################################################################################################################################################
//############################################################################################################################################################
//############################################################################################################################################################



Zum Vergleich hier der Code für den Nano - der funktioniert ohne Probleme:
Code: [Select]

//Change this to YOUR matrix size!!
#define Num_Pixels 320


#define CMD_NEW_DATA 1

int SDI = 2;
int CKI = 3;

unsigned char display_buffer[Num_Pixels * 3];

static unsigned char *ptr;
static unsigned int pos = 0;

volatile unsigned char go = 0;

void setup()
{
  pinMode(SDI, OUTPUT);
  pinMode(CKI, OUTPUT);
 
  //UART Initialisation
  UCSR0A |= (1<<U2X0);                               
  UCSR0B |= (1<<RXEN0)  | (1<<TXEN0) | (1<<RXCIE0);   
  UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00)             ;
  UBRR0H = 0;
  UBRR0L = 3; //Baud Rate 0.5 MBit   --> 0% Error at 16MHz :-)
 
  ptr=display_buffer;
 
  //Enable global interrupts
  sei();
}

void loop()
{
  if (go==1) {shift_out_data(); go=0;}
}

//############################################################################################################################################################
// UART-Interrupt-Prozedur (called every time one byte is compeltely received)                                                                               #
//############################################################################################################################################################

ISR(USART_RX_vect)
{
  unsigned char b;
 
  b=UDR0;
 
  if (b == CMD_NEW_DATA)  {pos=0; ptr=display_buffer; return;}   
  if (pos == (Num_Pixels*3)) {} else {*ptr=b; ptr++; pos++;} 
  if (pos == ((Num_Pixels*3)-1)) {go=1;}
}


//############################################################################################################################################################
// Shift out Data                                                                                                                                            #
//############################################################################################################################################################

void shift_out_data()
{

  for (int i=0; i<Num_Pixels; i++)
  {
    byte r = display_buffer[i*3+0];
    byte g = display_buffer[i*3+1];
    byte b = display_buffer[i*3+2];
   
    for (byte j=0; j<8; j++)
    {
       digitalWrite(CKI, LOW);
       if (b & (byte)(1<<(7-j))) {digitalWrite(SDI, HIGH);} else {digitalWrite(SDI, LOW);}     
       digitalWrite(CKI, HIGH);
    }
   
    for (byte j=0; j<8; j++)
    {
       digitalWrite(CKI, LOW);
       if (r & (1<<(7-j))) {digitalWrite(SDI, HIGH);} else {digitalWrite(SDI, LOW);}     
       digitalWrite(CKI, HIGH);
    }
   
    for (byte j=0; j<8; j++)
    {
       digitalWrite(CKI, LOW);
       if (g & (1<<(7-j))) {digitalWrite(SDI, HIGH);} else {digitalWrite(SDI, LOW);}     
       digitalWrite(CKI, HIGH);
    }
   
  }
 
  digitalWrite(CKI, LOW);
  delayMicroseconds(800); //Latch Data

}

//############################################################################################################################################################
//############################################################################################################################################################
//############################################################################################################################################################


Ich verstehe zunächst nicht, wie beim Mega auf die Ports zugegriffen wird (oben im Comment steht 6&7, dann im Code 3&4), was das mit den PortX und DDRX auf sich hat, und an welche Pins ich die LEDS verbinden muss.
3&4 oder 6&7?
Bei beiden passiert aber nichts.

Kann mir hier jemand helfen?
Benötigt ihr weitere Infos?

Vielen Dank,
Witzman

Witzman

Problem behoben - der Sketch Funktioniert einwandfrei.

Es war das Problem mit dem AutoReset. Ich hatte zuerst die 120Ohm zw. 5V und Reset versucht, da ging nichts. Mit dem 10uf Elko zw. GND und Reset funktioniert alles.

uwefed

Gut daß wir das gemeinsam gelöst Haben ( Du hast geschrieben und wir gelesen)  ;)  ;)  ;)

Grüße Uwe

Helmuth


michael_x

Quote
Problem mit dem AutoReset. Ich hatte zuerst die 120Ohm zw. 5V und Reset versucht, da ging nichts. Mit dem 10uf Elko zw. GND und Reset funktioniert alles.
Das mit dem AutoReset kann ich bestätigen.  (Den "120 Ohm" Tip sieht man übrigens nur noch selten)

Aber das hätte ich nicht für einen sinnvollen Hinweis auf deine Problembeschreibung gehalten.

Go Up