TCL5940 + CerbuinoBee

Hello guys,

I’ve been trying to play around with the TCL5940 chip and i don’t know what more to try to make this work.

Been using this driver h??ps://tlc5490netduino.codeplex.com/SourceControl/latest#Tlc5940.cs

And my pins are:
SCLK_Pin --> GHI.Hardware.FEZCerb.Pin.PB3
SIN_Pin --> GHI.Hardware.FEZCerb.Pin.PB5
BLANK_Pin --> GHI.Hardware.FEZCerb.Pin.PA15
XLAT_Ping --> GHI.Hardware.FEZCerb.Pin.PA9
VPROG_Ping --> GHI.Hardware.FEZCerb.Pin.PB13 (not beeing used either on the wiring schemme I found)
GCCLK_Pin --> GHI.Hardware.FEZCerb.Pin.PC14

Pic shows 3.3v connection but I did try with 5v too, same result.

Does anyone have any ideia? none of the outputs have any signal. Although all connected PWM pins do.

Thank you

Hi Adias, welcome to the forum.

This is Mark’s original blog post Silverlight Developer » Blog Archive TLC5940 16 Channel PWM Driver - Silverlight Developer that might have more info. The second image you found, is that your as-wired diagram or is it just one you tried to copy ? I can’t see your breadboard wires clearly enough to see if you have that wired as per the diagram or not, can you clean up the wiring and take a better (top down?) shot ?

You may also need to show us code if you’ve made any change, and certainly it’d be worth showing us the initialisation and use-case code.

1 Like

https://www.ghielectronics.com/community/forum/search?q=TLC5940+

There’s a number of threads on this chip, and lots of trouble I gather. Some good knowledge here though, but no magic bullet

1 Like

Thank you
Here it goes, a decent picture so it’s easier to see the connections.
Brett, i did see those threads before posting. Did try to try them all with no success.
The code I’ve tried with that driver was the one is provided h??p://tlc5490netduino.codeplex.com/wikipage?title=Usage%20Examples&referringTitle=Home

The scheme i used was the one in the second picture yes. I realize that picture is from a Netduino board, but there should be no significant difference to the Cerbuino, am I right?

much neater breadboard :slight_smile:

I think you still need to give us the way you’re using the driver, that will show how you’re testing it.

Can you also elaborate on what your tests show, what works, what doesn’t, because this doesn’t accurately describe what is going on to diagnose…

edit: and as for VCC, you must connect it to 3v3; if you don’t then the assumed high signal will be above the signal level the cerbuino will output.

1 Like

Ok, it seems that disconnecting VCC from 5v and connecting it to 3.3 produced a change.
It seems now that all channels are pulsing at same time.
I replaced the resistors with a 10k regulated one and did set it to ~7k to reduce the the brightness of the RGB LEDs.

From what I understand, this test should light each one of the outputs at a time with a 300ms interval between

Here’s my testing code

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using SmudgeIT.Tlc5940;
using Gadgeteer.Modules.GHIElectronics;

namespace TCL5940NT
{
    public partial class Program
    {
        private static Tlc5940 chip;
        void ProgramStarted()
        {
            Debug.Print("TCL5940 Testing");
            chip = new Tlc5940(
                      (Cpu.Pin)19,  //PB3 - SCLK -> 13 (Green wire) Chip Pin 25
                      (Cpu.Pin)21,  //PB5 - SIN -> 11 (Orange wire) Chip Pin 26
                      (Cpu.Pin)15,  //PA15 - BLANK -> 10 (Blue wire) Chip Pin 23
                      (Cpu.Pin)9,   //PA9 - XTAT -> D9 (Yellow wire) Chip Pin 24
                      (Cpu.Pin)29,  //PB13 - VPROG -> D8 (none wire) Chip Pin 27
                      (Cpu.Pin)46   //PC14 - GCCLK -> D3 (White wire) Chip Pin 18
                      );
            chip.DotCorrectionValues = new int[] { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 };
            chip.Init();
            int active = 1;
            char_Display.SetBacklight(true);
            while (true)
            {
                chip.Update();
                chip.SetAll(0);
                char_Display.CursorHome();
                char_Display.Clear();
                char_Display.PrintString("CH: " + active.ToString());
                chip.Set(active, 100);
                chip.Update();
                active++;
                if (active == 17)
                { active = 1; }

                Thread.Sleep(300);
            }
        }
    }
}

how is your testing going here ?

You mention what you think the program should do - but you don’t really describe what it actually does ?

You should move your testing code out of ProgramStarted() because of this http://blogs.msdn.com/b/net_gadgeteer/archive/2011/12/19/why-not-while-true.aspx

Turn that into a new thread and let it run, see if that changes behaviour ?

1 Like

Finally got it working. yay!

Issue was related with wiring and an interesting thing, Once deployment if board not disconnected, the chip was betting a weird behavior.

Modified Tlc5940.cs to allow cascading chips:


using Microsoft.SPOT.Hardware;
using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using SmudgeIT.Tlc5940;
using Gadgeteer.Modules.GHIElectronics;

namespace CerbuinoBee
{
    public class Pins
    {
        public const Cpu.Pin D0 = (Cpu.Pin)0x1B; // PB11/I2C2_SDA/UART3_RX
        public const Cpu.Pin D1 = (Cpu.Pin)0x1A; // PB10/I2C2_SCL/SPI2_SCK/UART3_TX
        public const Cpu.Pin D2 = (Cpu.Pin)0x1C; // PB12/CAN2_RX
        public const Cpu.Pin D3 = (Cpu.Pin)0x2E; // PC14/XO32
        public const Cpu.Pin D4 = (Cpu.Pin)0x2F; // PC15/XI32
        public const Cpu.Pin D5 = (Cpu.Pin)0x08; // PA8/MC01/PWM
        public const Cpu.Pin D6 = (Cpu.Pin)0x0A; // PA10/LOADER1U2/PWM
        public const Cpu.Pin D7 = (Cpu.Pin)0x24; // PC4/ADC12_IN14
        public const Cpu.Pin D8 = (Cpu.Pin)0x1D; // PB13/SP2_SCK/CAN2_TX/PWM
        public const Cpu.Pin D9 = (Cpu.Pin)0x09; // PA9/VBUS
        public const Cpu.Pin D10 = (Cpu.Pin)0x0F; // PA15/J_TDI/PWM/SP1_SSEL
        public const Cpu.Pin D11 = (Cpu.Pin)0x15; // PB5/CAN2_RX/PWM/SP1_MOSI
        public const Cpu.Pin D12 = (Cpu.Pin)0x14; // PB4/J_TRST/PWM/SP1_MISO
        public const Cpu.Pin D13 = (Cpu.Pin)0x13; // PB3/J_TDO/PWM/SPI1_SCK

        public const Cpu.Pin A0 = (Cpu.Pin)0x11; // PB1/ADC12_IN9
        public const Cpu.Pin A1 = (Cpu.Pin)0x05; // PA5/SPI1_SCK/ADC12_IN5/DAC2
        public const Cpu.Pin A2 = (Cpu.Pin)0x10; // PB0/ADC12_IN8
        public const Cpu.Pin A3 = (Cpu.Pin)0x23; // PC3/ADC123_IN13/SPI2_MOSI
        public const Cpu.Pin A4 = (Cpu.Pin)0x21; // PC1/ADC123_IN11
        public const Cpu.Pin A5 = (Cpu.Pin)0x04; // PA4/SP1_SSEL/ADC12_IN14/DAC1

        public const Cpu.Pin LED = (Cpu.Pin)0x12; // PB2/BOOT1
        public const Cpu.Pin SDDetect = (Cpu.Pin)0x22; // SD Detect
    }
}


// <copyright file="Tlc5940.cs" company="Dave Smith">
//
// Copyright (C) 2010 Dave Smith http://dotnetdave.net
//
// This file is part of the TLC5940 driver for Netduino.

// The TLC5940 driver for Netduino 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 TLC5940 driver for Netduino 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 TLC5940 driver for Netduino.  If not, see http://www.gnu.org/licenses/.
// </copyright>
// <summary>
// Driver for the TI TLC 5490 written for the Netduino
// 
// Email: TLC5490@ dotnetdave.net
// </summary>
namespace SmudgeIT.Tlc5940
{
    using System;
    using System.Threading;
    using Microsoft.SPOT;
    using Microsoft.SPOT.Hardware;
    
    /// <summary>
    /// Driver for the TI TLC5940
    /// </summary>
    public class Tlc5940
    {
        /// <summary>
        /// Max Value for the pin
        /// </summary>
        private const int GlcCounterMax = 4096;

        /// <summary>
        /// The port for the SCLK pin
        /// </summary>
        private OutputPort sclk;

        /// <summary>
        /// The port for the SIN pin
        /// </summary>
        private OutputPort sin;

        /// <summary>
        /// The port for the BLANK pin
        /// </summary>
        private OutputPort blank;

        /// <summary>
        /// The port for the XLAT pin
        /// </summary>
        private OutputPort xlat;

        /// <summary>
        /// The port for the VPROG pin
        /// </summary>
        private OutputPort vprog;

        /// <summary>
        /// The port for the GCCLK pin
        /// </summary>
        private OutputPort gcclk;

        /// <summary>
        /// The port for the BLANK pin
        /// </summary>
        private int[] dotcorrection;

        /// <summary>
        /// Brightness data
        /// </summary>
        private int[] bright;

        /// <summary>
        /// Is this the first cycle
        /// </summary>
        private bool firstCycle = true;

        /// <summary>
        /// Counter for the GLCCLK pin
        /// </summary>
        private int glcCounter = 1;

        /// <summary>
        /// Gets or sets the dot correction values.
        /// </summary>
        /// <value>The dot correction values.</value>
        public int[] DotCorrectionValues
        {
            get { return this.dotcorrection; }
            set { this.dotcorrection = value; }
        }

        /// <summary>
        /// Gets or sets the grayscale color values.
        /// </summary>
        /// <value>The grayscale color values.</value>
        public int[] GrayscaleColorValues
        {
            get { return this.bright; }
            set { this.bright = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Tlc5940"/> class.
        /// </summary>
        /// <param name="sclkPin">The SCLK pin.</param>
        /// <param name="sinPin">The SIN pin.</param>
        /// <param name="blankPin">The BLANK pin.</param>
        /// <param name="xlatPin">The XLAT pin.</param>
        /// <param name="vprogPin">The VPROG pin.</param>
        /// <param name="gcclkPin">The GCCLK pin.</param>
        public int NumChips;

        public Tlc5940(
            Cpu.Pin sclkPin,
            Cpu.Pin sinPin,
            Cpu.Pin blankPin,
            Cpu.Pin xlatPin,
            Cpu.Pin vprogPin,
            Cpu.Pin gcclkPin,
            int _NumChips)
        {
            NumChips = _NumChips;

            this.sclk = new OutputPort(sclkPin, false);
            this.sin = new OutputPort(sinPin, false);
            this.blank = new OutputPort(blankPin, true);
            this.xlat = new OutputPort(xlatPin, false);
            this.vprog = new OutputPort(vprogPin, true);
            this.gcclk = new OutputPort(gcclkPin, false);
            this.bright = new int[16 * _NumChips];
            this.dotcorrection = new int[16 * _NumChips];
            this.DotCorrectionValues = new int[16 * _NumChips];
            for (int index = 0; index < 16 * _NumChips; index++)
            {
                this.bright[index] = 0x800;
                this.dotcorrection[index] = 0x20;
                this.DotCorrectionValues[index] = 10;
            }
        }

        /// <summary>
        /// Inits this instance.
        /// </summary>
        public void Init()
        {
            this.LoadDCValues();
            this.vprog.Write(false);
        }

        /// <summary>
        /// Sets all the outputs to the brightness value.
        /// </summary>
        /// <param name="brightness">The brightness.</param>
        public void SetAll(int brightness)
        {
            if (brightness > 0 || brightness < 101)
            {
                for (int i = 0; i < 16*NumChips; i++)
                {
                    this.Set(i + 1, brightness);
                }
            }
        }

        /// <summary>
        /// Clears all the outputs.
        /// </summary>
        public void Clear()
        {
            for (int i = 0; i < 16*NumChips; i++)
            {
                this.Set(i + 1, 0);
            }
        }

        /// <summary>
        /// Sets the specified channel.
        /// </summary>
        /// <param name="channel">The channel.</param>
        /// <param name="brightness">The brightness.</param>
        public void Set(int channel, int brightness)
        {
            if (channel < 1 || channel > 16 * NumChips || brightness < 0 || brightness > 101)
            {
                throw new ApplicationException("Bad Boy");
            }

            this.bright[channel - 1] = (int)System.Math.Ceiling(brightness * 20.48);
        }

        /// <summary>
        /// Updates this instance.
        /// </summary>
        public void Update()
        {
            this.LoadBrightValues(this.firstCycle);
        }

        /// <summary>
        /// Loads the DC values.
        /// </summary>
        private void LoadDCValues()
        {
            this.vprog.Write(true);
            for (int i = 15*NumChips; i >= 0; i--)
            {
                for (int j = 0x20; j != 0; j >>= 1)
                {
                    if ((this.dotcorrection[i] & j) == 0)
                    {
                        this.sin.Write(false);
                    }
                    else
                    {
                        this.sin.Write(true);
                    }

                    this.PulsePort(this.sclk);
                }
            }

            this.PulsePort(this.xlat);
        }

        /// <summary>
        /// Loads the bright values.
        /// </summary>
        /// <param name="first">if set to <c>true</c> [first].</param>
        private void LoadBrightValues(bool first)
        {
            this.blank.Write(false);
            for (int i = 15*NumChips; i >= 0; i--)
            {
                for (int j = 0x800; j != 0; j >>= 1)
                {
                    if ((this.bright[i] & j) == 0)
                    {
                        this.sin.Write(false);
                    }
                    else
                    {
                        this.sin.Write(true);
                    }
                                        
                    this.PulsePort(this.sclk);
                        
                    this.PulsePort(this.gcclk);
                    this.glcCounter++;
                }
            }

            while (this.glcCounter < Tlc5940.GlcCounterMax*NumChips)
            {
                this.PulsePort(this.gcclk);
                this.glcCounter++;
            }

            this.blank.Write(true);
            this.PulsePort(this.xlat);
            
            if (first)
            {
                this.PulsePort(this.sclk);
                this.firstCycle = false;
            }
        }

        /// <summary>
        /// Pulses the port.
        /// </summary>
        /// <param name="port">The port to set.</param>
        private void PulsePort(OutputPort port)
        {
            port.Write(true);
            port.Write(false);
        }
    }
}

Testing program…


using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using SmudgeIT.Tlc5940;
using Gadgeteer.Modules.GHIElectronics;

namespace TCL5940NT
{
    public partial class Program
    {
        private static SmudgeIT.Tlc5940.Tlc5940 chip;
        private SPI.Configuration _config;
        private SPI _spi = null;
        private byte[] _greyScaleBuffer = null;

        void ProgramStarted()
        {
            Debug.Print("TCL5940 Testing");
            
            int NumChips = 4;

	//Cerbuino Bee pins
            chip = new SmudgeIT.Tlc5940.Tlc5940(
                      (Cpu.Pin)19,  //PB3 - SCLK -> 13 | Chip Pin 17
                      (Cpu.Pin)21,  //PB5 - SIN -> 11 | Chip Pin 26
                      (Cpu.Pin)15,  //PA15 - BLANK -> 10 | Chip Pin 23
                      (Cpu.Pin)9,   //PA9 - XTAT -> D9 | Chip Pin 24
                      (Cpu.Pin)29,  //PB13 - VPROG -> D8 | Chip Pin 27
                      (Cpu.Pin)46,   //PC14 - GCCLK -> D3 | Chip Pin 25
                      NumChips
                      );

            chip.Init();
            
            
            char_Display.SetBacklight(true);
            Random rnd = new Random();
            chip.Clear();
	//I know...while true........it's just for testing purpose :)
            while (true)
            {
                for (int StartPin = 1; StartPin <= 16; StartPin++)
                {
                    for (int Chan = StartPin; Chan <= 16 * NumChips; Chan += 1)
                    {
                        chip.Update();
                        chip.SetAll(0);
                        char_Display.CursorHome();
                        char_Display.Clear();
                        char_Display.PrintString("CH: " + Chan.ToString());
                        chip.Set(Chan, 100);
                        chip.Update();
                    }
                    for (int Chan = 16 * NumChips; Chan > StartPin; Chan -= 1)
                    {
                        chip.Update();
                        chip.SetAll(0);
                        char_Display.CursorHome();
                        char_Display.Clear();
                        char_Display.PrintString("CH: " + Chan.ToString());
                        chip.Set(Chan, 100);
                        chip.Update();
                    }

                    for (int Chan = StartPin; Chan <= 16 * NumChips; Chan += 2)
                    {
                        chip.Update();
                        chip.SetAll(0);
                        char_Display.CursorHome();
                        char_Display.Clear();
                        char_Display.PrintString("CH: " + Chan.ToString());
                        chip.Set(Chan, 100);
                        chip.Update();
                    }
                    for (int Chan = 16 * NumChips; Chan > StartPin; Chan -= 2)
                    {
                        chip.Update();
                        chip.SetAll(0);
                        char_Display.CursorHome();
                        char_Display.Clear();
                        char_Display.PrintString("CH: " + Chan.ToString());
                        chip.Set(Chan, 100);
                        chip.Update();
                    }
                    

                    for (int Chan = StartPin; Chan <= 16 * NumChips; Chan += 3)
                    {
                        chip.Update();
                        chip.SetAll(0);
                        char_Display.CursorHome();
                        char_Display.Clear();
                        char_Display.PrintString("CH: " + Chan.ToString());
                        chip.Set(Chan, 100);
                        chip.Update();
                    }


                    for (int Chan = 16 * NumChips - StartPin; Chan > StartPin; Chan -= 3)
                    {
                        chip.Update();
                        chip.SetAll(0);
                        char_Display.CursorHome();
                        char_Display.Clear();
                        char_Display.PrintString("CH: " + Chan.ToString());
                        chip.Set(Chan, 100);
                        chip.Update();
                    }

                    chip.Update();
                    chip.SetAll(0);
                    for (int a=1;a<=NumChips;a++){
                        int pin = StartPin * a;
                        if (pin==0)
                            pin=1;

                        chip.Set(pin, 100);
                    }
                    chip.Update();
                }
                
            }
            
        }
    }
}

I got this working, although, couldn’t make the one from Mark Stevens Blog to work.
Thanks a lot for the help Brett.

Small demo

1 Like

12 points for blinky factor.

Nice example of how this forum can move things forward. Thanks for that Brett