Skip to content
This repository has been archived by the owner on Oct 26, 2023. It is now read-only.
MrHaroldA edited this page Feb 8, 2018 · 8 revisions

Welcome to the MS-3 Arduino library wiki!

Why use this library?

The Boss MS-3 is a really great product, but it lacks Midi IN functionality so we can't control it externally. Boss does provide Editor/Librarian software, which completely controls the MS-3 through "Midi SysEx over USB".

This is where the MS3 Library kicks in!

Asynchonous communication

The downside of using SysEx for communication is that everything is done asynchronous. For example: if you want to query the value of a parameter you have to send the query first, the MS-3 processes this request and adds the response to the list of messages it is sending back. A round-trip can take over 20ms, so you can't wait for it because that will block all I/O for your Arduino during that wait, and even then you could receive an other parameter value as well because that is what the MS-3 already had in it's send queue and because there is no relation between the query and the response.

So, all communication is asynchronous to prevent blocking the Arduino and/or receiving wrong values.

MS-3 library API

The MS-3 library only has a few public methods:

  • begin() // Init the USB layer. Call this from your setup() routine.
  • read() // Request the MS-3 to send us the value of a parameter.
  • write() // Set the value of a parameter.
  • update() // Check for link state, incoming data, and send out queued queries.
  • setEditorMode() // Set the MS-3 into 'editor mode' to prevent 'BULK DATA RECEIVING' messages and set the MS-3 to send out changes made on the MS-3 itself.

All read and write queries are added to a queue, which is sent to the MS-3 by calling update() in your main loop. You may add queries at any location in your sketch but be careful not to exceed the configured queue length or queries will be lost.

Update states

The update() method checks the MS-3 and USB status, and handles all communication. If there's no data to be picked up, update() also sends out any queued queries.

Calling the update() method will return one of these states:

  • MS3_NOT_READY // USB link is down.
  • MS3_READY // USB link just became ready; use this to call setEditorMode().
  • MS3_DATA_SENT // A queued item was sent.
  • MS3_DATA_RECEIVED // Data was received.
  • MS3_NOTHING_HAPPENED // There are still items in the queue, but we have to wait until the time-out expires before sending it out.
  • MS3_ALMOST_IDLE // The queue is empty, but the send time-out hasn't expired yet.
  • MS3_IDLE // The queue is empty, and the time-out has expired. We're done!
void loop() {

    // The MS-3 library stores the parameter and data in these variables.
    unsigned long parameter = 0;
    byte data = 0;

    // Check the state of the MS-3.
    switch (MS3.update(parameter, data)) {

        // Set the MS-3 to editor mode.
        case MS3_READY:
            MS3.setEditorMode();
            break;

        // Parse the incoming data.
        case MS3_DATA_RECEIVED:
            parseData(parameter, data);
            break;
    }
}

The parameter and data variables are filled by the update() method when data is received and can then be easily be parsed in a custom parseData() function.

void parseData(unsigned long parameter, byte data) {
    switch (parameter) {
        case P_PATCH:
            Serial.print(F("Program Change received: "));
            Serial.println(data);
            break;

        default:
            Serial.print(F("Unhandled parameter: 0x"));
            Serial.println(parameter, HEX);
    }
}

See the provided example sketches for more options.

Clone this wiki locally