Hi there!
I've been playing around with the TouchBoard by Bare Conductive, and I've hit a brickwall. I can seem to get to the MIDI messages. What I'm tying to do is use a proximity sensor and map the proximity for going forward or backward at the jogwheel in Traktor(using CC message 127 and 0 for clockwise and counterclockwise). The code is the following:
/*******************************************************************************
Bare Conductive Touch and Proximity USB MIDI interface
------------------------------------------------------
Midi_interface_generic.ino - USB MIDI touch and proximity example
Allows the mapping of each electrode to a key or control modulator in a
(relatively) simple manner. See the comments for details and experiment
for best results.
Remember to select Bare Conductive Touch Board (USB MIDI, iPad compatible)
in the Tools -> Board menu
Bare Conductive code written by Stefan Dzisiewski-Smith.
This work is licensed under a MIT license https://opensource.org/licenses/MIT
Copyright (c) 2016, Bare Conductive
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*******************************************************************************/
// compiler error handling
#include "Compiler_Errors.h"
#include <MPR121.h>
#include <Wire.h>
#include "Midi_object.h"
uint8_t channel = 1; // edit to change the channel number
#define numElectrodes 12
midi_object_t MIDIobjects[numElectrodes]; // create an array of MIDI objects to use (one for each electrode)
byte pin_jog = 0;
byte min_note = 0; // lowest midi pitch
byte max_note = 127; // highest midi pitch
byte direction_jog = 0; // 0 = highest pitch with touch, 1 = lowest pitch with touch
int nonlinear_jog = -10; // fscale 'curve' param, 0=linear, -10 = max change at large distance
int jog = 0;
int jog_old = 0;
byte note=0;
byte note_old=0;
int min_jog = 1000; // dummy start values - updated during running
int max_jog = 0; // dummy start values - updated during running
float fscale( float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve){
float OriginalRange = 0;
float NewRange = 0;
float zeroRefCurVal = 0;
float normalizedCurVal = 0;
float rangedValue = 0;
boolean invFlag = 0;
// condition curve parameter
// limit range
if (curve > 10) curve = 10;
if (curve < -10) curve = -10;
curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function
/*
Serial.println(curve * 100, DEC); // multply by 100 to preserve resolution
Serial.println();
*/
// Check for out of range inputValues
if (inputValue < originalMin) {
inputValue = originalMin;
}
if (inputValue > originalMax) {
inputValue = originalMax;
}
// Zero Refference the values
OriginalRange = originalMax - originalMin;
if (newEnd > newBegin){
NewRange = newEnd - newBegin;
}
else
{
NewRange = newBegin - newEnd;
invFlag = 1;
}
zeroRefCurVal = inputValue - originalMin;
normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float
/*
Serial.print(OriginalRange, DEC);
Serial.print(" ");
Serial.print(NewRange, DEC);
Serial.print(" ");
Serial.println(zeroRefCurVal, DEC);
Serial.println();
*/
// Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine
if (originalMin > originalMax ) {
return 0;
}
if (invFlag == 0){
rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;
}
else // invert the ranges
{
rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
}
return rangedValue;
}
void controlChange(byte channel, byte control, byte value) {
MIDIEvent event = {0x0B, 0xB0 | channel, control, value};
MIDIUSB.write(event);
}
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
MPR121.begin(0x5C);
MPR121.setInterruptPin(4);
// *************************
// Proximity (CC) electrodes
// *************************
// set up electrode 0 as a proxmity mapped controller attached to controller 102
MIDIobjects[1].type = MIDI_CONTROL;
MIDIobjects[1].controllerNumber = 102; // 102..119 are undefined in the MIDI specification
// start with fresh data
MPR121.updateAll();
}
void loop() {
MPR121.updateFilteredData();
jog_old = jog;
jog = MPR121.getFilteredData(1);
if (jog != jog_old){
// dynamically setup level max and mins
if (jog > max_jog){
max_jog = jog;
}
if (jog < min_jog){
min_jog = jog;
}
}
for(int i=0; i<numElectrodes; i++){
if(MIDIobjects[i].type==MIDI_CONTROL){ // if we have a control type object...
Serial.print("E");
Serial.print(i);
Serial.print(":"); // this prints some Serial debug data for ease of mapping
// e.g. E11:567 means E11 has value 567 (this is the input data)
// output the correctly mapped value from the input
int em3 = fscale(min_jog,max_jog,max_note,min_note,jog,nonlinear_jog);
Serial.println(em3);
if(em3>MIDIobjects[i].lastOutput){ // only output a new controller value if it has changed since last time
controlChange(1, MIDIobjects[i].controllerNumber, 127);
MIDIobjects[i].lastOutput=em3;
}
if(em3<MIDIobjects[i].lastOutput){ // only output a new controller value if it has changed since last time
controlChange(1, MIDIobjects[i].controllerNumber, 0);
MIDIobjects[i].lastOutput=em3;
}
}
// flush USB buffer to ensure all notes are sent
MIDIUSB.flush();
delay(10); // 10ms delay to give the USB MIDI target time to catch up
}
}
Am I missing something? Any suggestions or experiences?