Go Down

Topic: Serial MIDI and Arduino MIDI (Read 948 times) previous topic - next topic

j2sip

Is there a difference between a sketch written for serial MIDI use (thru a 5 pin DIN) and USB (direct from arduino?

I'm waing for an Arduino Pro micro to test it out but I can't wait.. I just have to ask now :D

Thanks a lot!

marco_c

Should be no difference. The sketches use a serial port (hardware or software implementation). The 5 pin DIN needs to be connected to the serial port and the USB already is.

If you want to share the standard serial lines for the 5 pin din you will need to work out how to switch between the two (arduino and MIDI) as downloading the compiled sketch will also end up in the MIDI stream.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

j2sip

thank you for the reply. I guess i still have a ton of reading to do :)

Grumpy_Mike

Quote
Is there a difference between a sketch written for serial MIDI use (thru a 5 pin DIN) and USB (direct from arduino?
As long as to have a helper app like "hairless" running on your PC then the code can be the same.

However, if you are using an Arduino Pro micro then by using the MIDIUSB library you can make your Arduino simply look like a USB HID MIDI interface with no need for a helper app. This means you have to communicate MIDI messages slightly differently by using the calls and methods provided by that library.   

j2sip

Thank you for the reply.

Yes, I am using a Arduino Micro which appears as a Midi input device.

I managed to edit a code i found on the net for testing. I had the LED and the switches to work (much to my delight!) except the MIDI part. It seems it's not transmitting at all.

There's a Midi learn function in the guitar amplifier sim that I am using but I always get a "no midi signal received" error every time I attempt to use it.  Arduino Micro is set as MIDI input device in its audio/midi setting.

I just want the two button to send MIDI program change.

Here's the code:

Code: [Select]
#include <MIDI.h>
#include <avdweb_Switch.h>
#include <frequencyToNote.h>
#include <MIDIUSB.h>
#include <MIDIUSB_Defs.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>

// Define analog pins for LEDs
int ledPin1 = 18;
int ledPin2 = 19;
   
// Switches
Switch buttonGND1 = Switch(9);    // button to GND, use internal 20K pullup resistor
Switch buttonGND2 = Switch(8);    // button to GND, use internal 20K pullup resistor

// MIDI init
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  //  Set serial baud rate:  31250 for MIDI  /  9600 for debugging
  Serial1.begin(31250);
  MIDI.begin(1);                      // Launch MIDI and listen to channel 1
}

void loop() {
  buttonGND1.poll(); 
  if(buttonGND1.released()) {
    Serial1.write("Button 1\n");
    MIDI.sendProgramChange(0,1);      // Send the MIDI command
    ledOffAll();
    digitalWrite(ledPin1, 255);
  }
  buttonGND2.poll(); 
  if(buttonGND2.released()) {
    Serial1.write("Button 2\n");
    MIDI.sendProgramChange(1,1);      // Send the MIDI command
    ledOffAll();
    digitalWrite(ledPin2, 255);
  }
 
 
}

void ledOffAll() {
    digitalWrite(ledPin1, 0);       
    digitalWrite(ledPin2, 0);
   
   
   
}

PieterP

#5
Aug 27, 2019, 02:06 pm Last Edit: Aug 27, 2019, 02:07 pm by PieterP
The default MIDI instance is on Serial, it's not USB MIDI.

You have to use this:
Code: [Select]
MIDI_CREATE_INSTANCE(UsbTransport, sUsbTransport, MIDI);


Have a look at the examples:
https://github.com/FortySevenEffects/arduino_midi_library/blob/master/examples/MidiUSB/MidiUSB.ino

Pieter

Grumpy_Mike

Code: [Select]
Switch buttonGND1 = Switch(9);    // button to GND, use internal 20K pullup resistor
Switch buttonGND2 = Switch(8);    // button to GND, use internal 20K pullup resistor

But you have no command in the setup function to set those two buttons to be a pulled up input. By default inputs are not pulled up.

Code: [Select]
// Define analog pins for LEDs
int ledPin1 = 18;
int ledPin2 = 19;

That will not work on an Arduino Micro, use the A4 & A5 notation when using the analogue pins on anything but a Uno.

Why are you using <avdweb_Switch.h> it is not smart to use a library for something that simple. If you must use it then the guidelines say you should include a link to obscure libraries.

Quote
// Launch MIDI and listen to channel 1
But your code is not doing any listening.


j2sip

Code: [Select]
Switch buttonGND1 = Switch(9);    // button to GND, use internal 20K pullup resistor
Switch buttonGND2 = Switch(8);    // button to GND, use internal 20K pullup resistor

But you have no command in the setup function to set those two buttons to be a pulled up input. By default inputs are not pulled up.

Code: [Select]
// Define analog pins for LEDs
int ledPin1 = 18;
int ledPin2 = 19;

That will not work on an Arduino Micro, use the A4 & A5 notation when using the analogue pins on anything but a Uno.

Why are you using <avdweb_Switch.h> it is not smart to use a library for something that simple. If you must use it then the guidelines say you should include a link to obscure libraries.
But your code is not doing any listening.


Really is a mess. Shows the noob in me :).

Here's something that worked with the LED and button switches. How do I integrate the MIDI part in it is my question.  

Included also are some lines from the link provided by Pieter in his previous comment.
But I must also mention that there is an "unterminated #if" error in this line

#if defined(USBCON)




Code: [Select]
#include <frequencyToNote.h>
#include <MIDIUSB.h>
#include <MIDIUSB_Defs.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>

#include <MIDI.h>

#if defined(USBCON)
#include <midi_UsbTransport.h>

static const unsigned sUsbTransportBufferSize = 16;
typedef midi::UsbTransport<sUsbTransportBufferSize> UsbTransport;

UsbTransport sUsbTransport;

MIDI_CREATE_INSTANCE(UsbTransport, sUsbTransport, MIDI);


int ledPinRed = A1;  
int ledPinGreen = A0;
int buttonPin1 = 9;    
int buttonPin2 = 8;    
int buttonState1 = 0;  
int buttonState2 = 0;

void setup() {  

  pinMode(ledPinGreen, OUTPUT);
  pinMode(ledPinRed, OUTPUT);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
}

void loop() {

  buttonState1 = digitalRead(buttonPin1);
  if(buttonState1 == HIGH) {
    digitalWrite(ledPinRed, HIGH);
    ledOffAll();
   digitalWrite(ledPinRed, 255);
  
   }
   buttonState2 = digitalRead(buttonPin2);
  
  if(buttonState2 == HIGH)
  {
    digitalWrite(ledPinGreen, HIGH);
    ledOffAll();
    digitalWrite(ledPinGreen, 255);}
}

   void ledOffAll() {
    digitalWrite(ledPinRed, 0);      
    digitalWrite(ledPinGreen, 0);
  }
  

 




Thanks a lot for your guidance.



Grumpy_Mike

Can we get things straight. I am still not 100% sure what you want to do.

Do you want to send MIDI CC messages out to a 5 pin DIN socket on Serial1?
If so what are you doing with the USB MIDI library? Why is it in your sketch at all?

Or do you want to send MIDI CC messages through the USB to a computer? In which case what is Serial1 doing in your sketch.
This is for the code in reply#4.

j2sip

I'm sorry for the confusion.. I want to send MIDI Program Change thru the USB to the computer.

While tinkering with codes found in the web, I managed to make the attached (code) to function.  MIDI OX now show the note being pressed and it was also received (at last!) by the guitar amplifier sim software.


But I would like it to send Program Change instead. What should I edit to do that? Would changing the NoteOn to programChange and removing all NoteOff work?


Code: [Select]
/*
   This examples shows how to make a simple seven keys MIDI keyboard with volume control

   Created: 4/10/2015
   Author: Arturo Guadalupi <a.guadalupi@arduino.cc>
   
   http://www.arduino.cc/en/Tutorial/MidiDevice
*/

#include <frequencyToNote.h>
#include <MIDIUSB.h>
#include <MIDIUSB_Defs.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>

#include <MIDI.h>

#include <midi_UsbTransport.h>

static const unsigned sUsbTransportBufferSize = 16;
typedef midi::UsbTransport<sUsbTransportBufferSize> UsbTransport;

UsbTransport sUsbTransport;

MIDI_CREATE_INSTANCE(UsbTransport, sUsbTransport, MIDI);



#define NUM_BUTTONS  7

const uint8_t button1 = 9;
const uint8_t button2 = 8;
const uint8_t button3 = 7;
const uint8_t button4 = 6;
const uint8_t button5 = 5;
const uint8_t button6 = 4;
const uint8_t button7 = 3;

const int intensityPot = 0;  //A0 input

const uint8_t buttons[NUM_BUTTONS] = {button1, button2, button3, button4, button5, button6, button7};
const byte notePitches[NUM_BUTTONS] = {36, 37, 38, 39, 40, 41, 42};

uint8_t notesTime[NUM_BUTTONS];
uint8_t pressedButtons = 0x00;
uint8_t previousButtons = 0x00;
uint8_t intensity;

void setup() {
  for (int i = 0; i < NUM_BUTTONS; i++)
    pinMode(buttons[i], INPUT_PULLUP);
}


void loop() {
  readButtons();
  readIntensity();
  playNotes();
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void readButtons()
{
  for (int i = 0; i < NUM_BUTTONS; i++)
  {
    if (digitalRead(buttons[i]) == LOW)
    {
      bitWrite(pressedButtons, i, 1);
      delay(50);
    }
    else
      bitWrite(pressedButtons, i, 0);
  }
}

void readIntensity()
{
  int val = analogRead(intensityPot);
  intensity = (uint8_t) (map(val, 0, 1023, 0, 127));
}

void playNotes()
{
  for (int i = 0; i < NUM_BUTTONS; i++)
  {
    if (bitRead(pressedButtons, i) != bitRead(previousButtons, i))
    {
      if (bitRead(pressedButtons, i))
      {
        bitWrite(previousButtons, i , 1);
        noteOn(0, notePitches[i], intensity);
        MidiUSB.flush();
      }
      else
      {
        bitWrite(previousButtons, i , 0);
        noteOff(0, notePitches[i], 0);
        MidiUSB.flush();
      }
    }
  }
}

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}
   

Grumpy_Mike

Quote
Would changing the NoteOn to programChange and removing all NoteOff work?
Yes it should but remember to flush after sending any MIDI message, that seems to be missing from your earlier code.

j2sip

Yes it should but remember to flush after sending any MIDI message, that seems to be missing from your earlier code.
Thank you. i would definitely add that.

What should I do here? i really have no idea how to remove all reference to the MIDI note on and change it to Program change.

I appreciate any help..

Code: [Select]
void playNotes()
{
  for (int i = 0; i < NUM_BUTTONS; i++)
  {
    if (bitRead(pressedButtons, i) != bitRead(previousButtons, i))
    {
      if (bitRead(pressedButtons, i))
      {
        bitWrite(previousButtons, i , 1);
        noteOn(0, notePitches[i], intensity);
        MidiUSB.flush();
      }
      else
      {
        bitWrite(previousButtons, i , 0);
        noteOff(0, notePitches[i], 0);
        MidiUSB.flush();
      }
    }
  }
}

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

j2sip

I started a new topic about this with an appropriate title so as to help, in a way, other beginners like me.

Thanks!

Grumpy_Mike

Just to say for anyone finding this thread at a later date the continuing thread is here:- https://forum.arduino.cc/index.php?topic=633573.msg4289781#msg4289781

securitycamerateam


Go Up