I need help with Teensy 2++ and LED driver programing

Status
Not open for further replies.

Manjikac

Member
I am trying to control LEDs connected to outputs of multiple TLC5922 drivers.
How do I transfer the data from Teensy? Do I use SPI or bit banging?
 
May as well use SPI

These TLC chips have a bitch of a configuration data register though. 7 bits of dot correction data.
At least that's exactly 14 bytes. The TLC5955 is 96 bytes and 1 bit or something

Standard operation is just a 16 bit shift register which should work with shiftout if you do want bitbanging
 
Thank you for your reply.
Unfortunately I have to talk to TLC5922 since that is part of the design.
I tried SPI but I cannot see clock signal on the scope and the data does not see to be transferred.

Is there a certain library for this chip that I need to include?

This is my code:
Code:
/*
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <SPI.h>

#define txPin 2
#define MeterMode 18
#define MeterBlank 19
#define LevelLatch 20
#define SPICLOCK  21
#define SDOUT 22
#define SOUT 23
#define PCKT_LEN 65535 // the packet length 16 bits

SoftwareSerial LCD = SoftwareSerial(0, txPin);

//const int buttonState = 26; 
//int state = 0; 

uint8_t receivedVAL1;
uint8_t receivedVAL2;
uint8_t receivedVAL3;
uint8_t receivedVAL4;
uint8_t LEDs1 = 0;
uint8_t LEDs2 = 0;
byte LEDs3 = 00000000;
byte LEDs4 = 00000000;
SPISettings settingsA(125000, MSBFIRST, SPI_MODE1);    //(gives 8 microsecond period clock pulses)
//SPI.beginTransaction(SPISettings(125000, MSBFIRST, SPI_MODE3)); // to begin using the SPI port. The SPI port

void clearLCD(){
  LCD.write(0xFE);   //command flag
  LCD.write(0x01);   //clear command.
  delay(10);
}

void setup() {

 char buffer[PCKT_LEN];
 //Serial.begin(9600);
 LCD.begin(9600);

 pinMode(txPin, OUTPUT);
 pinMode(LevelLatch, OUTPUT);
 pinMode(MeterMode, OUTPUT);
 pinMode(MeterBlank, OUTPUT);

 digitalWrite(MeterMode, LOW); // connected to ON/OFF controll keep constant - digitalWrite(MeterBlank, HIGH); // all LEDs OFF
 digitalWrite(MeterBlank, LOW); // ON/OFF of OUTx outputs are controlled by input data
// SPI.transfer(0xCC);

   SPI.begin();
}  

void loop()
{
// SPI.beginTransaction(settingsA);
// digitalWrite(SPICLOCK, LOW);
 for (int i=0; i<PCKT_LEN;i++)
{
 SPI.transfer(buffer[i]);
}
  digitalWrite(LevelLatch, HIGH);
  delay(100);
  digitalWrite(LevelLatch, LOW);
  clearLCD();

   LCD.print("OUTPUT");
   LCD.print(digitalRead(SOUT));
   LCD.print(data, BIN);
    delay (2000);
   clearLCD();
   LCD.print(ner, BIN);
    delay (2000);
 
//  digitalWrite(MeterMode, LOW);
  LEDs1 = 0; // 0x00 = 00000000
  LEDs2 = 255;
  LEDs3 = 0x00;
  LEDs4 = 0x00;
 receivedVAL1 = SPI.transfer(255);
 receivedVAL2 = SPI.transfer(255);
 receivedVAL3 = SPI.transfer(1);
 receivedVAL4 = SPI.transfer(LEDs4);
  delay(1000);
// digitalWrite(LevelLatch, HIGH);
  delay(100);
  lcdPosition(0,0);
  LCD.print("passed to here");
  delay (1000);
  lcdPosition(1,0);
  LCD.print(receivedVAL2, BIN);
  LCD.print(receivedVAL3, BIN);
 // LCD.print(receivedVAL3, BIN);
  delay (1000);
 // LCD.print(receivedVAL3, BIN);
 // LCD.print(receivedVAL4, BIN);
 clearLCD();   
}


// wbp: goto with row & column
void lcdPosition(int row, int col) {
  LCD.write(0xFE);   //command flag
  LCD.write((col + row*64 + 128));    //position 
  delay(10);
}/


May as well use SPI

These TLC chips have a bitch of a configuration data register though. 7 bits of dot correction data.
At least that's exactly 14 bytes. The TLC5955 is 96 bytes and 1 bit or something

Standard operation is just a 16 bit shift register which should work with shiftout if you do want bitbanging
 
one more thing, my drivers are connected in parallel as clock, meter-mode, level-latch and meter-blank to all drivers
 
Try:
Code:
void setup() {
   pinMode(TLC_Latch, OUTPUT);
   digitalWriteFast(TLC_Latch, LOW);
   SPI.begin();
}

void loop() {
  // All on
  SPI.transfer(255);
  SPI.transfer(255);
  digitalWriteFast(TLC_Latch, HIGH);
  delay(5);
  digitalWriteFast(TLC_Latch, LOW);

  delay(500);

  // All off
  SPI.transfer(0);
  SPI.transfer(0);
  digitalWriteFast(TLC_Latch, HIGH);
  delay(5);
  digitalWriteFast(TLC_Latch, LOW);

  delay(500);
}

Mode pin must be low

Nope there is no library, but feel free to make one
 
Last edited:
Great.
I got all LEDs on/off. Nice!

It looks like I do not need to worry about clock and Meter mode and meter blank. Are those done automatically with SPI?

I will now have to work on setting those LED different colors and I may need help with that later.

Thanks a lot
 
It looks like I do not need to worry about clock and Meter mode and meter blank. Are those done automatically with SPI?
Yes that is the case.

I'm glad it worked for you!

If you wish to change brightness You'll have to do 14 SPI.transfer()s and a latch up->down whilst the mode pin is high. This will write the dot correction data

EDIT -
Actually meterblank isn't covered by SPI or my code. You normally don't need this pin
 
Last edited:
Yes that is the case.

I'm glad it worked for you!

If you wish to change brightness You'll have to do 14 SPI.transfer()s and a latch up->down whilst the mode pin is high. This will write the dot correction data

EDIT -
Actually meterblank isn't covered by SPI or my code. You normally don't need this pin

Thanks a lot for your help. I am controlling four of the 16-output drivers and the first part of this code works fine turning all LEDs on and off. However, when I try to switch to dot-connection for brightness control, my code is no longer good. Can you tell me where am I mistaking? Why did you say 14 SPI.transfer()s?

Thank you.
Code:
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <SPI.h>

#define txPin 2
#define MeterMode 18
#define MeterBlank 19
#define TLC_Latch 20
#define SPICLOCK  21
#define SDOUT 22
#define SOUT 23

SoftwareSerial LCD = SoftwareSerial(0, txPin);
const int LCDdelay=10;  // conservative, 2 actually works

SPISettings settingsA(125000, MSBFIRST, SPI_MODE1);    //(gives 8 microsecond period clock pulses)

void setup() {

 pinMode(txPin, OUTPUT);
 pinMode(TLC_Latch, OUTPUT);
 digitalWrite(TLC_Latch, LOW);
 SPI.begin();

 pinMode(txPin, OUTPUT);
 digitalWrite(MeterMode, LOW); // connected to Dot connection 
 digitalWrite(MeterBlank, LOW); // ON/OFF of OUTx outputs are controlled by input data

  LCD.begin(9600);

}  

void loop()
{
  clearLCD();
  LCD.print("Ready to test?");
  delay(1000);
  // set all LEDs off
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  digitalWrite(TLC_Latch, HIGH);
  delay(5);
  digitalWrite(TLC_Latch, LOW);
  delay(2000);

  clearLCD();
  LCD.print("Color");
   // set all LEDs on
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(255);
  digitalWrite(TLC_Latch, HIGH);
  delay(5);
  digitalWrite(TLC_Latch, LOW);
  delay(2000);

  clearLCD();
  LCD.print("Brightness low");
   // set brightness to lowest
  digitalWrite(MeterMode, HIGH);
  delay(5);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  digitalWrite(TLC_Latch, HIGH);
  delay(5);
  digitalWrite(TLC_Latch, LOW);
  delay(1500);
   clearLCD();
  LCD.print("Brightness high");
   // set brightness to highest
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(255); 
  digitalWrite(TLC_Latch, HIGH);
  delay(5);
  digitalWrite(TLC_Latch, LOW);
  delay(1500);
  digitalWrite(MeterMode, LOW);
  delay(500);
}


void clearLCD(){
  LCD.write(0xFE);   //command flag
  LCD.write(0x01);   //clear command.
  delay(LCDdelay);
}
 
Continuing to work on this project.
I got all LEDs working fine using SPI.trasfer() in Mode LOW.
I am having a difficult time switching to dot connection with Mode HIGH to control brightness.

This is my code that works for color only:
Code:
#include<SoftwareSerial.h>
#include <SPI.h>
#define txPin 45
#define LED_POW 44
#define MeterMode 38
#define MeterBlank 19
#define TLC_Latch 20
#define SPICLOCK  21
#define SDOUT 22
#define LCD_E 1
#define LCD_RW 0
#define LCD_RS 27
#define SW_408 42
int SW = 0; // Switch selected on the DUT board
int test=0; 
int SelectSW = 0; //select unit 408 or 816
SoftwareSerial LCD = SoftwareSerial(0, txPin); // since the LCD does not send data back to the Arduino, we should only define the txPin
const int LCDdelay=10;  // conservative, 2 actually works

SPISettings settingsA(125000, MSBFIRST, SPI_MODE1);    //(gives 8 microsecond period clock pulses)

void setup()
{
  pinMode(txPin, OUTPUT);
  pinMode(SW_408, INPUT);
  pinMode(TLC_Latch, OUTPUT);
  pinMode(MeterMode, OUTPUT);
  pinMode(LCD_RW, OUTPUT);
  pinMode(LCD_RS, OUTPUT);
  pinMode(LCD_E, OUTPUT);
  digitalWrite(MeterBlank, LOW); // ON/OFF of OUTx outputs are controlled by input data
  digitalWrite(MeterMode, LOW);
  digitalWrite(TLC_Latch, LOW);
  SPI.begin();
  LCD.begin(9600);
}

void loop()
{
    digitalWrite(MeterMode, LOW);
    LCD.print("Testing");
    delay(1000);
    selectUnit();
    delay(1000);
    AllLEDsOFF();
    delay(1000);
 clearLCD();
 LCD.print("testing switch board");
 delay(1000);
  LEDsRow1();
  LEDsRow2();
  LEDsRows3and4();
  LEDsRow5Red();
  LEDsRow5Green();
  
clearLCD(); 
LCD.printf("Lsst LEDs should be red");  
 //SW_LEDs red
  for (int i=0; i<SelectSW; i++){
  SPI.transfer(15);
  SPI.transfer(255);
  DoubleSpi(85);
  DoubleSpi(0);
  }
  DoubleSpi(0);
  Latch();
delay(2000);
clearLCD(); 
 LCD.printf("All LOW");  
digitalWrite(MeterMode, HIGH); 
delay(100);
 for (int i=0; i<SelectSW; i++){
      for (int j=0; j<28; j++){
      SPI.transfer(1);
      }
       for (int k=0; k<14; k++){
       SPI.transfer(0);      
      }
 }
  for (int l=0; l<14; l++){
       SPI.transfer(0);    
       }
  Latch();
  delay(10000);  
  
 clearLCD(); 
  LCD.print("ALL HIGH");
 for (int i=0; i<SelectSW; i++){
      for (int j=0; j<14; j++){
      SPI.transfer(127);
      }
       for (int k=0; k<28; k++){
       SPI.transfer(127);    
       }
 }
  for (int l=0; l<14; l++){
       SPI.transfer(127);    
       }
  Latch();
  delay(2000);  

  
   digitalWrite(MeterMode, LOW);

    clearLCD();
    LCD.print("End Brightness"); 
 delay(1000);

  
}//end of loop


void  AllLEDsOFF(){
 clearLCD(); 
 LCD.printf("All LEDs OFF");  
  for (int i=0; i<SelectSW; i++){
      for (int j=0; j<6; j++){
      SPI.transfer(0);
      }
  DoubleSpi(0);
  }
  Latch();
  delay(500);  
}

void   AllLEDsON(){
 clearLCD(); 
 LCD.printf("All LEDs ON");  
  for (int i=0; i<SelectSW; i++){
  SPI.transfer(255);
  SPI.transfer(255);
  SPI.transfer(85);
  SPI.transfer(85);
  SPI.transfer(255);
  SPI.transfer(255);
  }
  DoubleSpi(0);
  Latch();
  delay(500);  
}
void clearLCD(){
  LCD.write(254);   //command flag
  LCD.write(81);   //clear command.
  delay(LCDdelay);
}
void selectUnit(){
 if (digitalRead(SW_408)) { 
  SelectSW = 1;
  clearLCD();
  LCD.print("Testing Galaxy 408");
  delay(3000);
 }
 if (!digitalRead(SW_408)) { 
  SelectSW = 2;
   clearLCD();
   LCD.print("Testing Galaxy 816");
    delay(3000);
   }
 }  
void LEDsRow1(){
LCD.printf("First row LEDs should be red"); 
 // LED101-LED116 first four red
  for (int i=0; i<SelectSW; i++){
    for (int j=0; j<4; j++){
      SPI.transfer(0); 
    }
    DoubleSpi(17);
  }
  DoubleSpi(0);
  Latch();
}

void LEDsRow2(){
clearLCD(); 
LCD.printf("Second row LEDs should be orange"); 
// LED101-LED116 second four orange
  for (int i=0; i<SelectSW; i++){
  SPI.transfer(240);
   for (int j=0; j<3; j++){
      SPI.transfer(0); 
    }
  DoubleSpi(34);
  }
  DoubleSpi(0);
  Latch();
}

void LEDsRows3and4(){
clearLCD(); 
LCD.printf("Last two rows LEDs should be green");   
// LED101-LED116 last eight green
  for (int i=0; i<SelectSW; i++){
  DoubleSpi(0);
  DoubleSpi(0);
  DoubleSpi(204);
  }
  DoubleSpi(0);
  Latch();
}

void LEDsRow5Red(){
 clearLCD(); 
LCD.printf("LEDs should be red");  
  //LEDs1-8 red
  DoubleSpi(0);
  for (int i=0; i<SelectSW; i++){
  DoubleSpi(85);
  DoubleSpi(0);
  DoubleSpi(0);
  }
  Latch();
}

void LEDsRow5Green(){
 clearLCD(); 
LCD.printf("LEDs should be green");  
  // LEDs1-8 green
  DoubleSpi(0);
  for (int i=0; i<SelectSW; i++){
  DoubleSpi(170);
  DoubleSpi(0);
  DoubleSpi(0);
  }
  Latch();
}
void LEDsSW(){
 clearLCD(); 
LCD.printf("Lsst LEDs should be red");  
 //SW_LEDs red
  for (int i=0; i<SelectSW; i++){
  SPI.transfer(15);
  SPI.transfer(255);
  DoubleSpi(0);
  DoubleSpi(0);
  }
  DoubleSpi(0);
  Latch();
}
void Latch() {
  digitalWrite(TLC_Latch, HIGH);
  delay(5);
  digitalWrite(TLC_Latch, LOW);
  delay(100);
}
void DoubleSpi(int Spi){
  SPI.transfer(Spi);
  SPI.transfer(Spi);
  delay(100);
}


I have several boards connected and I need a lot of SPI.transfer()s. total of five TLC5922 used (16 outputs each but only 63 outputs in use).
 
Last edited:
Sorry Manjikac, your response must have slipped through the cracks. Sorry!

You're always welcome to poke me by personal message if you do need a hand

There's 14 bytes required by each TLC in dot correction mode (or 16x7bits). What happens if you try:
Code:
const uint32_t NUMTLCS = 5; // Number of TLCs connected in series on SPI

void setup() {
   pinMode(TLC_Latch, OUTPUT);
   digitalWriteFast(TLC_Latch, LOW);
   SPI.begin();
}

void loop() {
  // All on
  for(uint32_t i = 0; i < NUMTLCS; i++) {
    for(uint32_t i = 0; i < 14; i++) {
       SPI.transfer(0xFF);
    }
  }
  
  digitalWriteFast(TLC_Latch, HIGH);
  delay(5);
  digitalWriteFast(TLC_Latch, LOW);

  delay(500);

  // All off
  for(uint32_t i = 0; i < NUMTLCS; i++) {
    for(uint32_t i = 0; i < 14; i++) {
       SPI.transfer(0x00);
    }
  }
  
  digitalWriteFast(TLC_Latch, HIGH);
  delay(5);
  digitalWriteFast(TLC_Latch, LOW);

  delay(500);
}

Of course set the mode pins of the TLCs HIGH



This maybe not what you want at all. Can you elaborate on what you mean by colour only?
This is my code that works for color only
 
Thank you so much for your response.
I will try the code and keep you posted.

by "Color only" I meant that I can set the colors of LEDs but not the brightness.
 
Status
Not open for further replies.
Back
Top