Shopping list:
- 2 x BNO055 https://www.adafruit.com/product/2472
- Teensy 4.0 dev board https://www.pjrc.com/store/teensy40.html
- Wrist support gloves such as https://amz.run/6cQV
- Velcro, staples, flexible wire, cable ties
I also 3D-printed housings for the electronics. I used this box for the Teensy from Thingiverse and adapted and printed 2 of these for the BNO055s. Contact me if you want my versions – they are not particularly good, but good enough for my need. In a later post, I will describe a better version that will work with the hand straps that I am now using.
On boxing the electronics, I attached the boxes to the gloves using Velcro, and to stop the Velcro from peeling off the gloves, I added some staples. I mounted one sensor to each of the “back of hand” parts of the left and right gloves, and the Teensy to the wrist of the right glove. Make sure you have enough wire to connect to the left hand so you can wave your arms around! The instructions for wiring the sensors to the Teensy can be found on the Adafruit site (or you can ask ChatGPT). Just to note that they both connect to the I2C bus so you need to change the address of one of the boards by linking the ADR pin to the 3V pin. Other than that it is 4 wires in total for Vin and Gnd and SCL and SDA for the I2C bus.
If you are going to program your Teensy 4.0 via the Arduino IDE you will need to add “Teensyduino” into the mix. These are the instructions you will need to do it. You will also need to configure the Teensy for USB midi.
Having done all this, the program is actually quite trivial and could probably be improved hugely. You will need to add the sensor and midi libraries to your IDE first. Once programmed your computer will recognise the USB as a midi device and you can add it to your DAW. I use Ableton and I set up 6 different choir voices to 6 different midi channels. Moving the hand will send different notes to different channels. How often the notes are played will depend on your hand position, as will the volume of the notes.
Once you get the idea, you could send out all sorts of data. Let me know what you come up with. In the next post, I will show you my next experiments in a gloveless arrangement and using midi CC data.
#include <Adafruit_BNO055.h> #include <MIDI.h> MIDI_CREATE_DEFAULT_INSTANCE(); Adafruit_BNO055 bno1 = Adafruit_BNO055(1, 0x28); Adafruit_BNO055 bno2 = Adafruit_BNO055(2, 0x29); // Set the base note and interval const int notes[] = {43, 45, 46, 47, 49}; const int sopNote = 60; const int interval = 7; void setup(void) { Serial.begin(115200); Serial.println("Dual BNO055 and Midi Test"); Serial.println(""); // Begin MIDI usbMIDI.begin(); if(!bno1.begin() || !bno2.begin()) { Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!"); while(1); } } void loop(void) { sensors_event_t event1; bno1.getEvent(&event1); sensors_event_t event2; bno2.getEvent(&event2); // Map the sensor data to MIDI values. The sensor data comes out between -180 and 180 // degreens and is mapped to one of 24 positions - my hands don't twist that much but it // was convenient to do like this. To get one of 5 notes, I took modulo 5 so no other notes // would be produced. Similar for the midi chanels int lhnote = notes[map(int(event2.orientation.x), -180, 180, 0, 24) % 5]; int lhmidiChannel = map(int(event2.orientation.y), -180, 180, 0, 24) % 3 + 1; int rhnote = notes[map(int(event1.orientation.x), -180, 180, 0, 24) % 5] + 12; int rhmidiChannel = map(int(event1.orientation.y), -180, 180, 0, 24) % 3 + 4; int volume = map(event1.orientation.z, -180, 180, 0, 127); // the z axis varies the delay between when notes are played in this loop int tempo = map(event2.orientation.z, -180, 180, 100, 3000); // Calculate the note a fifth apart int lhfifth = lhnote + interval; int rhfifth = rhnote + interval; Serial.print(F("Left: ")); Serial.print(lhnote); Serial.print(F(" ")); Serial.print(lhfifth); Serial.print(F(" ")); Serial.print(lhmidiChannel); Serial.print(F(" Right: ")); Serial.print(rhnote); Serial.print(F(" ")); Serial.print(rhfifth); Serial.print(F(" ")); Serial.print(rhmidiChannel); Serial.print(F(" V: ")); Serial.print(volume); Serial.print(F(" T: ")); Serial.print(tempo); Serial.println(F("")); // Send the notes usbMIDI.sendNoteOn(lhnote, volume, lhmidiChannel); delay(10); // Send the note a fifth apart usbMIDI.sendNoteOn(lhfifth, volume, lhmidiChannel); usbMIDI.sendNoteOn(rhnote, volume, rhmidiChannel); delay(10); // Send the note a fifth apart usbMIDI.sendNoteOn(rhfifth, volume, rhmidiChannel); delay(tempo); // Turn off the note usbMIDI.sendNoteOff(lhnote, 0, lhmidiChannel); delay(10); // Turn off the note a fifth apart usbMIDI.sendNoteOff(lhfifth, 0, lhmidiChannel); delay(10); // Turn off the note usbMIDI.sendNoteOff(rhnote, 0, rhmidiChannel); delay(10); // Turn off the note a fifth apart usbMIDI.sendNoteOff(rhfifth, 0, rhmidiChannel); delay(500); }