Closed NikolajRFA closed 6 years ago
As mentioned in the ReadMe, you have to install the Encoder library (even if you don't use it, because of the way C++ handles dependencies). You shouldn't have to add it at the top of your sketch, however.
Are you sure that FL Studio supports Pitch Bend messages as controls? Have you tried the potentiometer example? It uses Control Change events (which are more widely supported).
The MIDI data works fine, my problem is that the Arduino sends duplicate values over MIDI and I would like it to only send one value... I find the potentiometer example to do this, but it is filled with noise and it is jumping back and forth a value.
That's rather strange, the running average work just fine for me, it does a great job at eliminating the noise.
AnalogHiRes sending duplicate values is weird as well: https://github.com/tttapa/MIDI_controller/blob/ff983c5c470464edab95af5033ec6f65c6ce47ba/src/MIDI_Outputs/AnalogHiRes.cpp#L20
What kind of duplicate values are you getting? Did you use a MIDI monitor?
turns out the midi data is just flickering and thereforeit is sending constant messages when i am using the "HiRes-Potentiometer" example. Is there anyway i can use the library to send a variable value so i can use a library i found to send the values?
I see the code you send me isen't the same as i am using... And i can't get i to work because im missing "analogHiRes.h"
The code I sent was a snippet from the source code. You don't have to use it yourself. Do you want to use ResponsiveAnalogRead? In that case, you can easily extend the Analog and AnalogHiRes classes with variants that use that as an alternative to a simple running average. If I find the time, I'll write you an example.
that would be nice as i don't know how to extend the classes, i have only been in the Arduino game for a month or so.
Untested! Put all three files in the same folder (with the same name as Main.ino).
#include <MIDI_Controller.h> // Include the library
#include "AnalogHiResResponsive.h"
// Create a new instance of the class 'AnalogHiResResponsive', called 'potentiometer', on pin A0,
// that sends MIDI Pitch Bend messages on channel 1
AnalogHiResResponsive potentiometer(A0, 1);
void setup() {}
void loop() {
// Refresh the MIDI controller (check whether the potentiometer's input has changed since last time, if so, send the new value over MIDI)
MIDI_Controller.refresh();
}
#ifndef AnalogHiResResponsive_h_
#define AnalogHiResResponsive_h_
#include "Arduino.h"
#include "MIDI_Controller.h"
#include <ResponsiveAnalogRead.h>
class AnalogHiResResponsive : public MIDI_Control_Element
{
public:
AnalogHiResResponsive(pin_t analogPin, uint8_t channel); // Constructor
void map(int (*fn)(int)); // Change the function pointer for analogMap to a new function. It will be applied to the raw analog input value in Analog::refresh()
private:
void refresh(); // Read the analog input value, update the average, map it to a MIDI value, check if it changed since last time, if so, send Pitch Bend message over MIDI
ResponsiveAnalogRead respAnalog = {0, true};
pin_t analogPin;
uint8_t channel;
int (*analogMap)(int) = identity; // function pointer to identity function f(x) → x
static int identity(int x) { // identity function f(x) → x
return x;
}
};
#endif // AnalogHiResResponsive_h_
#include "AnalogHiResResponsive.h"
AnalogHiResResponsive::AnalogHiResResponsive(pin_t analogPin, uint8_t channel) // Constructor
: analogPin(analogPin), channel(channel) {}
void AnalogHiResResponsive::refresh() // read the analog value, update the average, map it to a MIDI value, check if it changed since last time, if so, send Pitch Bend message over MIDI
{
ExtIO::analogRead(analogPin); // throw away first analog reading
analog_t input = ExtIO::analogRead(analogPin);
uint16_t value = analogMap(input); // apply the analogMap function to the value (identity function f(x) = x by default)
respAnalog.update(value); // update the responsive analog average
if (respAnalog.hasChanged()) // if the value changed since last time
{
value = respAnalog.getValue(); // get the responsive analog average value
value = value << 4; // make it a 14-bit number (pad with 4 zeros)
MIDI_Controller.MIDI()->send(PITCH_BEND, channel + channelOffset * channelsPerBank, value, value >> 7); // send a Pitch Bend MIDI event
}
}
void AnalogHiResResponsive::map(int (*fn)(int)) { // change the function pointer for analogMap to a new function. It will be applied to the raw analog input value in refresh()
analogMap = fn;
}
I just copied the AnalogHiRes.h and AnalogHiRes.cpp source files from the library, renamed the class, changed the includes, deleted the running average functions and variables, added ResponsiveAnalogRead and edited the refresh function to use the responsive analog read average instead of the running average.
This works really good. Now i just need to figure out how to program the rest of the controller... How will this AnalogHiResResponsive work? do i just add that library together with the MIDI_Controller library to get the "AnalogHiResResponsive"?
also. How do i adjust it to send messages on other channels not just the pitchbend?
You don't have to add anything to the library, after you include the header files, you can just use it like the other parts of the library.
You can do the same thing for the Analog class if you need to. What do you need for the rest of the controller?
I wanted to pu a couple of extra potentiometers on and some buttons
You can add multiple potentiometers by using arrays:
AnalogHiResResponsive potentiometers[] = {
{A0, 1},
{A1, 2},
{A3, 3},
// etc.
};
For adding buttons, take a look at the buttons example.
ohh i see, i will try that.
i still dont know how to send data over other channels than Pitch Bend.
That's what the Analog class is for. It sends the data as Control Change events. You can use it as is (works great for me, YMMV), or you can create a new class that uses the ResponsiveAnalogRead.
Everything should be in the documentation. If you think something is missing, or not clear enough, feel free to let me know :)
im glad you are helping with this, as i still am reallybad coding the arduino.
also... what does that "uint8_t" do i am seeing it everywhere that MIDI and arduino is mentioned
It is a data type. It's an unsigned integer (uint) of 8 bits wide. This means that it can store any value between 0 and 255 (=2^8-1).
It's used here because MIDI packets are constructed of multiple of these 8-bit bytes.
i see
I can't really get it to work by using your library and code... But i tried writing a piece of code with my current knowladge and a bit of googeling, only using the "ResponsiveAnalogRead" and the "MIDIUSB" libraries, and this works
Here is the code if interested.
#include <ResponsiveAnalogRead.h>
#include "MIDIUSB.h"
int val = 0;
int lastVal = 0;
const int Pot = A0;
ResponsiveAnalogRead PotRead(Pot, true);
void setup() {
Serial.begin(115200);
}
void loop() {
PotRead.update();
val = PotRead.getValue()/8;
midiEventPacket_t event = {0x0B, 0xB0 | 0, 104, val};
if(val != lastVal)
{MidiUSB.sendMIDI(event);
MidiUSB.flush();}
lastVal = val;
}
I have no idea why your library won't work (probably because i am really bad at coding) the code would probably be better if I could get your library to work...
Here's what a MIDI controller with potentiometers and buttons would look like using the library:
#include <MIDI_Controller.h> // Include the library
#include "AnalogHiResResponsive.h"
AnalogHiResResponsive hiResPotentiometers[] = { // 10-bit Pitch Bends
{A0, 1}, // pin A0, MIDI channel 1
{A1, 2},
{A2, 3},
{A3, 4},
};
Analog potentiometers[] = { // 7-bit Control Change
{A4, 0x20, 1}, // pin A4, controller 0x20, MIDI channel 1
{A5, 0x21, 1},
};
Digital buttons[] = { // Note On / Off
{2, 0x3C, 1}, // pin 2, note 0x3C (middle C), MIDI channel 1
{3, 0x3D, 1},
{4, 0x3E, 1},
{5, 0x3F, 1},
};
void setup() {}
void loop() {
MIDI_Controller.refresh();
}
You need to have the files "AnalogHiResResponsive.cpp" and "AnalogHiResResponsive.h" in the same folder (press CTRL+SHIFT+N in the IDE, enter the filename "AnalogHiResResponsive.cpp", then paste the code there and save, same for "AnalogHiResResponsive.h").
The codes is sendinf pitch bend messages together with my other midi messages when i am turning the potentiometers
Correct.
If you want 10-bit resolution, you have to use pitch bends (AnalogHiRes
and AnalogHiResResponsive
). If 7 bit is enough (in most cases it is), you can use control change (Analog
). The potentiometers on analog pins A0-A3 send pitch bend messages, the potentiometers connected to pins A4-A5 send control change messages. It's up to you to decide which ones you'd like to use. You can make all of them control change, make all of them pitch bends, or mix and match. You don't have to use pitch bends if you don't want to.
You can add as many potentiometers and buttons to the arrays as you'd like, and you can decide what controller numbers, note numbers, MIDI channels ... they use.
after fiddeling a bit with it i have gotten it to work with the stadart "MIDIUSB" library. FL Studio can't reassign pitchbend messages to control other parameters, which i would have needed for it to have worked.
anyways, thanks for the help.
I think I experienced what this user was talking about. In the examples the channels are different and the CC# is the same. There was crosstalk and the knobs were shaky. When each knob is given its own CC# they become nice and smooth.
/*
This is an example of the "Analog" class of the MIDI_controller library.
Connect a potentiometer to analog pin A0. This will be the MIDI channel volume of channel 1.
Map it in your DAW or DJ software.
Written by Pieter P, 08-09-2017
https://github.com/tttapa/MIDI_controller
*/
#include <MIDI_Controller.h> // Include the library
// Create a new instance of the class 'Analog', called 'potentiometer', on pin A0,
// that sends MIDI messages with controller 7 (channel volume) on channel 1
Analog potentiometer_A(A0, MIDI_CC::Sound_Controller_1, 1);
Analog potentiometer_B(A1, MIDI_CC::Sound_Controller_2, 1);
Analog potentiometer_C(A2, MIDI_CC::Sound_Controller_3, 1);
Analog potentiometer_D(A3, MIDI_CC::Sound_Controller_4, 1);
Analog potentiometer_E(A4, MIDI_CC::Sound_Controller_5, 1);
void setup() {}
void loop() {
// Refresh the MIDI controller (check whether the potentiometer's input has changed since last time, if so, send the new value over MIDI)
MIDI_Controller.refresh();
}
The master
version has significantly improved filtering on the potentiometer inputs. I don't have the time to release it, because updating the documentation takes a lot of work, and I have to level it with the Control Surface
library first, but you could consider it as stable for now (1ecbd2c86e2268b36391db0ae5a5390cdbe90b8a).
You can try git checkout origin/master
, or download the master files manually.
By the way, instead of:
Analog potentiometer_A(A0, MIDI_CC::Sound_Controller_1, 1);
Analog potentiometer_B(A1, MIDI_CC::Sound_Controller_2, 1);
Analog potentiometer_C(A2, MIDI_CC::Sound_Controller_3, 1);
Analog potentiometer_D(A3, MIDI_CC::Sound_Controller_4, 1);
Analog potentiometer_E(A4, MIDI_CC::Sound_Controller_5, 1);
You can do:
Analog potentiometers[] = {
{A0, MIDI_CC::Sound_Controller_1, 1},
{A1, MIDI_CC::Sound_Controller_2, 1},
{A2, MIDI_CC::Sound_Controller_3, 1},
{A3, MIDI_CC::Sound_Controller_4, 1},
{A4, MIDI_CC::Sound_Controller_5, 1},
};
"You can try git checkout origin/master, or download the master files manually."
How exactly do I do that? This is my first project.
When installing the library, you downloaded a ZIP file from the releases page. Now, instead of using the ZIP from the releases page, download the ZIP from the main page: Make sure to delete the old version before you install the new one.
Having problems with smoothing a potentiometer, when choosing the hires potentiometer exampe i get signal but it seems rather constant... and i really want single values so i dont loose midi info.
I also had to manually include som librarys it couldn't find when i was trying to compile the code. I dont know why this problem keeps happening. Could it be because i dont have the librarys installed in the default folders.
1 pot
Arduino Leonardo
Schematic: ?
Software versions:
MIDI Controller library: 3.0.0
Arduino IDE: ? 1.8.5
Operating System: Windows Operating System version: 10 (Teensyduino): ? 1.40 ? (Encoder library): Where do i find this? (MIDIUSB library): Where do i find this?
Settings in the IDE
Full code
i pretty much just put in the encoder library manually as i was getting errors saying that it couldn't find it.
i want to make a MIDI controller to control my DAW (FL Studio).