I'm still experimenting with my new Nano 33 BLE with the Control Surface library.
Currently trying to connect encoders. I'm able to make up to 4 encoders working at the same time. If I add a further encoder the script gets compiled but the Nano 33 BLE seems frozen and doesn't get recognised by the MidiMonitor.
Here's the code:
#include <Control_Surface.h>
USBMIDI_Interface midi;
using namespace MIDI_Notes;
// CCRotaryEncoders----------------------
CCRotaryEncoder enc1 = {
{ 1, 0 }, // pins
MCU::V_POT_3, // MIDI address (CC number + optional channel)
1, // optional multiplier if the control isn't fast enough
};
CCRotaryEncoder enc2 = {
{ 11, 12 }, // pins
MCU::V_POT_4, // MIDI address (CC number + optional channel)
1, // optional multiplier if the control isn't fast enough
};
CCRotaryEncoder enc3 = {
{ 9, 10 }, // pins
MCU::V_POT_5, // MIDI address (CC number + optional channel)
1, // optional multiplier if the control isn't fast enough
};
CCRotaryEncoder enc4 = {
{ 7, 8 }, // pins
MCU::V_POT_6, // MIDI address (CC number + optional channel)
1, // optional multiplier if the control isn't fast enough
};
//CCRotaryEncoder enc5 = {
// { 5, 6 }, // pins
// MCU::V_POT_7, // MIDI address (CC number + optional channel)
// 1, // optional multiplier if the control isn't fast enough
//};
//CCRotaryEncoder enc6 = {
// { 3, 4 }, // pins
// MCU::V_POT_8, // MIDI address (CC number + optional channel)
// 1, // optional multiplier if the control isn't fast enough
//};
void setup() {
Control_Surface.begin();
}
void loop() {
Control_Surface.loop();
}
Unfortunately this won't work because mbedOS is included in the Arduino Core as a pre-built library. It will not be recompiled when you edit the header files.
You'd have to check the datasheet of the nRF52840 to be sure. Have a look at chapter “6.9 GPIO” in the Product Specification (v1.11): Technical Documentation. There seems to be a "DETECT" feature on all GPIO pins that you could use to detect state changes from the encoders. The detect signals from multiple pins can be OR-ed together to generate an interrupt if any pin changes. I've never used this feature myself, so I can't really help you beyond the high-level idea.
Once you have a way to detect pin changes, you can easily reuse the pin change encoder example (and specifically, the RegisterEncoders class) in the Control Surface library: Control Surface: Pin-Change-Interrupt-Encoders.ino
(You'll need to replace the low-level register configuration and the ISR in that example by nRF52-specific code.)
If you cannot get the pin change interrupts to work, an alternative is to poll all encoders in a timer interrupt handler, at a high enough sampling rate so you don't miss any pulses: Control Surface: Timer-Interrupt-Encoders.ino
Interestingly, the nRF52840 also has a dedicated QDEC hardware peripheral to decode encoder signals, but IIUC, it is limited to a single pair of quadrature signals.