chipKIT® Development Platform

Inspired by Arduino™

Connecting DotStar (APA102C) LEDs To Fubarino SD

Created Mon, 19 Jan 2015 21:19:41 +0000 by BobCochran


BobCochran

Mon, 19 Jan 2015 21:19:41 +0000

[color=#0000FF]Friends,

I want to try connecting my Fubarino SD board to one (1) DotStar LED -- here is the datasheet. [url]https://www.adafruit.com/images/product-files/2343/APA102C.pdf[/url] I mounted this on an Adafruit "5050 LED Breakout" board.

I would like to run the DotStar from the Fubarino using the FastLed library. I have downloaded it from GitHub.

My question is about the connections needed to the Fubarino. I believe that the Fubarino has all 3.3v logic outputs, so I need to add a 74AHCT125 level shifter to shift the clock and data signals to 5v. Am I correct about this?

Secondly, the Fubarino offers SPI on silkscreen pins 24, 25, 26 and 27. I believe that I can use the pin 24 -- SCK as my clock signal, and pin 25 -- SDI as my data signal. Is this correct as well? This is another way of saying I am just now learning how to use hardware SPI.

Thanks!

Bob Cochran [/color]


EmbeddedMan

Mon, 19 Jan 2015 23:02:15 +0000

Bob,

How similar are the DotStard LEDs and NeoPixels? We have a great DMA based library for NeoPixels that works quite well on Fubarino SD. If they're similar enough, I'd suggest trying out our library. You can see a good instruction of how to use it here:

[url]http://www.instructables.com/id/Getting-Started-with-WS2812-LEDs-with-Digilent-chi/[/url]

*Brian


BobCochran

Tue, 20 Jan 2015 21:47:45 +0000

[color=#0000FF]Hi Brian,

The DotStar has additional pin connections as compared to the NeoPixel. I have both types of LEDs here with me. The Neopixels need 5v, ground, data in and data out connections; the DotStars need data in, clock signal in, ground, data out, clock signal out, and 5v. That is why I was asking about the SPI pins on the Fubarino.

You can be sure I will play with the Neopixel code you suggest -- I have lots of NeoPixels here, as rings, strips, and through-hole (4 wire) LEDs. But I also have one single DotStar that I soldered to a breakout board and it is the DotStar that grabs my interest at the moment.

I will experiment and see if i succeed. If I let the magic smoke out somewhere -- well, that is life, c'est la vie. I will try again. Eventually I will succeed.

Bob [/color]


majenko

Tue, 20 Jan 2015 22:20:53 +0000

DotStar just uses a fairly standard serial interface. Treat them like each LED is 3 74HC164 shift registers.

Just connect MOSI (aka SDO) to the data in, and SCK to the clock in. Provide it with power and ground, then just use SPI to transfer groups of three bytes - one group for each LED. If you have a chain of 100 LEDs that will be 300 bytes.

You only need to send the colour data when you want it to change - no need to keep refreshing like NeoPixels.


BobCochran

Wed, 21 Jan 2015 17:50:12 +0000

[color=#0000FF] Here is what I have done so far. I decided to edit some of the code I found in the examples, even though it was SPI code tailored to an Analog Devices potentiometer and not a DotStar LED. In addition, I hope to attach a photo of my wiring of the Fubarino to an 74AHCT125N level converter. The problem is, the DotStar turns on just fine. But it does not cycle through the red, green, and blue colors as I intend. Instead it shows just a steady, constant, pinkish color.

Any advice for fixing this is appreciated.

So many thanks!

Bob

/*
  Test APA102C (DotStar) LED
  
  This example controls APA102C "DotStar" LED.
  
 
 created 21 January 2015
 by Bob Cochran
 
 
 
*/


// inslude the SPI library:
#include <SPI.h>

//Define a test color value

int myRGB0[3] = {255, 0, 0};
int myRGB1[3] = {0, 255, 0};
int myRGB2[3] = {0, 0, 255};

// set pin 27 as the slave select for the digital pot:
// const int slaveSelectPin = 27;

void setup() {
  // set the slaveSelectPin as an output:
 // pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin(); 
}

void loop() {
  // go through the six channels of the digital pot:
  for (int d1 = 0; d1 < 3; d1++) { 
    // transfer bytes to the Dotstar
    
      SPI.transfer(myRGB0[d1]);
      delay(10);
      
    }
   
   delay(2000);
   
   for (int d2 = 0; d2 < 3; d2++) { 
    // transfer bytes to the Dotstar
    
      SPI.transfer(myRGB1[d2]);
      delay(10);
      
    }
    
    delay(2000);
    
    for (int d3 = 0; d3 < 3; d3++) { 
    // transfer bytes to the Dotstar
    
      SPI.transfer(myRGB2[d3]);
      delay(10);
      
    }
    
    delay(2000);
    
  }

[attachment=0]dotstar_conected_fubarino_small.jpg[/attachment] [/color]


EmbeddedMan

Thu, 22 Jan 2015 03:09:44 +0000

I would strongly suggest throwing a logic analyzer (Saleae makes some great ones that aren't too expensive) and seeing what's actually coming out those pins. That's the best way to find what's wrong with the code.

*Brian


BobCochran

Thu, 22 Jan 2015 03:24:48 +0000

[color=#0000FF]I'm having progress, of a sort. A lot of it is learning very basic C or C++ code, reading about how SPI is used, and then referring to the APA102C datasheet. It looks like the APA102C is expecting a "start frame" of 32 bits of zeroes, that is an "unsigned long", yes? Then it specifies a "LED frame" where the most significant 3 bits are on. followed by 5 bits that I assume can be anything, followed by three, 8-bit values in most significant bit to least significant bit order. Finally there is an "end frame" of 32 bits of all 1s.

If I try to transfer this using the code below, and hoping I will see the color red for a little more than 2 seconds followed by green for 3 seconds, I get the color red, and all the time.

It seems possible that I need to set a timing signal of some kind. The data sheet specifies a refresh rate of "400 cycle". That talks about timing, right? I'm not certain how to set a proper timing signal for it.

Brian, I just saw (part of?) your post while I was editing this one. I'll try to learn how to use a logic analyzer or my very expensive but only one time used Tektronix scope.

Thanks

Bob

/*
  Test APA102C (DotStar) LED
  
  This example controls APA102C "DotStar" LED.
  
 
 created 21 January 2015
 by Bob Cochran
 
 
 
*/


// include the SPI library:
#include <SPI.h>

//Define a test data frame for the APA102C

unsigned long startFrame = 0; //LED Start frame see datasheet page 3
unsigned long ledFrame1 = 0B11100000111111110000000000000000; // this appears to select red
unsigned long ledFrame2 = 0B11100000000000001111111100000000; // Hopefully this selects green
unsigned long endLedFrame = 0B11111111111111111111111111111111; // The end frame of the LED

byte myRGB0[3] = {255, 0, 0};
byte myRGB1[3] = {0, 255, 0};
byte myRGB2[3] = {0, 0, 255};

// set pin 27 as the slave select for the LED?
// It should not be needed?
const int slaveSelectPin = 27;

void setup() {
  Serial.begin(115200);
  delay(3000);
  Serial.println("Test message in the setup loop\n");
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin(); 
}

void loop() {
  // go through the six channels of the digital pot:
  // transfer 4 byte unsigned longs to the Dotstar
    
      digitalWrite(slaveSelectPin, LOW);
      SPI.transfer(startFrame);
      SPI.transfer(ledFrame1);
      SPI.transfer(endLedFrame);
      digitalWrite(slaveSelectPin, HIGH);
      delay(20);
      delay(2000);
      
      digitalWrite(slaveSelectPin, LOW);
      SPI.transfer(startFrame);
      SPI.transfer(ledFrame2);
      SPI.transfer(endLedFrame);
      digitalWrite(slaveSelectPin, HIGH);
      delay(3000);    
      
    }

[/color]


BobCochran

Thu, 22 Jan 2015 21:45:06 +0000

[color=#0000FF] I did look at the Saleae website and I will see if my spouse grants permission for purchasing one. Probably their smallest model. I need to check if their analyzer software works on OS X and Linux.

It will be interesting to make the leap from thinking about my code to understanding logic analyzer output and relating that output to lines of code.

I also took a quick look at parts of the APA102 code that is in the FastLed 3.0.3 release. I can't at all claim to be a skilled C or C++ person, but whoever wrote the APA102 *.h code seems to be using "start frames" and "LED fraames" too, but it looks to me as if the frames are being defined as unsigned bytes where I'm using unsigned longs.

Don't laugh, but I actually tried to include the FastLed library in MPIDE. When the code got compile errors, and I at last realized it is meant for AVR and Freescale parts, I had a "smacks head" moment.

Bob [/color]


EmbeddedMan

Thu, 22 Jan 2015 23:02:31 +0000

Yes, their software runs on Mac OS and Linux just fine. Their little 4 channel one is sure cute. If you can manage the price of the 8-channel though, I'd suggest it, as there are lots of times when 4 bits isn't quite enough, but 99% of the time 8 is (for me anyway, and I use my Saleae's almost daily).

*Brian


dangeljs

Fri, 23 Jan 2015 01:47:42 +0000

Bob,

It may be worth trying to send your data byte by byte, instead of putting a 32bit word in the 'SPI.transfer()' function. I tried doing a search on the MPIDE SPI library and it doesn't look like it supports any input parameter that isn't a byte size, so maybe that is part of your problem.

Also the 5 global bits appear to refer to the LED brightness, so instead of setting to zero try using all ones or some value larger than zero.

Not sure if this is the answer to all your problems but I hope it helps.

Best of luck,

Jason


BobCochran

Fri, 23 Jan 2015 02:52:42 +0000

[color=#0000ff]Thank you, Brian and Jason! I will keep plugging away at the code going byte by byte and I'll also see if I can get that 8 channel logic analyzer. I spent the evening reading about logic analyzers and thinking about how to bring this up to my spouse.

Bob [/color]


BobCochran

Sat, 24 Jan 2015 00:52:45 +0000

[color=#0000FF](Excited look) Jason, your suggestion seems to have worked. I changed my code to use byte arrays for the start, led, and end frames of the APA102C device and now the chip is cycling through the colors. The funny thing is...it starts with green, then blue, then red. I had thought it would start with red, then green, then blue. This has something to do with the most/least significant bit transfer ordering, does it?

Brian, I got spouse permission to order the logic analyzer. I will do that some time this weekend.

My code and a photo follow.

Thank you, Brian and Jason, for your advice!

Bob

/*
  Test APA102C (DotStar) LED
  
  This example controls APA102C "DotStar" LED.
  
 
 created 21 January 2015
 by Bob Cochran
 
 
 
*/


// include the SPI library:
#include <SPI.h>

//Define a set of test data frames for the APA102C, as unsigned byte arrays

byte myStartFrame[4] = {0, 0, 0, 0};                // LED "start frame" see datasheet page 3
byte ledFrame1[4] = {0B11111111, 0B11111111, 0, 0}; // this appears to select green
byte ledFrame2[4] = {0B11111111, 0, 0B11111111, 0}; // this appears to select a weakened blue
byte ledFrame3[4] = {0B11111111, 0, 0, 0B11111111}; // this appears to select red
byte endLedFrame[4] = {0xff, 0xff, 0xff, 0xff};     // The end frame of the LED

// set pin 27 as the slave select for the LED?
// It should not be needed?
const int slaveSelectPin = 27;

void setup() {
  Serial.begin(115200);
  delay(3000);
  Serial.println("Test message in the setup loop\n");
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin(); 
}

void loop() {
  
  // transfer 4 byte unsigned longs to the Dotstar
    
      digitalWrite(slaveSelectPin, LOW);
      
      for (int i = 0; i < 4; i++) {
         SPI.transfer(myStartFrame[i]);
      }
      
      for (int j = 0; j < 4; j++) {
        
        SPI.transfer(ledFrame1[j]);
      }
      
      for (int k = 0; k < 4; k++) {
        
        SPI.transfer(endLedFrame[k]);
      }
      
      digitalWrite(slaveSelectPin, HIGH);
      delay(5000);
      
      /* The code above seems to be selecting green. 
       * let us try ledFrame2[] and see what color 
       * we get.                                   */
      
      digitalWrite(slaveSelectPin, LOW);
      
      for (int i = 0; i < 4; i++) {
         SPI.transfer(myStartFrame[i]);
      }
      
      for (int j = 0; j < 4; j++) {
        
        SPI.transfer(ledFrame2[j]);
      }
      
      for (int k = 0; k < 4; k++) {
        
        SPI.transfer(endLedFrame[k]);
      }
      
      digitalWrite(slaveSelectPin, HIGH);
      delay(5000);
      
       /* The code above seems to be selecting blue. 
       * let us try ledFrame3[] and see what color 
       * we get.                                   */
      
      digitalWrite(slaveSelectPin, LOW);
      
      for (int i = 0; i < 4; i++) {
         SPI.transfer(myStartFrame[i]);
      }
      
      for (int j = 0; j < 4; j++) {
        
        SPI.transfer(ledFrame3[j]);
      }
      
      for (int k = 0; k < 4; k++) {
        
        SPI.transfer(endLedFrame[k]);
      }
      
      digitalWrite(slaveSelectPin, HIGH);
      delay(5000);
      
           
    }

[attachment=0]dotstar_running_from_pic32_board_small.jpg[/attachment] [/color]


dangeljs

Sat, 24 Jan 2015 03:08:37 +0000

Bob,

Glad to hear it worked! I know that feeling you get when you finally get something to work after spending frustrating hours trying what seems like everything. So I'm sure you have a little high.

As for the bit order, I wouldn't think this would have been a problem since you are only sending bytes of all 1's or all 0's. I wonder if the datasheet has a misprint on the ordering of the green and blue byte order.

It sounds like you are on the right track to fun project.

Enjoy,

Jason


ricklon

Mon, 21 Dec 2015 18:44:47 +0000

The Dotstar Library from Adafruit works great. Both hardware SPI and SoftSPI both function.

Here's a link to some examples: https://github.com/fubarlabs/circuitsunday/tree/master/week4

I recommend using the chipKIT-core plus Arudino. http://chipkit.net/wiki/index.php?title=ChipKIT_core