Leonardo with the TLC5940

I don't have F/M headers :frowning:

I should have mentioned that I tried connecting directly to the ICSP but didn't have any luck. I think the problem lays in my attempt at rewriting the pin layouts. The Atmega_xx8 file uses pin designations like PB0 and PD5 whereas the Teensy_XXuh file uses numbered pins such as 16, 17, etc..

I've tried both methods of mapping but still have the same blank result. Mind you I'm a complete newbie when it comes to this so I'm sure I'm missing something simple.

Interesting. You tried the PB# method? Maybe instead of PB# it uses PORTB#

Hello I'm a beginner with Arduino and I got same problem.

I've to clear the solution but it works and it's something.

You have to backup and then edit .../arduinoIDEfolder/libraries/TLC5940/pinouts/chip_includes.h
after the abbrevation port definitions (many sentences like '#define PB0 PORTB0') delete all and left it like this:

/* Copyright blablabla*/
#ifndef TLC_CHIP_INCLUDES_H
#define TLC_CHIP_INCLUDES_H

/** \file
Includes the chip-specfic defaults and pin definitions. */

#include <avr/io.h>

#ifndef PB0
#define PB0 PORTB0
...
#define PH7 PORTH7
#endif

/* Chip Specific Pinouts */
#if defined (AVR_ATmega32U4)

/* Leonardo */
#include "Arduino_Leonardo.h"

#else
#error "Unknown Chip!"
#endif

#endif

Then copy 'Teensy_xxU4.h' (in the same folder), rename the copy to 'Arduino_Leonardo.h' and edit it like this:

#ifndef TLC_Teensy_xxU4_h
#define TLC_Teensy_xxU4_h

#if DATA_TRANSFER_MODE == TLC_BITBANG
#error "If you want bitbang mode, insert pin defs here"
#endif

// MOSI (Leo outter center ICSP pin) -> SIN (TLC pin 26)
#define TLC_MOSI_PIN 2
#define TLC_MOSI_PORT PORTB
#define TLC_MOSI_DDR DDRB

// SCK (Leo inner center ICSP pin) -> SCLK (TLC pin 25)
#define TLC_SCK_PIN 1
#define TLC_SCK_PORT PORTB
#define TLC_SCK_DDR DDRB

// SS (Leo RX LED)
#define TLC_SS_PIN 0
#define TLC_SS_DDR DDRB

// OC1A (Leo pin 9) -> XLAT (TLC pin 24)
#define XLAT_PIN 5
#define XLAT_PORT PORTB
#define XLAT_DDR DDRB

// OC1B (Leo pin 10) -> BLANK (TLC pin 23)
#define BLANK_PIN 6
#define BLANK_PORT PORTB
#define BLANK_DDR DDRB

// OC3A (Leo pin 5) -> GSCLK (TLC pin 18)
#define GSCLK_PIN 6
#define GSCLK_PORT PORTC
#define GSCLK_DDR DDRC
#define TLC_TIMER3_GSCLK 1

#endif

You must advise that the pin numbers are different to the Teensy, even more, you must use the SCK and MOSI signals from the ICSP connector (not mapped to digital pins in Leonardo) and the SS signal from the RX LED board). See the next images for more help (the first is for the ICSP detail algthou is not Leonardo board, and the second is for the board conection to the SS signal)

ICSP:



SS:
http://provideyourown.com/wordpress/wp-content/uploads/rx-pin-150x148.jpg

Be sure too that in .../arduinoIDEfolder/libraries/TLC5940/tlc_config.h you have correctly the numbers of TLC you're using '#define NUM_TLCS 2' (for 2 TLC5940's) at Line55

I hope this helps anyone new with Arduino Leonardo board and the TLC5940 chip.
Sorry for my english.

This fix works?

funkyguy4000:
This fix works?

Yes, I've to integrate it correctly in 'chip_includes.h' in order to not delete the rest of include orders.

At the moment this fix is usefull only for Arduino Leornardo board as the rest of hardware (#includes) are being ignored.

Is "Love" a strong word for what I feel? Thanks so much.

The new pin definitions worked perfectly.

Happy days!

Of course its not.
I...(brings up courage) love it too

Oooh guys, you make me cry :slight_smile:

However, admittedly I do not fully understand which pin/part of the leonardo to connect exactly to which pin of TLC. Could someone be so kind to clearify this? Maybe in the form as it is done explained in the BasicUse example of the TLC library?

Thanks a lot already!!

Nvermind. I have figured it out myself.
The only thing I do not understand so far is what you do with the Rx Led pin...

Okay so I noticed last night while building a circuitboard that the TLC5940 Grayscale clock (for the PWM function) is connected to the INT1 pin when set-up with an ATmega328p. When connecting it up like that on the 32U4, I noticeced the INT1 pin is also the SDA pin (for I2C/TWI). Unfortunatly my project requires the I2C bus for a different IC.

Can I change the grayscale pin for this to another pin and will still work?

funkyguy4000:
Okay so I noticed last night while building a circuitboard that the TLC5940 Grayscale clock (for the PWM function) is connected to the INT1 pin when set-up with an ATmega328p. When connecting it up like that on the 32U4, I noticeced the INT1 pin is also the SDA pin (for I2C/TWI). Unfortunatly my project requires the I2C bus for a different IC.

Can I change the grayscale pin for this to another pin and will still work?

Hi funkyguy4000

This fix works succesfully with my Leonardo. In my project, this library controls the TLCs using ICSP (center wires) and the 5, 9, 10 pins on Leonardo board. Moreover, i'm sending data to an Colorduino through I2C using SDA and SCL pins.

They works perfectly without change any pin map on this fix!

No changes at all? Its just if you put them on the right pins, it works?

Wow. I haven't gotten a chance to try this, I've been too busy with my studies.

Hi -

This code was really helpful to me, but in fact it isn't the only fix you need for the Leonardo to work with the TLC 5940. I tried running a servo motor off of it, but the pulse width was wrong. As it turns out there are some issues with the Timers used in Leonardo that are only half-addressed in the servo header file (as the GSCLK is running about 16 times too fast), but if you look at the Tlc5940.cpp file than you can figure it out.

This is the code that your tlc_servos.h file should look like if you want to run servos off of the TLC5940 with your Leonardo.

Cheers,

Erin

/*  Copyright (c) 2009 by Alex Leone <acleone ~AT~ gmail.com>

    This file is part of the Arduino TLC5940 Library.

    The Arduino TLC5940 Library is free software: you can redistribute it
    and/or modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    The Arduino TLC5940 Library is distributed in the hope that it will be
    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with The Arduino TLC5940 Library.  If not, see
    <http://www.gnu.org/licenses/>. */

#ifndef TLC_SERVOS_H
#define TLC_SERVOS_H

/** \file
    TLC servo functions. */

#include <avr/io.h>
#include "Tlc5940.h"

#ifndef SERVO_MAX_ANGLE
/** The maximum angle of the servo. */
#define SERVO_MAX_ANGLE     180
#endif
#ifndef SERVO_MIN_WIDTH
/** The 1ms pulse width for zero degrees (0 - 4095). Default 204 */
#define SERVO_MIN_WIDTH     204
#endif
#ifndef SERVO_MAX_WIDTH
/** The 2ms pulse width for 180 degrees (0 - 4095). Default 410*/
#define SERVO_MAX_WIDTH     410
#endif
#ifndef SERVO_TIMER1_TOP
/** The top value for XLAT and BLANK pulses.  This is with the div8 prescale,
    so
    \f$\displaystyle f_{PWM} = \frac{f_{osc}}{2 * 8 * SERVO\_TIMER1\_TOP} \f$
    The default is 20000, which corresponds to 50Hz. */
#define SERVO_TIMER1_TOP    20000
#endif
#ifndef SERVO_TIMER2_TOP
/** The top value for GSCLK pulses.  Related to SERVO_TIMER1_TOP by
    \f$\displaystyle SERVO\_TIMER2\_TOP =
        \frac{2 * 8 * SERVO\_TIMER1\_TOP}{4096} - 1 \f$
    The default is 77. */
#define SERVO_TIMER2_TOP    77
#endif

void tlc_initServos(uint8_t initAngle = 0);
void tlc_setServo(TLC_CHANNEL_TYPE channel, uint8_t angle);
uint8_t tlc_getServo(TLC_CHANNEL_TYPE channel);
uint16_t tlc_angleToVal(uint8_t angle);
uint8_t tlc_valToAngle(uint16_t value);

/** \addtogroup ExtendedFunctions
    \code #include "tlc_servos.h" \endcode
    - void tlc_initServos(uint8_t initAngle = 0) - initializes the tlc for
            servos.
    - void tlc_setServo(TLC_CHANNEL_TYPE channel, uint8_t angle) - sets a
            servo to an angle
    - uint8_t tlc_getServo(TLC_CHANNEL_TYPE channel) - gets the currently set
            servo angle */
/* @{ */

/** Initializes the tlc.
    \param initAngle the initial angle to set all servos to
            (0 - SERVO_MAX_ANGLE). */
void tlc_initServos(uint8_t initAngle)
{
    Tlc.init(tlc_angleToVal(initAngle));
    TCCR1B &= ~(_BV(CS12) | _BV(CS11) | _BV(CS10)); // stop timer1
    ICR1 = SERVO_TIMER1_TOP;
    TCNT1 = 0;
#ifdef TLC_ATMEGA_8_H
    uint8_t oldTCCR2 = TCCR2;
    TCCR2 = 0;
    TCNT2 = 0;
    OCR2 = SERVO_TIMER2_TOP / 2;
    TCCR2 = oldTCCR2;
#elif defined(TLC_TIMER3_GSCLK)
	uint8_t oldTCCR3B = TCCR3B;
	TCCR3B = 0;
    TCNT3 = 0;
    ICR3 = SERVO_TIMER2_TOP;
    TCCR3B = oldTCCR3B;
#else
    uint8_t oldTCCR2B = TCCR2B;
    TCCR2B = 0;
    TCNT2 = 0;
    OCR2A = SERVO_TIMER2_TOP;
    TCCR2B = oldTCCR2B;
#endif
    TCCR1B |= _BV(CS11); // start timer1 with div 8 prescale
}

/** Sets a servo on channel to angle.
    \param channel which channel to set
    \param angle (0 - SERVO_MAX_ANGLE) */
void tlc_setServo(TLC_CHANNEL_TYPE channel, uint8_t angle)
{
    Tlc.set(channel, tlc_angleToVal(angle));
}

/** Gets the current angle that channel is set to.
    \param channel which channel to get */
uint8_t tlc_getServo(TLC_CHANNEL_TYPE channel)
{
    return tlc_valToAngle(Tlc.get(channel));
}

/** Converts and angle (0 - SERVO_MAX_ANGLE) to the inverted tlc channel value
    (4095 - 0). */
uint16_t tlc_angleToVal(uint8_t angle)
{
    return 4095 - SERVO_MIN_WIDTH - (
            ((uint16_t)(angle) * (uint16_t)(SERVO_MAX_WIDTH - SERVO_MIN_WIDTH))
            / SERVO_MAX_ANGLE);
}

/** Converts an inverted tlc channel value (4095 - 0) into an angle (0 -
    SERVO_MAX_ANGLE). */
uint8_t tlc_valToAngle(uint16_t value)
{
    return SERVO_MAX_ANGLE * (4095 - SERVO_MIN_WIDTH - value)
            / (SERVO_MAX_WIDTH - SERVO_MIN_WIDTH);
}

/* @} */

#endif

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

dodgerts:
Nvermind. I have figured it out myself.
The only thing I do not understand so far is what you do with the Rx Led pin...

Hello,

I know this post is already dated. However, since you asked for the pin mapping and figured it out yourself it would have been cool if you would have provided that mapping. Maybe you still have it somewhere and could post it here for reasons of documentation and helping out a n00b.

Thank you.

I echo minuteman's sentiments -- I would love to see the resolution to this.

I just want to confirm that I got the TLC5940 running with an Arduino Micro, which also is based on the ATmega32u4 and similar to the Leonardo.
I did not have to change anything in the TLC driver (except the NUM_TLCS in the tlc_config.h), the original Teensy support in the TLC library is working fine. Here is the pin mapping for the Arduino Micro:

Arduino Micro TLC5940
SCK (Pin 17) --> SCLK (Pin 25)
MOSI (Pin 18) --> SIN (Pin 26)
D9 (Pin 31) --> XLAT (Pin 24)
D10 (Pin 32) --> BLANK (Pin 23)
D5 (Pin 27) --> GSCLK (Pin 18)

I have such error Uknown Chip when uploading code for intel galileo using arduino ide

blaugelbweiss:
I just want to confirm that I got the TLC5940 running with an Arduino Micro, which also is based on the ATmega32u4 and similar to the Leonardo.
I did not have to change anything in the TLC driver (except the NUM_TLCS in the tlc_config.h), the original Teensy support in the TLC library is working fine. Here is the pin mapping for the Arduino Micro:

Arduino Micro TLC5940
SCK (Pin 17) --> SCLK (Pin 25)
MOSI (Pin 18) --> SIN (Pin 26)
D9 (Pin 31) --> XLAT (Pin 24)
D10 (Pin 32) --> BLANK (Pin 23)
D5 (Pin 27) --> GSCLK (Pin 18)

I don't know how relevant this is now but I want to confirm that this pin mapping works for Arduino Micro without any change to the TLC5940 library. This helped me a lot. Thank you.