Imbecillen:
I feel kind of stuck when I don't understand my whole code and have the flexibility of editing it exactly how I want it.
I totally understand, I'm just like that myself 
The goal of the library is to make abstraction of the low-level stuff that you don't have to worry about, but still allow for many customizations in places where it matters.
For example, MIDI I/O is all handled for you, but you can select many different MIDI Interfaces, and you can easily add ones yourself, while still being able to reuse the parts you want to keep.
Same for IO: shift registers and multiplexers are abstracted, and you can just use digitalRead, analogRead, digitalWrite, etc. as if the multiplexed pins are just normal IO pins.
For example, this sketch will blink an LED connected to a shift register. As you can see, the code in the setup and loop is identical to the normal Arduino blink example.
Code:
---
|
``` #include <Control_Surface.h> // Include the Control Surface library. |
using namespace ExtIO;
const pin_t latchPin = 10; // Pin connected to ST_CP of 74HC595
const pin_t dataPin = 12; // Pin connected to DS of 74HC595
const pin_t clockPin = 13; // Pin connected to SH_CP of 74HC595
/** Instantiate a shift registers on the correct pins, most significant bit
* first, and a total of 8 outputs. */
ShiftRegisterOut sreg = { dataPin, clockPin, latchPin, MSBFIRST, 8 };
const pin_t ledPin = sreg.pincolor=#000000[/color]; // first pin of the shift register
void setupcolor=#000000[/color] { /* Initialize everything. */
sreg.begincolor=#000000[/color];
pinMode(ledPin, OUTPUT); // You don't even need this line, since
// shift registers are always outputs
}
void loopcolor=#000000[/color] { /* Toggle the LED every ½ second. */
digitalWrite(ledPin, HIGH);
delaycolor=#000000[/color];
digitalWrite(ledPin, LOW);
delaycolor=#000000[/color];
}
```
|
If you want to add your own MIDI buttons that only send on release, you can just add your own MIDI Output Element. The code you have to write yourself is minimal.
The library automatically discovers your objects, you can use the debounced button classes provided by the library, you can use the MIDI output provided by the library, etc.
For example, this is the class that sends MIDI events based on input from a button:
You can see how easy it is. You just have to implement two methods: a begin
function that is called once (automatically, when calling Control_Surface.begin()
) that initializes your object, and a update
function, that is called continuously (automatically, when calling Control_Surface.loop()
).
template <DigitalSendFunction sendOn, DigitalSendFunction sendOff>
class MIDIButton : public MIDIOutputElement {
protected:
MIDIButton(pin_t pin, uint8_t baseAddress, uint8_t baseChannel)
: button{pin}, baseAddress(baseAddress), baseChannel(baseChannel) {}
public:
void begin() final override { button.begin(); }
void update() final override {
Button::State state = button.getState();
if (state == Button::Falling) {
sendOn(baseChannel, baseAddress);
} else if (state == Button::Rising) {
sendOff(baseChannel, baseAddress);
}
}
private:
Button button;
const uint8_t baseAddress;
const uint8_t baseChannel;
};
Source and documentation: https://tttapa.github.io/Control-Surface/Doc/Doxygen/dd/d47/Abstract_2MIDIButton_8hpp_source.html
Imbecillen:
I may be able to use some parts from your library, I will check out the things you linked, thanks! 
If you have any questions, just ask!