I realise there are various posts about this, but none that I have searched that have the solution as various apps are now out of date for mac.
I'm using a mac, arduino leo, ableton
I have Ableton recognising Leo as a midi controller, however, no midi messages are coming through.
I have soldered the adafruit mpr121 sheild onto the leo and the example test works well, everytime I touch the sensor it recognises it in arduino with the test sketch they have.
So the problem I have is converting these touch sensors into midi messages. I just need the touch to send two messages, on/off for 12 sensors.
Ableton recognises the leo as a midi device. But I don't know how to set up the MPR121 to send Midi. I went down some rabbit hole about serial to midi (hairless no longer available), I did find one java program called serial midi
The serialmidibridge isn't really giving any feedback as to whether what I'm doing is correct.
I've armed 'remote' and 'tracking' for all my midi devices, including leonardo. Still no midi notes are recognised in ableton. I'm not sure whether to put midi in as 'leonardo' or 'IAC bus 1', to which leonardo is theoretically being converted from serial to midi.
So as far as I see it I have two problems
Is ableton recognising Leonardo as a midi controller with the 'serialmidibridge', if yes...then the next problem is
are the touch sensors of the mpr121 being converted into midi?
I'm new to arduino, so I'm just using the test code they have provided and sketch - include library - midusb. I don't know if this is the right or wrong way.
Well the good news is, ableton is recognising midi from the arduino. Bad news is, that it's on a loop. Obviously, I don't want a note on/off cycle, but to turn notes on/off with touch sensor mpr121.
Proving a headache. I was hoping to create something similar ot the playtronica, but the continuous glitches with this makes me feel quite uncomfortable using this in a live performace!
Well how about you start by posting the code you have to do that within the code tag, so we can actually read it. i'm sure it's nothing complex, but still we can help you better when we see what you have done and what works.
So how have yo wired that up. Please show us a (hand)drawn schematic.
A very simple test would be to turn the internal LED on the leonardo on and off using it. Get that to work first.
#include <MIDIUSB.h>
#include <MIDIUSB_Defs.h>
#include <frequencyToNote.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>
/*********************************************************
This is a library for the MPR121 12-channel Capacitive touch sensor
Designed specifically to work with the MPR121 Breakout in the Adafruit shop
----> https://www.adafruit.com/products/
These sensors use I2C communicate, at least 2 pins are required
to interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
**********************************************************/
#include <Wire.h>
#include "Adafruit_MPR121.h"
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif
// You can have up to 4 on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap = Adafruit_MPR121();
// Keeps track of the last pins touched
// so we know when buttons are 'released'
uint16_t lasttouched = 0;
uint16_t currtouched = 0;
void setup() {
Serial.begin(9600);
while (!Serial) { // needed to keep leonardo/micro from starting too fast!
delay(10);
}
Serial.println("Adafruit MPR121 Capacitive Touch sensor test");
// Default address is 0x5A, if tied to 3.3V its 0x5B
// If tied to SDA its 0x5C and if SCL then 0x5D
if (!cap.begin(0x5A)) {
Serial.println("MPR121 not found, check wiring?");
while (1);
}
Serial.println("MPR121 found!");
}
void loop() {
// Get the currently touched pads
currtouched = cap.touched();
for (uint8_t i=0; i<12; i++) {
// it if *is* touched and *wasnt* touched before, alert!
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" touched");
}
// if it *was* touched and now *isnt*, alert!
if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" released");
}
}
// reset our state
lasttouched = currtouched;
// comment out this line for detailed data from the sensor!
return;
// debugging info, what
Serial.print("\t\t\t\t\t\t\t\t\t\t\t\t\t 0x"); Serial.println(cap.touched(), HEX);
Serial.print("Filt: ");
for (uint8_t i=0; i<12; i++) {
Serial.print(cap.filteredData(i)); Serial.print("\t");
}
Serial.println();
Serial.print("Base: ");
for (uint8_t i=0; i<12; i++) {
Serial.print(cap.baselineData(i)); Serial.print("\t");
}
Serial.println();
// put a delay so it isn't overwhelming
delay(100);
}
Wiring is pretty simple ... The Adafruit shield sits directly ontop of the arduino leo and all header pins are soldered. No other fancy wiring.
I can see through the code serial terminal that it is wired correctly, because when I touch the sensors it gives me an on/off message for each of the sensors.
My problem is translating these on/off to midi notes that are recognised in my DAW.
I don't have a touch shield so this code is a shot in the dark.
#include <USB-MIDI.h>
USBMIDI_CREATE_DEFAULT_INSTANCE();
#define BASE_NOTE 60
/*********************************************************
This is a library for the MPR121 12-channel Capacitive touch sensor
Designed specifically to work with the MPR121 Breakout in the Adafruit shop
----> https://www.adafruit.com/products/
These sensors use I2C communicate, at least 2 pins are required
to interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
**********************************************************/
#include <Wire.h>
#include "Adafruit_MPR121.h"
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif
// You can have up to 4 on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap = Adafruit_MPR121();
// Keeps track of the last pins touched
// so we know when buttons are 'released'
uint16_t lasttouched = 0;
uint16_t currtouched = 0;
void setup() {
Serial.begin(115200);
while (!Serial) { // needed to keep leonardo/micro from starting too fast!
delay(10);
}
Serial.println("Adafruit MPR121 Capacitive Touch sensor test");
// Default address is 0x5A, if tied to 3.3V its 0x5B
// If tied to SDA its 0x5C and if SCL then 0x5D
if (!cap.begin(0x5A)) {
Serial.println("MPR121 not found, check wiring?");
while (1);
}
Serial.println("MPR121 found!");
// Turn off software MIDI through
MIDI.turnThruOff();
// Initiate MIDI communications, listen to all channels
MIDI.begin(MIDI_CHANNEL_OMNI);
}
void loop() {
// Call MIDI.read the fastest you can for real-time performance.
// No callbacks are defined so this discards incoming MIDI.
MIDI.read();
// Get the currently touched pads
currtouched = cap.touched();
for (uint8_t i=0; i<12; i++) {
// it if *is* touched and *wasnt* touched before, alert!
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" touched");
MIDI.sendNoteOn(BASE_NOTE + i, 127, 1);
}
// if it *was* touched and now *isnt*, alert!
if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" released");
MIDI.sendNoteOff(BASE_NOTE + i, 0, 1);
}
}
// reset our state
lasttouched = currtouched;
}
The sketch that you are using for that is still not there, but i am going to assume it is something like this
/*
* MIDIUSB_test.ino
*
* Created: 4/6/2015 10:47:08 AM
* Author: gurbrinder grewal
* Modified by Arduino LLC (2015)
*/
#include "MIDIUSB.h"
// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}
void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}
void setup() {
Serial.begin(115200);
}
// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).
void controlChange(byte channel, byte control, byte value) {
midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
MidiUSB.sendMIDI(event);
}
void loop() {
Serial.println("Sending note on");
noteOn(0, 48, 64); // Channel 0, middle C, normal velocity
MidiUSB.flush();
delay(500);
Serial.println("Sending note off");
noteOff(0, 48, 64); // Channel 0, middle C, normal velocity
MidiUSB.flush();
delay(1500);
// controlChange(0, 10, 65); // Set the value of controller 10 on channel 0 to 65
}
now the idea is to combine the 2 code so that instead of sending a serial message, a midi message is sent.
#include "MIDIUSB.h"
#include <MIDIUSB_Defs.h>
#include <frequencyToNote.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>
#include <Wire.h>
#include "Adafruit_MPR121.h"
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif
Adafruit_MPR121 cap = Adafruit_MPR121();
uint16_t lasttouched = 0;
uint16_t currtouched = 0;
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}
void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}
void controlChange(byte channel, byte control, byte value) {
midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
MidiUSB.sendMIDI(event);
}
void setup() {
if (!cap.begin(0x5A)) {
Serial.println("MPR121 not found, check wiring?");
while (1);
}
Serial.println("MPR121 found!");
}
void loop() {
currtouched = cap.touched();
for (uint8_t i = 0; i < 12; i++) {
// it if *is* touched and *wasnt* touched before, alert!
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
//Serial.print(i); Serial.println(" touched");
noteOn(0, 48 + i, 64);
}
// if it *was* touched and now *isnt*, alert!
if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
//Serial.print(i); Serial.println(" released");
noteOff(0, 48 + i, 64);
}
}
if (lasttouched != currtouched) {
lasttouched = currtouched;
MidiUSB.flush();
delay(20); // to not flood the DAW with messages in case the sensor is over-sensitive
}
}
So something like this. I can't test it fully, i don't have the sensors, but it does compile.