GS 1903 LED Chip

I received a BUNCH strands of lights from China, They were marked as 2811 on the website but the chip shows

GS1903

I cannot find a data sheet and seller is less than cooperative, or there is a language barrier.

Using RGB calibrate from FASTLEDS library, none of the chipsets seem to have a proper 1 - 2 - 3 color setting. They are usually 1-1-1-3 or 1-1-1-1-2, weird ones.

Anyone ever run across these lights? i would rather not send them back or do a chargeback if i can use them. Hate to waste them.

Wiring
Setup as follows

12V wall wart to LED strip

Arduino ground going to 12V ground

Separate 5 V power supply to arduino

DIN going to pin 6.

The strange thing that i don't think other chips has seen, with 12V supplied all lights turn on.

Below is RGB Calibrate code.

#include <Adafruit_NeoPixel.h>

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(10, PIN, NEO_RGB + NEO_KHZ800);

void setup() {
strip.begin();
strip.setBrightness(1); //adjust brightness here
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(200);
//rainbowCycle(200);
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(200);
}
}

void rainbow(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}

It's a new type of pixel led, different from ucs1903 led.
I saw some bloggers in google about ucs1903 led vs gs1903 led before, but I forgot the links.
below is the datasheet of 1903 led in google diver, hope it can be helpful for you.

LindTan:
below is the datasheet of 1903 led in google diver, hope it can be helpful for you.
https://drive.google.com/file/d/15yQPMieUFUoezALY7gEHvVfIZT_hsZeQ/view

File isn't publically visible

This guy said his problems were down to the power source,
LED problem and they are the same as the WS2811.

Did you get these to work in the end? I've got the same strip and am at a bit of a dead end.

Did anyone get these strips to work? I am stuck with this too. Unfortunately, there is no information about GS1903 controller available and the controller chip on my LED strip has its markings removed.

Hi there, greetings..

Found datasheet here, in Chinese tho, hope can be useful http://read.pudn.com/downloads743/ebook/2961967/GS1903规格书-中文资料.pdf

I made successful light show with ArtNet and bunch of GS1903 couple years ago using Arduino Uno + Ethernet shield and FastLED library (using UCS1903 mode enabled). Now I working on Node MCU and aiming to control thousands pixel using wireless ArtNet without FastLED library. However, WS2812 working normally both with FastLED & bitbanging, but no luck with this GS1903 chip.

As far I know, at least in my home country, this GS1903 is 3 times cheaper than WS2812 and very abundant. Based on my experience, in order to get GS1903 working, I need to connect first led strip DI terminal that has an extra chip to the MCU (attached photo). Not sure what kind of chip it is, too lazy to check with magnifying glass, I'm not chip expert tho, just hobbyist. :fearful:


Left side has an extra chip

I'll try to update here if there's any luck.

Sorry for my bad english _

Hi all,

I think I solved my problem with GS1903 and Wemos/ESP MCUs. I need to put a 5V logic level shifter to data pin. 3.3V direct data drive from MCU to LED strip will cause flickering. Now I can drive my cheap GS1903 both with Arduino UNO & NodeMCU (ESP8266).

For anyone want to have fun with Arduino & GS1903 & FastLED library, just choose UCS1903 mode like below:

#include <FastLED.h>    // if not found, get it here http://fastled.io/

///////////////////////////////////////////////////////////////////////////////////////////
//
// Move a white dot along the strip of leds.  This program simply shows how to configure the leds,
// and then how to turn a single pixel white and then off, moving down the line of pixels.
// 

// How many leds are in the strip?
#define NUM_LEDS 60

// Data pin that led data will be written out over
#define DATA_PIN 3

// Clock pin only needed for SPI based chipsets when not using hardware SPI
//#define CLOCK_PIN 8

// This is an array of leds.  One item for each led in your strip.
CRGB leds[NUM_LEDS];

// This function sets up the ledsand tells the controller about them
void setup() {
	// sanity check delay - allows reprogramming if accidently blowing power w/leds
   	delay(2000);

      // Uncomment one of the following lines for your leds arrangement.
      // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
      // FastLED.addLeds<APA104, DATA_PIN>(leds, NUM_LEDS);
      // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);
          FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);           // <- this part
      // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);

      // FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS);
      
      // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
}

// This function runs over and over, and is where you do the magic to light
// your leds.
void loop() {
   // Move a single white led 
   for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();

      // Wait a little bit
      delay(100);

      // Turn our current led back to black for the next loop around
      leds[whiteLed] = CRGB::Black;
   }
}

Below is example to turn on GS1903 to red without library (bitbanging). Also as my foundation of any project I've made with ArtNet and LED stripes, as using library is slowing down my Arduino.

/*  This is for Arduino UNO & GS1903 LED stripes testing.
 *  This will turn on your LED to red 10 pixel count.
 *  With timing:  bit 1 -> 2us HI and then 0.5us LOW.
 *                bit 0 -> 0.5us LOW and then 2us HI.
 *  Timing based on FastLED library measured with Logic Analyzer resulting +/- 400KHz.
 *  This type of LED strip capable clocked at 800KHz, that means you can drive 340 pixel
 *  or more with decent refresh rate with single pin connection (tested).
 *  Din voltage minimum is 0.7 * Vin (12V) so if you are trying to use 3.3V MCU,
 *  it will not work, use logic level shifter instead, 5V should be OK, don't bind GND on shifter together.
 *  Datasheet can be found here https://www.mediafire.com/file/xysxxbxbifsy0sj/gs1903.pdf/file
 */

uint32_t t_f;

void setup() {
 DDRD = B00001000;  // Affect pin 3 (set pin 3 as out) see https://www.arduino.cc/en/Reference/PortManipulation
}

void loop() {  
  while((micros() - t_f) < 45L);  // wait for 50us
  cli(); // Disable interrupts so MCU only handle pin switching

for (byte ctr = 0; ctr <10; ctr++ ){            // This will turn on 10 LEDs
for (byte ctr = 0; ctr <8; ctr++ ){

PORTD = B00001000;                              // Set pin 3 to HIGH...              

// Below are dirty way to turn on and off pin signal
// The goal is sending 11111111 00000000 00000000 NRZ signal
//                          R         G       B
                          
// Start clocking first 8 bit to achieve RED -> 11111111 (255)
asm volatile( 
    "nopnt"             // 1    nop           (T = 13)    1 Cycle Arduino = 0.0625ns
    "nopnt"             // 1    nop           (T = 13)    so we repeat execute nothing 
    "nopnt"             // 1    nop           (T = 13)    31 times to get 2us
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
);
PORTD = B00000000;                              // Set pin 3 to LOW for 0.5us  
asm volatile ( 
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
  );
}


// Turn off second 8 bit (green off)
for (byte ctr = 0; ctr <8; ctr++ ){
PORTD = B00001000;
asm volatile( 
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
);
PORTD = B00000000;
asm volatile ( 
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
  );
}

// Turn off third 8 bit (blue off)
for (byte ctr = 0; ctr <8; ctr++ ){
PORTD = B00001000;
asm volatile( 
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
);
PORTD = B00000000;
asm volatile ( 
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
    "nopnt"             // 1    nop           (T = 13)
  );
}

}
  sei();                          // Enable interrupts to let Arduino breath and not crash/resetting
  t_f = micros();                 // t_f will be used to measure the 50us
                                  // 50us means tell the LED strip if 10 pixel data has end, start over.

}