we have installed the following setup:
8 LED Stripes WS2812B, each 1,50m / 90 LED
Teensy with octo shield, wired via LAN to the LEDs
2x Power Supply (2x4 wired) to provide enough energy
Macbook with Madmapper
We did our first attemp with 4 Stripes to check if everything works correctly in 50% of the setup.
The first two LED stripes work fine, but when we want to adress more it doesnt work anymore,
E.g. 3 if we run simple animation to 4 LED stripes:
1 works fine
2 works fine
3 everything is blinking wrong
4 nothing happens
We took the code from the "two lines madmapper sketch" and adapted it. You can find it attached, maybe you may have a look at it and see the mistake?
If you need any further information just feel free to comment, thank you so much in advantage for your help!
Have a nice weekend, Moe
Code: Select all
#include <SPI.h>
#include <FastLED.h>
#define MAD_LED_PACKET_HEADER 0xFF
#define MAD_LED_DATA 0xBE
#define MAD_LED_DETECTION 0xAE
#define MAD_LED_DETECTION_REPLY 0xEA
#define MAD_LED_PROTOCOL_VERSION 0x01
//#define DEBUG_MODE
// To test LEDs (FastLED) without the need of MadMapper or MadRouter sending data on serial port
//#define JUST_TEST_LEDS
#define NUM_LEDS_LINE0 90
#define DATA_PIN_LINE0 2
#define NUM_LEDS_LINE1 90
#define DATA_PIN_LINE1 14
#define NUM_LEDS_LINE2 90
#define DATA_PIN_LINE2 7
#define NUM_LEDS_LINE3 90
#define DATA_PIN_LINE3 8
#define NUM_LEDS_LINE4 90
#define DATA_PIN_LINE4 6
#define NUM_LEDS_LINE5 90
#define DATA_PIN_LINE5 20
#define NUM_LEDS_LINE6 90
#define DATA_PIN_LINE6 21
#define NUM_LEDS_LINE7 90
#define DATA_PIN_LINE7 5
#if NUM_LEDS_LINE0 > NUM_LEDS_LINE1
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE0
#else
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE1
#endif
#if NUM_LEDS_LINE1 > NUM_LEDS_LINE2
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE1
#else
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE2
#endif
#if NUM_LEDS_LINE2 > NUM_LEDS_LINE3
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE2
#else
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE3
#endif
#if NUM_LEDS_LINE3 > NUM_LEDS_LINE4
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE3
#else
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE4
#endif
#if NUM_LEDS_LINE4 > NUM_LEDS_LINE5
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE4
#else
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE5
#endif
#if NUM_LEDS_LINE5 > NUM_LEDS_LINE6
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE5
#else
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE6
#endif
#if NUM_LEDS_LINE6 > NUM_LEDS_LINE7
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE6
#else
#define NUM_LEDS_IN_LONGEST_LINE NUM_LEDS_LINE7
#endif
/////////add for the other new LEDS
// Fast LED Buffers
CRGB leds_line0[NUM_LEDS_LINE0];
CRGB leds_line1[NUM_LEDS_LINE1];
CRGB leds_line2[NUM_LEDS_LINE2];
CRGB leds_line3[NUM_LEDS_LINE3];
CRGB leds_line4[NUM_LEDS_LINE4];
CRGB leds_line5[NUM_LEDS_LINE5];
CRGB leds_line6[NUM_LEDS_LINE6];
CRGB leds_line7[NUM_LEDS_LINE7];
/////////add for the other new LEDS
// MadLED protocol buffer
char dataFrame[NUM_LEDS_IN_LONGEST_LINE*3];
int readingFrameOnLine=-1;
bool gotNewDataFrame=false;
enum State {
State_WaitingNextPacket,
State_GotPacketHeader,
State_WaitingLineNumber,
State_WaitingChannelCountByte1,
State_WaitingChannelCountByte2,
State_ReadingDmxFrame
};
State inputState=State_WaitingNextPacket;
unsigned int readChannelsCount=0;
unsigned int channelsLeftToRead=0;
char* frameWritePtr=dataFrame;
void setup() {
Serial.begin(921600);
for (unsigned int i=0; i<sizeof(dataFrame); i++) dataFrame[i]=0;
// Here setup FastLED first LED line protocol
// Uncomment/edit one of the following lines for your leds arrangement.
// FastLED.addLeds<TM1803, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<TM1804, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<TM1809, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<WS2811, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<WS2812, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<WS2812B, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<NEOPIXEL, DATA_PIN_LINE0>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<APA104, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<UCS1903, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<UCS1903B, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<GW6205, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<GW6205_400, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<APA102, DATA_PIN_LINE0, CLOCK_PIN_LINE0, RGB, DATA_RATE_MHZ(2)>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<WS2801, DATA_PIN_LINE0, CLOCK_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<SM16716, DATA_PIN_LINE0, CLOCK_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<LPD8806, DATA_PIN_LINE0, CLOCK_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<P9813, DATA_PIN_LINE0, CLOCK_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
// FastLED.addLeds<DOTSTAR, DATA_PIN_LINE0, CLOCK_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
FastLED.addLeds<WS2812B, DATA_PIN_LINE0, RGB>(leds_line0, NUM_LEDS_LINE0);
FastLED.addLeds<WS2812B, DATA_PIN_LINE1, RGB>(leds_line1, NUM_LEDS_LINE1);
FastLED.addLeds<WS2812B, DATA_PIN_LINE2, RGB>(leds_line2, NUM_LEDS_LINE2);
FastLED.addLeds<WS2812B, DATA_PIN_LINE3, RGB>(leds_line3, NUM_LEDS_LINE3);
FastLED.addLeds<WS2812B, DATA_PIN_LINE4, RGB>(leds_line4, NUM_LEDS_LINE4);
FastLED.addLeds<WS2812B, DATA_PIN_LINE5, RGB>(leds_line5, NUM_LEDS_LINE5);
FastLED.addLeds<WS2812B, DATA_PIN_LINE6, RGB>(leds_line6, NUM_LEDS_LINE6);
FastLED.addLeds<WS2812B, DATA_PIN_LINE7, RGB>(leds_line7, NUM_LEDS_LINE7);
Serial.print("Setup done");
}
void processByte(unsigned char currentByte) {
#ifdef DEBUG_MODE
Serial.print("GOT BYTE: "); Serial.print(currentByte,HEX);
#endif
if (currentByte==MAD_LED_PACKET_HEADER) {
inputState=State_GotPacketHeader;
#ifdef DEBUG_MODE
Serial.print("GOT PH ");
#endif
} else
if (inputState == State_WaitingNextPacket) {
// Just ignore this byte, we're not processing a packet at the moment
// Wait for next packet start (xFF)
} else
if (inputState == State_GotPacketHeader) {
if (currentByte==MAD_LED_DETECTION) {
// Send back detection reply
Serial.write(MAD_LED_DETECTION_REPLY);
Serial.write(MAD_LED_PROTOCOL_VERSION);
inputState=State_WaitingNextPacket;
} else if (currentByte==MAD_LED_DATA) {
inputState=State_WaitingLineNumber;
#ifdef DEBUG_MODE
Serial.print("GOT LD ");
#endif
} else {
// Unknown packet start, reset
inputState=State_WaitingNextPacket;
}
} else
if (inputState == State_WaitingLineNumber) {
if (currentByte>0x7F) {
// Error, reset
inputState=State_WaitingNextPacket;
#ifdef DEBUG_MODE
Serial.print("ErrLineNum: "); Serial.print(currentByte);
#endif
} else {
readingFrameOnLine=currentByte;
inputState=State_WaitingChannelCountByte1;
#ifdef DEBUG_MODE
Serial.print("GOT LN ");
#endif
}
} else
if (inputState == State_WaitingChannelCountByte1) {
if (currentByte>0x7F) {
// Error, reset
inputState=State_WaitingNextPacket;
#ifdef DEBUG_MODE
Serial.print("ErrChCNT1: "); Serial.print(currentByte);
#endif
} else {
channelsLeftToRead=currentByte;
inputState=State_WaitingChannelCountByte2;
#ifdef DEBUG_MODE
Serial.print("GOT CHC1 ");
#endif
}
} else
if (inputState == State_WaitingChannelCountByte2) {
if (currentByte>0x7F) {
// Error, reset
inputState=State_WaitingNextPacket;
#ifdef DEBUG_MODE
Serial.print("ErrChCNT2: "); Serial.print(currentByte);
#endif
} else {
channelsLeftToRead+=(int(currentByte)<<7);
if (channelsLeftToRead==0) {
// Error, reset
inputState=State_WaitingNextPacket;
#ifdef DEBUG_MODE
Serial.print("ErrChCNT=0");
#endif
} else {
frameWritePtr=dataFrame;
readChannelsCount = channelsLeftToRead;
inputState=State_ReadingDmxFrame;
#ifdef DEBUG_MODE
Serial.print("GOT CHC2 ");
#endif
}
}
} else
if (inputState==State_ReadingDmxFrame) {
*frameWritePtr++ = currentByte;
channelsLeftToRead--;
if (channelsLeftToRead==0) {
// Finished reading DMX Frame
inputState=State_WaitingNextPacket;
gotNewDataFrame=true;
#ifdef DEBUG_MODE
Serial.print("GOT DATA ");
#endif
}
}
}
void loop() {
// We read a maximum of 30000 bytes before we should call FastLED.show again
// This is a good setting for the teensy, it depends on CPU speed, so it should be set lower on a slower CPU (ie arduino)
// This limit (bytesRead<30000) is useless for protocols with a clock
// But necessary when controlling more than 600 hundred RGB leds with WS2811 / WS2812
int bytesRead=0;
while (Serial.available() > 0 && bytesRead<30000) {
processByte(Serial.read()); bytesRead++;
if (gotNewDataFrame) break;
}
#ifdef JUST_TEST_LEDS
static int value=0;
value = (value + 1) % 255;
for (int i=0; i<NUM_LEDS_LINE0; i++) leds_line0[i]=CRGB(value,value,value);
#else
if (gotNewDataFrame) {
gotNewDataFrame=false;
char* dataPtr=dataFrame;
// Copy the data frame we received in the correct FastLED buffer
if (readingFrameOnLine==0) {
for (int i=0; i<readChannelsCount; i++) {leds_line0[i]=CRGB(dataPtr[0],dataPtr[1],dataPtr[2]); dataPtr+=3;}
} else if (readingFrameOnLine==1) {
for (int i=0; i<readChannelsCount; i++) {leds_line1[i]=CRGB(dataPtr[0],dataPtr[1],dataPtr[2]); dataPtr+=3;}
}
}
#endif
FastLED.show();
}