Tuesday, May 09, 2023

Musical Sphere Controllers

I made some musical sphere controllers. They use the Adafruit Feather Sense BLE nRF5284 board. Axis in six dimensions can be mapped to MIDI outputs via a Max patch. Details including code, patch and 3D files can be found in the github repo here: https://github.com/little-scale/Music-Sphere-Controller 

Wednesday, April 19, 2023

Simple Cinemag CM-DBX Transformer DI

I wired up a simple DI for my synths as I wanted to balance the output as well as push the signal through a transformer. I used a Cinemag CM-DBX transformer. 

I connected the primary coil (yellow for positive and orange for negative) to the 6.5mm mono socket, as well as the chassis of the primary coil and shield of the transformer to 6.5mm ground. I connected the secondary coil (red for positive - XLR pin 2 and brown for negative - XLR pin 3) to the XLR jack, as well as the chassis of the secondary coil to XLR pin 1 (ground)ses Cinemag CM-DBX for the transformer, 

I used Jaycar part PP1023 for the XLR jack and Jaycar part PS0162 for the 6.5mm mono socket. Even though the box is plastic I have not had any noise issues yet but this will depend on environmental conditions. 

No issues with modular levels going through the transformer so far! So it can handle pretty hot signals. 

Download the STL files here: https://www.thingiverse.com/thing:5979053 

Teensy 4.1 with QMC6310 Magnetometer to USB MIDI


The QMC6310 magnetometer sensor outputs 16 bit for each axis X, Y and Z. The code uses the Wire library to communicate via the I2C protocol. This example prints the raw axis values to the serial monitor and also sends as a USB MIDI control change message (scaled to 0 - 127). The datasheet for this sensor can be found here


The following connections should be made between the Teensy 4.1 and the QMC6310:
  • Teensy 4.1 3V to QMC6310 VCC - orange in the above photo
  • Teensy 4.1 ground to QMC6310 GND - blue in the above photo
  • Teensy 4.1 pin 19 / A5 / SCL / PWM to QMC6310 SCL - green in the above photo
  • Teensy 4.1 pin 18 / A4 / SDA / PWM to QMC6310 SDA - yellow in the above photo


const int address = 0x1c; // 0x1c if part number is QMC6310U or 0x3c if part number is QMC6310N
int16_t axis[3]; // array for axis data X, Y, Z - force 2's compliment for a signed 16 bit integer

#include <Wire.h>

void setup() {

// Begin serial port

// Begin Wire library

// set up magnetometer
// writeMag(0x29, 0x06); // define sign for XYZ
writeMag(0x0b, 0x00 | 0x01 << 2); // define set / reset on
// field range: 2gauss = 0x11 << 2, 8gauss = 0x10 << 2, 12gauss = 0x01 << 2, 30guass = 0x00 << 2
writeMag(0x0a, 0xcd); // set normal range and ODR to 200 Hz

void loop() {
if (readMag()) { // if there is new data present, print the values of the three axis as a sixteen bit value
Serial.print("X: ");
usbMIDI.sendControlChange(1, map(axis[0], -32768, 32767, 0, 127), 1);
Serial.print(" Y: ");
usbMIDI.sendControlChange(2, map(axis[1], -32768, 32767, 0, 127), 1);
Serial.print(" Z: ");
usbMIDI.sendControlChange(3, map(axis[2], -32768, 32767, 0, 127), 1);

// this function writes data to the magnetometer
void writeMag(byte reg, byte val) {

// this function reads X,Y,Z data from the magnetometer
int readMag() {
// set reg 9 to read from

// read from reg 9 for 1 byte - this is the status byte
byte status; // status byte which stores the
Wire.requestFrom(address, 1);
while (Wire.available()) {
status = Wire.read() & 1;

if (status == true) {
// set reg 1 to read from
// read from reg 9 for 6 bytes - these are the data bytes X LSB, X HSB, Y LSB, Y HSB, Z LSB, Z HSB
Wire.requestFrom(address, 0x06);
byte index = 0;

// read data into axis array
while (Wire.available()) {
axis[index] = Wire.read() | Wire.read() << 8;
return true; // true if new data is present

else {
return false; // false if no new data is present

Wednesday, April 12, 2023

Geophone as Infrasonic Microphone with Case and Magnet

An SM-24 geophone (Sparkfun part SEN-11744) with a rare earth magnet (Jaycar part LM1626) to attach to metal surfaces. 

The pin on the geophone with the notch is the positive terminal. This should be wired to XLR pin 2. The other pin of the geophone is the negative terminal. This should be wired to XLR pin 1 and 3. Additionally, a 10k resistor should be wired between pins 1 and 2 of the XLR. 

Note that phantom power (48V) should be turned off prior to connecting the XLR to an input and should never be turned on while connected. 

The case is 3D printed with a wall of 1.5mm, leaving plenty of strength of magnetic field of the magnet and more than enough contact with the geophone element to transmit through. 

The case assumes a magnet thickness of approximately 4.5mm, diameter of 25mm and a microphone cable thickness of 6mm. Download the STL file here: https://www.thingiverse.com/thing:5965625 

This setup has been tested with a 3m two conductor microphone cable (Jaycar part WB1530). 

The input device will need to support frequencies below 20 Hz in order to make full use of this setup. Examples include RME interfaces and Sound Devices recorders. 

Saturday, April 01, 2023

Connecting an Encoder to Teensy 4.2


An encoder is a digital input device that looks similar to a pot but can be rotated indefinitely and delta rotation in steps is measured by making or breaking contact between two pins and ground. The Teensy has an excellent and easy to use library for encoders. More than one encoder can be easily used. 


The encoder portion of an encoder usually has three pins, these may be labelled A, B and C. B is a common ground and should be connected to ground. A and C should each be connected to an individual digital pin on the Teensy. As the encoder is turned, the connection between A and B, and A and C is made and broken. This is, in turn, read as a series of high and low signals by the digital input pins. 

This particular encoder also has a push switch. When pressed down, the encoder will make the connection between sw1 and sw2. sw1 can be connected to a third digital input pin on the Teensy and sw2 can be connected to ground. 


The code uses the encoder library to create an encoder object on pins 0 and 1 as well as a button on pin 2. There is a boundary of 0 and 1023 for the encoder. Values of the button and encoder are printed to the serial monitor. 

#include <Encoder.h>

int enc_current;
int enc_previous;
int button = 2; // button on pin 2

int button_current;
int button_previous;

int enc_max = 255; // max value for encoder
int enc_min = 0; // min value for encoder

Encoder enc(0, 1); // create an encoder object named enc using digital pins 0 and 1

void setup() {
pinMode(button, INPUT_PULLUP);

void loop() {
enc_current = enc.read();

if (enc_current != enc_previous) {
if (enc_current < enc_min) {
enc_current = enc_min;
if (enc_current > enc_max) {
enc_current = enc_max;

enc_previous = enc_current;
Serial.print("Encoder: ");


button_current = digitalRead(button);

if (button_current != button_previous) {
button_previous = button_current;

Serial.print("Button: ");