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.
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
analogWriteon 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.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Full-size breadboard
- 1 × LED bar graph, 10 segmentsIn Spaceship Panel Kit.
- 1 × PotentiometerIn Halloween Prop Kit, Starter Projects Kit.
- 10 × Resistor, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
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 pin | Connects to |
|---|---|
| Resistor, 220 Ω (10) pin 1 | Arduino Uno R3 pin 11 |
| Resistor, 220 Ω (9) pin 1 | Arduino Uno R3 pin 10 |
| Resistor, 220 Ω (8) pin 1 | Arduino Uno R3 pin 9 |
| Resistor, 220 Ω (7) pin 1 | Arduino Uno R3 pin 8 |
| Resistor, 220 Ω (6) pin 1 | Arduino Uno R3 pin 7 |
| Resistor, 220 Ω (5) pin 1 | Arduino Uno R3 pin 6 |
| Resistor, 220 Ω (4) pin 1 | Arduino Uno R3 pin 5 |
| Resistor, 220 Ω (3) pin 1 | Arduino Uno R3 pin 4 |
| Resistor, 220 Ω (2) pin 1 | Arduino Uno R3 pin 3 |
| Resistor, 220 Ω (1) pin 1 | Arduino Uno R3 pin 2 |
| Potentiometer pin 1 | Arduino Uno R3 pin 5V |
| LED bar graph, 10 segments pin C10 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C9 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C8 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C7 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C6 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C5 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C4 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C3 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C2 | Arduino Uno R3 pin GND |
| LED bar graph, 10 segments pin C1 | Arduino Uno R3 pin GND |
| Potentiometer pin 3 | Arduino Uno R3 pin GND |
| Potentiometer pin 2 | Arduino Uno R3 pin A0 |
| Resistor, 220 Ω (1) pin 2 | LED bar graph, 10 segments pin A1 |
| Resistor, 220 Ω (2) pin 2 | LED bar graph, 10 segments pin A2 |
| Resistor, 220 Ω (3) pin 2 | LED bar graph, 10 segments pin A3 |
| Resistor, 220 Ω (4) pin 2 | LED bar graph, 10 segments pin A4 |
| Resistor, 220 Ω (5) pin 2 | LED bar graph, 10 segments pin A5 |
| Resistor, 220 Ω (6) pin 2 | LED bar graph, 10 segments pin A6 |
| Resistor, 220 Ω (7) pin 2 | LED bar graph, 10 segments pin A7 |
| Resistor, 220 Ω (8) pin 2 | LED bar graph, 10 segments pin A8 |
| Resistor, 220 Ω (9) pin 2 | LED bar graph, 10 segments pin A9 |
| Resistor, 220 Ω (10) pin 2 | LED 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.
// 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.