Analog input erratic behaviour - it doesn't reach 0

Hello!

I own and work in a small company called Yaeltex, in Argentina, where we are designing, making and selling tools for people to make their own MIDI Controllers.

One of our products is the Kilomux shield, which is an I/O expansion shield with MIDI IN/OUT circuitry.

Schematic for Kilomux shield is here.

This shield gives me 32 analog or digital inputs (whatever combination works) and 16 digital outputs.

To this shield I have connected 4 of these modules, with 8 pots (5K) each, with a flat ribbon cable with IDC connectors, like you can see here.

The code I am using is here. It is somewhat messy and not yet fully commented, but the reading of the analog inputs is inside a function called ReadInputs() on lines 601-624, and the handling of this input to determine whether or not it should send a MIDI message and what will this message be, is done inside the function called InputChanged(), lines 650-736.

When I read an analog input, I divide the value by 8 in order to have a 7bit value to send it through MIDI. This gives me a value between 0-127. This is working perfectly, most of the time.

Now, sometimes, the value doesn't go the full way down to 0, but it stops on 2 (23 if full I verify thhe full 10 bit resolution).

I've been using the code above for many MIDI controllers we've created, and never came across this issue before.

I noticed that usually when this happens, I am using an USB hub, where I plug the MIDI Controller, and then this HUB is connected to the computer's USB port. But most of the time the controller works just fine when connected to this HUB.

Every time that this happened, the problem went away when pluggin the USB directly to my computer. And sometimes reconnecting to the HUB.

But yesterday I tried this on a different computer and the problem persisted after disconnecting and reconnecting the USB cable on the computer's port, without any HUB.

The problem seems electrical, and not in the code, but I can't figure out if it's a problem with the USB power, with the ribbon cable and its length, or what.

Has anyone ever come across a simillar issue and solved it?

Now, sometimes, the value doesn't go the full way down to 0, but it stops on 2 (23 if full I verify thhe full 10 bit resolution).

Measure the voltage out or the pot (with a multimeter). Pot's don't always go all the way to "zero-Ohms". Welcome to the world of analog! :smiley:

And, measure the voltage right at the pot's "ground" terminal (referenced to the Arduino's ground). Any resistance in the ground wires/connectors will raise "ground" voltage as well as the pot's output voltage.

Attached is a sketch I wrote for 0-100% (=101 pot positions).
It removes the extremes and adds some deadband.
It might give you some ideas.
Leo…

// converts the position of a 10k lin(B) pot to 0-100%
// pot connected to A0, 5volt and ground

int rawValue;
int oldValue;
byte potPercentage;
byte oldPercentage;

void setup() {
  Serial.begin(115200); // set serial monitor to this baud rate, or change the value
}

void loop() {
  // read input twice
  rawValue = analogRead(A0);
  rawValue = analogRead(A0); // double read
  // ignore bad hop-on region of a pot by removing 8 values at both extremes
  rawValue = constrain(rawValue, 8, 1015);
  // add some deadband
  if (rawValue < (oldValue - 4) || rawValue > (oldValue + 4)) {
    oldValue = rawValue;
    // convert to percentage
    potPercentage = map(oldValue, 8, 1008, 0, 100);
    // Only print if %value changes
    if (oldPercentage != potPercentage) {
      Serial.print("Pot percentage is: ");
      Serial.print(potPercentage);
      Serial.println(" %");
      oldPercentage = potPercentage;
    }
  }
}

Wava, thank you for your answer, somehow I didn't get an email of notice when you posted both answers.

I have new evidence that inclines me further away from a hardware issue.

As a MIDI Monitor I am using two apps. One is the Kilowhat, which is a SysEx configurator to use with the Kilomux shield, and the other is MIDI OX, a well know MIDI monitor for Windows.

This doesn't happen all the time, but it did a couple of times on the past few days:
The test was as follows:

  1. Open MIDI input port on Kilowhat.
  2. CC messages range 2-127 or 1-126.
  3. Close MIDI input port on Kilowhat.
  4. Open MIDI input port on MIDI OX.
  5. CC messages have full range (0-127).
  6. Repeat and results are the same.

So code was always running, same code, same hardware, no rebooting on the arduino, just mere PC ports handling, and results were different.

And then, same as before, suddenly after an unplug and plug of the USB, I can see full range on both monitors.

Your code with the dead band is something similar to what I am using at the end of my code, with the function IsNoise(), which is a Histeresis filter with a dynamic threshold, which varies according to the range of the output, which could be a range of 0-1, or 0-16383.

Kilowhat let's you configure your min and max value for each input, so in the code, this filter uses this configuration for the threshold calculation.

What I will try is the leaving out 8 values on the extreme, but with little hope, due to what I said before.

Will come back with results.