1. New to Christmas lighting? Get started with the AusChristmasLighting 101 Manual:
    auschristmaslighting.com/wiki/AusChristmasLighting-101

9813 / 9816 pixel types

Discussion in 'The Development Lab' started by David_AVD, Sep 16, 2011.

  1. David_AVD

    David_AVD Bite my shiny metal ass!

    Joined:
    Jun 12, 2010
    Messages:
    3,536
    Likes Received:
    81
    Location:
    Victoria Point (Brisbane)
    Find Me On:
    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.
     
  2. j1sys

    j1sys There are no rules, and those are the rules. Community Project Designer

    Joined:
    May 19, 2010
    Messages:
    242
    Likes Received:
    0
    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
     
  3. OP
    OP
    David_AVD

    David_AVD Bite my shiny metal ass!

    Joined:
    Jun 12, 2010
    Messages:
    3,536
    Likes Received:
    81
    Location:
    Victoria Point (Brisbane)
    Find Me On:
    Just received some 9813 pixels in the mail, so will try to code something up in the next few days.
     
  4. OP
    OP
    David_AVD

    David_AVD Bite my shiny metal ass!

    Joined:
    Jun 12, 2010
    Messages:
    3,536
    Likes Received:
    81
    Location:
    Victoria Point (Brisbane)
    Find Me On:
    A few minutes of coding and voilà , we have flashing P9813 pixels!

    P9813 Pixels.mp4
     
  5. justinj

    justinj Apprentice Elf

    Joined:
    Aug 14, 2011
    Messages:
    88
    Likes Received:
    0
    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 :(
     
  6. OP
    OP
    David_AVD

    David_AVD Bite my shiny metal ass!

    Joined:
    Jun 12, 2010
    Messages:
    3,536
    Likes Received:
    81
    Location:
    Victoria Point (Brisbane)
    Find Me On:
    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.

    [​IMG][​IMG]
     
  7. justinj

    justinj Apprentice Elf

    Joined:
    Aug 14, 2011
    Messages:
    88
    Likes Received:
    0
    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
     
  8. justinj

    justinj Apprentice Elf

    Joined:
    Aug 14, 2011
    Messages:
    88
    Likes Received:
    0
    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.
     
  9. OP
    OP
    David_AVD

    David_AVD Bite my shiny metal ass!

    Joined:
    Jun 12, 2010
    Messages:
    3,536
    Likes Received:
    81
    Location:
    Victoria Point (Brisbane)
    Find Me On:
    Are you sending the "start/calibration" byte correctly?
     
  10. justinj

    justinj Apprentice Elf

    Joined:
    Aug 14, 2011
    Messages:
    88
    Likes Received:
    0
    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.
     
  11. OP
    OP
    David_AVD

    David_AVD Bite my shiny metal ass!

    Joined:
    Jun 12, 2010
    Messages:
    3,536
    Likes Received:
    81
    Location:
    Victoria Point (Brisbane)
    Find Me On:
    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
     
  12. justinj

    justinj Apprentice Elf

    Joined:
    Aug 14, 2011
    Messages:
    88
    Likes Received:
    0
    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)
     
  13. justinj

    justinj Apprentice Elf

    Joined:
    Aug 14, 2011
    Messages:
    88
    Likes Received:
    0
    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.
     
  14. OP
    OP
    David_AVD

    David_AVD Bite my shiny metal ass!

    Joined:
    Jun 12, 2010
    Messages:
    3,536
    Likes Received:
    81
    Location:
    Victoria Point (Brisbane)
    Find Me On:
    Yeah, I'm no help with Arduino questions. Sounds like a Mexican man's name to me. :D
     
  15. justinj

    justinj Apprentice Elf

    Joined:
    Aug 14, 2011
    Messages:
    88
    Likes Received:
    0
    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]
     

Share This Page