Potentiometer Position Monitor

Updated 17 June 2022

Bill of Materials

Arduino Nano Every

For the display I used a green LED to indicate the centre with a 10 LED yellow display above and below this to indicate position above and below the centre. These LEDs are connected in pairs working from the centre outwards. Each pair connected to 1 Arduino output. The LEDs operate in dot mode so each bank is connected common cathode and a single current limiting resistor used for each bank. Each bank then via a diode to an output (PWM capable) arranged to SINK the LED current when the bank is required to be ON. PWM is used here as a more convenient way to control brightness. An analog input and a pot could be used but as this would be a “set and forget” function I decided that manually entering numbers would be less hassle. Please note the “negative” logic. “0” = LOW or full-on while “255”= HIGH or off. The diodes are to isolate the LEDs from the 5V reverse voltage applied to the LEDs in the OFF bank. Signal diodes (1N4148/914) are used here as power diodes would not be effective at PWM frequencies.

I have created a virtual “centre zero” pot with ascending values above and below centre to drive the display by mapping the ADC output to “-20 to +21” to represent 41 LEDs. As only 21 are used this effectively monitors close to 50% of pot travel, 25% either side of centre. This can be changed simply by changing the mapped range. The Arduino input impedance seems to be high enough not to interfere with the normal operation of the pot. The negative region is sensed and bank switching arranged and ADC output multiplied by -1 to change sign and become useful.

With the quoted values the centre LED is on for 1.25% above and below centre and each subsequent LED is on for 2.5% of pot travel. The extreme LEDs are kept “ON” when pot goes “off-scale” or outside of the monitor range for indication purposes. I have the centre LED driven via a diode with another diode from 3.3V. This keeps this LED on dimly at all times. These diodes are necessary to isolate the two supplies. If this feature is not required, leave it out.

The departure from “normal” here is the use of, and method of obtaining, a centre zero potentiometer. I have not seen anything published along these lines so I hope my little project sparks some interest and may prove useful in the Arduino community.

I used this “centre zero” pot configuration years ago pre Arduino (read picaxe) days to help a guy in Melbourne. He needed to drive a small DC motor in both directions using a single pot for Telescope focus control. The requirement was to be able to drive the motor very slowly in either direction using one control. PWM and a bit of arithmetic involved but overall it was a fairly easy task!

Read the ADC value 0 - 1023

Subtract 512

Divide by 2

Result is -255 to +255

Do the same as here. Detect <0, initiate reversing of motor, multiply by -1 to change sign, apply PWM (now a positive number).

I created a small dead zone to help easily find 0 as I could not readily find a centre indent pot. And yes they did exist at one time (back in the day).

Ongoing saga.

Problems with voltage drop over very thin PS2 cable when powering Arduino from this supply. A temporary fix is to power the Arduino via a USB connector.

Back to sourcing a suitable Joystick controller. Settled on a board from Leo Bodnar Electronics in the UK designated BU0836A. Features 8 analog 12 bit inputs and 36 push button inputs arranged in a 6 column 6 row matrix. The last 4 are reserved for POV hat switch. The remaining 32 can be configured for up to 16 rotary encoders. Enquiries revealed this board can supply 100mA or so from the 5V analog connections. It seems the supply problem has been solved. A Teensy may have done this job but did not know of it at the time.

Initial Testing

Changed mapping to -30 - +31 to suit my application better. Monitoring is more sensitive, 33% of rotation instead of 50%. Each function in isolation works flawlessly. When together and the Arduino powered from a Bodnar board some interference/instability appeared. This showed up as a jittering of the elevator trim wheel on the screen graphic. Also a slight flickering of the LEDs. This did not seem to affect the aircraft flight but was quite annoying as I felt this should not happen. Temporary solution 10uF tantalum cap between analog inputs (both effectively connected together) and ground. This seemed to keep it quite a fair bit for the time being. Time constant due to 10uF did not prove to be a concern in practice.

Next Solution

I removed 10uF and fit a dual OP amp as a voltage follower to isolate the 2 analog inputs and provide a low impedance feed for them. This improved things but did not eliminate the problem. I decided the isolating OP amps were a good thing anyway so have been left in situ.

I originally used an OP amp LM258 which I had on hand. A useful device to keep a few. Wide supply (3V – 30V) voltage, single or split supply and overall fairly rugged. However, the output is not rail to rail which really should be used in this application. Consequently, I have changed this for an LMC6482AIN which has not affected the operation at all. I just feel better about it. The schematic at the bottom of this page covers the completed build.

I noted that instability seemed to disappear when the potentiometer was in the centre. I then disabled the PWM signal used for LED brightness and just switched the banks ON when required. This removed most of the problem.

For Flap Control, I found a 5 position lever switch recovered from somewhere and found that when an analogue axis assigned to this function the operation is quite linear. I wired 3 equal (3k3) resistors across it as a 4 position switched potentiometer for “UP, 10deg, 20deg, 30deg”. Works no problems.

The Bodnar board is housed in the grey box, that is the reason for the 350mm of wire between this and the Arduino. There are 9 rotary encoders also fitted. I have fitted the BU0836A Switch Matrix Breakout Board to simplify things and assigned switches 1 to 18 as rotary encoder inputs.


For mechanical reasons, I need to use about 350mm of wire between the Bodnar board and Arduino/potentiometer. I have not tried any measurements yet but am thinking the PWM switching of the LEDs causes some switching artefacts to appear on the 5V line. It would not need much and would not show up on the LED banks. Keep in mind the resolution of the Bodnar board would be about 1.2mV (0 - 4096) and the LED indicators due to my mapping would be in the order of 82mV. The bit left I almost completely removed with 100uF on the 5V line.

Another thing to consider as well as the resistance of the supply wire is the inductance. This can have an effect when the current is switched quickly as in the PWM switching of the LED current. This is known as a “charge pump” effect and shows up as an apparent increase of the supply voltage. More apparent when switching higher currents such as when I was repairing 12V golf buggies as a part-time exercise where the current could exceed 20A. The solution here is to use supply wiring as short and thick as practical (both reduce inductance). If this is not possible a capacitor of several thousand uF where the supply enters the control board is required. At times with the golf buggy bit, I had to use longer supply wires and this charge pump error could be 1V or more. Made checking and/or adjusting any low voltage cut off system pretty much impossible. My solution here was to fit a 10000uF cap temporarily. Ever noticed golf buggy battery supply wiring seems ridiculously short? That is the reason so don’t go making it longer or problems may appear.

I repeat this instability did not appear to affect flight operation but I know it is there and it annoys me.

I would like to not use this 100uF so my next experiment is to separately power the Arduino via the USB connector. This will have to be some time in the future but for now, all is working fine. I would also like to return to the PWM system of brightness control. When I get to it if I find the problem is due to the “charge pump” effect I may have to increase the 100uF to 470uF or more. The other alternative is to separately power the NanoEvery on a permanent basis. That is something to try later!

Arduino Sketch

I have commented out the PWM control of brightness and replaced with hard switch on. PWM control can be replaced easily if required.

Potentiometer Position Monitor sketch adapted from "Bargraph" example by Tom Igoe.

Changed to "Dot" mode as current not available for "Bar" mode

Objective: Provide position indication of a 10 turn potentiometer with respect to centre, (5 turns). Monitored over portion of range in this case 50% ie; +/- 25% either side of centre. Approx 25% to 75% of total.

There are two banks of 10 LEDs. Each bank wired common cathode via a single 220ohm limiting resistor and reverse voltage blocking diode to "Bank Select" output pins. These pins are PWM capable to control LED brightness. Blocking diodes used as LEDs usually only have a 5V reverse voltage maximum which will be the case when a Bank is "OFF". Do NOT use power diodes here as they will not respond quick enough to PWM signals. 1N914/1N4148 small signal diodes are OK. Corresponding anodes connected together ie; 1 to 1, 2 to 2 etc counting from the centre. Each digital output connected to 2 LED anodes.

Banks are arranged with a LED of a different colour between them to indicate "Zero" or centre position. Wired to Ground via 330ohm limiting resistor and driven from digital output 2 via a diode. Also connected via a diode to 3.3V so LED is dimly at all times. Disregard if this is not required. The diodes here are to isolate 2 different supplies and MUST be used. As above 1N914/1N4148 are OK.

Mapping ADC output from -20 to +21 provides a virtual centre zero on the potentiometer with ascending numerals either side of centre. Negative numbers are no use here so when in the negative region LED banks are switched and re-mapped and the ADC values are multiplied by -1, converting negative to positive. Non-symmetrical mapping moves the LED display slightly so the centre LED is ON when the pot moved equally either side of the centre. 48.8% to 51.2% of rotation. LEDs are switched on in turn for approx 2.5% of pot rotation in either direction. Last LED in each bank remains ON when the pot is past monitoring extremities or "out of range".

The monitored range of the Potentiometer can be changed by changing the mapping range. Example -25 to +26 would monitor 40%, -30 to +31 33.3% and so on.

The virtual zero point can also be moved by changing the symmetry of the mapping. In this sketch changing mapping to -15 to +26 would move the virtual zero point about 12.5% away from the actual centre of pot travel.

This is a fairly simple method of converting a normal pot to centre zero, I have used this to control speed and direction of a small DC motor using a single pot with the centre off or stopped. Used for this purpose a small "dead zone" needs to be created in the centre.

// these constants won't change:
const int analogPin = A0;   // the pin that the potentiometer is attached to
const int ledCount = 11;    // the number of LEDs in the bar graph
const int ledUp = 9;        //LED bank nose up
const int ledDn = 10;       //LED bank nose down

int ledPins[] = {
  2, 3, 4, 5, 6, 7, 8, A4, A5, 11, 12
};   // an array of pin numbers to which LEDs are attached

void setup() {
  // loop over the pin array and set them all to output:
  for (int thisLed = 0; thisLed < ledCount; thisLed++) {
    pinMode(ledPins[thisLed], OUTPUT);
    //set led bank switching pins to output:
    //Note LOW is active ie; led bank ON:
    pinMode(ledUp, OUTPUT);
    pinMode(ledDn, OUTPUT);

void loop() {
  // read the potentiometer:
  int sensorReading = analogRead(analogPin);

  //create virtual centre zero potentiometer:
  int ledLevel = map(sensorReading, 0, 1023, -30, 31);

      if (ledLevel > 0)
      digitalWrite(ledUp, HIGH);//ledUp nose up bank OFF:
      digitalWrite(ledDn, LOW);//ledDn nose down bank ON:
      //analogWrite(ledDn, 180);//ledDn nose down bank ON:
      //digitalWrite(ledDn, LOW);
      //pwm to control led brightness, 0=LOW (full on), 255=HIGH (off):

      // change sign for ledLevel when pot below centre:
      if (ledLevel < 0)
      ledLevel=(ledLevel * -1);
      //switch led banks:
      digitalWrite(ledUp, LOW);//ledUp nose up bank ON:
      //analogWrite(ledUp, 180);//ledUp nose up bank bank ON:
      //digitalWrite(ledUp, LOW);
      digitalWrite(ledDn, HIGH);//ledDn nose down bank OFF:
      //pwm to control led brightness, 0=LOW (full on), 255=HIGH (off):

      //keep LED 10 on when potentiometer outside monitor range:
      if (ledLevel >= 10)
        ledLevel = 10;

      // loop over the LED array:
      for (int thisLed = 0; thisLed < ledCount; thisLed++)
          // turn the pin for this element on:
          if (thisLed == ledLevel)
          digitalWrite(ledPins[thisLed], HIGH);
          // turn off all pins other than the ledLevel:
          digitalWrite(ledPins[thisLed], LOW);


Thank you for reading my project! Be sure to head over to the forum if you've got any questions!

Attachment - Project Files

Have a question? Ask the Author of this guide today!

Please enter minimum 20 characters

Your comment will be posted (automatically) on our Support Forum which is publicly accessible. Don't enter private information, such as your phone number.

Expect a quick reply during business hours, many of us check-in over the weekend as well.



Please continue if you would like to leave feedback for any of these topics:

  • Website features/issues
  • Content errors/improvements
  • Missing products/categories
  • Product assignments to categories
  • Search results relevance

For all other inquiries (orders status, stock levels, etc), please contact our support team for quick assistance.

Note: click continue and a draft email will be opened to edit. If you don't have an email client on your device, then send a message via the chat icon on the bottom left of our website.

Makers love reviews as much as you do, please follow this link to review the products you have purchased.