Go Down

Topic: Basic MIDI Code Examples w/ Genuino Micro (Read 1 time) previous topic - next topic

Grumpy_Mike

Yes but note that was using a different library to the one you need to use so check the order of the parameters .

_pmj

Ah, so that example was using the MIDI rather than the MIDIUSB library?

Need to get my head around the differences there, will read up on it.

PieterP

#17
Sep 08, 2016, 02:57 pm Last Edit: Sep 08, 2016, 05:24 pm by PieterP
If it can be of any use:
This is the code I use to send MIDI messages without extra libraries. Using libraries doesn't really help understanding what you are doing. They are extremely handy, don't get me wrong, but I just like to know what's going on under the hood as well.

I'd suggest that you read up on the MIDI protocol if you haven't already, here are some links to get you started:
http://www.instructables.com/id/Custom-Arduino-MIDI-Controller/step6/Code-time-Well-almost-/#MIDI_messages (It's an Instructable, I know, but I did know what I was talking about, agreed, there's a lot of bad information on there, but some really well documented, well researched articles as well.)
https://www.midi.org/specifications/item/table-1-summary-of-midi-message (They have recently updated their site, and the actual specification seems to have disappeared, maybe they'll add it again in the future ...)
https://www.nyu.edu/classes/bello/FMT_files/9_MIDI_code.pdf (Really good slides, taught me a lot.)

And finally: my code:
Code: [Select]
/* These are constants (actually preprocessor macros): whenever we put one of these 3 words (the ones in capitals) in our code, the precompiler will replace it by the 0xsomething after the word.
 This makes our code more readable, instead of typing the meaningless 0x90, we can now just type NOTE_ON, if we want a note to be on. */
#define NOTE_OFF       0x80
#define NOTE_ON        0x90
#define CC             0xB0

/* This is also a constant value (preprocessor macro). If you want to change the number of analog inputs, you can simply do it once on this line, instead of changing it everywhere in your code.*/
#define NUMBER_OF_ANALOG_INPUTS  6 // The Uno has 6 analog inputs, we'll use all of them in this example. If you only need 4, change this to 4, and you'll be able to use A4 & A5 as normal I/O pins.
// NOTE: if you change this value, also change the controllers array, to match the number of inputs and the number of controllers.

#define CHANNEL  1 // Send all messages on channel 1.

/* The list with the corresponding controller numbers: for example, the values of the potentiometer on A0 will be sent as the first controller number in this list, A1 as the second, etc...
 Here's the list with all controller numbers:  http://midi.org/techspecs/midimessages.php#3  You can change them if you want.*/
int controllers[NUMBER_OF_ANALOG_INPUTS] = {
  0x10, 0x11, 0x12, 0x13, 0x14, 0x15
}; 

int analogVal[NUMBER_OF_ANALOG_INPUTS];  // Declare an array for the values from the analog inputs

int analogOld[NUMBER_OF_ANALOG_INPUTS];  // Declare an array for the previous analog values. (To know if the knob has been turned since the last measurement)


/* The format of the message to send via serial. We create a new data structure, that can store 3 bytes at once.  This will be easier to send as MIDI. */
typedef struct {
  uint8_t status;   // first  byte   : status message (NOTE_ON, NOTE_OFF or CC (controlchange) and midi channel (0-15)
  uint8_t data1;    // second byte   : first value (0-127), controller number or note number
  uint8_t data2;    // third  byte   : second value (0-127), controller value or velocity
}
t_midiMsg;          // We call this structure 't_midiMsg'

void setup() // The setup runs only once, at startup.
{
  pinMode(13, OUTPUT);   // Set pin 13 (the one with the LED) to output
  digitalWrite(13, LOW); // Turn off the LED
  for(int i = 0; i < NUMBER_OF_ANALOG_INPUTS; i++){  // We make all values of analogOld -1, so it will always be different from any possible analog reading.
    analogOld[i]=-1;
  }
  Serial1.begin(31250);  // Start a serial connection @31250 baud or pulses per second on digital pin 0 and 1, 31250 baud is the original MIDI speed. The MIDI output is on pin 1 (TX)
  digitalWrite(13, HIGH);// Turn on the LED, when the loop is about to start.
}

void loop() // The loop keeps on repeating forever.
{
  t_midiMsg msg;                                     // create a variable 'msg' of data type 't_midiMsg' we just created
  for(int i = 0; i < NUMBER_OF_ANALOG_INPUTS; i++){  // Repeat this procedure for every analog input.

    analogVal[i] = analogRead(i+A0)/8;               // The resolution of the Arduino's ADC is 10 bit, and the MIDI message has only 7 bits, 10 - 7 = 3, so we divide by 2^3, or 8.
    if(analogVal[i] != analogOld[i]){                // Only send the value, if it is a different value than last time.
      msg.status = CC;                               // Controll Change
      msg.status = msg.status | CHANNEL-1;           // Channels are zero based (0 = ch1, and F = ch16). Bitwise or to add the status message (s) and channel (c) together:
                                                    /* status     = 0bssss0000
                                                     * channel    = 0b0000cccc
                                                     * | --------------------- (bitwise or)
                                                     * msg.status = 0bsssscccc       
                                                     */
      msg.data1   = controllers[i];                  // Get the controller number from the array above.
      msg.data2   = analogVal[i];                    // Get the value of the analog input from the analogVal array.
      Serial1.write((uint8_t *)&msg, sizeof(msg));   // Send the MIDI message. (send three bytes, starting at the address of msg)
      analogOld[i] = analogVal[i];                   // Put the analog values in the array for old analog values, so we can compare the new values with the previous ones.
      delay(10);                                     // Wait for 10ms, so it doesn't flood the computer/synth with MIDI-messages
    }
  }
}


I think it's fairly well documented, but if anything is unclear, don't hesitate to ask for help!

Pieter

Grumpy_Mike

Quote
(It's an Instructable, I know, but I did know what I was talking about, agreed, there's a lot of bad information on there, but some really well documented, well researched articles as well.)
That is why I said:-
by and large they are written by people who do not know what they are doing.

There is so much bad stuff the blanket advice must be to avoid the site at all costs. After you have been here a bit you will see how much crap we have to try and mop up from that site. The problem with it and the similar hackster.io is that there is absolutely no quality control. Anyone can put up anything.

PieterP

That is why I said:-
by and large they are written by people who do not know what they are doing.

There is so much bad stuff the blanket advice must be to avoid the site at all costs. After you have been here a bit you will see how much crap we have to try and mop up from that site. The problem with it and the similar hackster.io is that there is absolutely no quality control. Anyone can put up anything.
I know, that's definitely a problem, and I totally agree with you on that.

I think that part of the problem is that the really good documentation is too much and too complicated for beginners, so new users will go read articles that they can understand, and that are more practical, like on Instructables.

But a lot of these Instructables are grossly oversimplified, or encourage bad practices, like omitting LED resistors, driving motor's directly from the I/O pins, no flyback diodes ... all that kind of things. If you don't know what the actual purpose of something is, it's easy to just forget it, or simply ignore it.

But on the other hand, if you write an article explaining why you should use all those extra components, it'll be quite hard to digest for many new users.

Also, the documents at https://www.arduino.cc/en/Tutorial/ often don't make it on the first page of a Google search. I think it would help if they were easier to find, for example links to those pages in the built-in examples (not just a url in the comments that you have to copy and paste), a message when you first open the software.
Even on the Getting started page, there's no real help for new users. I mean, when you're new to Arduino, you don't care about libraries, cores, or an introduction, you want to know how you can write code, and make it do something.

I remember myself 'getting started' with Arduino, I opened up the IDE, and it was like Chinese to me: I didn't know anything, didn't know what a compiler was, didn't know what a COM port was ...
It would be nice to see an official page explaining those basics, and point you to some specific examples to get started, like blink. There should ideally be some structure, just a list of separate examples is not very handy: you don't know what the reader already knows, for example, if you offer the examples in a particular order, you can gradually explain things, you don't have to explain the basics in every example, etc ...

And I know that's exactly what those books do, but they can be pricey, I didn't really want to spend €20-€30 on a book without knowing if it was any good, and there were just too many choices. One or two recommendations on the Getting started page would be much easier for beginners.

Anyway, that was enough complaining for an entire week, I'm sorry ;) .

_pmj

Thanks very much PieterP and Grumpy_Mike, there's some really helpful stuff here.

This is the code
Great, let me work through this and the links and I'll come back with any issues.  Really appreciate your help.

Grumpy_Mike

Quote
And I know that's exactly what those books do, but they can be pricey, I didn't really want to spend €20-€30 on a book without knowing if it was any good,
For audio I can recommend this book:-
https://www.amazon.co.uk/Arduino-Music-Audio-Projects-Mike/dp/1484217209

Yes it is expensive but there are lots of pages and a rather specialized subject, but it happens to be the subject of this section of the forum. ;)

_pmj

#22
Sep 09, 2016, 08:43 am Last Edit: Sep 09, 2016, 08:49 am by _pmj
So you will need to have an external physical MIDI interface. See this project:-
http://www.thebox.myzen.co.uk/Hardware/MIDI_Shield.html
Sorry, another question...

On the circuit diagram for the shield it looks like only pins 4 and 5 being used on the MIDI output DIN.  Most other diagrams I've seen also have pin 2 (center pin) going to ground. 

5 = TX1
4 = +5v
2 = GND

Is that not the case?

Grumpy_Mike

No not the case.
Some MIDI out cables have a ground on pin 2 but that is only for screening. You must never put a ground on the  MIDI input because that defeats the purpose of the opto isolator. Many MIDI cables do not have three wires. Unless the cable is very long there is no need for screening.

_pmj

Many MIDI cables do not have three wires. Unless the cable is very long there is no need for screening.
Ah, makes sense.  Accounts for how some newer MIDI devices now use a 3.5mm jack for MIDI output.

Go Up