How do i get my stm32f103c to read MIDI signals?

Using the MIDI libraryfound here GitHub - FortySevenEffects/arduino_midi_library: MIDI for Arduino

Im a bit new so i dont know how serial works but, my stm32 is able to send serial info to my computer through the micro usb port it has, which i can monitor on the serial monitor in the arduino IDE.

Basically, im hoping i can use either a USART pin (in which case how with this?) via the MIDI output from my MIDI controller, or prefferebly use the MIDI over USB, whichever has the least latency.

Just to clarify, i want the stm32 to READ MIDI, not generate and output. I want to make a basic synth i can hook up to my MIDI controller so i can take it places and practice on it. The thing about MIDI controllers is that they generally dont have speakers or any capacity for anything other than making MIDI output, and similarly synthesizers, albeit just occasionally, dont have the capacity to operate without a controller.
So in this sense i want to make a synthesizer. there seems to be a great deal of confusion about this.
A very basic FM oscillator type synth at that, nothing fancy, its for learning, ill go with whatever the stm32 can handle.

So, i have tried using the libraries and examples in it, but i cant seem to get it to work, even on an arduino UNO R3 which apparently the examples are by default intended to be used on.

I only need to get to the point that i can get some sort of confirmation it read the signal, after that im pretty confident i can handle the rest, im only struggling in actually getting my MIDI controller (AXIOM OXYGEN 25) to talk to the stm32.

Again, either through MIDI over USB, or using the actual MIDI interface.

Thankyou in advance

-edit-

ive been trying more today and new mysteries have appeared. sometimes i cannot use serial monitor to see if things work. also, in every example, any time MIDI.h is used, it becomes impossible to use the built in led to indicate anything. I wanted it to flash when it reads midi, but it does nothing, but what is worse, even if i tell it to go high or low, nothing changes, it simply remains on, somehow the MIDI.h file prevents proper LED operations, i checked the libraries, and it makes no mention of LED control so i dont understan how this can happen, it defies logic.

Receiving MIDI is rather easy. Here's a simple sketch for receiving three-byte MIDI messages (all except system messages, program change and channel pressure):

const uint8_t CONTROL_CHANGE = 0xB;
const uint8_t NOTE_OFF = 0x8;
const uint8_t NOTE_ON = 0x9;

struct MIDI_message {
  union {
    struct {
      uint8_t channel : 4;
      uint8_t message_type : 4;
    };
    uint8_t status;
  };
  uint8_t data1;
  uint8_t data2;
};

bool receiveMIDI(Stream &s, MIDI_message &m) { // Receives 3-Byte MIDI messages
  static uint8_t header = 0;
  static uint8_t data1 = 0b10000000;
  if (!s.available())
    return false;
  uint8_t newByte = s.read();
  if (newByte & 0b10000000) {   // Header byte received
    header = newByte;
    return false;
  }
  if (header & 0b10000000) {
    if (data1 == 0b10000000) {  // First data byte received
      data1 = newByte;
      return false;
    }
    m.status = header;          // Second data byte received
    m.data1 = data1;
    m.data2 = newByte;
    data1 = 0b10000000;
    return true;
  }
  return false;                 // Data byte without header received
}

void setup() {
  Serial.begin(31250);
}

void loop() {
  MIDI_message midimsg;
  if (receiveMIDI(Serial, midimsg)) {
    if (midimsg.message_type == CONTROL_CHANGE) {
      /*
       * Don't print ASCII to a MIDI device, obviously, 
       * just for demonstration purposes.
       * 
      Serial.print("Received MIDI Control Change message on channel ");
      Serial.print(midimsg.channel + 1);
      Serial.print(", controller #");
      Serial.print(midimsg.data1);
      Serial.print(", value = ");
      Serial.println(midimsg.data2);
      */
    }
  }
}

Pieter

i tried using it, it doesnt seem to work the way im using it, how should everything be physically connected?

neither of the if statements in the loop ever get triggered when i start pressing keys, i do sort of understand this code, i think my only problem now is perhaps im not understanding something i probably should know or doing something i should be doing, like, am i meant to use the USB port, or should i be configuring one of the USART pins as serial? or, should i be using actual midi out? again, via the stm32s usb port or a USART pin.

Sorry if this question seems silly, im just rather new to hardware interactions, all my experience is in software programming

1 Like

You have to decide how you're connecting the controller. Is it via standard MIDI or MIDI over USB? Both are possible and MIDI.h can handle either but the code will be slightly different. Pick one method and stick with it.

If the controller has MIDI over USB as standard I'd probably use that but if it only has 5-pin MIDI ports I'd use them directly. I wouldn't bother with adding a separate MIDI-USB converter. When you've made a decision we can go on from there.

I think PieterP's code a) doesn't use the MIDI.h library and b) assumes using standard MIDI into a hardware Serial input via a MIDI input circuit (which you would need to have built or acquired from somewhere).

Steve

slipstick:
I think PieterP's code a) doesn't use the MIDI.h library and b) assumes using standard MIDI into a hardware Serial input via a MIDI input circuit (which you would need to have built or acquired from somewhere).

Correct.
But you can easily edit it to use a different Serial port (any Stream object, in fact).

Are you using the "standard" midi-in circuitry?

Aside from that, MIDI is just a 31250bps serial link.

The STM32 is a 3.3V device, so use 3.3V at pin 8 of the opto-isolator instead of 5V.

well, ive been trying a while to get MIDI over USB to work but now ive gone out and ordered an opto isolator which will be arriving some time later today, so ill be going for the direct MIDI instead. Which would have the lower latency?

Also is midi over usb going to work through the built in usb port on the bluepill? if not, ill probably go with the direct route then anyway.

So, im guessing i need to connect the midi output to pin A10, an RX pin or another one. How do i set that pin up to listen for serial input? is there anything special, besides the baud rate, i need to coinfigure for midi, or is that and your code or the midi.h libraries all i need?

thanks a bunch for your help so far all of you btw :slight_smile:

i set the pin A10 as an input but that doesnt seem to be enough, what else do i do? no code is still working yet. I went and bought the opto isolator and have everything set up as in that diagram.

-edit-

never mind figured it out, had to change Serial to Serial1, and do create midi instance, with actual values (hardware serial, Serial1, midi1). The default was MIDI.

Im now using the fortyseventeen library, ive gotten it to tell me pitches, next step now is generating sound, then, figuring out how to read input from the pads (see axiom 25) and also linking the various knobs to synth properties. plus pitch bending and modulation. Its gonna be a fun project.

Your project has my interest. Have you made any further progress with this?

Check this project, based on a Bluepill, allowing 3 MIDI IN / 3 MIDI OUT

Firmware is open source.

Project Github : https://github.com/TheKikGen/USBMidiKliK4x4