Go Down

Topic: Sending Cc over usb midi (Read 680 times) previous topic - next topic

gregchill

My question is about sending cc Midi via usb, here is a function for sending Program change via Usb
Code: [Select]
void SendMIDI(byte number)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[2];                 // Construct the midi message (2 bytes)
    Message[0]=0xC0;                 // 0xC0 is for Program Change
    Message[1]=number;               // Number is the program/patch
    Midi.SendData(Message);          // Send the message
    delay(10);

But how do send Control Change in a function is it
Code: [Select]
void SendMIDI(byte number)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[3];                 // Construct the midi message (2 bytes)
    Message[0]=0xB0;                 // 0x0B Control change
    Message[1]=number;                // Number of Control Change
Message[3]=number;                  // Velocity amount
    Midi.SendData(Message);          // Send the message
    delay(10);


if someone can correct this or point me in the right direction would be great.



Grumpy_Mike

#1
Aug 09, 2017, 10:52 pm Last Edit: Aug 09, 2017, 10:54 pm by Grumpy_Mike
You are not posting all your code so it is hard to tell what you are using.
Please read this:-
How to use this forum

You seem to be mixing up the two with your text introduction and your code. A CC is a three byte message where as a program change is only a two byte message.

If I were doing it with just a serial write I would use:-
Code: [Select]
//  change the voice
void programChange(char cmd, char data1) {
  cmd = cmd | char(midiChannel);  // merge channel number
  Serial.write(cmd);
  Serial.write(data1);
}


The program change command byte is 0xC0

PieterP

Here's what I use for sending MIDI over USB:
Code: [Select]
#if defined(USBCON) && !defined(CORE_TEENSY)
#include "MIDIUSB.h"
#endif

#if defined (CORE_TEENSY) && ! (defined (USB_MIDI_AUDIO_SERIAL) || defined (USB_MIDI) || defined (USB_MIDI_SERIAL))
#error "Please select a MIDI option in the 'Tools > USB Type' menu."
#endif

const uint8_t NOTE_OFF = 0x80;
const uint8_t NOTE_ON = 0x90;
const uint8_t KEY_PRESSURE = 0xA0;
const uint8_t CC = 0xB0;
const uint8_t PROGRAM_CHANGE = 0xC0;
const uint8_t CHANNEL_PRESSURE = 0xD0;
const uint8_t PITCH_BEND = 0xE0;

void sendUSBMIDI(uint8_t m, uint8_t c, uint8_t d1, uint8_t d2) {  // send a 3-byte MIDI event over USB
  c--; // Channels are zero-based
  m &= 0xF0;
  c &= 0xF;
  d1 &= 0x7F;
  d2 &= 0x7F;
#if defined(CORE_TEENSY)   //only include these lines when compiling for a Teensy board
  usb_midi_write_packed((m >> 4) | ((m | c) << 8) | (d1 << 16) | (d2 << 24));
#elif defined(USBCON)      //only include these lines when compiling for an Arduino if you're compiling for an Arduino that has USB connection in the main MCU but is not a Teensy
  midiEventPacket_t msg = {m >> 4, m | c, d1, d2};
  MidiUSB.sendMIDI(msg);
  MidiUSB.flush();
#else                      // If you're compiling for an Arduino that has no USB connection in the main MCU
  Serial.write(m | c); // Send the MIDI message over Serial.
  Serial.write(d1);
  Serial.write(d2);
#endif
}

void sendUSBMIDI(uint8_t m, uint8_t c, uint8_t d) {  // send a 2-byte MIDI event over USB
  c--; // Channels are zero-based
  m &= 0xF0;
  c &= 0xF;
  d &= 0x7F;
#if defined(CORE_TEENSY)   //only include these lines when compiling for a Teensy board
  usb_midi_write_packed((m >> 4) | ((m | c) << 8) | (d << 16));
#elif defined(USBCON)      //only include these lines when compiling for an Arduino if you're compiling for an Arduino that has USB connection in the main MCU but is not a Teensy
  midiEventPacket_t msg = {m >> 4, m | c, d, 0};
  MidiUSB.sendMIDI(msg);
  MidiUSB.flush();
#else                      // If you're compiling for an Arduino that has no USB connection in the main MCU
  Serial.write(m | c); // Send the MIDI message over Serial.
  Serial.write(d);
#endif
}


Pieter

gregchill

Hi Guys thanks for the help here is the whole code
Code: [Select]
#include <usbh_midi.h>
USB Usb;
USBH_MIDI Midi(&Usb);
int tuner = 6;
int switchPin[5] = {2,3,4,5,14};
int ledPin[5]={7,8,9,13,11};
int currentPreset =0;
int maxPresetNumber = 50; // for Zoom MS70cdr change by this = 50
bool pinState[5];
//int progChange[4] = {+1,-1,+10,-10};
/***********************************************************************************/
void setup()

{
 Serial.begin(115200);
 for(int i=0; i<5; i++)
  {
    pinMode(ledPin[i], OUTPUT);
    pinMode(switchPin[i], INPUT_PULLUP);
    pinMode(tuner,INPUT_PULLUP);
  } 
  if (Usb.Init() == -1)
  {
    digitalWrite(ledPin[5], HIGH);
    while(1);               // Halt
  }
  currentPreset = 0;
  //SendMIDI(currentPreset);
}
/***********************************************************************************/
void SendMIDI(byte programChange)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[2];                 // Construct the midi message (2 bytes)
    Message[0]=192;                 // 0xC0 is for Program Change
    Message[1]=programChange;               // Number is the program/patch
    Midi.SendData(Message);          // Send the message
    delay(10);
  }

}
/***********************************************************************************/
void ledsOff()
{
 for(int i=0; i<5; i++)
  {
    digitalWrite(ledPin[i], LOW);
  }
}
/***********************************************************************************/
/*void loop() //+1 -1 +10 -10 presets mode
{
  for(int i=0; i<4; i++)
  {
   pinState[i]=digitalRead(switchPin[i]);
    if(pinState[i] != HIGH)
    {
      //currentPreset = programChange[i];
      ledsOff();
     SendMIDI(programChange[i]);
     digitalWrite(ledPin[i], HIGH);
      delay(500);
    }
    else
    {
      NULL;
    }
  }

 /* if(currentPreset > maxPresetNumber)
  {
    currentPreset = 0;
  }
  if(currentPreset < 0)
  {
    currentPreset = maxPresetNumber;
  } 
 
}

***********************************************************************************/
//void loop() //for Zoom MS70cdr

  void loop() //4 presets mode
{
  for(int i=0; i<4; i++)
  {
    pinState[i]=digitalRead(switchPin[i]);
    if(pinState[i] != HIGH)
    {
      //Serial.print(pinState[i] ,BIN);
      SendMIDI(i); //presets from 1 to 4
      ledsOff();
      digitalWrite(ledPin[i], HIGH);
      delay(200);
    }
    else
    {
      NULL;
    }
  }
 
 
  int tunstate;
    tunstate = digitalRead(tuner); //Switchstate for the tuner.
      if(tunstate = HIGH){
        sendmidicc(74,0);
        delay(100);   
     
     }
     else
     {
     
      sendmidicc(74,127); 
      }
   
   
   
   
   

}
void sendmidicc (byte cmd, byte data1)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    Serial.write(0xB0);
    Serial.write(cmd);
    Serial.write(data1);
   
   
    delay(10);
  }
}


Its just the control change part im having the problem with.

gregchill

Hi Pieter have tried your sendmidi function in my code and its not working
Code: [Select]
//#include <SPI.h>
#include <usbh_midi.h>
USB Usb;
USBH_MIDI Midi(&Usb);
int tuner = 6;
const uint8_t CC = 0xB0;
int switchPin[5] = {2,3,4,5,14};
int ledPin[5]={7,8,9,13,11};
int currentPreset =0;
int maxPresetNumber = 50; // for Zoom MS70cdr change by this = 50
bool pinState[5];
//int progChange[4] = {+1,-1,+10,-10};
/***********************************************************************************/
void setup()

{
 Serial.begin(115200);
 for(int i=0; i<5; i++)
  {
    pinMode(ledPin[i], OUTPUT);
    pinMode(switchPin[i], INPUT_PULLUP);
    pinMode(tuner,INPUT_PULLUP);
  } 
  if (Usb.Init() == -1)
  {
    digitalWrite(ledPin[5], HIGH);
    while(1);               // Halt
  }
  currentPreset = 0;
  //SendMIDI(currentPreset);
}
/***********************************************************************************/
void SendMIDI(byte programChange)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[2];                 // Construct the midi message (2 bytes)
    Message[0]=192;                 // 0xC0 is for Program Change
    Message[1]=programChange;               // Number is the program/patch
    Midi.SendData(Message);          // Send the message
    delay(10);
  }

}
/***********************************************************************************/
void ledsOff()
{
 for(int i=0; i<5; i++)
  {
    digitalWrite(ledPin[i], LOW);
  }
}
/***********************************************************************************/
/*void loop() //+1 -1 +10 -10 presets mode
{
  for(int i=0; i<4; i++)
  {
   pinState[i]=digitalRead(switchPin[i]);
    if(pinState[i] != HIGH)
    {
      //currentPreset = programChange[i];
      ledsOff();
     SendMIDI(programChange[i]);
     digitalWrite(ledPin[i], HIGH);
      delay(500);
    }
    else
    {
      NULL;
    }
  }

 /* if(currentPreset > maxPresetNumber)
  {
    currentPreset = 0;
  }
  if(currentPreset < 0)
  {
    currentPreset = maxPresetNumber;
  } 
 
}

***********************************************************************************/
//void loop() //for Zoom MS70cdr

  void loop() //4 presets mode
{
  for(int i=0; i<4; i++)
  {
    pinState[i]=digitalRead(switchPin[i]);
    if(pinState[i] != HIGH)
    {
      //Serial.print(pinState[i] ,BIN);
      SendMIDI(i); //presets from 1 to 4
      ledsOff();
      digitalWrite(ledPin[i], HIGH);
      delay(200);
    }
    else
    {
      NULL;
    }
  }
 
 
  int tunstate;
    tunstate = digitalRead(tuner); //Switchstate for the tuner.
      if(tunstate = HIGH){
        sendUSBMIDI(0xB0,1,74,0);
        delay(100);   
     
     }
     else
     {
     
      sendUSBMIDI(0xB0,1, 74 ,127); 
      }
   
   
   
   
   

}
void sendUSBMIDI(uint8_t m, uint8_t c, uint8_t d1, uint8_t d2) {  // send a 3-byte MIDI event over USB
  c--; // Channels are zero-based
  m &= 0xF0;
  c &= 0xF;
  d1 &= 0x7F;
  d2 &= 0x7F;
#if defined(CORE_TEENSY)   //only include these lines when compiling for a Teensy board
  usb_midi_write_packed((m >> 4) | ((m | c) << 8) | (d1 << 16) | (d2 << 24));
#elif defined(USBCON)      //only include these lines when compiling for an Arduino if you're compiling for an Arduino that has USB connection in the main MCU but is not a Teensy
  midiEventPacket_t msg = {m >> 4, m | c, d1, d2};
  MidiUSB.sendMIDI(msg);
  MidiUSB.flush();
#else                      // If you're compiling for an Arduino that has no USB connection in the main MCU
  Serial.write(m | c); // Send the MIDI message over Serial.
  Serial.write(d1);
  Serial.write(d2);
#endif
}

Here it is looking for 4 characters to compile this is what i have (controlchange,midi channel,control change number,data amount)
Code: [Select]
sendUSBMIDI(0xB0,1, 74 ,127);where am i going wrong.
any help would be great.

PieterP

What what board are you using? I'm not familiar with the MIDI USB library you're trying to use.
Where did you get the code from, and why don't you use the MIDIUSB library?

Pieter

gregchill

Hi, its a Uno i'm using, got the sketch on the indestructible web site the sketch didnt work at all when i got it but i changed some of the code in it and got it working.

PieterP

The main MCU of an Arduino Uno doesn't support MIDI over USB.
Many of the articles on Instructables are just garbage.

Read this Wiki if you want to know more about MIDI over USB on Arduino boards.
You might be interested in my MIDI controller library as well. It contains installation instructions to get MIDI over USB working with an Uno, and is portable between pretty much all Arduino and Teensy boards.

Pieter

gregchill

Hi With the code you sent me would you able to show me an example of sending a CC message?

PieterP

This sketch takes the value of a potentiometer connected to analog input A0, and sends it over MIDI as a control change.
For using the functions in reply #2:
Code: [Select]
#if defined(USBCON) && !defined(CORE_TEENSY)
#include "MIDIUSB.h"
#endif

#if defined (CORE_TEENSY) && ! (defined (USB_MIDI_AUDIO_SERIAL) || defined (USB_MIDI) || defined (USB_MIDI_SERIAL))
#error "Please select a MIDI option in the 'Tools > USB Type' menu."
#endif

const uint8_t NOTE_OFF = 0x80;
const uint8_t NOTE_ON = 0x90;
const uint8_t KEY_PRESSURE = 0xA0;
const uint8_t CC = 0xB0;
const uint8_t PROGRAM_CHANGE = 0xC0;
const uint8_t CHANNEL_PRESSURE = 0xD0;
const uint8_t PITCH_BEND = 0xE0;

void setup() {
#ifndef USBCON
  Serial.begin(31250);  // Start Serial communication at MIDI hardware baud (use 115200 for Hairless MIDI)
#endif
}

const uint8_t analogInputPin = A0;

const uint8_t channel = 1;  // MIDI channel 1
const uint8_t controller = 0x7;  // defined as MIDI channel volume

void loop() {
  static uint8_t prevValue = 128;
  uint8_t value = analogRead(analogInputPin) >> 3;  // analogRead resolution is 10 bits, MIDI resolution is 7 bits, so shift 3 bits to the right
  if (value != prevValue) {
    sendUSBMIDI(CC, channel, controller, value);
    prevValue = value;
  }
}

void sendUSBMIDI(uint8_t m, uint8_t c, uint8_t d1, uint8_t d2) {  // send a 3-byte MIDI event over USB
  c--; // Channels are zero-based
  m &= 0xF0;
  c &= 0xF;
  d1 &= 0x7F;
  d2 &= 0x7F;
#if defined(CORE_TEENSY)   // only include these lines when compiling for a Teensy board
  usb_midi_write_packed((m >> 4) | ((m | c) << 8) | (d1 << 16) | (d2 << 24));
#elif defined(USBCON)      // only include these lines when compiling for an Arduino if you're compiling for an Arduino that has USB connection in the main MCU but is not a Teensy
  midiEventPacket_t msg = {m >> 4, m | c, d1, d2};
  MidiUSB.sendMIDI(msg);
  MidiUSB.flush();
#else                      // If you're compiling for an Arduino that has no USB connection in the main MCU
  Serial.write(m | c); // Send the MIDI message over Serial.
  Serial.write(d1);
  Serial.write(d2);
#endif
}

void sendUSBMIDI(uint8_t m, uint8_t c, uint8_t d) {  // send a 2-byte MIDI event over USB
  c--; // Channels are zero-based
  m &= 0xF0;
  c &= 0xF;
  d &= 0x7F;
#if defined(CORE_TEENSY)   // only include these lines when compiling for a Teensy board
  usb_midi_write_packed((m >> 4) | ((m | c) << 8) | (d << 16));
#elif defined(USBCON)      // only include these lines when compiling for an Arduino if you're compiling for an Arduino that has USB connection in the main MCU but is not a Teensy
  midiEventPacket_t msg = {m >> 4, m | c, d, 0};
  MidiUSB.sendMIDI(msg);
  MidiUSB.flush();
#else                      // If you're compiling for an Arduino that has no USB connection in the main MCU
  Serial.write(m | c); // Send the MIDI message over Serial.
  Serial.write(d);
#endif
}


The code below does exactly the same thing with much less lines of code, and it averages the input as well to eliminate noise:
Code: [Select]
#include <MIDI_controller.h> // include the library

const static byte Channel_Volume = 0x7;  // controller number 7 is defined as Channel Volume in the MIDI implementation.
const static size_t analogAverage = 8;   // Use the average of 8 samples to get smooth transitions and prevent noise

Analog potentiometer(A0, Channel_Volume, 1); // Create a new instance of the class 'Analog', called 'potentiometer', on pin A0, that sends MIDI messages with controller 7 (channel volume) on channel 1.

void setup(){
  USBMidiController.blink(LED_BUILTIN);  // flash the built-in LED (pin 13 on most boards) on every message
  USBMidiController.setDelay(15);        // wait 15 ms after each message not to flood the connection
  USBMidiController.begin();             // Initialise the USB MIDI connection
  potentiometer.average(analogAverage);  // Use the average of 8 samples to get smooth transitions and prevent noise
}

void loop(){
  potentiometer.refresh(); // refresh the potentiometer (check whether the input has changed since last time, if so, send it over MIDI)
}


Pieter

gregchill

Thank you for that

is the CC in the following code CC = CC or CC=B0
Code: [Select]
sendUSBMIDI(CC, channel, controller, value);

PieterP

Code: [Select]
const uint8_t CC = 0xB0;

Pieter

gregchill

Cheers, its the const uint8 that was throwing me.

Grumpy_Mike

const - this value is a constant it will not be changed
unit - unsigned interger
8 - this variable is 8 bits wide, or a single byte.

gregchill

Hi Thanks for all the help lads i managed to figure it out with your help
Code: [Select]
#include <usbh_midi.h>
USB Usb;
USBH_MIDI Midi(&Usb);
int tuner = 7;
int switchPin[5] = {2,3,4,5,14};
int ledPin[5]={6,8,9,13,11};
int currentPreset =0;
int maxPresetNumber = 50; // for Zoom MS70cdr change by this = 50
bool pinState[5];
//int progChange[4] = {+1,-1,+10,-10};
/***********************************************************************************/
void setup()

{
 Serial.begin(115200);
 for(int i=0; i<5; i++)
  {
    pinMode(ledPin[i], OUTPUT);
    pinMode(switchPin[i], INPUT_PULLUP);
    pinMode(tuner,INPUT_PULLUP);
  }
  if (Usb.Init() == -1)
  {
    digitalWrite(ledPin[5], HIGH);
    while(1);               // Halt
  }
  currentPreset = 0;
  //SendMIDI(currentPreset);
}
/***********************************************************************************/
void SendMIDI(byte programChange)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[2];                 // Construct the midi message (2 bytes)
    Message[0]=192;                 // 0xC0 is for Program Change
    Message[1]=programChange;               // Number is the program/patch
    Midi.SendData(Message);          // Send the message
    delay(10);
  }

}
/***********************************************************************************/
void ledsOff()
{
 for(int i=0; i<5; i++)
  {
    digitalWrite(ledPin[i], LOW);
  }
}
/***********************************************************************************/
/*void loop() //+1 -1 +10 -10 presets mode
{
  for(int i=0; i<4; i++)
  {
   pinState[i]=digitalRead(switchPin[i]);
    if(pinState[i] != HIGH)
    {
      //currentPreset = programChange[i];
      ledsOff();
     SendMIDI(programChange[i]);
     digitalWrite(ledPin[i], HIGH);
      delay(500);
    }
    else
    {
      NULL;
    }
  }

 /* if(currentPreset > maxPresetNumber)
  {
    currentPreset = 0;
  }
  if(currentPreset < 0)
  {
    currentPreset = maxPresetNumber;
  }
 
}

***********************************************************************************/
//void loop() //for Zoom MS70cdr

  void loop() //4 presets mode
{
  for(int i=0; i<4; i++)
  {
    pinState[i]=digitalRead(switchPin[i]);
    if(pinState[i] != HIGH)
    {
      //Serial.print(pinState[i] ,BIN);
      SendMIDI(i); //presets from 1 to 4
      ledsOff();
      digitalWrite(ledPin[i], HIGH);
      delay(200);
    }
    else
    {
      NULL;
    }
  }
 
 
  int tunstate;
    tunstate = digitalRead(tuner); //Switchstate for the tuner.
      if(tunstate == HIGH){
        sendmidicc(74,0);
        delay(100);   
     
     }
     else
     {
     
      sendmidicc(74,127);
     
      }
   
   
   
   
   

}
void sendmidicc (byte number, byte data1)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[3];                 // Construct the midi message (2 bytes)
    Message[0]=176;                 // 0x0B Control change
    Message[1]=number;                // Number of Control Change
Message[2]=data1;                  // Velocity amount
    Midi.SendData(Message);          // Send the message
   
   
    delay(10);
  }
}


This is the function for sending the CC Message over the USB Shield
Code: [Select]
void sendmidicc (byte number, byte data1)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[3];                 // Construct the midi message (2 bytes)
    Message[0]=176;                 // 0x0B Control change
    Message[1]=number;                // Number of Control Change
Message[2]=data1;                  // Velocity amount
    Midi.SendData(Message);          // Send the message
   
   
    delay(10);
  }


Regards

Greg

Go Up