Pages: [1]   Go Down
Author Topic: TLS3001 (not WS2811) not working just yet ..  (Read 2396 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi guys,


With my final LED purchase from China I decided to throw in some WS2811 for a change. I've been driving LPD6803 / IC1010 and WS2801 successfully but I hadn't touched anything else yet. The LEDs are supposed to be 5v (I can also read that off the small PCB inside each LED)

The LEDs are on what I would decribe as a strand. Seperated roughly 10~25 cm from each other, connected by 3 wires. I've downloaded a few libraries to drive them but I cannot seem to get any results.

Here's a list of what I have tried:


For each of these libraries I have tried driving a single pixel and multiples. I have tried various pins. For Alan's lib I tried PORTB pin 0 which should be digital pin 8 on the Uno. I have tried another Arduino device (Uno, Mini, Ethernet).

What happens:
  • Nothing when I plug them in
  • As they don't seem to have a direction, I've tried both ends
  • After some random time a few leds will light up with random colors

Any tips on how to proceed?

Here's some of the code I used:
Code:
#include <Adafruit_NeoPixel.h>

// I HAVE TRIED SEVERAL PINS AND THE NEO_KHZ400 option too
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, 11, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  colorWipe(strip.Color(255, 0, 0), 50); // Red
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  colorWipe(strip.Color(0, 0, 255), 50); // Blue
  rainbow(20);
  rainbowCycle(20);
}

Code:
#include "FastSPI_LED2.h"
#define NUM_LEDS 150

struct CRGB leds[NUM_LEDS];

void setup() {
   delay(2000);

   LEDS.setBrightness(64);
   LEDS.addLeds<WS2811, 11>(leds, NUM_LEDS);
}

void loop() {
for(int i = 0; i < 3; i++) {
for(int iLed = 0; iLed < NUM_LEDS; iLed++) {
memset(leds, 0,  NUM_LEDS * sizeof(struct CRGB));

switch(i) {
// You can access the rgb values by field r, g, b
case 0: leds[iLed].r = 128; break;

// or by indexing into the led (r==0, g==1, b==2)
case 1: leds[iLed][i] = 128; break;

// or by setting the rgb values for the pixel all at once
case 2: leds[iLed] = CRGB(0, 0, 128); break;
}

// and now, show your led array!
LEDS.show();
delay(10);
}

// fade up
for(int x = 0; x < 128; x++) {
// The showColor method sets all the leds in the strip to the same color
LEDS.showColor(CRGB(x, 0, 0));
delay(10);
}

// fade down
for(int x = 128; x >= 0; x--) {
LEDS.showColor(CRGB(x, 0, 0));
delay(10);
}

// let's fade up by scaling the brightness
for(int scale = 0; scale < 128; scale++) {
LEDS.showColor(CRGB(0, 128, 0), scale);
delay(10);
}

// let's fade down by scaling the brightness
for(int scale = 128; scale > 0; scale--) {
LEDS.showColor(CRGB(0, 128, 0), scale);
delay(10);
}
}
}

Code:
#include <avr/io.h>
#include <util/delay.h>
#include <WS2811.h>

#define BIT(B)           (0x01 << (uint8_t)(B))
#define SET_BIT_HI(V, B) (V) |= (uint8_t)BIT(B)
#define SET_BIT_LO(V, B) (V) &= (uint8_t)~BIT(B)

#define PAUSE  1000     // msec
#define DELAY    10 // msec
 
// Define the output function, using pin 0 on port b.
DEFINE_WS2811_FN(WS2811RGB, PORTB, 0)

// Drive the three pixels in an infinit loop.
void threepixeldemo(void)
{
    // Configure pin for output.
    SET_BIT_HI(DDRB, 0);
    SET_BIT_LO(PORTB, 0);

    // off->red, off->green, off->blue
    RGB_t rgb[3] = {{0,0,0},{0,0,0},{0,0,0}};
    WS2811RGB(rgb, ARRAYLEN(rgb));
    _delay_ms(PAUSE);
    for (int i = 0; i < 255; i++) {
        rgb[0].r += 1;
        rgb[1].g += 1;
        rgb[2].b += 1;
        WS2811RGB(rgb, ARRAYLEN(rgb));
        _delay_ms(DELAY);
    }

    // loop forever.
    for (;;) {
        // red->yellow, green->cyan, blue->magenta    
        for (int i = 0; i < 255; i++) {
            rgb[0].g += 1;
            rgb[1].b += 1;
            rgb[2].r += 1;
            WS2811RGB(rgb, ARRAYLEN(rgb));
            _delay_ms(DELAY);
        }
      
    }
}

All of the code compiles and seems to be running. I am using Aruino 1.0.4.
Any help and suggestion is greatly appreciated. Here's a pic of the LEDs.

« Last Edit: June 28, 2013, 08:30:47 am by Fexduino » Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

They do have a direction, data goes in one end and comes out the other.  You need to find which side it it.  The string I have is labeled right on the frosty covering for each pixel: a small arrow that points up or down.

I'm only familiar with the FastSPI library so:
Did you connect the string's data wire to pin 11 as your code states?
How are you powering the string?  150 pixels out of any AVR pin is too much.  Even one pixel at 100% duty cycle for all three channels will be too much.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

They do have a direction, data goes in one end and comes out the other.  You need to find which side it it.  The string I have is labeled right on the frosty covering for each pixel: a small arrow that points up or down.

I'm only familiar with the FastSPI library so:
Did you connect the string's data wire to pin 11 as your code states?
How are you powering the string?  150 pixels out of any AVR pin is too much.  Even one pixel at 100% duty cycle for all three channels will be too much.

Thanks, I've double checked but still no arrow. I'm cutting one open to see if the PCB gives any other details. That also gives me the opportunity to hopefully find an IC number.
As for the number of leds, I set it to 50 since that is what my string has. I am powering them with the Arduino right now, I plan to use an external PSU. Could that give me issues at this moment? Only one way to find out!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's a few pics, I only took off the first layer..





Not really sure what TLS3001 stands for but I don't see an arrow anywhere..  smiley-confuse
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

btw, the ws2811 datasheet shows that the IC has 8 pins where the tls3001 datasheet also shows 8 pins for the SOP8 (no idea what that is).
« Last Edit: June 26, 2013, 04:15:50 pm by Fexduino » Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, on one side of those pixels, the middle wire is labeled 'DO', that's 'Data Out'.  So the wires on the other side are for data in.  Now you know the direction.  However, you have a bigger issue here.  Unless you can definitely tell that the IC is a WS2811, I'm afraid you may have a strip made with the TLS3001 instead.  Different protocol all together.
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 150
Posts: 5666
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not really sure what TLS3001 stands for but I don't see an arrow anywhere..  smiley-confuse

If you type "TLS3001" into google you'll find it's a LED controller chip. One that doesn't respond to WS2811 signals.

Mystery solved!
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Ok, on one side of those pixels, the middle wire is labeled 'DO', that's 'Data Out'.  So the wires on the other side are for data in.  Now you know the direction. 

Thanks. Turns out I guessed right because I chose the side of the PCB that contains the IC. It's good to know that DO doens't stand for data but data out.

Quote
If you type "TLS3001" into google you'll find it's a LED controller chip. One that doesn't respond to WS2811 signals

Mystery yes, problem no! I'm trying to drive them none the less but I haven't found any code yet .. Some forums mention it here and there but I wasn't able to find any protocol implementation.

Does anyone want to help interpret this  (translated from chinese datasheet):
Quote
TLS3001 data communication protocol

Gave SDI input signal pin must follow the following definitions:

a.   valid input data must be Manchester encoded signal from high to low transition indicates "1", from low to high Jump indicates "0"

b.   During chip power after a synchronization frame must be sent to the chip detection of communication baud rate. Sync frame Format is: 15'b111111111111111 +4' b0001 +11' b00000000000, sending synchronization Frame must be delayed for some time and then send the data frame, so that each chip can be done in order to accurately detect To the communication baud rate, delay time (us) greater than: Connection chip count ÷ communication baud rate (MHz) × 30

c.   several frames in the transmission data, re-send a reset frame, wait 1ms later, send it again with the Step frames for the chip to eliminate the accumulated error, reset frame format: 15'b111111111111111 +4' b0100

d.   data frame format is: 15'b111111111111111 +4' b0010 (header) + first chip 39bit second chip 39bit data + data + ...... + n-th chip 39bit data

e.   first chip is first received data chips, chip data format is: 1 'b0 (identification bits) + 12'bxxxxxxxxxxxx (output port 1 data) + 1'b0 (flag) + 12'bxxxxxxxxxxxx (inputThe port 2 data) + 1'b0 (flag) + 12'bxxxxxxxxxxxx (output port 3 data),x is 1 or the 0

f.   data is first sent MSB (most significant bit)

g.   SDI input pin in the idle state, must remain low

h.   the same frame data transmission process, must be sent contiguously, in the middle, without interruption, transmission frequency can not be Changed

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's my attempt, did I miss anything important?

Quote
a.   valid input data must be Manchester encoded signal from high to low transition indicates "1", from low to high Jump indicates "0"

Data must be a manchester encoded signal. Jumps from HIGH to LOW should be sent as 1, jumps from LOW to HIGH should be sent as 0.
http://nl.wikipedia.org/wiki/Manchester-code

Quote
During chip power after a synchronization frame must be sent to the chip detection of communication baud rate. Sync frame Format is: 15'b111111111111111 +4' b0001 +11' b00000000000, sending synchronization Frame must be delayed for some time and then send the data frame, so that each chip can be done in order to accurately detect To the communication baud rate, delay time (us) greater than: Connection chip count ÷ communication baud rate (MHz) × 30

While powering the IC, a synchronization frame must be sent to allow it to detect the baud rate. After the synchronization frame a small delay (us) is needed to allow the IC and subsequent IC's to detect the baud rate. The minimum delay is LED pixel count ÷ communication baud rate (MHz) × 30. The synchronization frame format is: 15'b111111111111111 +4' b0001 +11' b00000000000

Quote
several frames in the transmission data, re-send a reset frame, wait 1ms later, send it again with the Step frames for the chip to eliminate the accumulated error, reset frame format: 15'b111111111111111 +4' b0100

After sending the data frame a reset frame is needed to keep the IC in sync and get rid of errors. The reset frame needs to be followed by a 1ms delay. The reset frame format is: 15'b111111111111111 +4' b0100

Quote
data frame format is: 15'b111111111111111 +4' b0010 (header) + first chip 39bit second chip 39bit data + data + ...... + n-th chip 39bit data

The data frame format is: 15'b111111111111111 +4' b0010 followed by 39 bits. The 39 bits consist of 13 bits for each channel. E.g.  39'b0xxxxxxxxxxxx0yyyyyyyyyyyy0zzzzzzzzzzzz. Where x, y and z represent the respective R, G, B channel bits.

Quote
first chip is first received data chips, chip data format is: 1 'b0 (identification bits) + 12'bxxxxxxxxxxxx (output port 1 data) + 1'b0 (flag) + 12'bxxxxxxxxxxxx (inputThe port 2 data) + 1'b0 (flag) + 12'bxxxxxxxxxxxx (output port 3 data),x is 1 or the 0

The format for each data frame 39 bits sequence is as following: 1'b0 12'bxxxxxxxxxxxx 1'b0 12'byyyyyyyyyyyy 1'b0 12'bzzzzzzzzzzzz.

Quote
data is first sent MSB (most significant bit)

Data must be sent MSB, meaning that bits are send from right to left.

Quote
the same frame data transmission process, must be sent contiguously, in the middle, without interruption, transmission frequency can not be Changed

Data must be sent repeatedly meaning you cannot pause submissions.



« Last Edit: June 27, 2013, 04:24:56 pm by Fexduino » Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sample code and datasheet attached.  I lifted this from a different forum.  Hope it helps.

Also, the TLS3001 is the same as the CYT3001 ...

* TLS3001(STC12C)[2].C.txt (9.49 KB - downloaded 45 times.)
* TLS3001_V2 e.pdf (469.29 KB - downloaded 63 times.)
« Last Edit: June 27, 2013, 01:58:07 pm by KirAsh4 » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
After sending the data frame a reset frame is needed to keep the IC in sync and get rid of errors. The reset frame needs to be followed by a 1ms delay. The reset frame format is: 15'b111111111111111 +4' b0001

Oops. This was supposed to say b0100.

Quote
Sample code and datasheet attached.  I lifted this from a different forum.  Hope it helps.

Awesome, I'm going to check it out right now. In the meanwhile I was writing some bitbanging code, to see if I could get it to do something. Didn't work though .. I hope I was on the right track.

Quote
uint32_t SyncFrame = 0x3FFF8800;     // 1111111111 1111100010 0000000000
uint32_t SyncFrameMask = 0x20000000; // 1000000000 0000000000 0000000000

uint32_t ResetFrame = 0x7FFF4;       // 1111111111 11111 0100
uint32_t ResetFrameMask = 0x40000;   // 1000000000000000000

uint32_t DataHeaderFrame = 0x7FFF2;     // 111111111111111 0010
uint32_t DataHeaderFrameMask = 0x40000; // 100000000000000 0000
uint32_t DataFrameMask = 0x1000;        // 1000000000000
uint32_t BitMask = 0;

uint16_t RGB[] = {0xFFF,0,0xFFF};

int dataPin = 11;
int SendMode = 0;
int Channel = 0;
int Led = 0;

void setup()
{
  pinMode(dataPin, OUTPUT);
  Serial.begin(9600); 
}

void loop()
{
  tick();
}

void tick()
{
  switch(SendMode)
  {
    case 0:
      BitMask = SyncFrameMask;
      SendMode = 1;
      break; 
     
    case 1:
      if (BitMask & SyncFrame)
        Serial.print('1'); // digitalWrite(dataPin, HIGH);
      else
        Serial.print('0'); // digitalWrite(dataPin, LOW);       

      BitMask >>= 1;
     
      if (BitMask == 0)
      {
        SendMode = 2;
        BitMask = DataHeaderFrameMask;
        Serial.println(" sync");
        delay(50);
      }
       
      break;

    case 2:
      if (BitMask & DataHeaderFrame)
        Serial.print('1'); // digitalWrite(dataPin, HIGH);
      else
        Serial.print('0'); // digitalWrite(dataPin, LOW);       
       
      BitMask >>= 1;
     
      if (BitMask == 0)
      {
        SendMode = 3;
        BitMask = DataFrameMask;
        Channel = 0;
        Led = 0;
        Serial.println(" header");
      }
     
      break;
     
     case 3:       
      if (BitMask & RGB[Channel])
        Serial.print('1'); // digitalWrite(dataPin, HIGH);
      else
        Serial.print('0'); // digitalWrite(dataPin, LOW);       
       
      BitMask >>= 1;
     
      if (BitMask == 0)
      {       
        if (Channel++ >= 2)
        {
          Serial.print(" led ");
          Serial.println(Led);
         
          if (Led >=  2)
          {
            SendMode = 4;
            BitMask = ResetFrameMask;
          }
          else
          {
             Led++;
             Channel = 0;
             BitMask = DataFrameMask;
          }
        }
        else
        {
          BitMask = DataFrameMask;
        }
      }

      break;
     
    case 4:
      if (BitMask & ResetFrame)
        Serial.print('1'); // digitalWrite(dataPin, HIGH);
      else
        Serial.print('0'); // digitalWrite(dataPin, LOW);   
       
      BitMask >>= 1;
     
      if (BitMask == 0)
      {
        SendMode = 2;
        BitMask = DataHeaderFrameMask;
        Serial.println(" reset");
        delay(1);
      }
     
      break;
  }
 
  delay(30);
}
It prints:

Quote
111111111111111000100000000000 sync
1111111111111110010 header
011111111111100000000000000111111111111 led 0
011111111111100000000000000111111111111 led 1
011111111111100000000000000111111111111 led 2
1111111111111110100 reset
1111111111111110010 header
011111111111100000000000000111111111111 led 0
011111111111100000000000000111111111111 led 1
011111111111100000000000000111111111111 led 2
1111111111111110100 reset

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sample code and datasheet attached.  I lifted this from a different forum.  Hope it helps.

Also, the TLS3001 is the same as the CYT3001 ...

Allright, looks good. I am getting a few build errors.. Am I missing an AVR library?
(i just pasted into the arduino ide)

Quote
sketch_jun27c:18: error: 'sfr' does not name a type
sketch_jun27c:19: error: 'sfr' does not name a type
sketch_jun27c:21: error: 'sbit' does not name a type
sketch_jun27c.ino: In function 'int main()':
sketch_jun27c:53: error: 'P1M1' was not declared in this scope
sketch_jun27c:54: error: 'P1M0' was not declared in this scope
sketch_jun27c:61: error: 'SDO' was not declared in this scope
sketch_jun27c.ino: In function 'void send_data()':
sketch_jun27c:104: error: 'SDO' was not declared in this scope
sketch_jun27c.ino: In function 'void send_reset_sys()':
sketch_jun27c:117: error: 'SDO' was not declared in this scope
sketch_jun27c.ino: In function 'void send_byte(unsigned char)':
sketch_jun27c:140: error: 'SDO' was not declared in this scope
sketch_jun27c:147: error: 'CY' was not declared in this scope
sketch_jun27c.ino: In function 'void send_head()':
sketch_jun27c:301: error: 'SDO' was not declared in this scope
sketch_jun27c.ino: In function 'void send_flag(unsigned char)':
sketch_jun27c:404: error: 'SDO' was not declared in this scope
sketch_jun27c:404: error: 'CY' was not declared in this scope
sketch_jun27c.ino: In function 'void send_addr()':
sketch_jun27c:469: error: 'SDO' was not declared in this scope
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah, you're probably missing the library included at the top (reg52.h).  I have no idea what it is.

The code seems to have been written for the STC12Cxxxx family of processors.  Again, no idea, I'm just reading it from the top in the code.  Seems to indicate a 20MHz processor.

I do know this: that code is a bit-bang method for the TLS3001.  So I'm thinking those SDO, CY, P1M1, P1M0 definitions may very well be pin assignments and timers.  Just a guess though.
« Last Edit: June 27, 2013, 03:12:55 pm by KirAsh4 » Logged

Pages: [1]   Go Up
Jump to: