joshnishikawa / MIDIcontroller

A library for creating Teensy MIDI controllers with support for hold or latch buttons, potentiometers, encoders, capacitive sensors, Piezo transducers and other velocity sensitive inputs with aftertouch.
223 stars 19 forks source link

Simple question about having multiple instances of Pots #18

Closed fabiendostie closed 1 year ago

fabiendostie commented 2 years ago

Hello, I am quite new to teensy in general... so my issue might be somewhat "noob" I tried different ways to add multiple instances of pots using your library And I can't seem to find the exact syntax for it here's what I got, it's compiling but only one out of the 4 pots are reacting:

#include "MIDIcontroller.h"

byte MIDIchannel = 5;
const int potPin = A0; // Change this to the ANALOG pin you want to use
const int potPin1 = A1;
const int potPin2 = A2; 
const int potPin3 = A3; 
// Pot parameters are: pin, CC number, KILL switch enabled
// When KILL is enabled, separate CC messages (with a different number) will be sent
// when you turn the pot all the way down and when you start turning it up again.
// Simply omit the "KILL" argument if you don't want that.
MIDIpot myPot(potPin, 22, KILL);
MIDIpot myPot1(potPin1, 23, KILL);
MIDIpot myPot2(potPin2, 24, KILL);
MIDIpot myPot3(potPin3, 25, KILL);

// OPTIONAL: use outputRange() to limit the min/max MIDI output values
//  myPot.outputRange(0, 127);

void setup(){
}

void loop(){
  myPot.send();

// This prevents crashes that happen when incoming usbMIDI is ignored.
  while(usbMIDI.read()){}

// Also uncomment this if compiling for standard MIDI
//  while(MIDI.read()){}
}

Any help would be greatly appreciated as it seems that your library is giving me excellent analog read for my pots, I have been struggling to find a library that effectively reduces the noise enough so that the pots aren't "giggly"

joshnishikawa commented 2 years ago

Use a pointer array and a couple of 'for' loops for that. The muxedInput example shows how that works but if you're not using a mux chip and want all the pots on different pins, it would be something like this.

#include "MIDIcontroller.h"
byte MIDIchannel = 5;

MIDIpot* myPots[4]; // Just declare the pointer array here (notice the *)

void setup(){
  // Create all the pots during setup.
  for(int i = 0; i < 4; i++){
    myPots[i] = new MIDIpot(14+i, 22+i, 102+i); // use unique CCs instead of KILL for multiple pots
  }
}

void loop(){
  for(int i = 0; i < 4; i++){
    myPots[i]->send(); // notice the -> operator  
  }

// This prevents crashes that happen when incoming usbMIDI is ignored.
  while(usbMIDI.read()){}

// Also uncomment this if compiling for standard MIDI
//  while(MIDI.read()){}
}
fabiendostie commented 2 years ago

Wow thanks, I think this is the fastest answer I have ever received!

I think I understand the logic, I'll take more time to really understand this. I'm from a completely different field originally so code is somewhat new to me. I am starting to make sense of this more and more every day. thanks to kind people like you.!

one question? Are these just some random CC you picked or is there a specific reason you chose those ones?

 myPots[i] = new MIDIpot(14+i, 22+i, 102+i); 

so, say I have 12 pots I would basically replace all the instances where the number is "4" in your example by the number 12 and obviously have 12 different cc's for it

also, I dont understand how the analog pins are specified in your example, which ones are used for pots for example...

joshnishikawa commented 2 years ago

Not exactly random. I chose 14+i because you specified the A0\~A3 pins and that's the same as 14\~17 (You can use either naming convention and still use analogRead). I chose 22+i because you specified CC 22~25. I chose 102+i because 102 begins a list of 18 undefined CC numbers in the general MIDI spec. It's probably not that important that they're previously undefined as long as they don't overlap with other CC numbers you're trying to use.

so, say I have 12 pots I would basically replace all the instances where the number is "4" in your example by the number 12 and obviously have 12 different cc's for it

That is correct...assuming you have 12 consecutive analog pins you can use.

fabiendostie commented 2 years ago

what does the 2nd number stand for in “ myPots[i] = new MIDIpot(14+i, 22+i, 102+i);” PINS 14+i = 14-15-16-17 ??? 22+i= 22-23-24-25 but what does it stand for it’s not the pin used or the cc what is it? cant be midi channel ;) CC number 102+i=102-103-104-105 CC

Its a little unclear for me right now.

Thanks!

On Mar 17, 2022, at 11:17 PM, joshnishikawa @.***> wrote:

include "MIDIcontroller.h"

byte MIDIchannel = 5;

MIDIpot myPots[4]; // Just declare the pointer array here (notice the )

void setup(){ // Create all the pots during setup. for(int i = 0; i < 4; i++){ myPots[i] = new MIDIpot(14+i, 22+i, 102+i); // use unique CCs instead of KILL for multiple pots } }

void loop(){ for(int i = 0; i < 4; i++){ myPots[i]->send(); // notice the -> operator
}

// This prevents crashes that happen when incoming usbMIDI is ignored. while(usbMIDI.read()){}

// Also uncomment this if compiling for standard MIDI // while(MIDI.read()){} }

joshnishikawa commented 2 years ago

The second number is the CC that the analog pot will control. The third number is an optional on/off switch that can be assigned to any other CC number. Sometimes, when you turn an effect all the way down, it still generates some noise or the effect won't go all the way 'dry'. This secondary CC allows you to assign the pot to the enable/disable button of an effect to kill it completely. You could probably come up with some other creative uses too but, if you just want a good old fashioned analog pot, just leave off the third number.

fabiendostie commented 2 years ago

Ooooh! Ok that makes sense now, actually I just noticed a little bit of a weird behaviour concerning the CC's when 8 look at midi monitor. The cc varies a bit for some reason. Using 1 pot to test all pins. For example I hook it up on pin 15 using cc 23, when I rotate the pot the cc is 23 about 85% of the time but it jumps to 24 the other 15%??

See picture attached

Any idea why that is? Any idea how to prevent it from happening?

Fabien Dostie Monteur Online / Coloriste Numérique (AQTIS) Datawrangler-DIT-Video Assist (AQTIS/IATSE)

On Mon., Mar. 21, 2022, 18:55 joshnishikawa @.***> wrote:

The second number is the CC that the analog pot will control. The third number is an optional on/off switch that can be assigned to any other CC number. Sometimes, when you turn an effect all the way down, it still generates some noise or the effect won't go all the way 'dry'. This secondary CC allows you to assign the pot to the enable/disable button of an effect to kill it completely. You could probably come up with some other creative uses too but, if you just want a good old fashioned analog pot, just leave off the third number.

— Reply to this email directly, view it on GitHub https://github.com/joshnishikawa/MIDIcontroller/issues/18#issuecomment-1074500537, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM22A2NPVYIGQDJ7KSGSCCTVBD445ANCNFSM5RATAGRQ . You are receiving this because you authored the thread.Message ID: @.***>

joshnishikawa commented 2 years ago

I don't see a 'picture attached' but, if you could post your sketch, that would help.

fabiendostie commented 2 years ago

Will do when I get home. Thank you for your time.

Fabien Dostie Monteur Online / Coloriste Numérique (AQTIS) Datawrangler-DIT-Video Assist (AQTIS/IATSE)

On Tue., Mar. 22, 2022, 00:27 joshnishikawa @.***> wrote:

I don't see a 'picture attached' but, if you could post your sketch, that would help.

— Reply to this email directly, view it on GitHub https://github.com/joshnishikawa/MIDIcontroller/issues/18#issuecomment-1074712880, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM22A2NPACLMZG37CJ345DDVBFDZHANCNFSM5RATAGRQ . You are receiving this because you authored the thread.Message ID: @.***>

fabiendostie commented 2 years ago

Actually, I'm testing using exactly the sketch you provided me:

#include "MIDIcontroller.h"
byte MIDIchannel = 5;

MIDIpot* myPots[4]; // Just declare the pointer array here (notice the *)

void setup(){
  // Create all the pots during setup.
  for(int i = 0; i < 4; i++){
    myPots[i] = new MIDIpot(14+i, 22+i, 102+i); // use unique CCs instead of KILL for multiple pots
  }
}

void loop(){
  for(int i = 0; i < 4; i++){
    myPots[i]->send(); // notice the -> operator  
  }

// This prevents crashes that happen when incoming usbMIDI is ignored.
  while(usbMIDI.read()){}

// Also uncomment this if compiling for standard MIDI
//  while(MIDI.read()){}
}

and here is the picture: midi_cc_issue if I can get this to be stable and free of "jittering and wiggling, " I'll move on to implement it to the rest of my interface, which has 12 pots, 2 X rotary 3 poles 4 positions switches and four buttons.

By the way, I do have another question regarding those switches, I'm not sure which bit of code I should be used for those, I think you do not have anything for those. Or do you?

joshnishikawa commented 2 years ago

Yeah, that looks a bit noisy. It looks like you're testing the pot for CC 23. Do you have pots hooked up on the other pins that are reading CC 22, CC 24 and CC 25? If not, you'll get noisy analog readings from naked pins peppered in like that.

Even just the readings for CC 23 are a little jumpy though. Is the pot is wired as a potentiometer (one pin to voltage, one pin to ground and the center 'wiper' to the analog pin)? If you only have it wired as a variable resistor (using 2 pins) it'll be dirty.

As for the switches, just hook each pole to a pin and use the MIDIbutton class. That makes me think maybe I should change the name of that class to MIDIswitch since flip switches and rotary switches are handled the same as push switches.

fabiendostie commented 2 years ago

Only was testing with only one potentiometer but you're right it's normal that it's noisy when there are pins that are unconnected when they are specified in the code. Yes all wired as pots!

Ill try to wire, at least those 4 pots plus two of the switches and I'll get back to you with an update.

Thanks again for your time!

Fabien Dostie Monteur Online / Coloriste Numérique (AQTIS) Datawrangler-DIT-Video Assist (AQTIS/IATSE)

On Wed., Mar. 23, 2022, 07:20 joshnishikawa @.***> wrote:

Yeah, that looks a bit noisy. It looks like you're testing the pot for CC

  1. Do you have pots hooked up on the other pins that are reading CC 22, CC 24 and CC 25? If not, you'll get noisy analog readings from naked pins peppered in like that.

Even just the readings for CC 23 are a little jumpy though. Is the pot is wired as a potentiometer (one pin to voltage, one pin to ground and the center 'wiper' to the analog pin)? If you only have it wired as a variable resistor (using 2 pins) it'll be dirty.

As for the switches, just hook each pole to a pin and use the MIDIbutton class. That makes me think maybe I should change the name of that class to MIDIswitch since flip switches and rotary switches are handled the same as push switches.

— Reply to this email directly, view it on GitHub https://github.com/joshnishikawa/MIDIcontroller/issues/18#issuecomment-1076252566, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM22A2L6NT3W5M7RA6HC5E3VBL46HANCNFSM5RATAGRQ . You are receiving this because you authored the thread.Message ID: @.***>

fabiendostie commented 2 years ago

Hey Josh, Hope you're well. I tried hooking up 6 of my potentiometers and one of the 3 pole 4 stop rotary switch. And results are not as great as when I had only one potentiometer. Any clue as to what I can do to make it more stable and have less fluctuations? switches and pots are good quality Japanese made "Alps" here's the code i used, it's probably wrong:

#include "MIDIcontroller.h"
byte MIDIchannel = 5;
const int latchPin = 10; //any digital pin
// const int ledPin = 13;   //Set an LED to show the state of a latch button.

MIDIpot* myPots[7]; // Just declare the pointer array here (notice the *)
// MOMENTARY buttons are the default. LATCH or TRIGGER may also be set
MIDIbutton* myInput[4];
void setup(){
  // Create all the pots during setup.
  for(int i = 0; i < 7; i++){
    myPots[i] = new MIDIpot(14+i, 22+i, 102+i); // use unique CCs instead of KILL for multiple pots
  }  
    // Create all the switch inputs during setup.
    for(int s = 0; s < 4; s++){
    myInput[s] = new MIDIbutton(33+s, 34+s, 114+s); // use unique CCs instead of KILL for multiple pots
  }
  // pinMode(ledPin, OUTPUT);
}

void loop(){
  for(int i = 0; i < 7; i++){
    myPots[i]->send(); // notice the -> operator
  }
  for(int s = 0; s < 4; s++){
    myInput[s]->send(); 
    } 
// This prevents crashes that happen when incoming usbMIDI is ignored.
  while(usbMIDI.read()){}

// Also uncomment this if compiling for standard MIDI
//  while(MIDI.read()){}
}

Thanks midiInt_1 midiint_2

joshnishikawa commented 2 years ago

the rotary encoder switch does not behave as expected, but that is probably due to the "kill" function thing in the code, but it would not compile when I took it out. Three problems with this: 1) I don't think you're using a 'rotary encoder'. That's a different kind of component. It looks like you have a rotary switch in that second photo. 2) You're right, you can't put anything but MOMENTARY, LATCH or TRIGGER as the third argument when making a button. You want MOMENTARY for that kind of switch.

for(int s = 0; s < 4; s++){
myInput[s] = new MIDIbutton(33+s, 34+s, MOMENTARY);
}

It's not meant to be required. I need to fix that but for now, as long as it says MOMENTARY there, it'll work.

As for the noise, I'd look at the wiring first. There's a lot going on here and it's hard to see what goes where. I can't tell by the color of the wires whether the post are wired correctly. They're nice pots but they prefer to be panel-mounted. Then it would be easy to run a single wire across all of them for voltage, another single wire across all of them for ground and just have the returns running directly to the Teensy. Maybe set the Teensy somewhere in that perfboard to keep the wires as short as possible. The more solder joints and splices, the more opportunities for noise.

fabiendostie commented 2 years ago

I thought that a 3 pole 4 stop rotary encoder switch was the proper name for that, my bad!

As for the wiring, One wire going to each pot for power and another single one for ground, was actually how they were wired first and the noise was a LOT worse for some reason I really have been struggling with these for the better part of the last two years. But your code seems to be the most stable one I've tried so far.

This is actually a test for my already built 12 track mixing console midi controller. For which I need to completely redesign the wiring etc .. my old wiring is way too noisy.

It has 1 linear fader and 4 pots plus one led and a button on each track.

I'll try the I'll try rewiring with even less length of wire possible. And I'll use MOMENTARY instead Thanks for your suggestions and help. It's really kind of you, really appreciated!

Fabien Dostie Monteur Online / Coloriste Numérique (AQTIS) Datawrangler-DIT-Video Assist (AQTIS/IATSE)

On Sun., Mar. 27, 2022, 20:23 joshnishikawa @.***> wrote:

the rotary encoder switch does not behave as expected, but that is probably due to the "kill" function thing in the code, but it would not compile when I took it out. Three problems with this: 1) I don't think you're using a 'rotary encoder'. That's a different kind of component. It looks like you have a rotary switch in that second photo. 2) You're right, you can't put anything but MOMENTARY, LATCH or TRIGGER as the third argument when making a button. You want MOMENTARY for that kind of switch.

for(int s = 0; s < 4; s++){ myInput[s] = new MIDIbutton(33+s, 34+s, MOMENTARY); }

It's not meant to be required. I need to fix that but for now, as long as it says MOMENTARY there, it'll work.

As for the noise, I'd look at the wiring first. There's a lot going on here and it's hard to see what goes where. I can't tell by the color of the wires whether the post are wired correctly. They're nice pots but they prefer to be panel-mounted. Then it would be easy to run a single wire across all of them for voltage, another single wire across all of them for ground and just have the returns running directly to the Teensy. Maybe set the Teensy somewhere in that perfboard to keep the wires as short as possible. The more solder joints and splices, the more opportunities for noise.

— Reply to this email directly, view it on GitHub https://github.com/joshnishikawa/MIDIcontroller/issues/18#issuecomment-1080055946, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM22A2JDKFFU2PTDVWYZHZDVCD3XZANCNFSM5RATAGRQ . You are receiving this because you authored the thread.Message ID: @.***>