DycoLED

Has anyone here have any experience with UBLed's DycoLED product? From the datasheet:

  • Self-addressed led, single point control.
  • Small package with integrated RGB leds and drive IC.
  • Easy controlled by MCU.
  • Simplifying circuit design and PCB layout for designer.
  • Diffused encapsulant to make excellent distribution for luminous intensity and radiation. (patent pending)
  • Wide viewing angle. (120°)

They are tiny at 5.1mm x 5.0mm x 1.3mm. They have DATA/CLK in and out pins, voltage range of 4.5V - 7V (5.0V typical), and a forward current of 60mA (absolute max, doesn't give a typical value). Clock frequency 15MHz.

I'm trying to figure out how to write code for this thing. Whether I can modify a library or something. Again, from the datasheet:

  • The first 32 bits of "0" is the start frame data, followed by data frame. At the rising edge of Cin (clock in), the high bit of start frame is sent first, then the low bit.
  • The MCU next to the controller receives the first data frame, the frame contains one start bit of "1" and three sets of 5-bit gray level data for RGB.
  • After the data is read into the MCUs, the controller send the corresponding pulse to MCUs, then the new data goes into effect.

Pulse characteristics from the datasheet:

| Clock Pulse Width High | 30 | ns | | - | - | - | | Clock Pulse Width Low | 30 | ns | | Data Setup Before Clock | 10 | ns | | Data Hold Time | 5 | ns | | Rise Time | 500 | ns | | Fall Time | 400 | ns |

Some examples from the datasheet:

MSB will be transmitted first.

Case I : 100%Red for 1st LED, 100% Blue for 2nd LED, 100% Green for 3rd LED? 0000 0000 0000 0000 0000 0000 0000 0000 1111 1100 0000 0000 1000 0011 1110 0000 1000 0000 0001 1111

Case II : 16/31 Red for 1st LED, 16/31 Blue for 2nd LED, 16/31 Green for 3rd LED? 0000 0000 0000 0000 0000 0000 0000 0000 1100 0000 0000 0000 1000 0010 0000 0000 1000 0000 0001 0000

Case III : 100%White for 1st LED, 16/31 Blue +16/31 Green for 2nd LED, 15/31 Green for 3rd LED? 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1000 0010 0001 0000 1000 0000 0000 1111

Suggestions anyone? Figured I'd start asking now while I make a breakout board for these things.

For case one:

shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B00000000);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B00000000);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B00000000);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B00000000);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B11111100);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B00000000);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B10000011);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B11100000);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B10000000);
shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, B00011111);

You’ll need to #define your pin numbers for DATAPIN and CLOCKPIN, of course.

If you’re new to bit math you might find forming those bit strings tricky. To send an RGB of 31, 15, 7 or “1111110111100111” that would be done something like:

unsigned int ledmessage = 32768; // This is 1000000000000000 in binary; spec requires 1 in front of message.
// Per spec there are five bits of brightness for each color, or 0 to 31.
unsigned int red = 31;   // this is 0000000000011111 in binary
unsigned int green = 15; // this is 0000000000001111 in binary
unsigned int blue = 7;   // this is 0000000000000111 in binary

red = red << 10;       // shift it 10 bits, making 0000000000011111 now 0111110000000000.
green = green << 5;    // shift it 5 bits, making 0000000000001111 now 0000000111100000.
blue = blue << 0;      // this is redundant but here for readability; stays as 0000000000000111.

ledmessage = ledmessage | red | green | blue; // "or" everything together into one message.

shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, ledmessage);

Have you bought any of these yet? I looked on Mouser and Digikey (“dycoled” and “ubled”) and didn’t find much; all I could find was the LED and the manufacturer (how new is this product?)…

Based on the datasheet, it looks like it needs to somehow be attached on the PCB to a heatsink area (probably copper ground plane, from what I could see) - thermal “superglue” (like artic silver paste)? Then solder?

These LEDs look interesting, but they don’t look “hobbyist friendly”…

The manufacturer sent me 10 to test. They are similar to say a 5050 smd, except they are lower profile and the ground plane is underneath, so when creating a pcb, one has to remember to do that. Or you can leave the ground unconnected and use the Vss pin as the negative.

I'm considering getting the test module from them, 100 leds on a board and a controller, SD and software. But I won't do that till I get test these guys individually.

As for using ShiftOut, how well does that hold up on lone distances (take 100 on a string), and how fast can that be done? What about using hardware SPI?

Bumping. I just got my test PCBs back today and I will probably start soldering them tomorrow and see how that goes. I'm still curious about my last two questions, how well does ShiftOut hold up on a long string, how fast can one push data out. And what about using hardware SPI instead?

Ok, I can't figure this out. Taken the following piece of code:

int DTPin = 2;
int CKPin = 4;

void setup() {
  pinMode(DTPin, OUTPUT);
  pinMode(CKPin, OUTPUT);
}

void loop() {
  // Turn all LEDs on as red
  // Initialize by sending 0000000 0000000 0000000 0000000
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  // Led 1
  shiftOut(DTPin, CKPin, MSBFIRST, B11111100);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  // Led 2
  shiftOut(DTPin, CKPin, MSBFIRST, B11111100);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  // Led 3
  shiftOut(DTPin, CKPin, MSBFIRST, B11111100);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  delay(500);

  // Turn everything off
  // Initialize by sending 0000000 0000000 0000000 0000000
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  // Led 1
  shiftOut(DTPin, CKPin, MSBFIRST, B10000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  // Led 2
  shiftOut(DTPin, CKPin, MSBFIRST, B10000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  // Led 3
  shiftOut(DTPin, CKPin, MSBFIRST, B10000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  delay(500);
}

I thought what I'm doing is first turn all three on, red, then 500ms later turn everything off and loop. However, that's not what happens.

What happens is only the first and second LEDs come on red, and 500ms later they go off and the third one comes on red. It flip flops like that, the first two versus the last one.

Just don't get it.

Anyone? Bueller? Bueller? Bueller?

Moving on. I decided to try and drive these things using FastSPI. Dg (FastSPI maintainer) mentioned that the protocol on these LEDs is similar to the LPD1101’s. Looking that up on the web, I found some references stating that the LPD1101 is the same as the LPD6803. Well, as luck would have it, FastSPI already has code for the LPD6803, so I thought, oh why not, let’s try.

Sure enough. Using the LPD6803 option within FastSPI, one can drive these LEDs, no problem! I have ten of them (the samples they sent me), happily going through the ‘testleds’ sketch that comes with the FastSPI library. That makes me a happy camper. Now that I know I can get these to work, I’ll be ordering a much larger quantity from the vendor.

I’d still like to be able to have an alternate way of controlling these guys, bit-banging comes to mind. I like the way bit-banging works with the WS2801. This is the routine that shifts all the data out to the string and then pulls the clock pin low for >500us to latch the data"

void post_frame() {
  for(int LED_number = 0 ; LED_number < STRIP_LENGTH ; LED_number++) {
    long this_led_color = strip_colors[LED_number]; //24 bits of color data

    for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) {
      //Feed color bit 23 first (red data MSB)
      digitalWrite(SCK, LOW); //Only change data when clock is low

      long mask = 1L << color_bit;
      //The 1'L' forces the 1 to start as a 32 bit number, otherwise it defaults to 16-bit.

      if(this_led_color & mask) 
        digitalWrite(SDA, HIGH);
      else
        digitalWrite(SDA, LOW);

      digitalWrite(SCK, HIGH); //Data is latched when clock goes high
    }
  }
  //Pull clock low to put strip into reset/post mode
  digitalWrite(SCK, LOW);
  delayMicroseconds(500); //Wait for 500us to go into reset
}

What I can’t figure out is how to modify that so it works with these LEDs, or if that’s even possible. What I do know is, the WS2801 takes 3 sets of 8 bits for a total of 24 bits. These DycoLEDs take 3 sets of 5 bits. However, unlike the WS2801, these guys need a start frame of 32 bits of “0” at the beginning of the transmission, followed by the data frames for each LED in the string. Each frame contains one start bit of “1” and the 3 sets of 5 bits (so there are 16 bits total). After that, there isn’t a whole lot more from the datasheet. The clock pulse is 30ns HIGH and 30ns LOW, rise time 500ns, fall time 400ns. I’ve attached the relevant pages of the datasheet in case someone wants to take a gander at this …

The only reason I’d like the capability of bit-banging these guys is because that opens up the possibility of having a strip of them on any arbitrary pins, as opposed to always being on the SPI port. It also allows me to add multiple strings, using multiple different pins pairs.

Ideas or suggestions anyone?

DycoLED - 7-8.pdf (149 KB)

KirAsh4:
I thought what I’m doing is first turn all three on, red, then 500ms later turn everything off and loop. However, that’s not what happens.

What happens is only the first and second LEDs come on red, and 500ms later they go off and the third one comes on red. It flip flops like that, the first two versus the last one.

It sounds to me that at the end of all the shiftOuts, the clock line is being left in the wrong state. shiftOut generates a positive-going clock, and maybe you need a negative-going clock. Try copying the shiftOut function from file wiring_shift.c and swapping the HIGH and LOW written to the clock pin, also set the clock pin to HIGH in setup().

shiftOut is very slow because it is poorly implemented. Here’s a faster version (not as fast as SPI, but a great deal better than the standard shiftOut). It sends data MSB first, with a positive-going clock.

void fastShiftOut(uint8_t data)
{
  volatile uint8_t *sclkPort = portOutputRegister(digitalPinToPort(clockPin));
  volatile uint8_t *dataPort = portOutputRegister(digitalPinToPort(dataPin));
  uint8_t sclkMask = digitalPinToBitMask(clockPin);
  uint8_t dataMask = digitalPinToBitMask(dataPin);
  
  uint8_t oldSREG = SREG;
  cli();
  for (uint8_t i = 0; i < 8; ++i)
  {
    if (data & 0x80)
    {
      *dataPort |= dataMask;
    }
    else
    {
      *dataPort &= ~dataMask;
    }
    *sclkPort |= sclkMask;
    data <<= 1;
    // insert a delay here if you need a longer clock pulse
    *sclkPort &= ~sclkMask;
  }
  SREG = oldSREG;
}

Ok, after much back and forth with the manufacturer, I am going to put these guys on the back burner and keep them as a "special" item. For one, I don't like that the LED must be turned on when one applies power to the unit, but according to the manufacturer, this is how it's supposed to behave. Which makes me wonder, if they're used in a large panel, and you turn the thing on, there will be a rather large rush of current to turn all the LEDs on for the fraction of a second it takes before the uController kicks in and turns everything back off.

And the other reason is cost. They're $0.65 a piece. Now, that's not that bad to be honest [1], however they will only sell in large quantities. Minimum order would be 10,000 units. I don't know about you, but I don't have $6,500 laying around collecting dust. Apparently they have a European distributor that sells them for $0.85 a piece so I suppose they were giving me a 20 cents discount. But for that quantity, I was expecting it to be lower. And even if I turn around and sell them at $0.75 a piece (or hell, even $0.85), 1) it's a big investment, 2) it's a big gamble, assuming people will buy them.

I will stick to the regular 5050RGB series which I get for $0.12, or even the ones I prefer better, which are made by Cree, at a little under $0.50 a piece.

[1] 50x Cree RGB will run $0.66 each - but I buy them in quantities of 1,000 which drops it to $0.406 each. I'm still looking for a more direct purchase path which could potentially drop that even more.

Yep, basically the conclusions I came to while evaluating them a few months ago. A 15-20 cent price drop would get me excited, or maybe when they finally release their 24bit model and smooth out some of the rough edges on usability. Was glad to see someone had made an actual smart LED, but just need a tiny bit more from them. May still come up with a use, but only if they drop minimum qty.

Yep, that's by far the biggest drawback for me, that minimum order quantity. I mean, sure I can probably come up with a use for 10K worth of LEDs, but damn, that's still a lot. :) Unfortunately I think until they start selling a bunch of them, the price might stay high for quite some time.

Here a solution for ONE led in software, an optimized and more flexible version will come out soon:

/* Dyco Led Demo for Arduino
   Code by Christian Vengels
   coded 2012
   feel free to modify
*/
   

word ledColor;
byte ledColorMSB;
byte ledColorLSB;

int DTPin = 2;
int CLKPin = 3;

void setup() {

  pinMode(DTPin, OUTPUT);
  pinMode(CLKPin, OUTPUT);
  //black
  dycoLed(0, 0, 0);
  delay(500);
  //red
  dycoLed(31, 0, 0);
  delay(500);
  //green
  dycoLed(0, 31, 0);
  delay(500);
  //blue
  dycoLed(0, 0, 31);
  delay(500);
  //yellow
  dycoLed(31, 31, 0);
  delay(500);
  // magenta
  dycoLed(31, 0, 31);
  delay(500);
  // cyan
  dycoLed(0, 31, 31);
  delay(500);
  // white
  dycoLed(31,31,31);
  delay(500);
  // and again black
  dycoLed(0, 0, 0);
  delay(500);
  
}

void loop() {
  dycoLed(random(31), random(31), random(31));
  delay(random(50, 200));
}

/* ########################################## */
// MID-level functions

// sets the color of the Dyco Led
void dycoLed(byte r, byte g, byte b) {
  //init LED
  initLed();
  //set red
  setLedColor(r,g,b);
  sendLedColor();
  endLed();
}

/* ########################################## */
// LOW-level functions

// merges the three colors to one word
void setLedColor(byte r, byte g, byte b) {
  word ledMessage;
  word red, green, blue;
  bitSet(ledMessage, 15); // set MSB to 1.
  
  red = r << 10;       // shift it 10 bits, making 0000000000011111 now 0111110000000000.
  blue = b << 5;    // shift it 5 bits, making 0000000000001111 now 0000000111100000.
  green = g << 0;      // this is redundant but here for readability; stays as 0000000000000111.

  ledMessage = ledMessage | red | blue | green;
  
  setColorByte(ledMessage);
}

// divite color word into MSB and LSB bytes
void setColorByte(word led16) {
  ledColorLSB = lowByte(led16);
  ledColorMSB = highByte(led16);
}

// sending color bytes after init
void sendLedColor() {
  shiftOut(DTPin, CLKPin, MSBFIRST, ledColorMSB);
  shiftOut(DTPin, CLKPin, MSBFIRST, ledColorLSB);
}

// init before any color change
void initLed() {
  shiftOut(DTPin, CLKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CLKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CLKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CLKPin, MSBFIRST, B00000000);
}

// is sent after last led
void endLed() {
  digitalWrite(CLKPin, HIGH); digitalWrite(CLKPin, LOW);
  digitalWrite(CLKPin, HIGH); digitalWrite(CLKPin, LOW);
}

thx :)

A small and very basic code for a LED simular to the dycoled only with 8bit greylevel
It’s my third program on the arduino. I hope it will help somebody. :wink:

int DTPin = 8;
int CKPin = 9;

void setup() {
  pinMode(DTPin, OUTPUT);
  pinMode(CKPin, OUTPUT);
}

void loop() {
  
  for (int i=0; i<139; i++){       //Loop for 139 LED
   startframe();
   
   for (int a=0; a<i; a++){      //Black for all LED before i
     pixelblack();
   }
   
   pixelblue();                  //Turn on the LED on Position=i 
   
   for (int b=139; b>i; b--){    //Black for all LED after i
   pixelblack();                              
   }
  
  endframe();
  }

}

void startframe(){
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
}

void endframe(){
  shiftOut(DTPin, CKPin, MSBFIRST, B11100000);
  shiftOut(DTPin, CKPin, MSBFIRST, B11111111);
  shiftOut(DTPin, CKPin, MSBFIRST, B11111111);
  shiftOut(DTPin, CKPin, MSBFIRST, B11111111);
}

void pixelblue(){
    shiftOut(DTPin, CKPin, MSBFIRST, B11111111); //3Bit Startframe for 1LED; 5Bit global greylevel for the LED
    shiftOut(DTPin, CKPin, MSBFIRST, B11111111); //8Bit_Blue
    shiftOut(DTPin, CKPin, MSBFIRST, B00000000); //8Bit_Green
    shiftOut(DTPin, CKPin, MSBFIRST, B00000000); //8Bit_Red
    }
  
  
void pixelblack(){  
    shiftOut(DTPin, CKPin, MSBFIRST, B11111111);
    shiftOut(DTPin, CKPin, MSBFIRST, B00000000); 
    shiftOut(DTPin, CKPin, MSBFIRST, B00000000); 
    shiftOut(DTPin, CKPin, MSBFIRST, B00000000);
  }

What is the LED? I know that when I talked to UB LEDs last year, they said a 3x8bit version was in the works. Did UB LEDs finally release them, or did someone else start making them?

I got 20 of these for Demo purposes.

Haven't gotten to them yet, as I really need about 80 for my project.

they are T-I-N-Y indeed. It's unfortunate that the price isn't.

Glad to see that someone has been making progress on these.

I have ten of them, got them when I first started this thread. I also have the datasheet on them, though you can get that online as well. They are the same size as the regular 5050 sized ones, only thinner at 1.2mm compared to 1.6mm on the 5050s.

As far as I know, they don't have a 32bit version yet. And they are looking for distributors ... minimum purchase is 10K at $0.65 per piece. Unfortunately for them, I don't have $6,500 just "sitting around" ... From what they've told me, their distributor in Europe sells them for almost $1.10 each (0.85 Euro).

For the time being, I decided to stick with the regular 5050 RGB ones, 1,000 for $0.12 each. Sure I have to use an IC with them, but at $0.155 for a WS2801, together that's still $0.275 against the $0.65 for the DycoLED (whole sale). And the WS2801 gives me 24-bit color.

For the $1.10 retail it would cost for a single DycoLED (through their European distributor, whoever that may be), I can get a single WS2803 (18 channels) and six 5050 RGBs up and running, or four WS2801 paired with four 5050 RGBs. As I said before, UB would have to start selling a crap load of them, saturate the market, before the prices start to come down.

As far as programming them, I run them using FastSPI with the LPD6803 driver. However, my gripe with them is that as soon as power is applied to them, they come on bright white, and it's not till you send a shut off signal to them will them turn off. That's a huge in-rush current when you have a bunch of them connected together and you turn the device on. The WS280x ICs are off by default. Again, they win.

A basic library for the DycoLeds is now ready:

http://arduino.cc/forum/index.php/topic,105142.0.html

At the moment this is only for an ATtiny85, but support for other chips will follow soon.