Potentiometer jittering

Hi. I made a gaming device with an Arduino Pro Micro using the joystick library. The device has 2 PT10 10k potentiometers, and they jitter a bit in game. See video:

The relevant code is very basic:

  rudder_ = analogRead(gain);
  Joystick.setRudder(rudder_);

  throttle_ = analogRead(lev);
  Joystick.setThrottle(throttle_);

How can I remove the jitter? the pots are connected to VCC, GND and an analog pin each directly. Should I add a capacitor or is this something that can be fixed by code?

Here's the full code:

#include "Joystick.h"
#include "Wire.h"
#include <Keypad.h>

#define NUMROWS 3
#define NUMCOLS 7
#define joyX A1
#define joyY A0
#define gain A3
#define lev A2
#define address 0x20
#define address2 0x21

byte buttonsMFD[NUMROWS][NUMCOLS] = {
  { 74, 72, 73, 61, 62, 63, 64 },
  { 71, 65, 66, 67, 68, 69, 70 },
  { 75, 77, 76, 78, 79, 80, 81},
};

byte rowPins[NUMROWS] = { 4, 5, 6 };
byte colPins[NUMCOLS] = { 7, 8, 9, 10, 16, 14, 15 };

Keypad MFD = Keypad(makeKeymap(buttonsMFD), rowPins, colPins, NUMROWS, NUMCOLS);

byte buttons[8][8] = {
  { 0, 1, 2, 3, 4, 5, 6, 7 },
  { 86, 86, 86, 86, 12, 13, 14, 15 },
  { 16, 17, 18, 19, 20, 21, 22, 23 },
  { 24, 86, 86, 86, 86, 86, 30, 32 },
  { 96, 97, 98, 99, 37, 38, 39, 40 },
  { 41, 42, 43, 44, 45, 46, 47, 49 },
  { 50, 51, 52, 87, 53, 54, 55, 57 },
  { 58, 59, 60, 83, 82, 85, 84, 86 },
};

byte buttons2[2][8] = {
  { 8, 9, 10, 11, 33, 34, 35, 36 },
  { 25, 26, 27, 28, 29 },
};

bool buttonvalues[8][8] = {
  { 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1, 1, 1, 1 },
};

bool buttonvalues2[2][8] = {
  { 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1 },
};

const bool initAutoSendState = true;

int xAxis_ = 0;
int yAxis_ = 0;
int rudder_ = 0;
int throttle_ = 0;

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK, 86, 0, true, true, false, false, false, false, true, true, false, false, false);

void setup() {
  Wire.begin();
  Wire.beginTransmission(address);
  Wire.write(0xFF);
  Wire.write(0xFF);
  Wire.endTransmission();
  Joystick.begin();
}

void loop() {
  CheckGrips();
  CheckAllAxis();
  CheckMFD();
  CheckExtraPCF();
}

void CheckExtraPCF() {
  byte read_value1;
  byte read_value2;
  if (Wire.requestFrom(address2, 2) == 2) {
    read_value1 = (Wire.read());
    read_value2 = (Wire.read());
  }

  for (int i = 0; i < 8; i++) {

    if (bitRead(read_value1, i) != buttonvalues2[0][i]) {
      Joystick.setButton(buttons2[0][i], !bitRead(read_value1, i));
      buttonvalues2[0][i] = bitRead(read_value1, i);
    }
  }
  for (int i = 0; i < 5; i++) {

    if (bitRead(read_value2, i) != buttonvalues2[1][i]) {
      Joystick.setButton(buttons2[1][i], !bitRead(read_value2, i));
      buttonvalues2[1][i] = bitRead(read_value2, i);
    }
  }
}

void CheckGrips() {
  byte read_value1;
  byte read_value2;
  byte write_value = 1;
  for (int n = 0; n < 8; n++) {
    byte temp = ~write_value;
    Wire.beginTransmission(address);
    Wire.write(temp);
    Wire.write(0xFF);
    Wire.endTransmission();
    if (Wire.requestFrom(address, 2) == 2) {
      read_value1 = (Wire.read());
      read_value2 = (Wire.read());
    }
    for (int i = 0; i < 8; i++) {

      if (bitRead(read_value2, i) != buttonvalues[i][n]) {
        Joystick.setButton(buttons[i][n], !bitRead(read_value2, i));
        buttonvalues[i][n] = bitRead(read_value2, i);
      }
    }
    write_value <<= 1;
  }
  if ((buttonvalues[3][6] == 1) && (buttonvalues[3][7] == 1)) {
    Joystick.setButton(31, 1);
  } else {
    Joystick.setButton(31, 0);
  }
  if ((buttonvalues[5][6] == 1) && (buttonvalues[5][7] == 1)) {
    Joystick.setButton(48, 1);
  } else {
    Joystick.setButton(48, 0);
  }
  if ((buttonvalues[6][6] == 1) && (buttonvalues[6][7] == 1)) {
    Joystick.setButton(56, 1);
  } else {
    Joystick.setButton(56, 0);
  }
}

void CheckAllAxis(void) {

  xAxis_ = analogRead(joyX);
  xAxis_ = map(xAxis_, 0, 1023, 1023, 0);
  Joystick.setXAxis(xAxis_);

  yAxis_ = analogRead(joyY);
  Joystick.setYAxis(yAxis_);

  rudder_ = analogRead(gain);
  Joystick.setRudder(rudder_);

  throttle_ = analogRead(lev);
  Joystick.setThrottle(throttle_);
}

void CheckMFD(void) {

  if (MFD.getKeys()) {
    for (int j = 0; j < LIST_MAX; j++) {
      if (MFD.key[j].stateChanged) {
        switch (MFD.key[j].kstate) {
          case PRESSED:
          case HOLD:
            Joystick.setButton(MFD.key[j].kchar, 1);
            break;
          case RELEASED:
            break;
          case IDLE:
            Joystick.setButton(MFD.key[j].kchar, 0);
            break;
        }
      }
    }
  }
}

Hi, @Assamita
Can you please post your code?

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

What is your power supply?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

A capacitor may not work

Try this code:
rudder_ = 0;
rudder_ = rudder_ + analogRead(gain);
rudder_ = rudder_ + analogRead(gain);
rudder_ = rudder_ + analogRead(gain);
rudder_ = rudder_ + analogRead(gain);
rudder_ = rudder_ + analogRead(gain);
rudder_ = rudder_ + analogRead(gain);
rudder_ = rudder_ + analogRead(gain);
rudder_ = rudder_ + analogRead(gain);
rudder_ = rudder_>> 8;

Joystick.setRudder(rudder_);

1 Like

I'd prefer to use an exponential filter Jim - mainly because it will allow more time between readings.

eg
int oldrudder = 512; //start with a centre value

rudder_ = (3*oldrudder + analogRead(gain))/4;
oldrudder = rudder_;

1 Like

Hi TomGeorge. I did post my code. Check OP.
All hardware will be complicated. It's an 86 buttons and switches devices, with a thumb joystick and two potentiometers. It runs two button matrices, one with diodes and managed by a 16 I/O port expander, one without diodes because that one doesn't require multiple buttons being pressed at the same time, connected directly to the arduino, and an additional port expander for more inputs.
It's powered via USB because it's all inputs.

Why starting with a centre value? although it's called rudder, it's actually not used for a rudder, but for a knob, so values should go from 0 to 1023.
How do I assign the value to the joystick output? Joystick.setRudder(oldrudder);?

Because you have to HAVE a start value (although you could read it in setup) but for a rudder straight ahead makes sense.

yes, of course. That makes sense. (?)

Your readings from the ADC will go from low ( - around 0-20, depending on ADC offset error) to high (depending on the supply and ADC reference.)

Like this

In your code I dont see where "gain" and "lev" are declared?

It's called rudder because I assigned this value to Joystick.setRudder(rudder_); and I just copy/pasted some working code and adjusted to my needs, but it really doesn't matter what the variable is called. I just told you it was not a rudder to let you know that it didn't necessarily need to be a centered position pot, like a thumb joystick or a rudder. It's a knob.

Lines 9 and 10

Anyway, I'll test your code and let you know how it works.

I think that worked, yes. Thank you!! I'll do some more tests, but the preliminary one I just very quickly did seems to have gotten rid of the jitter

Shouldn't that be >>4?

Duh! YES

Or >> 3.

a7

You are right!

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