Super simple midi keyboard

this thread its for this project!

you may notice the addition of 2 220r resistors, this is due to a number of people commenting about them not being there. Usually in these projects resistors are added to prevent possible damage to the opto isolator in the midi input circuit of whatever you plug this midi controller into, the midi standard does say to do this, so i don’t want anyone to break their synths. so add those 220r resistors to save a possibly broken midi input on your synthesiser!!! and also don’t let me plug any of my midi gear into your synths as not many of my creations have these…


Have you ever had any issues without an optoisolator for midi out? Because I’ve been running without any, with only some resistors per the spec for midi outs and it’s been fine.

I’m convinced that the isolation is really only necessary for inputs or maybe if you want extra protection? I don’t know, it’s usually fine with my stuff anyway.


The MIDI spec doesn’t mention anything about optoisolators for MIDI out, just MIDI in.


to be honest, I have started just ditching opto isolators completely for midi, the way I see it is I usually know what I’m plugging things into, and its just the same as any other digital signal, so I just dont bother, purely for speed. only time I bother with them now is if the thing needs to always work, but for just a random thing I have built for myself in a few hours I just dont bother with one

edit*** this also goes for the 220r resistors you usually see on either the 5v line or the tx line. like in the above pic I haven’t bothered, sure there is a risk of you shorting the 5v line but I mean… just dont short it hahaha

edit******* again. just because I haven’t blown any opto isolators on my synths doesn’t mean some poor bugger isnt going to! so I added the 220r’s to the pic as @diyelectromusic mentions in this thread “for the sake of 2 resistors what’s the point in not bothering”. and if you havent got a 220r resistor to hand, just use a chewing gum wrapper!


I know! i’ve said this elsewhere somewhere around this forum, but i keep getting worried about posting things with authority!

@lookmumnocomputer cool, just wanted to see if it wasnt a singular experience is all.

Even midi 2 has the same vagueness about power limits. I only get fancy when it stubbornly refuses to play ball.

The new virtual / hardware mix with both audio and midi mixing eagerly with IP, ethernet, and WiFi is the simpler and much more promising frontier I’m heading too. Sigh.

That said. I do, always, mostly use the op amp as the situation arrises. It’s like the quick wash downstairs and a condom for all your in’s and outs, however you like to connect.

Fundamentals like pots ,caps, filters, dividers etc still have a place.


Please excuse me. I acknowledge the fact that I’m being a dick.

Okay, so the video sort of annoyed me. Don’t get me wrong, Sam was great explaining the stuff for beginners - it’s just that the code itself annoyed me.

So I may have tweaked it to be a bit more concise, and a bit more effecient in terms of memory. Sorry.

#include <MIDI.h>

//const makes things read only when declared. 
//Attempting the change this programmatically will cause compile errors
//This is a map between pin and midi node code.
const struct _MidiButton
  int pin;
  int midinote;
} g_midi_buttons[] = {
  { 2,  36},
  { 3,  38},
  { 4,  40},
  { 5,  41},
  { 6,  43},
  { 7,  45},
  { 8,  47},
  { 9,  48},
  { 10, 50},
  { 11, 52},
  { 12, 53},

//Declare the array where we will store the states for all the buttons
//The size thingy causes the compiler to make the array big enough to store the 
//states for all the buttons declared above in the map.
bool g_buttonStates[ sizeof(g_midi_buttons) / sizeof(g_midi_buttons[0]) ] = {0};

void setup()

  //Go through (loop through) the map of buttons and set them all to pin up
  //INPUT_PULLUP means the pin is in input mode with an internal pull up resistor, so it is waiting to receive ground to do something
  const size_t numButtons = sizeof(g_midi_buttons) / sizeof(g_midi_buttons[0]);
  for(size_t x=0; x < numButtons; ++x)
    pinMode(g_midi_buttons[x].pin, INPUT_PULLUP);   

    //Also initialise the state for the current button so that it is marked as 'off'
    g_buttonStates[x] = false;

void loop()

  //go through all the buttons, reading their current status and 
  //handling button up/down events
  const size_t numButtons = sizeof(g_midi_buttons) / sizeof(g_midi_buttons[0]);
  for(size_t x=0; x < numButtons; ++x)
    int state = digitalRead(g_midi_buttons[x].pin); 
    // ! is not - you could also use !g_buttonStates[x], but == false is more readable
    if((state == LOW) && (g_buttonStates[x] == false))
      MIDI.sendNoteOn(g_midi_buttons[x].midinote, 127, 1); //turn midi note on velocity 127, midi channel 1. 
      //Mark the button  state as TRUE, since the button is now on
      g_buttonStates[x] = true;
    else if((state == HIGH) && (g_buttonStates[x] == true))
      MIDI.sendNoteOff(g_midi_buttons[x].midinote,0,1);  //turn midi note off, midi channel 1.

      //Mark the button  state as FALSE, since the button is now on
      g_buttonStates[x] = false;

hey up marcnet all good its not being a dick at all. I hope people will do their own versions of the same thing so people can compare.

the reason I did it the way I did as it was building blocks just to show how linear and simple it can be, because in reality when the code is in the Arduino no one would tell the difference.

and arguably, if you are doing code that Is so minimal and not using anywhere near what an arduino can handle. being inefficient isnt really a priority no??

but really appreciate it I will link this on the page as what an actual coder would do hahaha


I imagine the code being slightly irksome is going to get more people involved than would have otherwise haha. :slight_smile:


Yeah, I had to change parts of the 8 step sequencer code not to add features (though I did that too) but just because I felt like “it’s better if you do it like this!” even though it makes zero difference in the functionality…


Look Mum A PCB and Schematic!

Licensed under CC-0, do what you like with it.


The chips you sometimes see in MIDI out circuits are usually buffers I believe. Often they will be implemented using an inverting buffer, so a circuit would end up using two of them to get the original signal back.

For most of my own messing about, I rarely bother with a buffer, but I would never build a 5-pin DIN socket OUT port without the two resistors. They are there (with the third in the corresponding IN circuit) to limit the current to the receiving opto-isolator, so for the cost of two resistors, why take the risk that you might overload something?



right, i think the resistors are a good idea. The only reason i can think of to add optoisolation here is if you got ground loop noise massing up transmission.

The way i see this project is its like the Super Simple Oscillator. You can tinker with it, learn from it, but its simple by design. Not everyone wants to learn to code, or even learn enough to compile someone elses source code even. Some folks just wanted a bog basic DIY midi keyboard, and this does the job.


ill add a note on the site and update the image to include resistors.
probably wont change my actions of skipping them(as in open stuff up and pop em in but you know!), …so people who are protective of their synths dont let me plug anything into their midi sockets lol.


looking good!±!!!±!

look forward to seeing it if someone makes one :smiley:


This is great. I got my first Arduino Nano in the post yesterday, I wanted to mod the code to drive a circuitbender cb55 (DR55 clone) board via midi and have it mapped to the 4 drum sounds and it worked perfectly, just waiting on some switches before i make the box. Top Stuff


marcnet mind if I mention this code in the next video on the matter???

Of course mate. You might want to mention that it’s untested. I don’t have a device to test it with at the moment. It does build successfully though

1 Like

ill give it a test! by the way finally getting to the exchange stuff in a week or two, its been in limbo for the past month or so as there is something big that might still be happening which would require a rearrange, when its done oneofthe things is baudot kosmo!!! if you still wanted to get it going :D. by summer there will be a whole external phone line/livestream to the things working on it all just need to get it implemented