-
-
Save sleiner/94c0157cd51f19c19ed04fea3758ed1a to your computer and use it in GitHub Desktop.
gigbox v0.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "MIDIcontroller.h" | |
#include "softdebounce.h" | |
byte MIDIchannel = 1; | |
const int expPin = A2; | |
const int susPin = A1; | |
const byte expCC = 52; | |
const byte susCC = 50; | |
// This enables sending a binary variant of the Sustain Pedal, as in 0 OR 127 | |
// instead of 0...127. This is basically the same as the kill switch | |
const int sustainBinaryCC = susCC + 1; | |
const int debounceInterval_ms = 300; | |
Debounce<int> sustainPedalBinary(debounceInterval_ms); | |
// Pot parameters are: pin, CC number, KILL switch enabled | |
// When KILL is enabled, separate CC messages (with a different number) will be sent | |
// when you turn the pot all the way down and when you start turning it up again. | |
// Simply omit the "KILL" argument if you don't want that. | |
MIDIpot expPedal(expPin, expCC, KILL); | |
MIDIbutton susPedalBinary(susPin, sustainBinaryCC, MOMENTARY); | |
void setup(){ | |
expPedal.inLo = 100; | |
expPedal.inHi = 1010; | |
susPedalBinary.outHi = 0; | |
susPedalBinary.outLo = 127; | |
pinMode(expPin, INPUT); | |
pinMode(susPin, INPUT); | |
auto sendSustainBinaryMessage = | |
[](int val) { | |
usbMIDI.sendControlChange(sustainBinaryCC, val, MIDIchannel); | |
}; | |
sustainPedalBinary.registerOnRisingEdge(sendSustainBinaryMessage); | |
sustainPedalBinary.registerOnFallingEdge(sendSustainBinaryMessage); | |
} | |
void loop(){ | |
expPedal.send(); | |
susPedalBinary.send(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// To give your project a unique name, this code must be | |
// placed into a .c file (its own tab). It can not be in | |
// a .cpp file or your main sketch (the .ino file). | |
#include "usb_names.h" | |
// Edit these lines to create your own name. The length must | |
// match the number of characters in your custom name. | |
#define MIDI_NAME {'G','i','g','b','o', 'x', ' ', 'M', 'I', 'D','I'} | |
#define MIDI_NAME_LEN 11 | |
// Do not change this part. This exact format is required by USB. | |
struct usb_string_descriptor_struct usb_string_product_name = { | |
2 + MIDI_NAME_LEN * 2, | |
3, | |
MIDI_NAME | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#if defined(ARDUINO) && ARDUINO >= 100 | |
#include "Arduino.h" | |
#else | |
#include "WProgram.h" | |
#endif | |
template<class T> | |
class Debounce | |
{ | |
public: | |
Debounce(int interval_ms) | |
{ | |
this->newValueReceived = false; | |
this->intervalMs = interval_ms; | |
this->lastUpdateTime = 0; | |
this->callbackFunctionRising = nullptr; | |
this->callbackFunctionFalling = nullptr; | |
}; | |
int setIntervalMs(int interval_ms) | |
{ | |
this->intervalMs = interval_ms; | |
return interval_ms; | |
} | |
T input(T newValue) | |
{ | |
if(newValue != this->currentValue) | |
{ | |
this->newValue = newValue; | |
this->newValueReceived = true; | |
} | |
return newValue; | |
} | |
T get() | |
{ | |
this->update(); | |
return this->currentValue; | |
} | |
void update(T newValue) | |
{ | |
this->input(newValue); | |
this->update(); | |
} | |
void update() | |
{ | |
if(this->newValueReceived) | |
{ | |
long currentTime = millis(); | |
long timeSinceLastUpdate_ms = currentTime - this->lastUpdateTime; | |
if(timeSinceLastUpdate_ms > this->intervalMs) | |
{ | |
T previousValue = this-> currentValue; | |
this->currentValue = this->newValue; | |
this->lastUpdateTime = currentTime; | |
this->newValueReceived = false; | |
if(this->currentValue > previousValue) | |
{ | |
if(this->callbackFunctionRising != nullptr) | |
{ | |
(*this->callbackFunctionRising)(this->currentValue); | |
} | |
} | |
else if(this->currentValue < previousValue) | |
{ | |
if(this->callbackFunctionFalling != nullptr) | |
{ | |
(*this->callbackFunctionFalling)(this->currentValue); | |
} | |
} | |
} | |
} | |
} | |
void registerOnRisingEdge(void (*callbackFunction)(T newValue)) | |
{ | |
this->callbackFunctionRising = callbackFunction; | |
} | |
void registerOnFallingEdge(void (*callbackFunction)(T newValue)) | |
{ | |
this->callbackFunctionFalling = callbackFunction; | |
} | |
protected: | |
bool newValueReceived; | |
T currentValue; | |
T newValue; | |
void (*callbackFunctionRising)(T value); | |
void (*callbackFunctionFalling)(T value); | |
long lastUpdateTime; | |
int intervalMs; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment