Getting different LED results with same message using MIDI and SPI hardware

Hi,

I am making a midi controller. I am using a Teensy 3.6. I have some RGB LED button switches, controlled by an TLC5947 board. I finally figured out how to use SPI hardware on the Teensy to send a color to an RGB LED.

Incoming midi data is used to change the color of an LED. In my code, in the function myControlChange() the “value” number selects a given RGB color. If I send that value from midi software once, it works. If I send that value once, then send it again, and again, ect. from the 2nd time forward I will keep getting different colors, and often other LEDs will even turn on.

I think what I need to do is clear or erase the previous value before the new one comes in. Any ideas on how to do that? or perhaps create an if statement that will ignore if value ==value.

Also, this is a more general project question and possibly related: What would be a good way to store values, then send all the data out at once? Because this midi controller will have 17 LEDs in the end, I think the colorChange() function I made isn’t the best idea, but it’s ok to test things out.

Ideally I’d like the incoming data to be read, have all the different changes of LEDs set (like controller number 15, 16, 17 ect) then send all the data to SPIwrite() at the end. Any thoughts on how to organize all this?

Please let me know your thoughts or suggestions.

Thanks, Nick

#include <Bounce.h>
#include <Adafruit_NeoPixel.h>
#include <Wire.h> // wire library for LED matrix

#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

#include "Adafruit_TLC5947.h"  // for LED breakout board

//  #include <Adafruit_TLC5947.h>
#include <SPI.h>

const int slaveSelectPin = 10;
#define clock 13 // 10 
#define data 11
#define oe  15  //  12
#define latch  10 // 11
#define NUM_TLC5974 2     // how many LED boards


unsigned long frame;
Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch,  oe);


// the MIDI channel number to send messages
const int channel = 1;
const int MIDIchannel = 1;   // this will only apply to midi channel 1


const int ledcontroller16 = 16;    // midi control change 16

const int numMatrixControllers = 5;
const int firstMatrixController = 76;



Adafruit_7segment matrix = Adafruit_7segment();

Adafruit_8x16matrix matrix2 = Adafruit_8x16matrix();

void setup() {

  pinMode(latch, OUTPUT);
  digitalWrite(latch, LOW);
  pinMode(clock, OUTPUT);
  digitalWrite(clock, LOW);
  pinMode(data, OUTPUT);
  digitalWrite(data, LOW);


  SPI.setCS(10);
  SPI.setMOSI(11);
  SPI.setSCK(13);
  SPI.begin();
  //tlc.begin();

  // Serial.begin(38400); if you don't comment this out the board goes off line

  // wire 3.3V to AREF for 3.3V reference
  analogReference(DEFAULT);




  usbMIDI.setHandleControlChange(myControlChange);
  setupLedDisplays();


}






void loop() {


  

  // MIDI Controllers should discard incoming MIDI messages.
  // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
  while (usbMIDI.read()) {
    // ignore incoming messages
  }
}



void myControlChange(byte channel, byte control, byte value) { // for LEDs, MIDI output

  if (channel == MIDIchannel) {

   
    /////// new 16
    if (control == ledcontroller16 && value == 0)
      colorChange( 1, 0, 0, 0);   // off              check

    if (control == ledcontroller16 && value == 10)
      //light pink
      colorChange( 1, 90, 2, 10);                          


    if (control == ledcontroller16 && value == 20)
      //blue                                         
      colorChange( 1, 0, 0, 100);

    if (control == ledcontroller16 && value == 30)
      //lavender
      colorChange( 1, 70, 2, 10);                   

    if (control == ledcontroller16 && value == 40)
         //pink                                   check
        colorChange( 1, 90, 2, 2);                     

    if (control == ledcontroller16 && value == 50)
     colorChange( 1, 100, 0, 0);       //red         

    if (control == ledcontroller16 && value == 60)
       colorChange( 1, 100, 8, 0);        //orange      

    if (control == ledcontroller16 && value == 70)
       colorChange( 1, 100, 60, 0);     // yellow    

    if (control == ledcontroller16 && value == 80)
      colorChange( 1, 0, 100, 0);        // green       

    if (control == ledcontroller16 && value == 90)
      colorChange( 1, 2, 100, 2);        //light green     

    if (control == ledcontroller16 && value == 100)
       colorChange( 1, 0, 50, 20);       //turquoise       

    if (control == ledcontroller16 && value == 110)
        colorChange( 1, 0, 50, 40);        //light blue    

    if (control == ledcontroller16 && value == 120)
       colorChange( 1, 0, 100, 41);    //   aqua turquoise

    if (control == ledcontroller16 && value == 127)
       colorChange( 1, 100, 90, 100);    // white        




  }
}

void colorChange(uint16_t i, uint16_t r, uint16_t g, uint16_t b) {
  tlc.setLED(i, r, g, b);
 
  SPIwrite();

}




void SPIwrite() {
#define TSPEED 1000000 //1Mhz
  unsigned int chan1 = 0;
  unsigned int chan2 = 0;
  byte address1 = 0;
  byte address2 = 0;
  byte address3 = 0;
  SPISettings TLC5947(TSPEED , MSBFIRST, SPI_MODE0);
  // packing each 2 channel (12bit*2) to 3 byte (8bit*3) for transfering
  SPI.beginTransaction(TLC5947);
  // digitalWriteFast(latch, HIGH);
  digitalWriteFast(latch, LOW);
  for (unsigned int ledpos = 24  * NUM_TLC5974 ; ledpos > 0; ledpos = ledpos - 2) {
    chan1 = tlc.getCHAN(ledpos - 1);
    chan2 = tlc.getCHAN(ledpos - 2);
    address1 = (byte)(chan1 >> 4) ;
    address2 = (byte)((chan1 << 4) & (B11110000)) + (byte)((chan2 >> 8) & (B00001111));
    address3 = (byte)chan2;
    /* address1 = B00000000;
      address2 = B00000000;
      address3 = B00000000;*/
    SPI.transfer(address1);
    SPI.transfer(address2);
    SPI.transfer(address3);
  }

  SPI.endTransaction();
  //  digitalWriteFast(latch, LOW);
  digitalWriteFast(latch, HIGH);
  digitalWriteFast(latch, LOW);
  digitalWriteFast(clock, LOW);
}