EE question about crosstalk in wiring to Analog pins

Status
Not open for further replies.
I'm trying to do something that may or may not be possible. I'm trying to turn a set of actual hammond drawbars into a midi controller. (Well, actually I've at least proven it's possible to do it badly!)

The way Hammond drawbars work, each of the 9 drawbars can be pulled out to one of 8 different positions. As it does so, it makes contact with each of 8 buss bars, which run perpendicular to the drawbars. In the process, it increases the volume of one oscillator from zero to maximum in 8 increments. The 9 oscillators make up the tone of a note.

So what I did was put a 1k resistor between each buss bar, and attached the rear buss bar to ground, and the front buss bar to voltage. Each drawbar has a wire attached at the rear that then becomes a wiper. I attached each one to an analog input.

It actually works, but there is an issue. I tested it by pulling each drawbar all the way out, and then pushing it back in. This works great. Then I installed it in the cabinet. But in use, I discovered that when one or more of the bars is in a midway position, the movement of other bars causes the voltage to fluctuate.... oops. I expected crosstalk, but I neglected to consider it would be minimized at the extremes. I guess I'll be opening it back up.

Now I'm wondering if someone with greater understanding of electrical engineering could tell me if there is likely to be a practical fix for this. If not, I have a set of 10k (cheap! plastic!) drawbar pots I could retrofit. But if there's some magic I could work by wiring in a few resistors or some other arcane component I don't even begin to understand (I don't know, DIODES????) ...well it's worth asking, I guess.

Thanks in Advance!
-eric
 
A fluctuation could be a lot of things - can you describe it better?

If it's a mechanical problem (which I think it is), the "fluctuation" will happen only when you move the sliders. After you stop moving them, the readings will be what you expect. So the core problem would be a temporarily unreliable connection. You could try adding a smallish capacitor (1n?) on each input to keep it "afloat" at a voltage near the last good one, until things calm down and you have a solid electrical connection to the divider again. Or do an equivalent of a software debounce - don't change the output, until you have seen the same value for N milliseconds?
 
A debounce sounds like a good idea... I'll try that. It does only happen when I move the sliders, you are correct.

There is lots of room for 'noise' in the system. The original design for the drawbars had dropouts as they moved from position to position, but then they redesigned them so they always contact at least one buss bar. That means they contact TWO buss bars in between positions. So that seems like a potentially complicated circuit. I'll look into software smoothing options. I only have to manage 8 discrete values, and I don't need lightning response. I'll look at it some more, and see if, for instance:

The bars return to the correct values after fluctuations, and
The fluctuations seem to be related to whether the bar is between positions

Thanks so much for the suggestions!
 
A debounce sounds like a good idea... I'll try that.
Thanks so much for the suggestions!

Coming back to this.... can someone suggest code for debouncing? I'm not very clear on the topic.

Can I just use the bounce library as is, and add the function to the drawbar inputs? Hmmm, I'll try that.... Would I use 'falling edge'?

Here's my Drawbar Code as it stands:
Code:
#include <Bounce.h>

const int COUNT_D = 8;
const int COUNT_A = 11;
const int percUP=0;
const int percDN=1;
const int chorUP=2;
const int chorDN=3;
const int vToglUP=4;
const int vToglDN=5;
const int auxUP=6;
const int auxDN=7;

const int PINS_D[] = {percUP,percDN,chorUP,chorDN,vToglUP,vToglDN,auxUP,auxDN};
const int CCS_D[] = {80,81,82,83,84,85,86,87};

const int aTouch = 0; 
const int bCtl = 10;
const int aux = 12; //on pin 26--next to pin13
const int reverb = 10; //on pin 24--inside pin 22
const int dist = 11; //on pin 25--inside pin 21

const int PINS_A[] = {aTouch, 1,  2,  3,  4,  5,  6,  7,  8,  9, bCtl};
const int CCS_A[] = { 3, 20,21,22,23,24,25,26,27,28,2};
int VALUES_A[COUNT_A];
int PrevVal = 0; // needs global scope

int midiChan = 2;
// range of ctls is 0-1023, divide by 8 for midi value
const int SENSITIVITY = 64;
const int DBR_SENS = 70;
const int SCALE_A = 8;
const int BREATH_THRESHOLD = 16;

//ccVal = map(sensorValue, 0, 1023, 0, 127);  //more precise, I suppose

int sens = 4;

//button debounce time
// Debounce
long debounceDelay = 20;
 
Bounce buttons[] = {
  Bounce(PINS_D[0], debounceDelay),
  Bounce(PINS_D[1], debounceDelay),
  Bounce(PINS_D[2], debounceDelay),
  Bounce(PINS_D[3], debounceDelay),
  Bounce(PINS_D[4], debounceDelay),
  Bounce(PINS_D[5], debounceDelay),
  Bounce(PINS_D[6], debounceDelay),
  Bounce(PINS_D[7], debounceDelay),
  Bounce(PINS_D[8], debounceDelay),
  Bounce(PINS_D[9], debounceDelay),
  Bounce(PINS_D[10], debounceDelay),
  Bounce(PINS_D[11], debounceDelay),
  Bounce(PINS_D[12], debounceDelay)
};

// *************   function to convert pot to MIDI cc. Pass it the pin number, the cc to transmit, and the MIDI channel ***************
void pot_to_cc(byte pinNum, byte PotCC, byte Ch,int sens, int reverse ){   
    int CurVal = analogRead(pinNum) ; // get the raw value
    int margin = VALUES_A[pinNum] * sens; // .02 = get 2% of the raw value.  Tune for lowest non-jitter value.
    int outVal = 0;
    /*
     * Next we add (or subtract...) the 'standard' fixed value to the previous reading. 
     * (PotPrevVal needs to be declared outside the function so it persists.)
     * Here's the twist: Since the jitter seems to be worse at high raw vals, 
     * we also add/subtract the 2% of total raw. Insignificantat on low 
     * raw vals, but enough to remove the jitter at raw >900 without wrecking 
     * linearity or adding 'lag', or slowing down the loop, etc.
     */
    if (CurVal > VALUES_A[pinNum] + (4 + margin) || CurVal < VALUES_A[pinNum] - (5 + margin)) { // a 'real' change in value? Tune the two numeric values for best results
          if (reverse > 0) outVal = 1024-outVal else outVal = CurVal;
          MIDI1.sendControlChange(PotCC,OutVal >> 3,Ch);  // scale to 0-127 and send the cc
      VALUES_A[pinNum] = CurVal; // store valid raw val  for next comparison
      //Serial.print("PotCurVal-"); // uncomment to debug
      //Serial.println(PotCurVal); // uncomment to debug
    }    
}

void setup() {
  for (int ctl = 0; ctl < COUNT_A; ctl++)
  {
    VALUES_A[ctl] = 0;
  }  
  for (int btn = 0; btn < COUNT_D; btn++) //int btn = 0;
  {
    pinMode (btn, INPUT_PULLUP);
  }  
}

void loop() {
  //BUTTONS
  for (int btn = 0; btn < COUNT_D; btn++)  //int btn = 0;
  {
    buttons[btn].update();
    if (buttons[btn].risingEdge())
    { 
         usbMIDI.sendControlChange(CCS_D[btn], 0, midiChan);
    }
    else if (buttons[btn].fallingEdge()) {        
        usbMIDI.sendControlChange(CCS_D[btn], 127, midiChan);
    }
  }
  //CONTROLS  --may need tweaking for aT.
  for (int ctl = 0; ctl < COUNT_A; ctl++)  { //int ctl = 0;
     int reverse = 0;
     int sens = 0;
     if (0 < ctl) && (ctl < 10) reverse = 1 else reverse = 0;
     if (0 < ctl) && (ctl < 10) sens = .1 else sens = .02;
     pot_to_cc(PINS_A[ctl],CCS_A[ctl],sensitivity,reverse)
  }
    /*
    int value = analogRead(PINS_A[ctl]);
    int reverse = 1023 - value;
    if ((0 < ctl) && (ctl < 10)) {sens = DBR_SENS;} else {sens = SENSITIVITY;} //reduce sensitivity for drawbars
    if (abs(VALUES_A[ctl]-value) > sens)
    {
      if (0 < ctl) && (ctl < 10) usbMIDI.sendControlChange(CCS_A[ctl], reverse/SCALE_A, midiChan)  //CC,val,CH   //reverse drawbars 
         else usbMIDI.sendControlChange(CCS_A[ctl], value/SCALE_A, midiChan)
      VALUES_A[ctl] = value;
      delay(25);
    }
  }*/

  //pin test 
  /*
  int pin = bCtl;
  int value = analogRead(PINS_A[pin]);
  if (abs(VALUES_A[pin] - value) > sens)  {
    usbMIDI.sendControlChange(CCS_A[pin],VALUES_A[pin] / SCALE_A, midiChan);
    VALUES_A[bCtl] = value;
    delay(50);
  }*/
  
  //==============================================================================
  // MIDI Controllers should discard incoming MIDI messages.
  // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
  while (usbMIDI.read())
  {
    // ignoring incoming messages, so don't do anything here.
  }
}
 
100 ohm resistors (for a total of 800 ohms) will be more stable than 1K. Also make sure that the front and rear buss bars don't vary in voltage.
 
okay, that's good to know. I thought the analog ins expected 0-10k ohms, that's why I did 1k each. I'd like to find a software solution if possible--it's a pain to rewire... but maybe unavoidable.
 
Status
Not open for further replies.
Back
Top