Open davidgauze opened 4 years ago
working with grandMA2 lighting software
You could use something like this:
#include <Control_Surface.h>
struct ContinuousNoteSender {
void send(uint8_t value, MIDIAddress address) {
Control_Surface.sendNoteOn(address, value);
}
static constexpr uint8_t precision() { return 7; }
};
struct NotePotentiometer : MIDIFilteredAnalogAddressable<ContinuousNoteSender> {
NotePotentiometer(pin_t analogPin, MIDIAddress address)
: MIDIFilteredAnalogAddressable(analogPin, address, {}) {}
};
USBMIDI_Interface midi;
using namespace MIDI_Notes;
NotePotentiometer pots[] = {
{A0, note(C, 4)},
{A1, note(Db, 4)},
{A2, note(D, 4)},
{A3, note(Eb, 4)},
};
void setup() {
Control_Surface.begin();
}
void loop() {
Control_Surface.loop();
}
hello, it didn't work. could write using midi controller library ? use it but fader send crontrol change and not midi
What doesn't work? Please be more specific. As far as I can see, the code I posted does what you asked for.
When turning the potentiometer, it sends MIDI Note events with the velocity representing the potentiometer position:
could write using midi controller library?
What do you mean? The MIDI Controller library is no longer supported and has no built-in support for these kinds of things.
I'm using arduino UNO, it keeps oscillating values and doesn't recognize, I converted using hyduino and firmaware also didn't work
I converted using midi hairless and midi loop but does not send a note is showing infinite values
What makes you think grandMA2 supports MIDI note input for potentiometers? As far as I can see, it only supports MSC: http://help2.malighting.com/Page/grandMA2/remote_control_msc/en/3.9
You'll have to figure out the required MIDI messages before trying it out with an Arduino.
If the values oscillate, this probably means the resistance of the potentiometers you're using is too high, or there's something wrong with your power supply or wiring.
even note on what you recognize, use bome midi translation to convert control change
this and another controller that I set up sends control change ai use software to convert it into note on
For when the fader increases, only the value changes, note that it remains the same
I don't understand. Why would the note change?
as shown in photo V would have to vary from 0 to 127. C is channel and p = it has to change 0 and 1 and n = it has to be a fixed note
MIDI Remote The MIDI Remotes tab used received MIDI notes as the input. There are two special columns in this tab. They are called Note and Channel. These are used to set the MIDI note and channel.
If the Type is set to Exec and the Button is set to Fader, then the velocity of the MIDI note is used to set the position of the executor fader. All other inputs are simple triggers.
The code I posted yesterday changes the velocity of a fixed note.
I'm using 1 fader only, I delete the others from the code. should that be a problem?
No, that shouldn't be a problem.
What is the exact issue you have right now?
+5.75 - Warning: got a status byte when we were expecting 2 more data bytes, sending possibly incomplete MIDI message 0x80
value does not change it always remains
Are you using HairlessMIDI_Interface
or USBMIDI_Interface
? What baud rate are you using in Hairless? If you modified the code I posted, please include the full sketch.
USBMIDI_Interface
I haven't changed anything this same thing this USBMIDI_Interface
If you're using an Arduino Uno, USBMIDI_Interface
only works with the right firmware. If you're using Hairless MIDI, you have to use the HairlessMIDI_Interface
.
got it not low value of 60 now. minimum is 60 and maximum is 127
The note number should be 60 (0x3C) and the velocity should vary between 0 and 127 (0x7F).
If the velocity value doesn't go all the way to zero, there's probably a problem with the wiring of the potentiometer.
I got a friend, thank you very much. question of encoder can I send note on too? I will complement my midi with 16 fader and 45 button and 3 encoder as I do
Sure, encoders can be made to send notes, but grandMA2 has to know how to interpret it.
Once you know what type of messages it expects for encoders, you can simply turn this into a MIDI Sender
and use it with the Control Surface library, like the example code for note potentiometers I posted.
yes it works through midi on, example when turning left sends a note and when turning right sends another note you know? so I did another media
Then all you have to do is write your own RelativeNoteSender
class with a send(long delta, MIDIAddress address)
function.
You can see how it's done for normal encoders here: https://github.com/tttapa/Control-Surface/blob/367730b4cfdd36adc4c61cf2b56e56f60e4c625b/src/MIDI_Senders/RelativeCCSender.hpp#L93-L103
thank you very much for now, i am very grateful, i hope to get here and send me an account for tipped tip as a way to help because rare people in the world like you are difficult
friend encoder note for example, error in the sketches that trying to neither accept note together
I don't understand what you mean. If you want help with a sketch, please post your code.
I want to make my encoder send note on, I tried more I couldn't do it
#include <Encoder.h> // Include the Encoder library.
// This must be done before the Control Surface library.
#include <Control_Surface.h> // Include the Control Surface library
struct ContinuousNoteSender {
void send(uint8_t value, MIDIAddress address) {
Control_Surface.sendNoteOn(address, value);
}
static constexpr uint8_t precision() { return 7; }
};
struct NotePotentiometer : MIDIFilteredAnalogAddressable<ContinuousNoteSender> {
NotePotentiometer(pin_t analogPin, MIDIAddress address)
: MIDIFilteredAnalogAddressable(analogPin, address, {}) {}
};
// Instantiate a MIDI over USB interface.
USBMIDI_Interface midi;
// Instantiate a CCRotaryEncoder object
CCRotaryEncoder enc = {
{2, 3}, // pins
NoteOn::0x1, // MIDI address (CC number + optional channel)
1, // optional multiplier if the control isn't fast enough
};
void setup() {
// Select the correct relative MIDI CC mode.
// Options:
// - TWOS_COMPLEMENT (default)
// - BINARY_OFFSET
// - SIGN_MAGNITUDE
// Aliases:
// - REAPER_RELATIVE_1
// - REAPER_RELATIVE_2
// - REAPER_RELATIVE_3
// - TRACKTION_RELATIVE
// - MACKIE_CONTROL_RELATIVE
RelativeCCSender::setMode(relativeCCmode::MACKIE_CONTROL_RELATIVE);
Control_Surface.begin(); // Initialize Control Surface
}
void loop() {
Control_Surface.loop(); // Update the Control Surface
}
This could be a starting point:
#include <Encoder.h> // Include the Encoder library.
// This must be done before the Control Surface library.
#include <Control_Surface.h> // Include the Control Surface library
struct RelativeNoteSender {
static void send(int delta, MIDIAddress address) {
delta = constrain(delta, -127, 127);
if (delta > 0) {
Control_Surface.sendNoteOn(address, delta);
// Send whatever your software expects
} else {
Control_Surface.sendNoteOn(address + 1 /* ??? */, -delta);
// Send whatever your software expects
}
}
};
struct NoteEncoder : MIDIRotaryEncoder<RelativeNoteSender> {
NoteEncoder(EncoderPinList pins, MIDIAddress address)
: MIDIRotaryEncoder(pins, address, 1, 4, {}) {}
};
// Instantiate a MIDI over USB interface.
USBMIDI_Interface midi;
NoteEncoder enc = {
{2, 3}, // pins
0x01, // MIDI address (note number + optional channel)
};
void setup() {
Control_Surface.begin(); // Initialize Control Surface
}
void loop() {
Control_Surface.loop(); // Update the Control Surface
}
I have no idea how your software implements relative note messages, so you'll have to provide your own implementation for the send function.
friend I can't add more encoder where I change to add because button and fader works well wanted by 3 encoder sorry to bother you
#include <Encoder.h> // Include the Encoder library.
// This must be done before the Control Surface library.
#include <Control_Surface.h> // Include the Control Surface library
const int speedMultiply = 1; // If the jog wheels or other encoders are too slow in your software, increase this value
// (it will be multiplied with the actual speed of the encoder, as the name implies.) Default is 1.
struct RelativeNoteSender {
static void send(int delta, MIDIAddress address) {
delta = constrain(delta, -127, 127);
if (delta > 0) {
Control_Surface.sendNoteOn(address, delta);
// Send whatever your software expects
} else {
Control_Surface.sendNoteOn(address + 1 /* ??? */, -delta);
// Send whatever your software expects
}
}
};
struct NoteEncoder : MIDIRotaryEncoder<RelativeNoteSender> {
NoteEncoder(EncoderPinList pins, MIDIAddress address)
: MIDIRotaryEncoder(pins, address, 1, 4, {}) {}
};
struct ContinuousNoteSender {
void send(uint8_t value, MIDIAddress address) {
Control_Surface.sendNoteOn(address, value);
}
static constexpr uint8_t precision() { return 7; }
};
struct NotePotentiometer : MIDIFilteredAnalogAddressable<ContinuousNoteSender> {
NotePotentiometer(pin_t analogPin, MIDIAddress address)
: MIDIFilteredAnalogAddressable(analogPin, address, {}) {}
};
// Instantiate a MIDI over USB interface.
USBMIDI_Interface midi;
NoteEncoder enc[] = {
{2,3, 0x01},
{4,5, 0x02},
{6,7, 0x03},
};
NoteButtonLatching switches[] = {
{2, 0x10, 1}, // Create a new instance of class 'DigitalLatch' on pin 0, note number 16 (mute) on MIDI channel 1
{3, 0x11, 1},
{5, 0x12, 1},
{7, 0x13, 1},
};
using namespace MIDI_Notes;
NotePotentiometer pots[] = {
{A1, note(0x4, 1)},
{A2, note(0x5, 1)},
{A3, note(0x6, 1)},
};
void setup() {
Control_Surface.begin(); // Initialize Control Surface
}
void loop() {
Control_Surface.loop(); // Update the Control Surface
}
You forgot a pair of braces around the pins.
NoteEncoder enc[] = {
{{2,3}, 0x01},
{{4,5}, 0x02},
{{6,7}, 0x03},
};
Keep in mind that only pins 2 and 3 are interrupt pins on an Uno. Using encoders on non-interrupt pins may result in incorrect readings. You can use pin 2 for one encoder and pin 3 for a second encoder, so you have two encoders with interrupts instead of just one.
Hola Pieter, he estado todo el dia tratando de añadirle banco a esta estructura
struct ContinuousNoteSender {
void send(uint8_t value, MIDIAddress address) {
Control_Surface.sendNoteOn(address, value);
}
static constexpr uint8_t precision() { return 7; }
};
struct NotePotentiometer : MIDIFilteredAnalogAddressable
Hice la prueba con todos los archivos de ccpotentiometer cambiando el continuousccsender por el continuosnotesender y al igual que ccpotentiometer por notepotentiometer pero no me reconoce el NotePotentiometer como parte del bankable, no se si haya que definirlo en otro lugar o si haya que añadir algun texto contenido en algun archivo de la libreria, podrias orientarme un poco. Te lo agradezco.
friend noa can put more than 9 pots, I did not do it declared, I already made changes and it did not work, I need a minimum of 10 pots
// This must be done before the Control Surface library.
struct RelativeNoteSender { static void send(int delta, MIDIAddress address) { delta = constrain(delta, -127, 127); if (delta > 0) { Control_Surface.sendNoteOn(address, delta); // Send whatever your software expects } else { Control_Surface.sendNoteOn(address + 1 / ??? /, -delta); // Send whatever your software expects } } };
struct NoteEncoder : MIDIRotaryEncoder
struct ContinuousNoteSender {
void send(uint8_t value, MIDIAddress address) {
Control_Surface.sendNoteOn(address, value);
}
static constexpr uint8_t precision() { return 10; }
};
struct NotePotentiometer : MIDIFilteredAnalogAddressable
NoteEncoder enc [] = { {{ 36 , 37 }, 0x2F }, {{ 38, 39 }, 0x3F },
};
NoteButton switches[] = { {2, 0x10, 1}, // Create a new instance of class 'DigitalLatch' on pin 0, note number 16 (mute) on MIDI channel 1 {3, 0x11, 1}, {4, 0x12, 1}, {5, 0x13, 1}, {6, 0x14, 1}, {7, 0x15, 1}, {8, 0x16, 1}, {9, 0x17, 1}, {10, 0x18, 1}, {11, 0x19, 1}, {12, 0x20, 1}, {13, 0x21, 1}, {14, 0x22, 1}, {15, 0x23, 1}, {16, 0x24, 1}, {17, 0x25, 1}, {18, 0x26, 1}, {19, 0x27, 1}, {20, 0x28, 1}, {21, 0x29, 1}, {22, 0x30, 1}, {23, 0x31, 1}, {24, 0x32, 1}, {25, 0x33, 1}, {26, 0x34, 1}, {27, 0x35, 1}, {28, 0x36, 1}, {29, 0x37, 1}, {30, 0x38, 1}, {31, 0x39, 1}, {32, 0x40, 1}, {33, 0x41, 1}, {34, 0x42, 1}, {35, 0x43, 1},
};
using namespace MIDI_Notes; NotePotentiometer pots[] = {
{A0, note(0x51, 4)}, {A1, note(0x52, 4)}, {A2, note(0x53, 4)}, {A3, note(0x54, 4)}, {A4, note(0x55, 4)}, {A5, note(0x56, 4)}, {A6, note(0x57, 4)}, {A7, note(0x58, 4)}, {A8, note(0x59, 4)}, {A9, note(0x60, 4)},
};
void setup() { Control_Surface.begin(); // Initialize Control Surface }
void loop() { Control_Surface.loop(); // Update the Control Surface }
What doesn't work? What error are you getting?
exit status 1 'A8' was not declared in this scope
he does not accept that I put more than 7 potentiometer, I already made a change in the return I put 10 instead of 7 that counts even so it does not recognize
put 10 potentiometer from A7 not accepted
using namespace MIDI_Notes; NotePotentiometer pots [] = {
{A0, note (0x51, 4)}, {A1, note (0x52, 4)}, {A2, note (0x53, 4)}, {A3, note (0x54, 4)}, {A4, note (0x55, 4)}, {A5, note (0x56, 4)}, {A6, note (0x57, 4)}, {A7, note (0x58, 4)}, {A8, note (0x59, 4)}, {A9, note (0x60, 4)},
};
Does your board have a pin labeled A8? Did you select the right board in the Tools menu of the IDE?
An Arduino UNO only has 6 analog pins: A0-A5.
If you want more analog pins, you'll have to use a multiplexer: https://tttapa.github.io/Control-Surface-doc/Doxygen/d5/d7d/md_pages_Getting-Started.html
yes friend I did this programming for Arduino Mega that I used in another controller because I added more pin
If you select the Arduino Mega in the Arduino IDE, you'll have access to the pins A6-A11.
note (0x60, 4)
might not do what you expect. It's not used like that, the first argument is the note, e.g. C
or `Bb, as shown in this example: https://tttapa.github.io/Control-Surface-doc/Doxygen/de/dcc/NoteButton_8ino-example.html
Also see the documentation here: https://tttapa.github.io/Control-Surface-doc/Doxygen/d7/d78/namespaceMIDI__Notes.html
hello i would like to know how to change control change potentiom to note on, software that work only recognizes midi Note On both button and fader. how do I send these notes to the faders?