Building a MIDI interface to receive data on the RX port of the 3.3V powered modules

Would the hardware side of such an expander be something as simple as what you detailed in this post about Grids?

Also, am I right in assuming Rings would need a custom firmware to implement this hypothetical expander?

This wouldn’t work, Rings’ UART lines have a 3.3V level.

Of course!

1 Like

How about this:

(maybe we should split this to a new topic)

Any reason why the 3.3v couldn’t be pulled off the jtag pin header?

Sure it can be done!

Hi @pichenettes - I’ve been working on prototyping this idea for Rings with @jeaux. I’m trying to get the firmware side off the ground and confirm the hardware is working by just blinking the lights in response to any message. This is what I’ve got so far: respond to any message by blinking lights · lylepmills/eurorack@40eeb32 · GitHub

Sorry to bother you for coding advice, but does it look like I’m on the right track here? Have I missed anything? So far I haven’t been able to get it working :confused:. I’m especially wondering if you have any advice for me in terms of anything I might need to do differently in DebugPort::Init, I’ve tried a number of different permutations of the GPIO+USART settings (things like GPIO_Mode_IN instead of GPIO_Mode_AF, etc) but so far haven’t hit on a working combination, and I’m also finding it hard to get good documentation on that side of things.

Any pointers appreciated, thanks much!

I don’t see anything wrong with the code.

You don’t have to change anything to the GPIO settings.

Are you sure it’s not a hardware problem?

It’s certainly possible it’s hardware - but it’s very helpful to have your input to narrow it down (bit of a chicken-and-egg problem debugging hardware and firmware at the same time) - thanks!!

Does your hardware resemble the schematic @jeaux showed? Getting opto isolator circuits right can be trickier than you might think, so I’d start with just a USB->TTL converter with the option of setting it to 3.3V.

They’re very cheap. Some of the PL2303 based ones use fake chips, which might get rejected by the driver installer, so maybe the CH340G based ones are now a better bet.

You can then plug that into a PC and use something like Tera Term or PuTTy (serial terminal emulators you can type into) to send test data to your Rings. I don’t know what the Mac equivalents are, but no doubt they exist. Just set the baud rate, number of bits, parity and stop bits to match.

Opto isolators are basically analog amps, with a current gain that can vary a lot between individual chips. It comes down to selecting good values for a resistor or two, to get into the right range of voltage swing and response time, with enough leeway to allow for the variations in chips.

Yes, I made him the hardware, exactly like the schematic above. Any tips on getting the resistor values right? Or is it a matter of trial and error?

What does the signal look like on the scope? Are the edges steep or soft?

1 Like

Unfortunately I am away from all my gear until Friday, but will hopefully be able to do some testing and sort it out then.

A scope would definitely help, and also refer to the H11L1 datasheet, and the MIDI spec.

You can reduce both resistors, because you’re working on 3.3V. The 220R on the input side is a normal value for 5V MIDI. The LED on the input side is somewhere in the range of 1V to 1.2V, when it’s turned on (from the datasheet). Using the normal 5V MIDI Spec diagram, you have another two 220R resistors, on the MIDI device that’s outputting to this one, effectively in series with the LED and the 220R you have already.

On 5V, that would give, say, (5V - 1.1V) / 660R = 6mA, roughly. On 3.3V, you get (3.3V - 1.1V) / 660R= 3.3mA or so, which might be okay, but it’s a little on the low side. If you had no resistor (or 0R), you’d have (3.3V-1.1V) / 440R = 5mA. I wouldn’t suggest not having a resistor there though, just in case. I’ve seen 75R used for that, on 3.3V.

For the resistor on the output side, which the datasheet calls Rl (R with a subscript capital L), their examples use 270R for 5V, so you can go lower for 3.3V. The output voltage goes down to about 0.3V for a logic low, when it’s all working as it should, so we can guesstimate a suitable value for 3.3V by aiming for the same current through that resistor:

I = (5V - 0.3V) / 270R = 17.4 mA or so.

For 3.3V, that gives
Rl= (3.3V-0.3V) / 17.4mA = 172R ish.

So, 180R seems like a reasonable choice.

You could experiment with a pot in series with a fixed resistor to provide a minimum value, I suppose (to avoid overloading it), but you’d need to use a scope to be able to see what difference it was making. The sort of problem you would see is a slope that isn’t very steep, and an “on” (output low) value that doesn’t go all the way on - some way above the 0.3V that’s expected when it’s working.

Another option is to power the H11L1 from 5V, then use a small Schottky diode between the output of the H11L1 and the input on the Rings, if necessary with a 10k pull up resistor to 3.3V. The H11L1 output is active low, so you have to put the cathode facing the output pin, and the anode facing the MCU input pin.

I’ve made a MIDI interface for an STM32F407G-Discovery board like that, which has a similar MCU - I used a MIDI breakout board meant for 5V, and did that for the serial input, just to make sure I didn’t over voltage it. It’s possible to find Schottky diodes that turn on at around 0.2V. A normal silicon one is closer to 0.6V, which would probably be too high.

Excellent information, thanks so much!

I’m pulling the 3.3v off of Rings via the jtag pin header in an attempt to simplify things, so I don’t think 5v is an option unfortunately. I think tweaking those resistors might just do the trick, but we’ll see when I get back in town. Thanks again!

1 Like

The MIDI input schematics I’ve used on several 3.3V project (AVR and STM32F1):


I don’t know how I overlooked Yarns this whole time … should have totally just started with that. Ah well, I’ll keep fiddling with what I have for now, but probably get some 6n137s on the way. Thanks as always! :pray:

Cool. I’ve seen that Yarns schematic before, but I hadn’t thought to look at that either. I’ll work from that when I make MIDI interfaces for STM32s, in future.

Correcting what I said yesterday - we should still assume it’s going to be driven by 5V, from the MIDI controller / keyboard, so that input side resistor probably ought to stay at 220R.

The ideal values will depend on the type of chip used, but the H11L1 datasheet says the maximum input current (LED current) is 60mA, so even a 0R resistor wouldn’t do any harm to the chip (5V/440R = 11ma, or allowing for a LED turn on voltage of around 1.1V, 3.9V/440R = 8.9mA ish), but it’s more current than you need, based on looking at the graphs for Transfer Characteristics, and Threshold Current vs. Supply Voltage.

They give some figures for 10mA input current, at 5V supply voltage (not necessarily the same as the voltage driving the LED, but you only have to think about LED current, and turn on voltage) but it looks like even 1.5mA would be enough.

I also recommend looking at the Yarns firmware if you want to add MIDI to your project. There is a very handy MidiHandler class that can easily be reconfigured to add MIDI to any STM32 project.

I think this is how it works:

You can set up a timer peripheral to generate interrupts at 8kHz and then poll the UART RX line to see if any data has been received. When a midi message is received, it is shoved in a ring buffer for later use. :

void TIM6_DAC_IRQHandler(void) {
	// Clear timer interrupt flag

	// Try to read some MIDI input, if available.
	if (midirx.readable()) {

Then, somewhere else where you have some processing power (maybe in the while loop or after ui.poll() ) you can call midi_handler.ProcessInput(), which will push the data through a parser, which filters it and calls back various functions that can be used to implement things like MIDI CC changes, etc.

@lylem is handling the software side, so I’ll let him digest all that :wink:

1 Like

Thanks! Yeah I’ve been consulting the Yarns codebase already and it has been immensely helpful. Will definitely make development much faster once we get off the ground.