Introduction

A potentiometer is a variable resistor that functions as an adjustable voltage divider. It's essentially a knob that allows you to modify resistance values, which can be read as analog input on any analog pin of an Arduino board.

In practical applications, such as the multidimensional box project, potentiometers are used to fine-tune parameters like the maximum distance threshold for ultrasonic sensors, providing real-time configuration adjustments without code modifications.

Wiring the Potentiometer

To connect a potentiometer to your Arduino board, you need three wires:

By rotating the potentiometer shaft, you change the resistance on either side of the wiper, which alters the voltage at the center pin. This voltage is proportional to the position of the shaft and can be read as an analog value.

Arduino Potentiometer Wiring Diagram

Important Note: Be careful not to confuse potentiometers with digital rotary encoders. Potentiometers provide analog values (0-1023), while rotary encoders provide digital signals and require different handling.

Reading Analog Values

To read values from a potentiometer, start by declaring an integer variable to store the reading:

int potValue;

Then, use the analogRead() function to read the analog value from the pin connected to the potentiometer's center pin:

// Define the analog pin connected to the potentiometer
#define POTENTIOMETER_PIN A0

// Read the analog value (returns 0-1023)
potValue = analogRead(POTENTIOMETER_PIN);

The analogRead() function returns a value between 0 and 1023:

This range is valid for both 5V and 3.3V Arduino boards (like the Arduino 101). The Arduino's analog-to-digital converter (ADC) automatically scales the input voltage to this 10-bit range (2^10 = 1024 values).

Using the map() Function

Often, you'll want to map the potentiometer's raw value (0-1023) to a different range that's more useful for your application. Arduino provides the map() function for this purpose, eliminating the need to write complex conversion code.

Function Prototype

map(value, fromLow, fromHigh, toLow, toHigh)

Basic Usage

To map a value from the 0-1023 range to a 0-100 range:

int newValue = map(potValue, 0, 1023, 0, 100);

How It Works

The map() function re-maps a number from one range to another:

Important: The map() function does not constrain values to within the range. Out-of-range values are sometimes intended and useful. If you need to limit values, use constrain() in combination with map().

Advanced Examples

Reversing a range: You can reverse a range by swapping the target bounds:

// Maps 1-50 to 50-1 (reversed)
int y = map(x, 1, 50, 50, 1);

Mapping to negative values: The function also handles negative numbers:

// Maps 1-50 to 50 to -100 (inverted and scaled)
int y = map(x, 1, 50, 50, -100);

Flexible bounds: The "lower bounds" of either range may be larger or smaller than the "upper bounds", allowing for creative value transformations.

Practical Applications

Potentiometers are excellent for storing physical configuration values that can be adjusted in real-time without reprogramming. This is particularly useful in robotics applications where fine-tuning parameters is essential.

For example, in the Arduporter robot project, multiple potentiometers are used to fine-tune critical parameters such as:

Using potentiometers allows you to increment or decrement variables in your code and use those values as real-time configuration parameters, making your projects more flexible and easier to calibrate.

Complete Example Code

The following function demonstrates how to use a potentiometer to store a "minDistance" value for robotics applications. This example includes proper timing control to avoid reading the potentiometer too frequently:

// Global variables
unsigned long previousMillis = 0;
const unsigned long potentiometerInterval = 100; // Read every 100ms
int MinDistance = 0;
int oldMinDistance = -1;

void checkPotentiometer() {
    char buf[32];
    unsigned long currentMillis = millis();

    // Only read potentiometer at specified intervals
    if (currentMillis - previousMillis >= potentiometerInterval) {
        previousMillis = currentMillis;

        // Read potentiometer and map to desired range (0-20)
        // Adjust the fromHigh value (690) based on your potentiometer's actual range
        MinDistance = map(analogRead(A4), 0, 690, 0, 20);

        // Only update display if value has changed
        if (oldMinDistance != MinDistance) {
            sprintf(buf, "MinDistance changed to: %d", MinDistance);
            // Display on TFT screen (adjust for your display method)
            tft.drawString(buf, 0, yDraw, 2);
            yDraw = scroll_line();
            oldMinDistance = MinDistance;
        }
    }
}

Code Explanation

Tips and Best Practices

Need More Information?

If you need additional specific information about using potentiometers with Arduino or want to discuss your project personally, please send an email.