Grumpenspiel MIDI SysEx Reference

SysEx message format

All MIDI SysEx messages accepted by Grumpenspiel MIDI instruments follow the pattern:

BlockSize (bytes)ValueDescription
SysEx Begin 1 0xF0 required by MIDI specification
Manufacturer ID 1 0x1E rescinded ID formerly assigned to Key Concepts (0x1E, 30 dec)
Device ID 1 various refer to table below
Model ID 1 various ignored by Grumpenspiel, no plans to differentiate instruments via Model ID, included for Roland pseudo-compatibility
Instruction ID 1 various 0x12 is address/data EEPROM update</br> 0x13 is servo tap
Data var data payload specific to the instruction type
Checksum 1 Roland algorithm (details below)
SysEx End 1 0xF7 required by MIDI specification

Manufacturer ID

Grumpenspiel instruments use MIDI manufacturer ID 0x1E. It is a rescinded ID formerly assigned to Key Concepts. It was chosen as the lowest inactive single-byte ID.

To gain official recognition through the MIDI Manufacturer’s Association you need to pay $200 annual fee. Grumpenspiel instruments are not commercial products, there will never be more of them than can fit in my van (plus some dogs and people), so seems appropriate to grab on to an unused ID.

Device IDs

InstrumentDevice IDNotes
Frown Elaine 1
Franklin Bean 2
Demonic Tapioca 5
Cow Baby Drum Set 10 - unassigned built (and deployed to my niece’s house) before Grumpenspiel MIDI standard was finalized

Instruction IDs

This page covers the standard instructions across all Grumpenspiel instruments. Unique instrument instructions are documented on the page for that instrument.

Clear seventh bit

Remember, MIDI System Exclusive spec says all bytes in the message must have bit 7 clear. This means they can value 0-127. Grumpenspiel wants full unsigned byte values that range from 0-255.

Grumpenspiel SysEx controllers encode the data block of the message before sending. Input values can range 0-255. Encoding grows the size of the output data by 1 byte for every 7 input bytes. An additional byte is inserted, and contains the MSBs of the following 7 bytes, who’s MSBs have been cleared.

Grumpenspiel instruments/synths decode the data block after receiving, removing the added bytes, and restoring the MSBs of the remaining input bytes.

This encoding/decoding pattern comes from the Arduino MIDI library at FortySevenEffects.

The next sections describe specific instructions that Grumpenspiel instruments support. The data format is the raw unencoded input format. Encoding/decoding happens on top of this.

0x12 Address/Data EEPROM Update

This instruction is used to save a data byte into a specific EEPROM address.

BlockSize (bytes)Description
EEPROM address 2 The two bytes form a 16-bit integer value, MSB first. Used as the address in the Arduino EEPROM address space. Technically only need 12 bits to cover the maximum address (ATmega2560 has 4k storage), but all 16 are used.
Data bytes var write these bytes into sequential locations, starting at the specified address.

0x13 Servo Position

This instruction is used to calibrate/tune servo tappers, which are abundant in Grumpenspiel. Move the specified motor to the specified position and hold it there.

Instruments are expected to treat the values as volatile and not save them.

BlockSize (bytes)Description
Motor ID 1 the motor number to be actuated
Position 1 Value expected 0-180, to be fed into servo library.

0x14 Servo Tap

This instruction is used to calibrate/tune servo tappers, which are abundant in Grumpenspiel. Move to the strike position, delay for the specified time, move to the rest position.

Instruments are expected to treat the values as volatile and not save them.

BlockSize (bytes)Description
Motor ID 1 the motor number to be actuated
Strike Position 1 Value expected 0-180, to be fed into servo library.
Delay Millis 2 The two bytes form a 16-bit integer value, MSB first. Number of milliseconds to wait between strike and rest. Use a non-blocking technique (i.e. avoid delay()) to continue processing while waiting.
Rest Position 1 Value expected 0-180, to be fed into servo library.

0x15 MIDI Channel Select

This instructs the device to listen to the specified MIDI channel. Optionally instructs to save the channel setting or keep it volatile.

0x16 Verify Identity

This allows the technician to verify the identity of devices on the MIDI network. Two flavors of this message, one verifies using Device ID, the other verifies using MIDI Channel.

It is up to the target instrument to implement some sort of verification signal. An example would be to flash the lights, or wiggle the motors. Anything that would be clear to the technician.

Checksum

The final data byte of Grumpenspiel SysEx messages is a checksum to ensure data integrity. If the checksum does not match, the message is discarded.

Checksum is calculated on the full message. This includes manufacturer id, device id, model id, instruction id, and encoded data portions of the SysEx message. The leading status byte, the checksum itself (duh, circular reference much?) and trailing status byte are not included.

We use the Roland checksum algorithm for the calculation. Here is a good explanation, and here is a different good one, possibly written by the same person.

  1. add up all the bytes
  2. divide by 128
  3. subtract remainder from 128

checksum = 128 - ( sum(deviceID, data) % 128 )

EEPROM

All Grumpenspiel instruments store the same reference information in the same EEPROM address space. Wherever possible, they also include a serial interface to allow update of this address space. Worst case scenario, a temporary firmware can be uploaded to write new values to EEPROM and then the old firmware restored.

There is a helper application for generating the EEPROM .hex file encoded to this spec. Edit the XML config file with device and motor information, run the program to generate Intel HEX formatted data, then run avrdude to upload the EEPROM image to Servo Slam.

AddressDescription
0-9 Reserved for future use
10 Grumpenspiel Manufacturer ID (0x1E) (30 dec)
11 Device ID
12 Default MIDI Channel (0-16)
13-19 Reserved for future use
20-1023 Device specific storage. Grumpenspiel generally uses Arduino Nano with ATmega328P having 1024 byte EEPROM.