home.social

#midi2cv — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #midi2cv, aggregated by home.social.

  1. USB MIDI to Serial and CV/GATE

    This project uses my Arduino Pro Mini MIDI USB CV PCB for a USB MIDI to Serial MIDI and CV/GATE device that has a CV/GATE that is compatible with my Korg Volca Modular.

    It takes MIDI NoteOn/NoteOff and translates them into CV that can be used to set the pitch of a CV/GATE synth.

    IMPORTANT: I strongly recommend that you do not connect this to your Volcas. I am not an electronics person but have accepted the risk of causing a possibly expensive problem. I will not be held responsible if you end up doing the same.

    https://makertube.net/w/puRwMGeELa5zq3YhMrMC4h

    https://makertube.net/w/cPjFeqigcrBHgMMPLjPNPb

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to Arduino, see the Getting Started pages.

    The Circuit

    This is an application for my completed Arduino Pro Mini MIDI USB CV PCB.

    The Code

    The board was designed to require a PWM output on D3. With hindsight, D9 might have been more useful as D9 is a “Timer 1” timer on the ATMega328, but D3 is a “Timer 2” timer. The former are 16-bit timer/counters. The latter are only 8-bit.

    No matter. I still have 255 levels of PWM to play with.

    The initial PWM criteria I wanted were:

    • No prescalar – run at full CPU speed. In the case of a 3V3 Pro Mini this is 8MHz.
    • Use FastPWM mode – this will count up and then reset to zero.
    • Use a TOP value of 255 – the maximum.
    • Use the OC2B output, which is connected to D3. OC2A is not used.
    • Use the mode where OC2B is cleared on compare match; set at 0 (BOTTOM).
    • The PWM value is therefore written into OCR2B.

    At some point the code will have to translate from MIDI note number over to a PWM value. My previous project mapped MIDI note C2 (36) onto 0V and went up from there for 5 octaves to C7 (96). This is a range of 60 steps, so actually, revisiting the PWM code, if we change the mode to use an alternative TOP Value of 239, that means each MIDI note corresponds to a specific step of 4. That would be pretty useful!

    So the updated PWM criteria is now as follows:

    • No prescalar – still run at full CPU speed. In the case of a 3V3 Pro Mini this is 8MHz.
    • Use FastPWM mode – this will count up and then reset to zero.
    • Use a TOP value of OCR2A, which will be set to 239.
    • Use the OC2B output, which is connected to D3. OC2A is not used.
    • Use the mode where OC2B is cleared on compare match; set at 0 (BOTTOM).
    • The PWM value is therefore written into OCR2B.

    The PWM operating frequency is given by a formula in the datasheet, but is basically the time it takes for the counter to count from 0 to 239 and reset, whilst running at 8MHZ. So the PWM frequency = 8000000 / 240 = 33.3kHz.

    At such a frequency the (now updated) PWM filter components chosen give a pretty smooth output between 0V and 3.3V, which are them amplified using the OpAmp for a 0V to 5V range.

    Note: No interrupts are required for the operating of PWM in this manner. We can just update the PWM value whenever is useful during the operation of the code.

    The complete PWM code is thus as follows

    void initPwm() {
    pinMode(3, OUTPUT);
    TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
    TCCR2B = _BV(WGM22) | _BV(CS20);
    OCR2A = 239;
    }

    void setPwm (uint8_t pwmval) {
    OCR2B = pwmval;
    }

    The value used for PWM will only be active for 0-239. Any value of 240 or higher will just be considered “always on”.

    This all means that converting from MIDI to PWM value is now pretty trivial:

    #define MIDI_LOWEST_NOTE  36 // C2
    #define MIDI_HIGHEST_NOTE 95 // C7
    uint8_t midi2pwm (uint8_t note) {
    if (note < MIDI_LOWEST_NOTE) note = MIDI_LOWEST_NOTE;
    if (note > MIDI_HIGHEST_NOTE) note = MIDI_HIGHEST_NOTE;
    return (note - MIDI_LOWEST_NOTE) * 4;
    }

    Logging the average voltage for each MIDI note (pre and post amplification) gives me the following:

    C20.080.08C30.721.06C41.352.03C52.023.01C62.653.95C73.284.90

    Plotting these on a graph looks like this:

    That is a pretty good linear response, but is slightly under in terms of the top-end output. At 1V/oct a semitone is around 83mV, so dropping 0.1V at the top ought to be dropping a semitone.

    But jumping through the octaves it sounds all right to me. It’s definitely not dropping a semitone anyway, so I’m not sure what is going on. I might need to come back to this one!

    The rest of the code is fairly straightforward MIDI reception and processing that I’ve done several times before now. There are a few design notes:

    • Automatic MIDI THRU is turned off or both serial and USB MIDI.
    • When a note that is not on the required channel or is out of the C2-C7 range is received, it is ignored.
    • Anything received over USB is automatically sent to the serial OUT and anything received over serial is automatically sent to the USB OUT.
    • NoteOff is only processed if received for the currently playing note.
    • Consecutive NoteOn messages update the CV and replace the previously playing note.
    • There is an option for a GATE type operation:
      • GATE goes HIGH on NoteOn.
      • GATE goes LOW on NoteOff.
    • Or for a TRIGGER pulse type operation:
      • GATE goes HIGH on NoteOn.
      • GATE remains HIGH for a defined time (e.g. 10mS) then automatically goes off.
    • On reception of NoteOff there are several possible options for what to do with the CV:
      • Leave it and do nothing. This allows any envelopes to complete on removal of the GATE signal with no change of CV. But the CV will remain at the last level until a new note is received.
      • Set it to the NoteOff pitch received. Although in reality this is probably going to be the same as “do nothing”.
      • Set the CV to 0. This means there is no “dangling” CV voltage, but the synth will probably respond to the changing CV.
    • I’ve left in a compile-time PWMTEST mode that just plays the different Cs for measuring voltages, and so on.

    Find it on GitHub here.

    Closing Thoughts

    This actually seems to work surprisingly well. I did wonder if the apparent inaccuracies of the output might cause an issue, but it doesn’t seem to.

    The PWM filter issue was annoying, but on the one hand, it was a lot easier to build and debug with a PCB in hand; but of course on the other hand, if I’d done it first on solderless breadboard, the problem would have almost certainly be spotted and the design would probably have been right.

    This has only looked at a pitch CV. It would be interesting at some point to do some kind of MIDI CC to CV control device.

    Kevin

    #arduinoProMini #cv #define #korg #midi #midi2cv #usbMidi #volca

  2. USB MIDI to Serial and CV/GATE

    This project uses my Arduino Pro Mini MIDI USB CV PCB for a USB MIDI to Serial MIDI and CV/GATE device that has a CV/GATE that is compatible with my Korg Volca Modular.

    It takes MIDI NoteOn/NoteOff and translates them into CV that can be used to set the pitch of a CV/GATE synth.

    IMPORTANT: I strongly recommend that you do not connect this to your Volcas. I am not an electronics person but have accepted the risk of causing a possibly expensive problem. I will not be held responsible if you end up doing the same.

    https://makertube.net/w/puRwMGeELa5zq3YhMrMC4h

    https://makertube.net/w/cPjFeqigcrBHgMMPLjPNPb

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to Arduino, see the Getting Started pages.

    The Circuit

    This is an application for my completed Arduino Pro Mini MIDI USB CV PCB.

    The Code

    The board was designed to require a PWM output on D3. With hindsight, D9 might have been more useful as D9 is a “Timer 1” timer on the ATMega328, but D3 is a “Timer 2” timer. The former are 16-bit timer/counters. The latter are only 8-bit.

    No matter. I still have 255 levels of PWM to play with.

    The initial PWM criteria I wanted were:

    • No prescalar – run at full CPU speed. In the case of a 3V3 Pro Mini this is 8MHz.
    • Use FastPWM mode – this will count up and then reset to zero.
    • Use a TOP value of 255 – the maximum.
    • Use the OC2B output, which is connected to D3. OC2A is not used.
    • Use the mode where OC2B is cleared on compare match; set at 0 (BOTTOM).
    • The PWM value is therefore written into OCR2B.

    At some point the code will have to translate from MIDI note number over to a PWM value. My previous project mapped MIDI note C2 (36) onto 0V and went up from there for 5 octaves to C7 (96). This is a range of 60 steps, so actually, revisiting the PWM code, if we change the mode to use an alternative TOP Value of 239, that means each MIDI note corresponds to a specific step of 4. That would be pretty useful!

    So the updated PWM criteria is now as follows:

    • No prescalar – still run at full CPU speed. In the case of a 3V3 Pro Mini this is 8MHz.
    • Use FastPWM mode – this will count up and then reset to zero.
    • Use a TOP value of OCR2A, which will be set to 239.
    • Use the OC2B output, which is connected to D3. OC2A is not used.
    • Use the mode where OC2B is cleared on compare match; set at 0 (BOTTOM).
    • The PWM value is therefore written into OCR2B.

    The PWM operating frequency is given by a formula in the datasheet, but is basically the time it takes for the counter to count from 0 to 239 and reset, whilst running at 8MHZ. So the PWM frequency = 8000000 / 240 = 33.3kHz.

    At such a frequency the (now updated) PWM filter components chosen give a pretty smooth output between 0V and 3.3V, which are them amplified using the OpAmp for a 0V to 5V range.

    Note: No interrupts are required for the operating of PWM in this manner. We can just update the PWM value whenever is useful during the operation of the code.

    The complete PWM code is thus as follows

    void initPwm() {
    pinMode(3, OUTPUT);
    TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
    TCCR2B = _BV(WGM22) | _BV(CS20);
    OCR2A = 239;
    }

    void setPwm (uint8_t pwmval) {
    OCR2B = pwmval;
    }

    The value used for PWM will only be active for 0-239. Any value of 240 or higher will just be considered “always on”.

    This all means that converting from MIDI to PWM value is now pretty trivial:

    #define MIDI_LOWEST_NOTE  36 // C2
    #define MIDI_HIGHEST_NOTE 95 // C7
    uint8_t midi2pwm (uint8_t note) {
    if (note < MIDI_LOWEST_NOTE) note = MIDI_LOWEST_NOTE;
    if (note > MIDI_HIGHEST_NOTE) note = MIDI_HIGHEST_NOTE;
    return (note - MIDI_LOWEST_NOTE) * 4;
    }

    Logging the average voltage for each MIDI note (pre and post amplification) gives me the following:

    C20.080.08C30.721.06C41.352.03C52.023.01C62.653.95C73.284.90

    Plotting these on a graph looks like this:

    That is a pretty good linear response, but is slightly under in terms of the top-end output. At 1V/oct a semitone is around 83mV, so dropping 0.1V at the top ought to be dropping a semitone.

    But jumping through the octaves it sounds all right to me. It’s definitely not dropping a semitone anyway, so I’m not sure what is going on. I might need to come back to this one!

    The rest of the code is fairly straightforward MIDI reception and processing that I’ve done several times before now. There are a few design notes:

    • Automatic MIDI THRU is turned off or both serial and USB MIDI.
    • When a note that is not on the required channel or is out of the C2-C7 range is received, it is ignored.
    • Anything received over USB is automatically sent to the serial OUT and anything received over serial is automatically sent to the USB OUT.
    • NoteOff is only processed if received for the currently playing note.
    • Consecutive NoteOn messages update the CV and replace the previously playing note.
    • There is an option for a GATE type operation:
      • GATE goes HIGH on NoteOn.
      • GATE goes LOW on NoteOff.
    • Or for a TRIGGER pulse type operation:
      • GATE goes HIGH on NoteOn.
      • GATE remains HIGH for a defined time (e.g. 10mS) then automatically goes off.
    • On reception of NoteOff there are several possible options for what to do with the CV:
      • Leave it and do nothing. This allows any envelopes to complete on removal of the GATE signal with no change of CV. But the CV will remain at the last level until a new note is received.
      • Set it to the NoteOff pitch received. Although in reality this is probably going to be the same as “do nothing”.
      • Set the CV to 0. This means there is no “dangling” CV voltage, but the synth will probably respond to the changing CV.
    • I’ve left in a compile-time PWMTEST mode that just plays the different Cs for measuring voltages, and so on.

    Find it on GitHub here.

    Closing Thoughts

    This actually seems to work surprisingly well. I did wonder if the apparent inaccuracies of the output might cause an issue, but it doesn’t seem to.

    The PWM filter issue was annoying, but on the one hand, it was a lot easier to build and debug with a PCB in hand; but of course on the other hand, if I’d done it first on solderless breadboard, the problem would have almost certainly be spotted and the design would probably have been right.

    This has only looked at a pitch CV. It would be interesting at some point to do some kind of MIDI CC to CV control device.

    Kevin

    #arduinoProMini #cv #define #korg #midi #midi2cv #usbMidi #volca

  3. Arduino Pro Mini MIDI USB CV PCB Design

    This is essentially a version of my Korg Volca Modular MIDI to CV PCB Design merged with my Arduino Pro Mini MIDI USB HOST PCB Design to give me USB MIDI to serial MIDI and CV.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to electronics and microcontrollers, see the Getting Started pages.

    The Circuit

    As previously mentioned this is largely a merging of two existing designs. The main elements are:

    • Arduino Pro Mini (3V3/8MHz) with optional USB Host Shield already attached.
    • 3V3 compatible Serial MIDI IN/OUT circuit.
    • 5V power circuit via a 7805 regulator feeding the VIN of the Pro Mini.
    • PWM output filter.
    • 3V3 to 5V opamp amplifier stage (largely based on HAGIWO’s designs).
    • Korg Volca compatible Gate/CV out via a TRS socket.

    I’m using a MCP6232 rail-to-rail dual OpAmp, but I’m only using one of them, so apparently good practice dictates normalising the input of the unused OpAmp to ideally the mid-voltage of the power rails, which I’ve done using two resistors as a potential divider.

    The OpAmp is set up for a noninverting amplifier aiming for, as I understand things, a gain of 5/3.3 or ~1.51 as follows:

    • Non-Inv Gain = 1 + R(feedback) / R(toground) = 1 + 2K9 / 5K6 = 1.51

    Note: the capacitor in the PWM output circuit is actually an error. It isn’t required for a CV output.

    Also, the CV output is amplified to make it a 0-5V signal, but the GATE output remains a 0-3.3V signal.

    A note on the PWM Filter.

    The circuit was originally pasted on from somewhere else and I have to confess I didn’t think about the differing nature of a PWM circuit for a control voltage compared to audio.

    As such, the stated component values of 220Ω and 10nF, with a cut-off frequency of upwards of 70kHz whilst useful for audio, are pretty useless for a CV. In the actual build, I’ve used values of 1K and 100nF which gives a cutoff frequency of around 1.5kHz.

    That will teach me to properly think about my requirement before cutting and pasting in one of my previous circuits 🙂

    PCB Design

    Unlike my last design this one assumes the USB host shield will be fixed to the Pro Mini, keeping the footprint as small as possible.

    I’ve allowed for both MIDI DIN and TRS sockets. There is also an option for individual GATE and CV out via jumper headers in addition to the Korg Volca compatible TRS.

    I’ve included a MIDI switch with the footprint of a 2×3 set of 2.54mm headers so that could be jumpers or a switch as required. If the Pro Mini is socketed (which isn’t so easy if a USB Host shield is attached, but would be possible with longer pin headers), then the MIDI switch could be omitted. It is only there to disconnect MIDI from the Pro Mini UART when uploading sketches.

    There is a bit of space around the 7805 in case a small heatsink is required. There is also the option to power the board directly from a 5V supply via a two-pin jumper header.

    The Pro Mini footprint includes the programing header, but this isn’t used on the board and should probably be ignored.

    Closing Thoughts

    My previous MIDI to CV was code for an ATtiny85, so I’ll need to rewrite the code for the ATMega328 on the Pro Mini to support the USB to Serial MIDI routing in addition to CV and GATE.

    Kevin

    #arduinoProMini #cv #korg #midi2cv #pcb #usbHost #volca

  4. Arduino Pro Mini MIDI USB CV PCB Design

    This is essentially a version of my Korg Volca Modular MIDI to CV PCB Design merged with my Arduino Pro Mini MIDI USB HOST PCB Design to give me USB MIDI to serial MIDI and CV.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to electronics and microcontrollers, see the Getting Started pages.

    The Circuit

    As previously mentioned this is largely a merging of two existing designs. The main elements are:

    • Arduino Pro Mini (3V3/8MHz) with optional USB Host Shield already attached.
    • 3V3 compatible Serial MIDI IN/OUT circuit.
    • 5V power circuit via a 7805 regulator feeding the VIN of the Pro Mini.
    • PWM output filter.
    • 3V3 to 5V opamp amplifier stage (largely based on HAGIWO’s designs).
    • Korg Volca compatible Gate/CV out via a TRS socket.

    I’m using a MCP6232 rail-to-rail dual OpAmp, but I’m only using one of them, so apparently good practice dictates normalising the input of the unused OpAmp to ideally the mid-voltage of the power rails, which I’ve done using two resistors as a potential divider.

    The OpAmp is set up for a noninverting amplifier aiming for, as I understand things, a gain of 5/3.3 or ~1.51 as follows:

    • Non-Inv Gain = 1 + R(feedback) / R(toground) = 1 + 2K9 / 5K6 = 1.51

    Note: the capacitor in the PWM output circuit is actually an error. It isn’t required for a CV output.

    Also, the CV output is amplified to make it a 0-5V signal, but the GATE output remains a 0-3.3V signal.

    A note on the PWM Filter.

    The circuit was originally pasted on from somewhere else and I have to confess I didn’t think about the differing nature of a PWM circuit for a control voltage compared to audio.

    As such, the stated component values of 220Ω and 10nF, with a cut-off frequency of upwards of 70kHz whilst useful for audio, are pretty useless for a CV. In the actual build, I’ve used values of 1K and 100nF which gives a cutoff frequency of around 1.5kHz.

    That will teach me to properly think about my requirement before cutting and pasting in one of my previous circuits 🙂

    PCB Design

    Unlike my last design this one assumes the USB host shield will be fixed to the Pro Mini, keeping the footprint as small as possible.

    I’ve allowed for both MIDI DIN and TRS sockets. There is also an option for individual GATE and CV out via jumper headers in addition to the Korg Volca compatible TRS.

    I’ve included a MIDI switch with the footprint of a 2×3 set of 2.54mm headers so that could be jumpers or a switch as required. If the Pro Mini is socketed (which isn’t so easy if a USB Host shield is attached, but would be possible with longer pin headers), then the MIDI switch could be omitted. It is only there to disconnect MIDI from the Pro Mini UART when uploading sketches.

    There is a bit of space around the 7805 in case a small heatsink is required. There is also the option to power the board directly from a 5V supply via a two-pin jumper header.

    The Pro Mini footprint includes the programing header, but this isn’t used on the board and should probably be ignored.

    Closing Thoughts

    My previous MIDI to CV was code for an ATtiny85, so I’ll need to rewrite the code for the ATMega328 on the Pro Mini to support the USB to Serial MIDI routing in addition to CV and GATE.

    Kevin

    #arduinoProMini #cv #korg #midi2cv #pcb #usbHost #volca

  5. OKILY DOKILY!

    #midi is finally working well enough in the #micropython #synthdiy #muvco that I can tell how it sounds. And that sound is: Like a video game.

    Which makes sense, since this is a bare squarewave (barewave) quantized to 1/16th notes and no variation in velocity.

    I'm not making the #midi2cv module yet, so beautiful #music will have to wait. I can proceed on whatever-the-fuck I was doing before I started this #sidequest

    diode.zone/w/mgUy2iet3UL3drs6V