Hallo,
erstmal danke für dieses gelungene Programm!
Ich hätte noch folgende Anregungen/Wünsche:
Eine einfach zu nutzende Schnittstelle. Ich würde die LEDs gerne aus meiner Haussteuerung anpsrechen. Ginge evtl über die FB Schnittstelle. Einfacher wäre sowas wie eine Steuerdatei.
2 Mbit Baudrate
Denn habe ich eine 32x32 Matrix. Also immehrin satte 1024 LED. Es ist mir gelungen die mit einem Arduino Uno anzusteuern. (Der modifizierte Sketsch anbei). Leider geht jedoch die Wiederholrate auf 12 FPS. Das is eindeutig zu langsam für bewegte Effekte. Wird aber mit einem Mega wohl auch nicht besser, da es an der Baudrate liegt. Ich glaube der Arduino könnte 2 MBit, könnte man das nicht im Programm auch noch integrieren?
Welche Möglichkeit zur Ansteurung wäre sonst sinnvoll? 2 Arduinos geht ja auch nicht, oder ?
Hier der Code. Der Trick ist mit 2 Pins zu arbeiten und nacheinander die 1ste und 2te Hälfte zu aktualisieren. Funktioniert einwandfrei nur zu langsam.
Spoiler anzeigen
//##############################################################################
//##############################################################################
// #
// Glediator to WS2812 pixel converter #
// by R. Heller #
// V 1.0 - 07.01.2014 #
// wwww.SolderLab.de #
// #
// Receives serial data in Glediator protocol format @ 1 MBit/s #
// and distributes it to a connectect chain of WS2812 pixels #
// #
// Adjust the correct DATA PIN and the correct NUMBER OF PIXELS you are using #
// in the definitions section below before uploading this sketch to your #
// Arduino device. #
// #
// Maxiumim number of supported pixeles is 512 !!! #
// #
// In the Glediator software set output mode to "Glediator_Protocol", #
// color order to "GRB" and baud rate to "1000000" #
// #
//##############################################################################
//##############################################################################
//##############################################################################
// #
// Definitions --> Make changes ONLY HERE #
// #
// To find out the correct port, ddr and pin name when you just know the #
// Arduino's digital pin number just google for "Arduino pin mapping". #
// In the present example digital Pin 6 is used which corresponds to "PORTD", #
// "DDRD" and "6", respectively. #
// #
//##############################################################################
#define DATA_PORT PORTD
#define DATA_DDR DDRD
byte DATA_PIN;
#define DATA_PIN1 6
#define DATA_PIN2 7
#define NUMBER_OF_PIXELS 512
// size on 1 pin
// zwei Blöcke zu 512 = 1024
//##############################################################################
// #
// Variables #
// #
//##############################################################################
unsigned char display_buffer[NUMBER_OF_PIXELS * 3 ];
static unsigned char *ptr;
static unsigned int pos = 0;
volatile unsigned char go = 0;
//##############################################################################
// #
// Setup #
// #
//##############################################################################
void setup()
{
pinMode(13, OUTPUT);
// Set data pin as output
DATA_DDR |= (1 << DATA_PIN1);
DATA_DDR |= (1 << DATA_PIN2);
// Initialize UART
UCSR0A |= (1<<U2X0);
UCSR0B |= (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00) ;
UBRR0H = 0;
UBRR0L = 1; //Baud Rate 1 MBit (at F_CPU = 16MHz)
ptr=display_buffer;
DATA_PIN = DATA_PIN1;
//Enable global interrupts
sei();
}
int x = 0;
//##############################################################################
// #
// Main loop #
// #
//##############################################################################
void loop()
{
if (go==1)
{
DATA_PIN = DATA_PIN1;
cli();
ws2812_sendarray(display_buffer, NUMBER_OF_PIXELS * 3);
sei();
go=2;
}
if (go==3)
{
DATA_PIN = DATA_PIN2;
cli();
ws2812_sendarray(display_buffer, NUMBER_OF_PIXELS * 3);
sei();
go=0;
}
// delay (1); // Helps maybe if you have a flickering problem With 512 on one Pin this has helped me
}
//##############################################################################
// #
// UART-Interrupt-Prozedur (called every time one byte is compeltely received) #
// #
//##############################################################################
ISR(USART_RX_vect)
{
unsigned char b;
b=UDR0;
if (b == 1) {pos=0; ptr=display_buffer; return;}
if (pos == (NUMBER_OF_PIXELS*3*2)) {} else {*ptr=b; ptr++; pos++;}
if (go == 0 && pos == ((NUMBER_OF_PIXELS*3)-1)) {go=1;}
if (pos == ((NUMBER_OF_PIXELS*3))) ptr=display_buffer;
if (pos >= (NUMBER_OF_PIXELS*3) ) digitalWrite(13, HIGH); else digitalWrite(13, LOW);
if (go == 2 && pos == ((NUMBER_OF_PIXELS*3*2)-1)) {go=3;}
}
//##############################################################################
// #
// WS2812 output routine #
// Extracted from a ligh weight WS2812 lib by Tim (cpldcpu@gmail.com) #
// Found on wwww.microcontroller.net #
// Requires F_CPU = 16MHz #
// #
//##############################################################################
void ws2812_sendarray(uint8_t *data,uint16_t datlen)
{
uint8_t curbyte,ctr,masklo;
uint8_t maskhi = _BV(DATA_PIN);
masklo =~ maskhi & DATA_PORT;
maskhi |= DATA_PORT;
while (datlen--)
{
curbyte = *data++;
asm volatile
(
" ldi %0,8 \n\t" // 0
"loop%=:out %2, %3 \n\t" // 1
"lsl %1 \n\t" // 2
"dec %0 \n\t" // 3
" rjmp .+0 \n\t" // 5
" brcs .+2 \n\t" // 6l / 7h
" out %2,%4 \n\t" // 7l / -
" rjmp .+0 \n\t" // 9
" nop \n\t" // 10
" out %2,%4 \n\t" // 11
" breq end%= \n\t" // 12 nt. 13 taken
" rjmp .+0 \n\t" // 14
" rjmp .+0 \n\t" // 16
" rjmp .+0 \n\t" // 18
" rjmp loop%= \n\t" // 20
"end%=: \n\t"
: "=&d" (ctr)
: "r" (curbyte), "I" (_SFR_IO_ADDR(DATA_PORT)), "r" (maskhi), "r" (masklo)
);
}
}
//##############################################################################
// #
// End of program #
// #
//##############################################################################
Alles anzeigen