Arduino micro and the the ADAFRUIT TLC59711

Hello,

Just bought me an arduino micro to control 4 RGB leds with the adafruit TLC59711 break out board.

I'm a newbie wih arduino but have some experiene with microcontrollers from the 8051 family mainly the C8051F120 from silabs.

I downloaded and installed the adafruit library and tried to use the sketch from it .
The sketch itself was written for the arduino UNO .
In order to get it running on the MICRO I changed the definition of the data pin from the CLK and DATA as follows :

#define data 11
#define clock 13

to

#define data 10
#define clock 9

The sketch from adafruit with the adapted definitions for the data and clock and the ammount of drivers (1 instead of 2)

#include "Adafruit_TLC59711.h"
#include <SPI.h>

// How many boards do you have chained?
#define NUM_TLC59711 1

#define data   10
#define clock  9

Adafruit_TLC59711 tlc = Adafruit_TLC59711(NUM_TLC59711, clock, data);
//Adafruit_TLC59711 tlc = Adafruit_TLC59711(NUM_TLC59711);

void setup() {
  Serial.begin(9600);
  
  Serial.println("TLC59711 test");
  pinMode(10, OUTPUT);
  tlc.begin();
  tlc.write();
}

void loop() {
  colorWipe(65535, 0, 0, 100); // "Red" (depending on your LED wiring)
  delay(200);
  colorWipe(0, 65535, 0, 100); // "Green" (depending on your LED wiring)
  delay(200);
  colorWipe(0, 0, 65535, 100); // "Blue" (depending on your LED wiring)
  delay(200);
  
  rainbowCycle(5);
}


// Fill the dots one after the other with a color
void colorWipe(uint16_t r, uint16_t g, uint16_t b, uint8_t wait) {
  for(uint16_t i=0; i<8*NUM_TLC59711; i++) {
      tlc.setLED(i, r, g, b);
      tlc.write();
      delay(wait);
  }
}

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

  for(j=0; j<65535; j+=10) { // 1 cycle of all colors on wheel
    for(i=0; i < 4*NUM_TLC59711; i++) {
      Wheel(i, ((i * 65535 / (4*NUM_TLC59711)) + j) & 65535);
    }
    tlc.write();
    delay(wait);
  }
}

// Input a value 0 to 4095 to get a color value.
// The colours are a transition r - g - b - back to r.
void Wheel(uint8_t ledn, uint16_t WheelPos) {
  if(WheelPos < 21845) {
    tlc.setLED(ledn, 3*WheelPos, 65535 - 3*WheelPos, 0);
  } else if(WheelPos < 43690) {
    WheelPos -= 21845;
    tlc.setLED(ledn, 65535 - 3*WheelPos, 0, 3*WheelPos);
  } else {
    WheelPos -= 43690;
    tlc.setLED(ledn, 0, 3*WheelPos, 65535 - 3*WheelPos);
  }
}

The library file from adafruit:

#include <Adafruit_TLC59711.h>
#include <SPI.h>

Adafruit_TLC59711::Adafruit_TLC59711(uint8_t n, uint8_t c, uint8_t d) {
  numdrivers = n;
  _clk = c;
  _dat = d;

  BCr = BCg = BCb = 0x7F;

  pwmbuffer = (uint16_t *)calloc(2, 12*n);
}

Adafruit_TLC59711::Adafruit_TLC59711(uint8_t n) {
  numdrivers = n;
  _clk = -1;
  _dat = -1;

  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  SPI.setDataMode(SPI_MODE0);
  BCr = BCg = BCb = 0x7F;

  pwmbuffer = (uint16_t *)calloc(2, 12*n);
}

void  Adafruit_TLC59711::spiwriteMSB(uint32_t d) {

  if (_clk >= 0) {
    uint32_t b = 0x80;
    //  b <<= (bits-1);
    for (; b!=0; b>>=1) {
      digitalWrite(_clk, LOW);
      if (d & b)  
	digitalWrite(_dat, HIGH);
      else
	digitalWrite(_dat, LOW);
      digitalWrite(_clk, HIGH);
    }
  } else {
    SPI.transfer(d);
  }
}

void Adafruit_TLC59711::write(void) {
  uint32_t command;

  // Magic word for write
  command = 0x25;

  command <<= 5;
  //OUTTMG = 1, EXTGCK = 0, TMGRST = 1, DSPRPT = 1, BLANK = 0 -> 0x16
  command |= 0x16;

  command <<= 7;
  command |= BCr;

  command <<= 7;
  command |= BCg;

  command <<= 7;
  command |= BCb;

  cli();
  for (uint8_t n=0; n<numdrivers; n++) {
    spiwriteMSB(command >> 24);
    spiwriteMSB(command >> 16);
    spiwriteMSB(command >> 8);
    spiwriteMSB(command);

    // 12 channels per TLC59711
    for (int8_t c=11; c >= 0 ; c--) {
      // 16 bits per channel, send MSB first
      spiwriteMSB(pwmbuffer[n*12+c]>>8);
      spiwriteMSB(pwmbuffer[n*12+c]);
    }
  }

  if (_clk >= 0)
    delayMicroseconds(200);
  else
    delayMicroseconds(2);
  sei();
}



void Adafruit_TLC59711::setPWM(uint8_t chan, uint16_t pwm) {
  if (chan > 12*numdrivers) return;
  pwmbuffer[chan] = pwm;  
}


void Adafruit_TLC59711::setLED(uint8_t lednum, uint16_t r, uint16_t g, uint16_t b) {
  setPWM(lednum*3, r);
  setPWM(lednum*3+1, g);
  setPWM(lednum*3+2, b);
}


boolean Adafruit_TLC59711::begin() {
  if (!pwmbuffer) return false;

  if (_clk >= 0) {
    pinMode(_clk, OUTPUT);
    pinMode(_dat, OUTPUT);
  } else {
    SPI.begin();
  }
  return true;
}

Header file from adafruit:

#ifndef _ADAFRUIT_TLC59711_H
#define _ADAFRUIT_TLC59711_H

#include <Arduino.h>


class Adafruit_TLC59711 {
 public:
  Adafruit_TLC59711(uint8_t n, uint8_t c, uint8_t d);
  Adafruit_TLC59711(uint8_t n);

  boolean begin(void);

  void setPWM(uint8_t chan, uint16_t pwm);
  void setLED(uint8_t lednum, uint16_t r, uint16_t g, uint16_t b);
  void write(void);
  void spiwriteMSB(uint32_t d);

 private:
  uint16_t *pwmbuffer;

  uint8_t BCr, BCg, BCb;
  int8_t numdrivers, _clk, _dat;

};


#endif

When the sketch is compiled and downloaded into the Arduino micro the leds, are all off.
I'm quite sure that the leds are hooked up correctly as i was able to drive the breakout bord with my 8051 microcontroller.

I also tried to connect the pins for the SPI bus directly from the ISP header and from the dedicated pins but no results. The LEDS are still off.

I can not measure any activity on the CLK pin and data pin when the sketch is running.

To test some things out i printed out some comments in the main loop so that i could see if the program is doing something.

  colorWipe(65535, 0, 0, 100); // "Red" (depending on your LED wiring)
  Serial.println("colorwipe1");
  delay(200);
  colorWipe(0, 65535, 0, 100); // "Green" (depending on your LED wiring)
  Serial.println("colorwipe2");
  delay(200);
  colorWipe(0, 0, 65535, 100); // "Blue" (depending on your LED wiring)
  Serial.println("colorwipe3");
  delay(200);

I had to comment out the : rainbowCycle(5) line as the program hangs in this line.
The serial monitor shows me that the programming is looping

Anybody out there that could help me to get these sketch working on the arduino micro ?
I suspect that there is something wrong with the SPI communication and/definition.

Thanks on advance for the help!

regards,
Luc

In order to get it running on the MICRO I changed the definition of the data pin from the CLK and DATA as follows

Why? Why did you feel that this was necessary?

Hello,

Solved the problem with the SPI by defining the data and clk as follows:

#define data MOSI
#define clock SCK

Regards,
Luc

Hi PaulS,

Thx for responding.

I had a wrong picture of the pin layout of the Arduino Micro.
on that drawing pin 9 was defined as SCLk and Pin 10 as MOSI.

It was until I played with the example of the potentiometer that I realised that something was wrong.
On that same drawing A0 was actually A5 so i looked a bit further till I found the correct pin drawing.

lucske:
Hello,

Solved the problem with the SPI by defining the data and clk as follows:

#define data MOSI
#define clock SCK

Regards,
Luc

Yes, this is the right way to do it. The Micro has some pins which don't exactly fit into the conventional numbering scheme. Note that this will also work on every other Arduino*, as the macros for MOSI etc. are defined for them too.

*the Arduino Robot board is missing a few crucial details like this in its config files.