digitalelements
Active member
Greetings !
After several days of research, Some trial and error, I've landed on using the Encoder Template written by Theremingenieur. It really does clean things up quite a bit when using not so great encoders. I dove straight into trying to add code to send USB MIDI messages. I've been successful in getting the behavior I'm looking for but fear the location of the code I added is just not the best place. Especially If I add some additional buttons to this sketch.
I'm a noob/begginer So please go easy on me ... any guidance and or suggestions would be greatly appreciated and a learning experience.
Kind Regards,
Chris
After several days of research, Some trial and error, I've landed on using the Encoder Template written by Theremingenieur. It really does clean things up quite a bit when using not so great encoders. I dove straight into trying to add code to send USB MIDI messages. I've been successful in getting the behavior I'm looking for but fear the location of the code I added is just not the best place. Especially If I add some additional buttons to this sketch.
I'm a noob/begginer So please go easy on me ... any guidance and or suggestions would be greatly appreciated and a learning experience.
Kind Regards,
Chris
Code:
// Encoder MIDI PGC Inc Dec
#include <Bounce.h>
const int channel = 1;
byte pgcNum = 0;
template<uint8_t pinA, uint8_t pinB>
class rotKnob {
public:
void begin(int8_t startVal, int8_t lowBound, int8_t hiBound) {
d._sValue = startVal;
d._lBound = lowBound;
d._hBound = hiBound;
d._aConf = digital_pin_to_info_PGM[(pinA)].config;
d._bConf = digital_pin_to_info_PGM[(pinB)].config;
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
delay(1);
d._aVal = digitalReadFast(pinA);
d._bVal = digitalReadFast(pinB);
attachInterrupt(pinA, intPinA, CHANGE);
attachInterrupt(pinB, intPinB, CHANGE);
}
void begin(int8_t startVal) {
begin(startVal, 0, 127);
}
void begin() {
begin(0, 0, 127);
}
void end() {
detachInterrupt(pinA);
detachInterrupt(pinB);
}
int8_t read() {
d._avail = false;
return d._sValue;
}
bool available() {
return d._avail;
}
private:
struct objData {
volatile uint32_t* _aConf, *_bConf;
volatile int8_t _lBound, _hBound, _sValue;
volatile bool _aVal, _bVal, _avail;
};
static objData d;
static void intPinA() {
*d._aConf &= ~0x000F0000; // disable pin A interrupts
// decoding logic
if (!d._aVal) {
if ((d._sValue < d._hBound) && !d._bVal) {
d._sValue++;
d._avail = true;
pgcNum++;
usbMIDI.sendProgramChange(pgcNum,channel);
}
if ((d._sValue > d._lBound) && d._bVal) {
d._sValue--;
d._avail = true;
pgcNum--;
usbMIDI.sendProgramChange(pgcNum,channel);
}
}
d._bVal = digitalReadFast(pinB); // read pinB which is stable after pinA transition
*d._bConf |= 0x000B0000; // (re-) enable pinB interrupts
}
static void intPinB() {
*d._bConf &= ~0x000F0000; // disable pinB interrupts
d._aVal = digitalReadFast(pinA); // read pinA which is stable after pinB transition
*d._aConf |= 0x000B0000; // (re-) enable pinA interrupts
}
};
template<uint8_t pinA, uint8_t pinB>
typename rotKnob<pinA, pinB>::objData rotKnob<pinA, pinB>::d;
/* Describe your hardware connections, pins and knobs */
rotKnob<9, 10> enc1;
void setup() {
Serial.begin(57600);
while (!Serial)
;
delay(5);
pinMode(LED_BUILTIN, OUTPUT);
/* Configure your encoders */
enc1.begin();
}
void loop() {
if (enc1.available()) {
Serial.print("Encoder 1: ");
Serial.println(enc1.read());
}
}