9813 / 9816 pixel types

David_AVD

Bite my shiny metal ass!
Community project designer
Generous elf
Joined
Jun 12, 2010
Messages
4,030
Location
Victoria Point (Brisbane)
A few nights ago, Justin mentioned in chat that he'd gotten a 5V pixel string from Ray Wu that uses a "9813" chip.

It seems that they are 8 bit, but the data format is probably not the same as the 2801. The Chinese data sheet for the P9816 (9/18 channel version) is in the ACL wiki and I found reference to it on the seedstudio wiki.

I haven't had a chance to see if the P9813 data is readily available. If someone finds the P9813 data sheet, please post a link to it and I'll add it to the wiki.

The P9816 version is interesting as it has has 9 outputs (3x RGB) with a select pin, so you can have two banks of 9 LEDs.

I hope to get some of these pixels to play around with and maybe confirm the protocol so it can be added to the various pixel controllers available through ACL.
 

j1sys

There are no rules, and those are the rules.
Community project designer
Joined
May 19, 2010
Messages
242
Location
Knoxville TN USA
I found a product/project that says it uses these chips. It has a wiki page with the communication protocol. kind of weird but doable. they at least use 32 bits per pixel so it can be done with hardware SPIs easily.
Their link for spec sheet pulls up a Chines for the P9816. So the protocol might be the same.
-Ed
http://seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED
 

David_AVD

Bite my shiny metal ass!
Community project designer
Generous elf
Joined
Jun 12, 2010
Messages
4,030
Location
Victoria Point (Brisbane)
Just received some 9813 pixels in the mail, so will try to code something up in the next few days.
 

justinj

Apprentice elf
Joined
Aug 14, 2011
Messages
88
Location
Pakenham, Victoria
YAY you got them to work :)

Good work Dave!
How is the refresh rate and colour compared to the 2801's? I don't have anything to test my half of the string with so I can't report back yet :(
 

David_AVD

Bite my shiny metal ass!
Community project designer
Generous elf
Joined
Jun 12, 2010
Messages
4,030
Location
Victoria Point (Brisbane)
I dunno, they all just look like pixels to me. LOL

They are definitely 8-bit. Use the data diagram in that seedstudio thread I linked to above and you'll have them going in no time.

 

justinj

Apprentice elf
Joined
Aug 14, 2011
Messages
88
Location
Pakenham, Victoria
Several minutes on my Arduino and Voila: (Sorry about the bad video, my only video camera is in my phone)
At first the lights are white after receiving power, then the Arduino get's it's code and start's the blinky flashy!

Arduino 9813
 

justinj

Apprentice elf
Joined
Aug 14, 2011
Messages
88
Location
Pakenham, Victoria
I've programmed my Arduino since yesterday, to hook up using the generic serial plugin from Vixen and output to the pixels (Yesterday's demonstration was just a standalone Arduino sketch), but it's not working correctly...
Is anyone here skilled with Arduino to give me a hand?
In a nutshell:
- I have it setup for only 3 nodes / 9 channels whilst testing
- The 3rd node always* has blue on slightly (This isn't a fault with the node as it works in standalone). This discolours when red or green are on and doesn't go to full intensity when blue should be on that node.
- The nodes only turn the selected colour AFTER the command finishes (If 00:00 - 00:01 should turn on Red, it doesn't turn on until 00:01 and then stays on until the next node updates)
*Always = When data is transmitting to the board. As part of void setup() I have it sending 0,0,0 to each node which blanks them all fine.
 

justinj

Apprentice elf
Joined
Aug 14, 2011
Messages
88
Location
Pakenham, Victoria
Perhaps not...What's the start/calibration byte?
That may also be the reason why the 3rd node thinks it's the first until I reset the Arduino 1 or 2 times.
I also copied most of the data from my standalone version and just added in the serial stuff where it needs to go, so I don't know why it would work on 1 and not the other.
 

David_AVD

Bite my shiny metal ass!
Community project designer
Generous elf
Joined
Jun 12, 2010
Messages
4,030
Location
Victoria Point (Brisbane)
Check the DataDealWithAndSend function in the code on the seedstudio page.

  • 32 zero bits
  • start + inverse of bits 7,6 of each colour
  • blue byte
  • green byte
  • red byte
  • Repeat steps 2..5 for all pixels
  • 32 zero bits
 

justinj

Apprentice elf
Joined
Aug 14, 2011
Messages
88
Location
Pakenham, Victoria
I worked out the issue with the nodes lighting up after they were meant to finish - I started the serial buffer from 0 instead of 1. That issue is sorted but I'm still having the 3rd node on blue, and it not working until it's been reset.
I copied the whole initialisation section from my standalone to the serial version so I'm not sure why it would work in one and not the other.
It also appears as if the void setup() process is running AGAIN after it receives the first byte of data, then after resetting the Arduino it doesn't run void setup() more than once and the lights continue normally (With the exception of the partially blue one)
 

justinj

Apprentice elf
Joined
Aug 14, 2011
Messages
88
Location
Pakenham, Victoria
Almost perfect now :)
It looks like it was more incorrect serial buffer settings causing the 3rd node to remain blue (For whatever reason it needs an extra byte in the buffer and therefor works when it's (%NodeCount% x 3) + 1)
So now after resetting the Arduino after it get's some serial data, it works perfect.
My only issue still is why I still have to reset it to stop it going through void setup the first time it receives serial data... That might be a question best directed to the Arduino forums unless I can work it out myself.
 

justinj

Apprentice elf
Joined
Aug 14, 2011
Messages
88
Location
Pakenham, Victoria
Sorry for the delay - I'd been asked to post my code here to help others.
So the following code works for 12 pixels. It's pretty easy to adapt to further, I just didn't as I was only using it for tests (There's also heavy optimisations and line reductions that could be had but again, it was a test so it was copy pasted quickly for results). Make sure that the Arduino and the Pixels share a common ground otherwise it wont work, then connect the clock lead of the pixels (Green on mine) to PIN5 and the data lead (Blue on mine) to PIN6 of the Arduino.
The following code is what I loaded onto my Arduino. It then communicates via the USB with Vixen using the Generic Serial plugin. There did seem to be a bug (At least on my Arduino but I've never updated it's bootloader which may or may not have an impact) where the Arduino would basically reset itself and go through the startup phase (I had code that flashed the pixels white > off quickly so I could see what it was doing. Feel free to omit that part of the code if desired) again and then cause the data going to the unit to be invalid and produce incorrect results. Every time this happened I reset the Arduino with it's reset button and it worked again but it only ever happened once each time it was unplugged/plugged in.
Anyhow - The code (Like I said, big, messy and a little buggy but it's great for testing. If you're capable feel free to refine and repost back here :) )
Code:
#define uint8 unsigned char 
#define uint16 unsigned int
#define uint32 unsigned long int
 
// connect to digital 0,1;
int Clkpin = 5;
int Datapin = 6;
 
void ClkProduce(void)
{
  digitalWrite(Clkpin, LOW)
  delayMicroseconds(20); 
  digitalWrite(Clkpin, HIGH);
  delayMicroseconds(20);   
}
 
void Send32Zero(void)
{
    unsigned char i;
 
 for (i=0; i<32; i++)
 {
          digitalWrite(Datapin, LOW);
          ClkProduce();
    }
}
 
uint8 TakeAntiCode(uint8 dat)
{
    uint8 tmp = 0;
 
    if ((dat & 0x80) == 0)
    {
     tmp |= 0x02; 
 }
 
 if ((dat & 0x40) == 0)
 {
     tmp |= 0x01; 
 }
 
 return tmp;
}
 
// gray data
void DatSend(uint32 dx)
{
    uint8 i;
 
 for (i=0; i<32; i++)
 {
     if ((dx & 0x80000000) != 0)
  {
            digitalWrite(Datapin, HIGH);
  }
  else
  {
                    digitalWrite(Datapin, LOW);
  }
 
  dx <<= 1;
        ClkProduce();
 }
}
 
// data processing
void DataDealWithAndSend(uint8 r, uint8 g, uint8 b)
{
    uint32 dx = 0;
 
    dx |= (uint32)0x03 << 30;             // highest two bits 1,flag bits
    dx |= (uint32)TakeAntiCode(b) << 28;
    dx |= (uint32)TakeAntiCode(g) << 26; 
    dx |= (uint32)TakeAntiCode(r) << 24;
 
    dx |= (uint32)b << 16;
    dx |= (uint32)g << 8;
    dx |= r;
 
    DatSend(dx);
}
int t = 0;     // Loop counter
int incomingByte[10];
 
void setup()  { 
  Serial.begin(9600);        // set up Serial at 9600 bps
  pinMode(Datapin, OUTPUT);
  pinMode(Clkpin, OUTPUT);
  Send32Zero(); // blank all outputs in string
  //Feel free to leave this next section out until ^^^^ if you don't want to see when the Arduino inits
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  DataDealWithAndSend(255, 255, 255);
  Send32Zero();
  delay(50);
  Send32Zero(); // blank all outputs in string
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  DataDealWithAndSend(0, 0, 0);
  Send32Zero();
  // ^^^^^^^
} 
void loop()
{  
   if (Serial.available() >= 36) {
    // read the oldest byte in the serial buffer:
     for (int t=1; t<37; t++) {
      // read each byte
      incomingByte[t] = Serial.read();
     }
    
    Send32Zero(); // output data to first 3 nodes (The others are neglected for testing purposes)
    DataDealWithAndSend(incomingByte[1], incomingByte[2], incomingByte[3]);
    DataDealWithAndSend(incomingByte[4], incomingByte[5], incomingByte[6]);
    DataDealWithAndSend(incomingByte[7], incomingByte[8], incomingByte[9]);
    DataDealWithAndSend(incomingByte[10], incomingByte[11], incomingByte[12]);
    DataDealWithAndSend(incomingByte[13], incomingByte[14], incomingByte[15]);
    DataDealWithAndSend(incomingByte[16], incomingByte[17], incomingByte[18]);
    DataDealWithAndSend(incomingByte[19], incomingByte[20], incomingByte[21]);
    DataDealWithAndSend(incomingByte[22], incomingByte[23], incomingByte[24]);
    DataDealWithAndSend(incomingByte[25], incomingByte[26], incomingByte[27]);
    DataDealWithAndSend(incomingByte[28], incomingByte[29], incomingByte[30]);
    DataDealWithAndSend(incomingByte[31], incomingByte[32], incomingByte[33]);
    DataDealWithAndSend(incomingByte[34], incomingByte[35], incomingByte[36]);    
    Send32Zero();
   }
}
[/code]
 
Top