Showing posts with label MIDI. Show all posts
Showing posts with label MIDI. Show all posts

Sunday, May 10, 2026

MPXV7002 as Breath Sensor

Breath sensor made from an MPXV7002 and a silicon tube. The tube has incisions added near the breathing end to allow air to flow through while still building pressure at the sensor end. Enough pressure is still built up within the tube to allow circular breathing if desired. The sensor sends note on / off and continuous control data.

To improve this I might consider a wider tube that is coupled with the sensor or try more or different-sized puncture holes or a 3D printed mouthpiece. However, it still works really well as-is.

Wiring is simple as the sensor outputs an analog voltage and works fine on 3v3 or 5v power supply. The output voltage is rail to rail across the power supply voltage range, and can represent both positive and negative pressure, meaning that the neutral pressure will output at halfway of the voltage supply.

For a Teensy 3.x or 4.x: 3v3 to the 5V pin on the sensor, ground to ground and output of the sensor to Teensy A0 analog input pin.



Here is some code as an example: 


int air_pin = A0;
int air_pressure;
int air_pressure_prev;
int breath_controller = 1;

int threshold = 75;
int play_flag = 0;

int channel = 1;
int pitch = 60;
int velocity = 127;

void setup() {
Serial.begin(57600);
usbMIDI.read();
}

void loop() {
air_pressure = analogRead(air_pin) >> 3;
if(air_pressure != air_pressure_prev) {
air_pressure_prev = air_pressure;
usbMIDI.sendControlChange(breath_controller, air_pressure, channel);
Serial.println(air_pressure);
delay(10);
}

if(air_pressure > threshold && play_flag == 0) {
usbMIDI.sendNoteOn(pitch, velocity, channel);
Serial.println("note on");
play_flag = 1;
}

if(air_pressure < threshold && play_flag == 1) {
usbMIDI.sendNoteOff(pitch, 0, channel);
Serial.println("note off");
play_flag = 0;
}

}


Wednesday, March 08, 2023

Teensy 4.1 with TMP117 Temperature to USB MIDI

Overview

The TMP117 is a high precision temperature sensor with I2C output and can measure between -55˚C to 150˚C. 


Hardware







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




In order to set the correct I2C address for the TMP117 device for this code example, make sure the first bit of the four address bits is set and the rest are cleared. 

Software

The Arduino code uses the Wire library to communicate with the TMP117 via the I2C bus. The TMP117-Arduino library by Nils Minor is required and can be installed via the Arduino IDE. If the temperature changes, the new value is sent as a scaled, simple USB MIDI control change message. 

#include "TMP117.h"

double temp;
int data;
int data_prev;
const int chan = 1;
const int cc = 1;

TMP117 tmp(0x48);

void setup() {
Wire.begin();
Serial.begin(115200);
tmp.init(NULL);
}

void loop() {
temp = tmp.getTemperature();
data = constrain(map(temp, 0.0, 48.0, 0.0, 127.0), 0.0, 127.0);
Serial.println(temp);

if (data != data_prev) {
usbMIDI.sendControlChange(cc, data, chan);
delay(10);
}
}



The temperature can be viewed in Max via this example patch: 






Saturday, February 25, 2023

Teensy 4.1 with GY-521 MPU-6050 Accel / Gyro / Temp to USB MIDI

 Overview

The GY-521 board uses an MPU-6050 IC with an accelerometer, gyroscope and thermometer. An I2C bus is used to communicate with the board using the Teensy 4.1. 


Hardware






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

Software

The Arduino code uses the Wire library to communicate with the GY-521 via the I2C bus. The data from seven registers (accel x, y, z; temperature; gyro x, y, z). If these values change, they are sent as a simple USB MIDI control change message 

#include "Wire.h" // This library allows you to communicate with I2C devices.
const int MPU_ADDR = 0x68; // I2C address of the MPU-6050

int16_t value[7];
const int chan = 1;
const int cc_offset = 0;

void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
}

void loop() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B); // starting with register 0x3B
Wire.endTransmission(false); // active connection
Wire.requestFrom(MPU_ADDR, 7 * 2, true); // request a total of 7*2=14 registers

for (int i = 0; i < 7; i++) {
int16_t data = Wire.read() << 8 | Wire.read();
data = constrain(map(data, -17000, 17000, 0, 127), 0, 127);

if (data != value[i]) {
value[i] = data;
usbMIDI.sendControlChange(i + cc_offset, data, chan);
delay(5);
}
}
}




The data can be seen via a Max patch such as this one. 

Wednesday, June 03, 2020

Simple USB MIDI Keyboard

I needed a simple USB MIDI keyboard, so I made this one with a Teensy 3.6 and some buttons. 

The button values are stored and read via arrays. There is also an octave up and down button. 

Saturday, May 23, 2020

Teensy 3.6 Basics: Receiving MIDI Clock

MIDI clock messages (see System Real-Time Messages) are used to synchronise software or hardware playback transport using MIDI messages. One device sends the clock messages, and another device receives. The device receiving the messages is synchronised to the device that sends the messages.

MIDI clock messages do not carry song position, location or absolute time. Instead, this is transport information for synchronising.

There are four relevant message types - 'start', 'stop', 'continue' and 'clock'. Start and stop are self explanatory - they represent the transport beginning to play and ending to play. Continue represents a transport that is not at the start of the sequence to carry on from the current position. The clock message is sent 24 times per quarter note (a resolution of 24 ppqn). The clock message interval is, of course, depending on the beats-per-minute and can be calculated as (60 / beats-per-minute) / 24 seconds.

Teensy and the Teensyduino add-on can send and receive MIDI clock messages over USB as a USB-compliant MIDI device.

To receive MIDI clock messages on the Teensy, four functions must be written, that correspond with the following:

  • void myClock()
  • void myStart()
  • void myContinue()
  • void myStop()

These functions are created by the user, and each function will only be called when that type of message is received by the Teensy.

In setup(), each function must be connected by name to the message type it should respond to.

  • usbMIDI.setHandleClock(myClock);
  • usbMIDI.setHandleStart(myStart);
  • usbMIDI.setHandleContinue(myContinue);
  • usbMIDI.setHandleStop(myStop);

MIDI clock can be used with Ableton Live to sync the Teensy to the Transport. In Ableton Live, set up the Teensy as a sync output source in the Link MIDI tab in preferences.


When the transport is played in Live, this will then send MIDI clock messages from Live to Teensy. 

Here are three examples of sending MIDI clock messages from Live to Teensy. 



Turn on LED when transport is playing, turn off when transport is stopped







Turn on LED with every beat



View the code here: https://github.com/little-scale/arduino-sketches/blob/master/MIDI_Clock_Receive_2.ino



Two pots generate notes at 1/16ths that are synchronised to Live



View the code here: https://github.com/little-scale/arduino-sketches/blob/master/MIDI_Clock_Receive_3.ino

Teensy 3.6 Basics: Sending MIDI Clock Messages

MIDI clock messages (see System Real-Time Messages) are used to synchronise software or hardware playback transport using MIDI messages. One device sends the clock messages, and another device receives. The device receiving the messages is synchronised to the device that sends the messages.

MIDI clock messages do not carry song position, location or absolute time. Instead, this is transport information for synchronising.

There are four relevant message types - 'start', 'stop', 'continue' and 'clock'. Start and stop are self explanatory - they represent the transport beginning to play and ending to play. Continue represents a transport that is not at the start of the sequence to carry on from the current position. The clock message is sent 24 times per quarter note (a resolution of 24 ppqn). The clock message interval is, of course, depending on the beats-per-minute and can be calculated as (60 / beats-per-minute) / 24 seconds.

Teensy and the Teensyduino add-on can send and receive MIDI clock messages over USB as a USB-compliant MIDI device.

To send MIDI clock messages, four functions are used:

  • usbMIDI.sendRealTime(usbMIDI.Clock);
  • usbMIDI.sendRealTime(usbMIDI.Start);
  • usbMIDI.sendRealTime(usbMIDI.Continue);
  • usbMIDI.sendRealTime(usbMIDI.Stop);


To use a particular function, simple send it at the required point in time.

MIDI clock can be used with Ableton Live to sync the transport to the Teensy. In Ableton Live, set up the Teensy as a sync input source in the Link MIDI tab in preferences. This will enable an EXT button near the BPM. Click on this to enable external sync to the Teensy.




Here are three examples of sending MIDI clock messages from Teensy to Live. 



Sending Start and Clock



View code here: https://github.com/little-scale/arduino-sketches/blob/master/MIDI_Clock_Send_1.ino



Sending Tempo Based on Potentiometer



View code here: https://github.com/little-scale/arduino-sketches/blob/master/MIDI_Clock_Send_2.ino



Sending Tempo Based on Potentiometer, with a Button for Start and Stop




Friday, June 08, 2018

Eurorack Patch Examples of Sequencing, LFOs and MIDI Control

Here are a few examples of patches and modules I've been making lately.















Tuesday, November 07, 2017

MIDI Data Over UDP Via OSC Using An ESP8266



This is a simple example of sending MIDI data over UDP via OSC using an ESP8266. The ESP is programmed using the Arduino IDE. The Arduino ESP8266 Arduino Core is used alongside the WiFi UDP library and the OSC library for Arduino. A Max for Live UDP OSC Packet to MIDI message device receives the data within Live.

The button is pressed. The change in state (either high or low) is read by the ESP8266. A note on message is formatted, with MIDI channel 1, note 60 and a velocity that is either 127 or 0 depending on the state of the button. These three bytes are then wrapped up in an OSC message with the name "MIDI", and sent via UDP. One MIDI message is sent per OSC message, and one OSC message is sent per UPD packet.



Download the code here: http://milkcrate.com.au/_other/downloads/arduino/ESP8266_UDP_OSC_MIDI.ino

Tuesday, April 11, 2017

Teensy 3.6 Basics: MIDI Sequencing

Overview
The Teensy 3.6 can read the values from up to 25 potentiometers without any additional hardware.

By combining multiple potentiometers, and then reading each one after the other, a basic MIDI sequencer can be constructed. Each pot represents a note (for example, pitch) - but additional pots could also represent velocity and interval.

Many considerations can be made in regards to how one or more pots are read, in which order, what scaling, what each pot represents and so on.

Here are some simple examples exploring different combinations.


Teensy 4.1 Note: You can adapt many of these examples to work with 4 or 5 pots. Also, Teensy 4.1 only appears to be able to have a analogReadResolution of 8, 10 or 12 bits so adjust this code accordingly by multiplying or dividing. 





Hardware Setup
Eight pots are connected to analog inputs 0 - 7. The outside legs of the pots are connected to 3.3V and ground.







Example 1 - Basic Sequencing
The eight pots represent eight notes. Each pot sets the pitch value of a note. Each note is played one after the other. The velocity and time interval are static, and set as part of the code.



Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/MIDI_Sequencing_Example_1/







Example 2 - Sequencing with Step Enable and Time Interval Control

Another pot is added. The first eight pots set the pitch values of notes. Each note is played one after the other. The velocity is static, and set as part of the code. The time interval is set by the ninth pot. If a given pot is all the way at minimum, then that particular step is disabled.












Example 3 - Pitch and Velocity Control
Nine pots control a total of four notes. The first four  pots control pitch. The next four pots control velocity. The last controls the time interval for all notes. 








Example 4 - Pitch, Velocity and Time Interval Control
Nine pots control a total of three notes. The first three pots control the pitches. The next three pots control the velocities. The last three pots control the time intervals. 









Example 5 - Pitch and Interval are Out of Phase
Nine pots in total. The first four pots control pitch. The last five pots control time interval. These two parameters combine to form notes. The pitch and time interval are out of phase with one another, thereby forming a pattern of twenty notes that repeat by combining the possibilities of pitch / time interval pairs. 



Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/MIDI_Sequencing_Example_5/






Summary
The Teensy 3.6 can be used to create a simple MIDI sequencer. Many pots can be read in different ways and orders, and mapped to note parameters in different ways - making lots of different possibilities. 

Teensy 3.6 Basics: Using Rotary Encoders

Overview
A rotary encoder, although looking similar to a potentiometer, is actually a pair of mechanical connections that are closed and then opened in a particular order and timing depending on the direction and speed that the connecting shaft is rotated.

Furthermore, an encoder (unlike a potentiometer) does not have a maximum and minimum excursion, making it ideal for contextual values, delta data points, and parameters that need accurate adjustment beyond a finite number of turns.

As a result, the output of an encoder can be read and interpreted to give direction (left or right) as well as some sense of speed of turning, in combination with limitless rotations.

The Teensy has a great library for using the encoder, which is part of the Teensyduino installation. More information about the library and its use can be found here: https://www.pjrc.com/teensy/td_libs_Encoder.html.

An encoder can make for a useful MIDI control.



Hardware Setup
To begin with a single encoder is connected to digital pins 25 and 26. The middle leg of the encoder is connected to ground.





Example 1 - Reading the Value of One Encoder
In this example, an encoder object is created, using digital pins 25 and 26. The value of the encoder is read and compared to the previous reading. If the value of the reading has changed compared to the previous reading, then the value is sent to the Serial Monitor.

No constraints are set on reading the value of the encoder, and so there is no limit on the reading when turning the encoder left or right.




Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/Using_Encoders_Example_1/






Example 2 - Reading the Value of One Encoder, and Send as MIDI Continuous Control Message
In this example, an encoder object is created, using digital pins 25 and 26. The value of the encoder is read and compared to the previous reading. If the value of the reading has changed compared to the previous reading, then the value is sent as a MIDI continuous control message

The value is constrained to the range 0 - 127, so turning the encoder beyond 127 or below 0 will have no effect.



Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/Using_Encoders_Example_2/






Example 3 - Reading the Value of Two Encoders, and Send as MIDI Continuous Control Messages
In this example, two encoder object are created, using digital pins 25 - 28. The value of the encoders are read and compared to previous readings. If the value of a reading has changed compared to the previous reading, then the value is sent as a MIDI continuous control message. Each encoder has a separate controller number.


The values are constrained to the range 0 - 127, so turning the encoders beyond 127 or below 0 will have no effect.




Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/Using_Encoders_Example_3/






Example 4 - Four Encoders Plus One Button as Bank of Switchable MIDI Controllers
In this example, four encoders are used alongside a button. The button switches between four different banks. Each bank is represented by the four physical encoders. Each bank has unique, four MIDI controller numbers, thereby having a total of sixteen MIDI controllers.

All values are stored as the banks are switched.






Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/Using_Encoders_Example_4/






Summary
Encoders can be used in addition to buttons and switches for controlling parameters. The limitless rotation can be used in different contexts than a standard potentiometer.

Monday, March 27, 2017

Teensy 3.6 Basics: Sending Pitchbends

Overview
The Teensy can send many types of MIDI data of USB, including pitchbends. MIDI pitchbend data has a resolution of 14 bits, which covers the range of 0 - 16383. This is far higher than continuous controller data, which has a range of 0 - 127 with 7 bits.

As such, the pitchbend messages are useful when requiring a higher degree of control.

Teensy 4.1 Note: You may need to set analogReadResolution() to 12 bits and then multiply the analogRead() value by 4 in order for this code to work correctly. 





Hardware Setup
In this example, a potentiometer is connected to analog input 0. A push button is connected to digital pin 32.









Example 1 - Sending Pitchbend Data
In this example, the pitchbend value is sent based on the potentiometer and the push button sends note on / note off messages.

Note the use of analogReadResolution to set the range to 14 bits (0 - 16383), and analogReadAveraging to smooth out the data values by averaging 32 samples.

The pitchbend function, usbMIDI.sendPitchBend() takes the argument of value and channel, where value is an int in the range of 0 - 16383.






Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/Sending_Pitchbends_Example_1/









Summary
If a higher resolution of MIDI control is required, sending pitch bend data may be a suitable solution.

Teensy 3.6 Basics: Sending MIDI Continuous Control

Overview
The Teensy can send MIDI data over USB. This include sending MIDI note on and note off events. Built-in functions make sending MIDI data simple. A summary of Teensy MIDI message types that can be sent over USB can be found here.

Teensy 4.1 Note: You may need to set analogReadResolution() to 8 bits and then divide the analogRead() value by 2 in order for this code to work correctly. 




Hardware Setup
A potentiometer is connected to 3.3V, ground and analog input 0.









Software Setup
The analogRead() function is used to measure a voltage at an analog input. The analogReadResolution() function is used to set the range of the reading value to 0 - 127. The usbMIDI.sendControlChange() function is used to send a MIDI continuous control message via USB.

The order of arguments for the usbMIDI.sendControlChange() are control number, control value, MIDI channel.

The DAW that receives the controller data must be set up to see the Teensy as a control input.







Example 1 - Sending the Value of One Potentiometer as a Continuous Control Message
In this example, the aim is to read the value of a potentiometer and, if the value has changed compared to the previous reading, send the new value as a MIDI control message.





Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/Sending_MIDI_Continuous_Control_Example_1/







Example 2 - Sending the Value of Two Potentiometers as Continuous Control Messages
In this example, the aim is to read the value of two potentiometers and, if a value has changed compared to the previous reading, send the new value as a MIDI control message. The two potentiometers are completely separate.







Download here: http://milkcrate.com.au/_other/downloads/arduino/teensy_3_6_basics/Sending_MIDI_Continuous_Control_Example_2/





Summary
The Teensy can easily send continuous controller messages using the USB MIDI functions.