Seemingly unable to get ccControls to run on separate channels

Hi, I’ve been trying to work out why this is for the past couple of days but am no closer. Basically I am using the MidiUSB library to try and send CC messages from multiple controls. However, whenever I move one potentiometer, all the values change at once, even when I hard code separate channels for each analogue input.

I have tried this with multiple libraries/ implementations, and even rewired the Arduino so there was literally just one potentiometer connected at a time.

Here’s my most recent code, which uses an array instead of hard coding, but the functionality is identical:

#include "MIDIUSB.h"

const int inputCount = 4;
int analogInputs[inputCount] = {A0, A1, A2, A3};

int midiChannel = 1;
int ccChannel = 1;
int ccValue [inputCount];

void setup() {

}

void loop() {
  
  // Read all inputs and store values
  
  for (int i=0; i<inputCount; ++i) {
    int val = analogRead(analogInputs[i]);
    ccValue[i] = (uint8_t) (map(val, 0, 1023, 0, 127));

    ccChannel = (i);

    sendControlChange (midiChannel, ccChannel, ccValue[i]);  
    delay (50); 
  }

}

void sendControlChange (byte channel, byte control, byte value) 
  {
    midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
    
    MidiUSB.sendMIDI(event);
  }

I also continue to get this warning, which doesn’t seem to break anything, but is a little disconcerting:

C:\Users\PaulDB\Desktop\sketch_feb22a\sketch_feb22a.ino: In function 'void sendControlChange(byte, byte, byte)':
warning: narrowing conversion of '(int)(176 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
     midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
                                      ~~~~~^~~~~~~~~

I can connect to my DAW and control parameters, below is an example of the output, notice that the value on all 4 channels is almost the same, and they all change together.

Port1 Ch 2 CC      B1 02 44 [002 Breath]
Port1 Ch 2 CC      B1 03 3F [003 ---]
Port1 Ch 2 CC      B1 00 3E [000 Bank (MSB)]
Port1 Ch 2 CC      B1 01 41 [001 Modulation]
Port1 Ch 2 CC      B1 02 44 [002 Breath]
Port1 Ch 2 CC      B1 03 40 [003 ---]
Port1 Ch 2 CC      B1 00 3E [000 Bank (MSB)]
Port1 Ch 2 CC      B1 01 47 [001 Modulation]

Does anyone have any suggestions? I could be making some obvious slip up!

Many thanks,
Paul

It’s not entirely clear to me what problem you’re describing. If you notice cross-talk between ADC channels, that might be because the resistance of your potentiometers is too high. 10kΩ is ideal, 22kΩ is fine, anything higher is beyond the spec for most Arduino boards and will result in crosstalk.

If the problem is that you get MIDI messages for all four controls even if you only changed one of them, then the answer is simple: because you just send MIDI messages in a for loop, without checking if any of the values changed since last time.

I’d highly recommend checking out the Control Surface library I maintain, it includes digital filters for the analog inputs and only sends MIDI data when you actually turn the potentiometers.

Your code would translate to:

#include <Control_Surface.h>

USBMIDI_Interface midi;

CCPotentiometer potentiometers[] {
  {A0, {0, CHANNEL_2}},
  {A1, {1, CHANNEL_2}},
  {A2, {2, CHANNEL_2}},
  {A3, {3, CHANNEL_2}},
};

void setup() {
  Control_Surface.begin();
}
void loop() {
  Control_Surface.loop();
}

Pieter

Hey Pieter, thanks for your reply - I had actually tried your library as well and had the same issue, however I took the code that you wrote (thank you!) and gave it another shot.
Given that the code itself was guaranteed to be correct, I instead experimented with various potentiometers like you suggested - Hey presto it works, thanks very much for your help :slight_smile: I'll definitely be using your library from now on.

Cheers, Paul

Glad to hear you got it to work!

If you want to keep using the high-resistance potentiometers, you could try adding a small cap between the wiper and ground, so the ADC sees a lower impedance. Alternatively, you could try doing a dummy read on each ADC channel (where you throw away the result) before you do the actual measurement that you'll be using, this should also reduce the cross-talk.

That's great, thanks for the tips :slight_smile:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.