Built-in project · Arduino Uno R3

Level meter on an Arduino Uno

A potentiometer on A0 and a ten-segment LED bar graph with a resistor a bar. The top bar dims with PWM where its pin has it, so the meter moves more smoothly. The whole build, an Arduino Uno and 12 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Intermediate About 20 minutes to build and run. Runs in your browser. Free, and no account needed.

The parts retail for about $34. On Mokxi they're free.

The circuit runs here once the page has loaded.

What you'll learn

  • Reading a potentiometer with analogRead
  • Scaling a reading with integer math
  • A bar graph as ten LEDs with ten resistors
  • Dimming with analogWrite on PWM pins
  • Difficulty: Intermediate
  • Time: About 20 minutes
  • Board: Arduino Uno R3
  • Parts: 14

How it works

The potentiometer's wiper goes to A0. The sketch reads it, scales the 0 to 1023 count to 0 to 100, and splits that into whole bars (tens) and a leftover part (ones).

A bar graph is ten separate LEDs in one block, so each of the ten segments has its own 220 ohm resistor and its own pin, 2 to 11. Bars below the level turn fully on.

The next bar shows the leftover as a dim glow using PWM, but only on pins 3, 5, 6, 9, 10 and 11. The other pins skip the dimming and jump from off to on.

Parts list

14 parts, plus the jumper wires. They retail for about $34; on Mokxi they're free.

Kits that can build it

This starter kit has every part in the circuit. Each kit's page lists what else it can build.

Wiring table

Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.

Part and pinConnects to
Resistor, 220 Ω (10) pin 1Arduino Uno R3 pin 11
Resistor, 220 Ω (9) pin 1Arduino Uno R3 pin 10
Resistor, 220 Ω (8) pin 1Arduino Uno R3 pin 9
Resistor, 220 Ω (7) pin 1Arduino Uno R3 pin 8
Resistor, 220 Ω (6) pin 1Arduino Uno R3 pin 7
Resistor, 220 Ω (5) pin 1Arduino Uno R3 pin 6
Resistor, 220 Ω (4) pin 1Arduino Uno R3 pin 5
Resistor, 220 Ω (3) pin 1Arduino Uno R3 pin 4
Resistor, 220 Ω (2) pin 1Arduino Uno R3 pin 3
Resistor, 220 Ω (1) pin 1Arduino Uno R3 pin 2
Potentiometer pin 1Arduino Uno R3 pin 5V
LED bar graph, 10 segments pin C10Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C9Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C8Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C7Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C6Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C5Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C4Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C3Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C2Arduino Uno R3 pin GND
LED bar graph, 10 segments pin C1Arduino Uno R3 pin GND
Potentiometer pin 3Arduino Uno R3 pin GND
Potentiometer pin 2Arduino Uno R3 pin A0
Resistor, 220 Ω (1) pin 2LED bar graph, 10 segments pin A1
Resistor, 220 Ω (2) pin 2LED bar graph, 10 segments pin A2
Resistor, 220 Ω (3) pin 2LED bar graph, 10 segments pin A3
Resistor, 220 Ω (4) pin 2LED bar graph, 10 segments pin A4
Resistor, 220 Ω (5) pin 2LED bar graph, 10 segments pin A5
Resistor, 220 Ω (6) pin 2LED bar graph, 10 segments pin A6
Resistor, 220 Ω (7) pin 2LED bar graph, 10 segments pin A7
Resistor, 220 Ω (8) pin 2LED bar graph, 10 segments pin A8
Resistor, 220 Ω (9) pin 2LED bar graph, 10 segments pin A9
Resistor, 220 Ω (10) pin 2LED bar graph, 10 segments pin A10

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// Level meter: a potentiometer on A0 and a ten-segment LED bar graph.
//
//   potentiometer   ends to 5 V and GND, wiper -> A0
//   bar graph       anodes A1..A10 -> pins 2 to 11, each through its own 220 ohm
//                   cathodes C1..C10 -> GND
//
// A bar graph is ten separate LEDs in one block, each with its own two legs,
// so it wants ten resistors exactly as ten LEDs would. Turn the knob and the
// bar follows; the top bar is dimmed with PWM in proportion to how far the
// reading is into it, so the meter moves smoothly rather than in tenths.

const uint8_t BAR_PINS[10] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

void setup() {
  for (uint8_t i = 0; i < 10; i++) pinMode(BAR_PINS[i], OUTPUT);
}

void loop() {
  // 0..1023 into 0..100: whole bars, and hundredths of the next one.
  long level = (long)analogRead(A0) * 100 / 1023;
  uint8_t whole = (uint8_t)(level / 10);
  uint8_t part = (uint8_t)(level % 10);
  for (uint8_t bar = 0; bar < 10; bar++) {
    uint8_t pin = BAR_PINS[bar];
    if (bar < whole) {
      digitalWrite(pin, HIGH);
    } else if (bar == whole && part > 0 && (pin == 3 || pin == 5 || pin == 6 || pin == 9 ||
                                           pin == 10 || pin == 11)) {
      analogWrite(pin, part * 25);  // the pins with PWM can show the fraction
    } else {
      digitalWrite(pin, LOW);
    }
  }
  delay(20);
}

Code walkthrough

The key functions of the sketch, and what each one does.

setup sketch.ino

setup makes all ten bar pins outputs. Nothing else needs setting up because analogRead works without it.

void setup() {
  for (uint8_t i = 0; i < 10; i++) pinMode(BAR_PINS[i], OUTPUT);
}

loop sketch.ino

loop reads A0 and scales it to 0 to 100. The tens say how many bars are fully lit. The ones become a PWM brightness for the next bar, if that pin supports PWM. Every other bar is turned off. A 20 ms delay keeps it steady.

void loop() {
  // 0..1023 into 0..100: whole bars, and hundredths of the next one.
  long level = (long)analogRead(A0) * 100 / 1023;
  uint8_t whole = (uint8_t)(level / 10);
  uint8_t part = (uint8_t)(level % 10);
  for (uint8_t bar = 0; bar < 10; bar++) {
    uint8_t pin = BAR_PINS[bar];
    if (bar < whole) {
      digitalWrite(pin, HIGH);
    } else if (bar == whole && part > 0 && (pin == 3 || pin == 5 || pin == 6 || pin == 9 ||
                                           pin == 10 || pin == 11)) {
      analogWrite(pin, part * 25);  // the pins with PWM can show the fraction
    } else {
      digitalWrite(pin, LOW);
    }
  }
  delay(20);
}

Troubleshooting

The usual mistakes with this circuit, and the fix for each.

  • Bars light out of order. This project
    Anodes A1 to A10 go through resistors to pins 2 to 11 in order.
  • One bar never lights. This project
    Each segment has its own resistor. Check that one resistor and its cathode wire to GND.
  • Some bars jump instead of fading in. This project
    Only pins 3, 5, 6, 9, 10 and 11 can dim. That is how the Uno works.
  • Segments are dim, uneven, or the chip is damaged. LED bar graph
    Every segment is its own LED and needs its own current-limiting resistor, about 220 to 330 ohms at 5 V. One shared resistor makes brightness change with how many are lit.
  • The bar lights in reverse order or a segment never lights. LED bar graph
    Check pin 1 and the orientation. Anode and cathode sides are on opposite rows. Some bars are numbered the other way around, so test with one segment at a time.
  • The reading jumps around or only covers part of the range. Potentiometer
    Wire the two outer legs to 5 V and ground and the middle leg (the wiper) to an analog pin. Using the wrong two legs gives a dead or partial range.
  • Turning the knob does nothing, or the value is stuck at 0 or 1023. Potentiometer
    Check that the wiper goes to an analog input (A0 to A5 on an Uno), not a digital pin. Make sure both ends are connected, since a floating end gives noise.
  • The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
    Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.