How to connect a rotary encoder to a BELA-enabled BeagleBone Black.
Hardware used in this post:
- BeagleBone Black with BELA board
- simple Gray-code rotary encoder with hat switch
- three 10k resistors
- three 10uF capacitors
Connect rotary encoder Link to heading
The rotary encoder is connected to the digital pins on the BELA as shown in the figure below. The capacitors are used to do assure a minimum of debouncing.
SuperCollider Link to heading
I captured the data with SuperCollider running on my laptop. Encoding is done via UGens within the synthdef itself.
Preparation Link to heading
Start the server remotely, either by ssh’ing into the board or directly from within your SuperCollider IDE.
$ ssh root@192.168.7.2
bela$ scsynth bash -c 'scsynth -u 57110 -z 16 -J 8 -K 8 -G 16 -i 2 -o 2'
"ssh root@192.168.7.2 \"screen -dm -S scsynth bash -c 'scsynth -u 57110 -z 16 -J 8 -K 8 -G 16 -i 2 -o 2 > scsynth.log'\"".unixCmd
Initialise the server
Server.default = s = Server("belaServer", NetAddr("192.168.7.2", 57110));
s.initTree;
s.startAliveThread;
First steps Link to heading
First, listen to how the raw values coming from the pins can be used directly as amplitude envelopes for oscillators:
// simply listen to the pulses
Ndef(\a, {
var trigs = DigitalIn.ar([0, 1, 2]); // A, B, button
Splay.ar(SinOsc.ar([100, 800, 1900], 0, amps))
}).play;
The pulses of the pins can be interpreted as a 2bit gray-encoded number.
// convert gray code into binary values
Ndef(\a, {
var pA = DigitalIn.ar(0);
var pB = DigitalIn.ar(1);
var gray = [pA, (pB * 2)].sum;
// convert to standard binary encoding
var bin = Select.ar(gray, DC.ar([0, 1, 3, 2]));
// for every change in the signal, create a trigger
var changed = Changed.ar(pA) + Changed.ar(pB);
// poll whenever something changed
bin.poll(changed); //poll changes (output on bela!)
SinOsc.ar(100 * (bin + 1)) * Decay.ar(changed, 0.2).tanh!2;
})
)
Integrate Link to heading
If only one update per click is required, the code can be simplified. Additionally, we compute the direction of turning and feed this into an integrator to get absolute value changes.
Ndef(\a, {
var pA = DigitalIn.ar(0);
var pB = DigitalIn.ar(1);
var trig = HPZ1.ar(pA * pB) > 0;
var sign = Delay1.ar(pA - pB);
// sign.poll(trig, "sign");
// trig.poll(trig, "trig");
var note = Integrator.ar(trig * sign).poll(trig, "int");
SinOsc.ar(note.midicps)!2;
})