Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: Looking for simple MIDI CC code

  1. #1

    Looking for simple MIDI CC code

    Hi! Newbie coder, but pretty good with MIDI. I've written code that sends MIDI notes to my computer using sensors and it's working great. Now I need to do kind of the opposite and I'm at a loss. I need to send MIDI CC to a Tensy 3.2 to alter stuff in the code.

    Basically like this:

    1. Send MIDI CC #40 from my MIDI controller (like this one) to Teensy
    2. If MIDI CC #40 = 127, do something
    3. Else if MIDI CC #40 = 0, do something else

    I've looked at the tutorials and just don't understand it. I know basic if/else code, but not how to get the MIDI CC data to manipulate. I'm up against a deadline and could use some help. If I could get the basic setup and loop code required I would greatly appreciate it.

    TIA!

  2. #2
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Location
    Florida
    Posts
    467
    If your MIDI controller is only USB midi you’ll be much better off using either a T3.6 or T4.0 which have a second USB port that can be used as a host for other USB devices like the one you linked. If you want it to work with DIN based MIDI then any Teensy can be used rather simply and there are examples already available for this using the MIDI library included with the Teensyduino install, for USB based MIDI there are some examples in the USBHost_t36 library included as well.

  3. #3
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Location
    Florida
    Posts
    467
    The good thing is you can use the same control change callback function between all the libraries so without even having all the hardware you aer able to test this while only being connected to a computer and use a program such as MIDI Tools which I use to test MIDI hardware as I build it.

    So something like this should work on the T3.6/T4.0 for all forms of midi whether USB device or USB host or DIN.
    Code:
    #include <MIDI.h>
    
    MIDI_CREATE_DEFAULT_INSTANCE();
    
    #include <USBHost_t36.h>
    
    USBHost myusb;
    USBHub hub1(myusb);
    USBHub hub2(myusb);
    MIDIDevice midi1(myusb);
    
    void setup() {
      myusb.begin();
      MIDI.begin();
      MIDI.setHandleControlChange(onControlChange);
      usbMIDI.setHandleControlChange(onControlChange);
      midi1.setHandleControlChange(onControlChange);
    }
    
    void loop() {
      myusb.Task();
      while(usbMIDI.read() || MIDI.read() || midi1.read()){
      }
    }
    
    void onControlChange(uint8_t channel, uint8_t control, uint8_t value){
      if(control == 40){
        if(value == 127){
          //Do something
        }
        else if(value == 0){
          //Do something else
        }
      }
    }
    If you want to just test it at this point and still use the T3.2 with only a computer program and no external hardware you can just do something like this.
    Code:
    void setup() {
      usbMIDI.setHandleControlChange(onControlChange);
    }
    
    void loop() {
      while(usbMIDI.read()){
      }
    }
    
    void onControlChange(uint8_t channel, uint8_t control, uint8_t value){
      if(control == 40){
        if(value == 127){
          //Do something
        }
        else if(value == 0){
          //Do something else
        }
      }
    }

  4. #4
    I don't need a second port because I'm running everything through a computer with MIDI routing software. I'm using in and out through one USB cable. I've got that stuff covered.

    I looked at the MIDI InputFunctionsBasics and MIDI InputRead examples. I'm sorry, I'm just so basic a coder. I need to get CC# 40 from MIDI Channel one (no virtual cables, not using MIDIx4 or MIDIx16). Then {if CC #40 = 127} do {this code} else do {this code}. I feel dumb about it, but the example code still isn't making sense to me. I'll paypal $5 to someone who can spell it out for me.

  5. #5
    Oh cool. Thanks, vjmuzik! I think I can make that second block of code work. Want the $5?

  6. #6
    BTW, I use Cantabile for routing controllers and VST plugins. It has a bit of a learning curve, but really powerful.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,357
    Run the InputFunctionsComplete example on your Teensy, and then open the Arduino Serial Monitor. As your PC sends MIDI messages, you should see info about each message Teensy receives printed to the serial monitor.

    Step 1: Just run it and make sure the Control Change lines it prints have the correct info.

    Step 2: Delete code for all the messages you don't care to see. That example is long. If the basic version prints the right info, it might save you a little time with less code to delete. As you delete stuff, keep uploading the code to your Teensy to make sure it still works for the Control Change printing you care about.

    Step 3: Change the myControlChange() function to do whatever you want with the CC message.

  8. #8
    Quote Originally Posted by vjmuzik View Post
    If you want to just test it at this point and still use the T3.2 with only a computer program and no external hardware you can just do something like this.
    Code:
    void setup() {
      usbMIDI.setHandleControlChange(onControlChange);
    }
    
    void loop() {
      while(usbMIDI.read()){
      }
    }
    
    void onControlChange(uint8_t channel, uint8_t control, uint8_t value){
      if(control == 40){
        if(value == 127){
          //Do something
        }
        else if(value == 0){
          //Do something else
        }
      }
    }
    Question: I'm using the Adafruit library to drive lights with my MIDI code (it's working fine), so this line:

    void onControlChange(uint8_t channel, uint8_t control, uint8_t value)

    is giving me this error:

    Arduino: 1.8.10 (Windows 10), TD: 1.48, Board: "Teensy 3.2 / 3.1, Serial + MIDI, 96 MHz (overclock), Faster, US English"

    Sabre_code_final_002:198: error: 'void onControlChange(uint8_t, uint8_t, uint8_t)' redeclared as different kind of symbol
    void onControlChange(uint8_t channel, uint8_t control, uint8_t value){

    ^

    C:\Users\timea\Documents\Arduino\Sabre_code_final_ 002\Sabre_code_final_002.ino:38:5: note: previous declaration 'int onControlChange'

    int onControlChange;

    ^

    Sabre_code_final_002: In function 'void setup()':
    C:\Users\timea\Documents\Arduino\Sabre_code_final_ 002\Sabre_code_final_002.ino:58:49: warning: invalid conversion from 'int' to 'void (*)(uint8_t, uint8_t, uint8_t) {aka void (*)(unsigned char, unsigned char, unsigned char)}' [-fpermissive]

    usbMIDI.setHandleControlChange(onControlChange);

    ^

    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/WProgram.h:59:0,

    from C:\Users\timea\AppData\Local\Temp\arduino_build_40 7726\pch\Arduino.h:6:

    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/usb_midi.h:305:14: note: initializing argument 1 of 'void usb_midi_class::setHandleControlChange(void (*)(uint8_t, uint8_t, uint8_t))'

    void setHandleControlChange(void (*fptr)(uint8_t channel, uint8_t control, uint8_t value)) {

    ^

    Sabre_code_final_002: In function 'void onControlChange(uint8_t, uint8_t, uint8_t)':
    Sabre_code_final_002:198: error: 'void onControlChange(uint8_t, uint8_t, uint8_t)' redeclared as different kind of symbol
    void onControlChange(uint8_t channel, uint8_t control, uint8_t value){

    ^

    C:\Users\timea\Documents\Arduino\Sabre_code_final_ 002\Sabre_code_final_002.ino:38:5: note: previous declaration 'int onControlChange'

    int onControlChange;

    ^

    Sabre_code_final_002:205: error: expected '}' at end of input
    }

    ^

    Sabre_code_final_002:205: error: expected '}' at end of input
    Multiple libraries were found for "Adafruit_TLC5947.h"
    Used: C:\Users\timea\Documents\Arduino\libraries\Adafrui t_TLC5947-master
    'void onControlChange(uint8_t, uint8_t, uint8_t)' redeclared as different kind of symbol
    I'm lost on that.

  9. #9
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Location
    Florida
    Posts
    467
    Looks like you have a variable with the same name as the function “onControlChange” so one or other needs to be changed to a different name.

  10. #10
    Oh! Dumb me. I initialized the function as a variable. It's compiling now. Thanks!!

  11. #11
    Okay, I'm finally at the stage where I can try to get this working. I'm going to post my full code. The sensor to MIDI section and the lights are working perfectly. I *know* my code isn't elegant. I'm having difficulty making 'for' loops work right with this application, so it's a lot of replication -- and I'm fine with that for now because I'm up against a deadline. After this Sunday, I'll work on slimlining the code.

    Right now I need to to this: I need to send a CC # to turn off all of the light channels and another CC # to turn them back on. It will be send via USB MIDI, the same MIDI that's transmitting the MIDI notes back to my software synth. I don't really understand functions or how to incorporate the CC code into my existing code. Here is where I'm at. Thanks in advance!

    Code:
    // LED
    #include "Adafruit_TLC5947.h"
    #define NUM_TLC5974 1
    #define data   11
    #define clock   13
    #define latch   10
    #define oe  -1  // set to -1 to not use the enable pin (its optional)
    Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch);
    // END LED
    
    int noteIsOn0;
    int noteIsOn1;
    int noteIsOn2;
    int noteIsOn3;
    int noteIsOn4;
    int noteIsOn5;
    int noteIsOn6;
    int noteIsOn7;
    int thresh;
    
    
    
    void setup() {
    
    // LED Setup
      Serial.begin(9600);
      
      Serial.println("TLC5974 test");
      tlc.begin();
      if (oe >= 0) {
        pinMode(oe, OUTPUT);
        digitalWrite(oe, LOW);
      }
    // END LED  
    
    // Harp Setup
    thresh = 480;
    // End Harp
    
     usbMIDI.setHandleControlChange(onControlChange);
    }
    
    void onControlChange(uint8_t channel, uint8_t control, uint8_t value){
      if(control == 40){
        if(value == 127){
            tlc.setLED(0, 0, 0, 0);
        delay (500);
            tlc.setLED(1, 0, 0, 0);
        delay (500);
            tlc.setLED(2, 0, 0, 0);
        delay (500);
            tlc.setLED(3, 0, 0, 0);
        delay (500);
            tlc.setLED(4, 0, 0, 0);
        delay (500);
            tlc.setLED(5, 0, 0, 0);
        delay (500);
            tlc.setLED(6, 0, 0, 0);
        delay (500);
            tlc.setLED(7, 0, 0, 0);
        delay (500);
        }
      }
     if(control == 41){
        if(value == 127){
            tlc.setLED (0, 4095, 4095, 1);
        delay (500);
            tlc.setLED (1, 4095, 4095, 1);
        delay (500);
            tlc.setLED (2, 4095, 4095, 1);
        delay (500);
            tlc.setLED (3, 4095, 4095, 1);
        delay (500);
            tlc.setLED (4, 4095, 4095, 1);
        delay (500);
            tlc.setLED (5, 4095, 4095, 1);
        delay (500);
            tlc.setLED (6, 4095, 4095, 1);
        delay (500);
            tlc.setLED (7, 4095, 4095, 1);
        delay (500);
        }
      }
    }
    
    void loop() {
    
    // Sensor Start 0 
      
      if (noteIsOn0 == false) {
        if (analogRead(0) > (thresh)) {
          usbMIDI.sendNoteOn(60, (random(115,127)), 1);
          tlc.setLED(0, 0, 4095, 0); 
          noteIsOn0 = true;
        }
      } else {
        if (analogRead(0) < thresh) {
          usbMIDI.sendNoteOff (60, 0, 1);
          noteIsOn0 = false;
          tlc.setLED (0, 4095, 4095, 1);     
        }
      }
    
    // Sensor Start 1
      if (noteIsOn1 == false) {  
        if (analogRead(1) > thresh+30) {
          usbMIDI.sendNoteOn(62, (random(115,127)), 1);
          tlc.setLED(1, 0, 4095, 0); 
          noteIsOn1 = true;
        }
      } else {
        if (analogRead(1) < thresh) {
          usbMIDI.sendNoteOff (62, 0, 1);
          noteIsOn1 = false;
          tlc.setLED (1, 4095, 4095, 1); 
          }
      }
    
    // Sensor Start 2
      if (noteIsOn2 == false) {  
        if (analogRead(2) > thresh) {
          usbMIDI.sendNoteOn(64, (random(115,127)), 1);
          tlc.setLED(2, 0, 4095, 0); 
          noteIsOn2 = true;
        }
      } else {
        if (analogRead(2) < thresh) {
          usbMIDI.sendNoteOff (64, 0, 1);
          noteIsOn2 = false;
          tlc.setLED (2, 4095, 4095, 1);      
        }
      }
    
      
    // Sensor Start 3
      if (noteIsOn3 == false) {
        if (analogRead(3) > thresh) {
          usbMIDI.sendNoteOn(65, (random(115,127)), 1);
          tlc.setLED(3, 0, 4095, 0); 
          noteIsOn3 = true;
        }
      } else {
        if (analogRead(3) < thresh) {
          usbMIDI.sendNoteOff (65, 0, 1);
          noteIsOn3 = false;
          tlc.setLED (3, 4095, 4095, 1);     
        }
      }
    
    
    // Sensor Start 4
      if (noteIsOn4 == false) {
        if (analogRead(4) > thresh + 25) {
          usbMIDI.sendNoteOn(67, (random(115,127)), 1);
          tlc.setLED(4, 0, 4095, 0); 
          noteIsOn4 = true;
        }
      } else {
        if (analogRead(4) < thresh) {
          usbMIDI.sendNoteOff (67, 0, 1);
          noteIsOn4 = false;
           tlc.setLED (4, 4095, 4095, 1);     
        }
      }
    
    // Sensor Start 5
      if (noteIsOn5 == false) {
        if (analogRead(5) > thresh) {
          usbMIDI.sendNoteOn(69, (random(115,127)), 1);
          tlc.setLED(5, 0, 4095, 0); 
          noteIsOn5 = true;
        }
      } else {
        if (analogRead(5) < thresh) {
          usbMIDI.sendNoteOff (69, 0, 1);
          noteIsOn5 = false;
          tlc.setLED (5, 4095, 4095, 1);      
        }
      }
    
    // Sensor Start 6
      if (noteIsOn6 == false) {
        if (analogRead(6) > thresh) {
          usbMIDI.sendNoteOn(71, (random(115,127)), 1);
          tlc.setLED(6, 0, 4095, 0); 
          noteIsOn6 = true;
        }
      } else {
        if (analogRead(6) < thresh) {
          usbMIDI.sendNoteOff (71, 0, 1);
          noteIsOn6 = false;
          tlc.setLED (6, 4095, 4095, 1);      
        }
      }
    
    // Sensor Start 7
      if (noteIsOn7 == false) {
        if (analogRead(7) > thresh) {
          usbMIDI.sendNoteOn(72, (random(115,127)), 1);
          tlc.setLED(7, 0, 4095, 0); 
          noteIsOn7 = true;
        }
      } else {
        if (analogRead(7) < thresh) {
          usbMIDI.sendNoteOff (72, 0, 1);
          noteIsOn7 = false;
          tlc.setLED (7, 4095, 4095, 1);     
        }
      }
    
    
    // END Sensors 
    
      while (usbMIDI.read()) {}
    
      tlc.write();
      delay(5);
       
    }

  12. #12
    How about just letting onControlChange() set a boolean that uses or doesn't use the lights?

    Code:
    // LED
    #include "Adafruit_TLC5947.h"
    #define NUM_TLC5974 1
    #define data   11
    #define clock   13
    #define latch   10
    #define oe  -1  // set to -1 to not use the enable pin (its optional)
    Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch);
    // END LED
    
    bool usingLights = true;
    int noteIsOn0;
    int noteIsOn1;
    int noteIsOn2;
    int noteIsOn3;
    int noteIsOn4;
    int noteIsOn5;
    int noteIsOn6;
    int noteIsOn7;
    int thresh;
    
    
    
    void setup() {
    
    // LED Setup
      Serial.begin(9600);
      
      Serial.println("TLC5974 test");
      tlc.begin();
      if (oe >= 0) {
        pinMode(oe, OUTPUT);
        digitalWrite(oe, LOW);
      }
    // END LED  
    
    // Harp Setup
    thresh = 480;
    // End Harp
    
     usbMIDI.setHandleControlChange(onControlChange);
    }
    
    void onControlChange(uint8_t channel, uint8_t control, uint8_t value){
      if(control == 40 && value == 127){
        usingLights = true;
      }
      else if(control == 41 && value == 127){
        usingLights = false;
        tlc.setLED(0, 0, 0, 0);
        delay (500);
        tlc.setLED(1, 0, 0, 0);
        delay (500);
        tlc.setLED(2, 0, 0, 0);
        delay (500);
        tlc.setLED(3, 0, 0, 0);
        delay (500);
        tlc.setLED(4, 0, 0, 0);
        delay (500);
        tlc.setLED(5, 0, 0, 0);
        delay (500);
        tlc.setLED(6, 0, 0, 0);
        delay (500);
        tlc.setLED(7, 0, 0, 0);
        delay (500);
      }
    }
    
    void loop() {
    
    // Sensor Start 0 
      
      if (noteIsOn0 == false) {
        if (analogRead(0) > (thresh)) {
          usbMIDI.sendNoteOn(60, (random(115,127)), 1);
          if (usingLights) tlc.setLED(0, 0, 4095, 0); 
          noteIsOn0 = true;
        }
      } else {
        if (analogRead(0) < thresh) {
          usbMIDI.sendNoteOff (60, 0, 1);
          noteIsOn0 = false;
          if (usingLights) tlc.setLED (0, 4095, 4095, 1);     
        }
      }
    
    // Sensor Start 1
      if (noteIsOn1 == false) {  
        if (analogRead(1) > thresh+30) {
          usbMIDI.sendNoteOn(62, (random(115,127)), 1);
          if (usingLights) tlc.setLED(1, 0, 4095, 0); 
          noteIsOn1 = true;
        }
      } else {
        if (analogRead(1) < thresh) {
          usbMIDI.sendNoteOff (62, 0, 1);
          noteIsOn1 = false;
          if (usingLights) tlc.setLED (1, 4095, 4095, 1); 
          }
      }
    
    // Sensor Start 2
      if (noteIsOn2 == false) {  
        if (analogRead(2) > thresh) {
          usbMIDI.sendNoteOn(64, (random(115,127)), 1);
          if (usingLights) tlc.setLED(2, 0, 4095, 0); 
          noteIsOn2 = true;
        }
      } else {
        if (analogRead(2) < thresh) {
          usbMIDI.sendNoteOff (64, 0, 1);
          noteIsOn2 = false;
          if (usingLights) tlc.setLED (2, 4095, 4095, 1);      
        }
      }
    
      
    // Sensor Start 3
      if (noteIsOn3 == false) {
        if (analogRead(3) > thresh) {
          usbMIDI.sendNoteOn(65, (random(115,127)), 1);
          if (usingLights) tlc.setLED(3, 0, 4095, 0); 
          noteIsOn3 = true;
        }
      } else {
        if (analogRead(3) < thresh) {
          usbMIDI.sendNoteOff (65, 0, 1);
          noteIsOn3 = false;
          if (usingLights) tlc.setLED (3, 4095, 4095, 1);     
        }
      }
    
    
    // Sensor Start 4
      if (noteIsOn4 == false) {
        if (analogRead(4) > thresh + 25) {
          usbMIDI.sendNoteOn(67, (random(115,127)), 1);
          if (usingLights) tlc.setLED(4, 0, 4095, 0); 
          noteIsOn4 = true;
        }
      } else {
        if (analogRead(4) < thresh) {
          usbMIDI.sendNoteOff (67, 0, 1);
          noteIsOn4 = false;
           if (usingLights) tlc.setLED (4, 4095, 4095, 1);     
        }
      }
    
    // Sensor Start 5
      if (noteIsOn5 == false) {
        if (analogRead(5) > thresh) {
          usbMIDI.sendNoteOn(69, (random(115,127)), 1);
          if (usingLights) tlc.setLED(5, 0, 4095, 0); 
          noteIsOn5 = true;
        }
      } else {
        if (analogRead(5) < thresh) {
          usbMIDI.sendNoteOff (69, 0, 1);
          noteIsOn5 = false;
          if (usingLights) tlc.setLED (5, 4095, 4095, 1);      
        }
      }
    
    // Sensor Start 6
      if (noteIsOn6 == false) {
        if (analogRead(6) > thresh) {
          usbMIDI.sendNoteOn(71, (random(115,127)), 1);
          if (usingLights) tlc.setLED(6, 0, 4095, 0); 
          noteIsOn6 = true;
        }
      } else {
        if (analogRead(6) < thresh) {
          usbMIDI.sendNoteOff (71, 0, 1);
          noteIsOn6 = false;
          if (usingLights) tlc.setLED (6, 4095, 4095, 1);      
        }
      }
    
    // Sensor Start 7
      if (noteIsOn7 == false) {
        if (analogRead(7) > thresh) {
          usbMIDI.sendNoteOn(72, (random(115,127)), 1);
          if (usingLights) tlc.setLED(7, 0, 4095, 0); 
          noteIsOn7 = true;
        }
      } else {
        if (analogRead(7) < thresh) {
          usbMIDI.sendNoteOff (72, 0, 1);
          noteIsOn7 = false;
          if (usingLights) tlc.setLED (7, 4095, 4095, 1);     
        }
      }
    
    
    // END Sensors 
    
      while (usbMIDI.read()) {}
    
      tlc.write();
      delay(5);
       
    }
    I'll let you worry about making this look good
    By the way, I think the maximum value for those last three parameters of setLED() should be 255, not 4095.
    Also, do you really need those 500 millisecond delays in there? Just wondering.

  13. #13
    I'll give this a try! The delays aren't necessary, just for effect. I'm not sure if I'll keep them. I'll double-check the parameter values. I thought the maximum 4095 had something to do with the LED driver board. Thanks!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •