-
Notifications
You must be signed in to change notification settings - Fork 12
How To Custom JSON with Oopsy
If you have custom hardware based on the Daisy Seed or Daisy Patch SM, Oopsy provides a way to describe your hardware just like any of the included boards. The interface uses the JSON format with just a few fields to tell Oopsy what's what. You can find all of Oopsy's board definitions here if you'd like more examples beyond this how to.
This is work-in-progress, so it's not yet available on the master branch (or fork) of Oopsy. For testing, you should check out the dev
branch using git
in your terminal:
git checkout dev
There are four fields that are essential for any board description:
- name
- This describes the name of the board, which helps with organizing file generation.
- som
- This describes the System On Module (SOM) used by your hardware. The options are
seed
andpatch_sm
.
- This describes the System On Module (SOM) used by your hardware. The options are
- audio
- This field should be structured as an object (contained by curly braces
{}
) with a "channels" field describing the number of audio channels.
- This field should be structured as an object (contained by curly braces
- components
- This field describes the board's I/O layout, and should be structured as an object with each field corresponding to the object name you'll use in Max. Each individual component object should have a "component" field describing what type of component it is and a "pin" field describing which pin it uses. Components that use multiple pins should use an object formatted according to its description in the following section.
Here's an example of a minimally viable JSON description with these fields:
{
"name": "my_board",
"som": "seed",
"audio": {"channels": 2},
"components": {
"knob": {
"component": "AnalogControl",
"pin": 21
}
}
}
Just wire up a potentiometer to the Seed on a breadbord and you're off to the races!
Note: You may encounter a compiler error if you have a space in your .json
file name.
The "defines" field, structured as an object with each field representing a C-style macro, allows the use of a few additional features. Here's a list of the currently valid macros:
- OOPSY_TARGET_HAS_MIDI_INPUT
- With its value set to
1
, this macro will provide a MIDI input stream that's accessed like an audio input (e.g.in 3 midi
if the board has two audio ins). This feature uses USART 1 on pins 13 and 14 of the Daisy Seed.
- With its value set to
- OOPSY_TARGET_HAS_MIDI_OUTPUT
- With its value set to
1
, this macro will output a MIDI data stream (e.g.out 3 midi
if the board is only using two outputs). This feature uses USART 1 on pins 13 and 14 of the Daisy Seed.
- With its value set to
The "aliases" field allows you to provide alternate names for a component. Structured as an object, each key represents the alias, and its corresponding item represent the original name of the component. As an example:
"aliases": {
"pot": "knob"
}
Appended to the first JSON example in this how to, this would allow you to refer to your component in Max as either pot
or knob
.
Here's a table of the main components:
Component | Pin description | Notes |
---|---|---|
Switch | Single pin | A momentary or toggle switch with an internal pullup |
Switch3 | {"a": (pin), "b": (pin)} | A SP3T switch with the outer terminals connected to "a" and "b" |
Encoder | {"a": (pin), "b": (pin), "click": (pin)} | A rotary encoder with a momentary pushbutton shaft |
GateIn | Single pin | A GPIO serving as a gate input |
AnalogControl | Single pin | Any analog input -- CV, potentiometer, or otherwise. Ensure the pin is a valid analog input! |
Led | Single pin | An LED |
RgbLed | {"r": (pin), "g": (pin), "b": (pin)} | An RGB LED |
GateOut | Single pin | A GPIO serving as a gate output |
CVOuts | Single pin | One of two DAC outputs on the Daisy |
Note that these names are case sensitive.
Let's combine all this together an take a look at the JSON describing the Daisy Pod:
{
"name": "pod",
"som": "seed",
"defines": {
"OOPSY_TARGET_HAS_MIDI_INPUT": 1
},
"audio": {
"channels": 2
},
"components": {
"sw1": {
"component": "Switch",
"pin": 27
},
"sw2": {
"component": "Switch",
"pin": 28
},
"knob1": {
"component": "AnalogControl",
"pin": 21
},
"knob2": {
"component": "AnalogControl",
"pin": 15
},
"encoder": {
"component": "Encoder",
"pin": {
"a": 26,
"b": 25,
"click": 13
}
},
"led1": {
"component": "RgbLed",
"pin": {
"r": 20,
"g": 19,
"b": 18
}
},
"led2": {
"component": "RgbLed",
"pin": {
"r": 17,
"g": 24,
"b": 23
}
},
"led3": {
"component": "Led",
"pin": 10,
},
"cvout": {
"component": "CVOuts"
},
"gatein": {
"component": "GateIn",
"pin": 12
},
"sw3": {
"component": "Switch3",
"pin": {
"a": 1,
"b": 2
}
}
},
"aliases": {
"cvout1": "cvout",
"switch": "sw1",
"button": "sw1",
"switch1": "sw1",
"button1": "sw1",
"switch2": "sw2",
"button2": "sw2",
"switch3": "sw3",
"gate": "gatein",
"gate1": "gatein",
"encswitch": "encoder_rise",
"enp": "encoder_press",
"press": "encoder_press",
"knob": "knob1",
"ctrl": "knob1",
"ctrl1": "knob1",
"ctrl2": "knob2",
"led": "led1"
}
}