STM32 based MIDI synth

I realized the STM32F103C i have has a pretty high clock speed, so currently im trying to turn it into a basic FM oscillator synth. In other words, it will read midi input from another device, like piano, midi controller, etc, then convert it into sound.

I am using this library https://github.com/FortySevenEffects/arduino_midi_library , its as its described, basically plug’n’play, though there is a small number of tweaks and understanding to utilize this as i have found, not just for the stm32, but any board you use this with, less so though for the UNO R3

Firstly, you need to understand how serial works, see, the examples and as much i could get out of the documentation, was that when it does its midi intialization, its just listening everywhere for midi, but actually, its defaulting on your Serial0 or, just Serial. On the stm32, this is the usb port, and, as far as i can tell, theres a special way to handle midi over USB which is not well documented. By default i would guess that it is listening for just serial over the USB port, which my MIDI controller does not do, like really every other MIDI producing instrument.

Anyway, if you knew how serial worked, youd realize that to utilize other serial inputs, like RX1, or Serial1, which is found at pin A10 on the stm32f103c, and by extension youd notice that for commands like

MIDI_CREATE_DEFAULT_INSTANCE();

its actually just defaulting, in the library you would see your options here. To get it working for serial input on A10, you would use this

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, midi1);

where Serial1 is how you reffer to serial input port 1 (at A10), i think it might also enable the use of the output pin at A11 or A9, whichever it is, not that it matters much.

“midi1” is the new name you give this midi instance, it can be anything you like, if the brackets are left empty, the default name is “MIDI”, which is why code like ,

MIDI.begin(MIDI_CHANNEL_OMNI);

confused me. i thought it reffered to the library, MIDI.h, but actually the name defaultly made is just MIDI, so, when setting up a specific port, i had to replace all instances of MIDI with midi1, or whatever i wrote as its name.

 

You cant see in the picture but the USB cable is on top of an opto-isolator, the one im using is the 6N138, im doing things according to this schematic

where D0/RX is the pin A10, though it could probably go to whichever USB pin is for reading, or another RX on the board. Again, for a board other than stm32, determine from the board pinout which pins are serial input (RX) then figure out how to access them (which in the case of pin A10, aka RX1, is to do Serial1.begin(); though the midi library does this automatically).

Also take note if the RX is 5v tolerant or not, i was advised to use 3.3v instead of 5v, but before getting it to work i switched over to 5v thinking it was the problem, it wasnt, but since A10 is 5v tolerant it didnt matter. some boards, the stm32f103c included has pins which are not 5v tolerant (3v only), so, keep an eye on anything like that in case you waste time on a fried port.

Im told the reason for using the opto isolator is to prevent ground loops, but, if potentially causing damage doesnt matter (not that i personally think it could, based on anything i know atm) then just run it through a resistor, and/or through a transistor, just check your output hitting the pin input is not too high. I dont know why it would be but, just check anyway.

 

Now that i can get serial output (via the usb plug to the computer serial monitor) which confirms basic things like key press/release, pitch, velocity (how hard you hit a key) and channel (not sure yet what that pertains too,), i have enough for basic synthesizing, all i need to do now is program a synth to use the midi pitch values, which range from 0-127, rather than notes, though i think the library has a way to identify notes as notes, not that i need to for the time being. I really want to be able to use the pads (which  i think are channel 10, according to a previous basic sketch i used to acknowledge A signal), but also use the dials on my axiom 25 for synth controlling on the go (with an FM oscillator synth this = bass drop wubs, albeit manually enveloped) , i also want to use the modulator wheel and the pitch bend wheel, should be fun.

Heres a pic of how im connected.

 

And heres the sketch im using which presently works as i mentioned.

#include <MIDI.h>

//MIDI_CREATE_DEFAULT_INSTANCE();
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, midi1);

// -----------------------------------------------------------------------------

// This function will be automatically called when a NoteOn is received.
// It must be a void-returning function with the correct parameters,
// see documentation here:
// http://arduinomidilib.fortyseveneffects.com/a00022.html

void handleNoteOn(byte channel, byte pitch, byte velocity)
{
    // Do whatever you want when a note is pressed.
Serial.println("noteonn");
Serial.println(channel);
Serial.println(pitch);
Serial.println(velocity);
    // Try to keep your callbacks short (no delays ect)
    // otherwise it would slow down the loop() and have a bad impact
    // on real-time performance.
}

void handleNoteOff(byte channel, byte pitch, byte velocity)
{
    // Do something when the note is released.
    // Note that NoteOn messages with 0 velocity are interpreted as NoteOffs.
    Serial.println("noteoff");
}

// -----------------------------------------------------------------------------

void setup()
{

  Serial.begin();
  //Serial1.begin(31250);
    // Connect the handleNoteOn function to the library,
    // so it is called upon reception of a NoteOn.
    midi1.setHandleNoteOn(handleNoteOn);  // Put only the name of the function

    // Do the same for NoteOffs
    midi1.setHandleNoteOff(handleNoteOff);

    // Initiate MIDI communications, listen to all channels
    midi1.begin(MIDI_CHANNEL_OMNI);
}

void loop()
{
    // Call MIDI.read the fastest you can for real-time performance.
    midi1.read();

    // There is no need to check if there are messages incoming
    // if they are bound to a Callback function.
    // The attached method will be called automatically
    // when the corresponding message has been received.
}

 

 

2 thoughts on “STM32 based MIDI synth”

  1. Wow! After all I got a web site from where I be capable of in fact obtain valuable information concerning my study and knowledge.|

  2. Heya! I’m at work surfing around your blog from my new apple iphone! Just wanted to say I love reading through your blog and look forward to all your posts! Carry on the great work!|

Leave a Reply

Your email address will not be published.