ATtiny85 MIDI Tester

January 25, 2019 at 10:28 pm (computers, music) (, , )

Having spent some time messing about with building simple synthesizer circuits, I’m putting together a simple MIDI to CV converter.  I have one using an ATtiny85 but think I’m struggling from the fact it is only using SoftwareSerial, so I plan to have another go with an ATtiny231w pretty soon now.

One thing I was missing though was a simple “hands free” MIDI tester.  Now it would be fairly simple to hook up my laptop or a keyboard to a MIDI cable and use that, but I wanted something I could just plug in and leave sending MIDI data out to whatever I was building.  So the idea of using a simple USB-powered ATTiny85 to creating a continuous set of MIDI note on and not off messages was born.

I’m using one of those cheap Digispark USB clones you can buy. I had no luck ever getting the USB programming side of it to work, (its supposed to be able to have the nucleus boot loader installed to provide a software USB implementation), but its easy to programme if you have an 8-pin DIL test clip, in my cased hooked up to a sparkfun tiny programmer.

2019-01-25 21.22.26

Basic design notes for the board:

  • P1 (equivalent to Arduino D1 and the ATtiny85 pin 6) has the built-in LED.
  • I’m using P2 as MIDI TX and P3 as (unused) MIDI RX (D2 and D3, mapped to ATtiny85 pins 7 and 2).
  • P0 (ATtiny85 pin 5) as a digital input with internal pull-up resistors enabled.

I’m using a simple MIDI out circuit from the Internet that shows:

  • DIN pin 5 – MIDI OUT signal directly connected to P2.
  • DIN pin 2 – MIDI ground.
  • DIN pin 4 – MIDI +5v via a 220R resistor.

The resistor was soldered inside an in-line female MIDI DIN socket.

2019-01-25 21.36.522019-01-25 21.42.10

A switch was soldered across from P0 to GND on the Digispark board.  The code will flash the LED when the switch is registered so you know you’ve done something.

That is pretty much it.

2019-01-25 21.51.47

2019-01-25 21.51.56

In terms of code, I just tested it with an increasing scale of a few octaves, with the switch being used to increase the tempo (by reducing the delay between notes). Of course, you can use whatever test pattern works for you.

My initial (simple) code below.

Important: You must “set the fuses” to use the internal 16MHz clock in order to get the MIDI baud rates for the SoftwareSerial implementation.


// MIDI Code Test Generator using ATtiny85
// NB: Use Sparkfun USB ATtiny85 Programmer
//     Set Arduino env to USBTinyISP
//     Set 16MHz Internal Clock (required for MIDI baud)
#include <SoftwareSerial.h>

// Pin Mapping for DigiSpark USB/ATtiny85
//  P0 = PB0/D0 = Pin 5 Attiny85
//  P1 = PB1/D1 = Pin 6 - built-in LED
//  P2 = PB2/D2 = Pin 7
//  P3 = PB3/D3 = Pin 2 - wired to USB+
//  P4 = PB4/D4 = Pin 3 - wired to USB-
//  P5 = PB5/D5 = Pin 1 - wired to RESET
// Use the Arduino D numbers below (which are the same as Digispark P numbers)
#define MIDITX   2
#define MIDIRX   3
#define BUTTON   0
#define BLTINLED 1

// MIDI Parameters for testing
#define MIDI_CHANNEL     1
#define MIDI_LOWNOTE     36
#define MIDI_HIGHNOTE    90
#define MIDI_VELOCITY    64
#define MIDI_DELAYMAX    550
#define MIDI_DELAYMIN    50
#define MIDI_DELAYSTEP   100

#define MIDI_NOTEON      0x90
#define MIDI_NOTEOFF     0x80

SoftwareSerial midiSerial(MIDIRX, MIDITX);

int delayRate;
int buttonState;
int lastButtonState;
byte midiNote;

void setup() {
  // Switch will trigger HIGH->LOW
  digitalWrite (BLTINLED, LOW);
  buttonState = HIGH;
  lastButtonState = HIGH;
  midiSerial.begin (31250); // MIDI Baud rate

  delayRate = MIDI_DELAYMAX;
  midiNote  = MIDI_LOWNOTE;

void loop() {
  buttonState = digitalRead (BUTTON);
  if ((lastButtonState == HIGH) && (buttonState == LOW)) {
    delayRate = delayRate - MIDI_DELAYSTEP;
    if (delayRate < MIDI_DELAYMIN) delayRate = MIDI_DELAYMAX;
  lastButtonState = buttonState;

  midiNoteOn (MIDI_CHANNEL, midiNote, MIDI_VELOCITY);
  delay (400); // Need note on long enough to sound
  midiNoteOff (MIDI_CHANNEL, midiNote);
  delay (delayRate);

  if (midiNote > MIDI_HIGHNOTE) midiNote = MIDI_LOWNOTE;

void midiNoteOn (byte midi_channel, byte midi_note, byte midi_vel) {
  midiSerial.write (midi_channel+MIDI_NOTEON);
  midiSerial.write (midi_note);
  midiSerial.write (midi_vel);

void midiNoteOff (byte midi_channel, byte midi_note) {
  midiSerial.write (midi_channel+MIDI_NOTEOFF);
  midiSerial.write (midi_note);
  midiSerial.write ((byte)0);

void ledOn () {
  digitalWrite (BLTINLED, HIGH);

void ledOff () {
  digitalWrite (BLTINLED, LOW);  


Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: