Lamp power meter on an Arduino Uno
A MAX471 board in a 6 V lamp’s supply lead: the volts, milliamps and milliwatts on a 16x2 I2C LCD, and the surge a cold filament draws. The whole build, an Arduino Uno and 5 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.
Beginner About 25 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $37. On Mokxi they're free.
What you'll learn
- Measuring current with a sensor board in series
- Scaling a voltage divider back to the real voltage
- Power as volts times amps
- Why a cold lamp filament draws a surge
- Averaging samples to reduce noise
- Difficulty: Beginner
- Time: About 25 minutes
- Board: Arduino Uno R3
- Parts: 6
How it works
A MAX471 board sits in the lamp's supply lead, between the bench supply and the lamp, with a button to switch it on. The board gives two voltages the Uno can read: A0 is 1 V for each amp, and A1 is a fifth of the supply voltage.
Ten times a second, the sketch averages 16 readings of each. It turns them into millivolts, then milliamps and milliwatts, and shows voltage, current, power and the highest current seen on a 16x2 I2C LCD and on serial. A cold filament has low resistance, so pressing the button gives a surge before the current settles.
Parts list
6 parts, plus the jumper wires and a bench instrument. The parts retail for about $37; on Mokxi they're free, and so are the instruments.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Half breadboard
- 1 × Current and voltage sensor, MAX471
- 1 × PushbuttonIn Starter Kit, Christmas Lights Kit, Logic Lab Kit.
- 1 × Filament lampIn Power Bank Kit.
- 1 × Bench power supplyIn Pinball Table Kit.
- 1 × Character LCD with I2C backpackIn Claw Machine Kit, Vending Machine Kit, Rhythm Game Kit.
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 |
|---|---|
| Character LCD with I2C backpack pin VCC | Arduino Uno R3 pin 5V |
| Current and voltage sensor, MAX471 pin GND | Arduino Uno R3 pin GND |
| Filament lamp pin 2 | Arduino Uno R3 pin GND |
| Bench power supply pin V- | Arduino Uno R3 pin GND |
| Character LCD with I2C backpack pin GND | Arduino Uno R3 pin GND |
| Current and voltage sensor, MAX471 pin AT | Arduino Uno R3 pin A0 |
| Current and voltage sensor, MAX471 pin VT | Arduino Uno R3 pin A1 |
| Character LCD with I2C backpack pin SDA | Arduino Uno R3 pin A4 |
| Character LCD with I2C backpack pin SCL | Arduino Uno R3 pin A5 |
| Pushbutton pin 2a | Current and voltage sensor, MAX471 pin VIN |
| Filament lamp pin 1 | Current and voltage sensor, MAX471 pin VOUT |
| Bench power supply pin V+ | Pushbutton pin 1a |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Lamp power meter: a MAX471 current sensor board in a lamp's supply lead,
// and the voltage, current and power on a 16x2 I2C LCD.
//
// A0 the MAX471 board's AT (1 V an amp)
// A1 the board's VT (a fifth of the supply voltage)
// GND the board's GND, which is also the supply's minus
// VIN the bench supply's plus; VOUT to the lamp
// LCD SDA -> A4 SCL -> A5 VCC -> 5 V GND -> GND
//
// The MAX471 puts 500 uA out for every amp through its 35 milliohm resistor,
// and the board turns that into a voltage across 2 kohm: 1 V an amp, so on a
// 5 V Uno one converter step is 4.9 mA. VT is the supply through a 30 k and
// 7.5 k divider, a fifth of it, so a step is 24 mV.
//
// Press the button to light the lamp. A cold tungsten filament has about a
// tenth of its hot resistance, so the current jumps and then settles as it
// warms up. The peak line keeps the highest reading, which with a reading
// every tenth of a second or so is the tail of that surge, not its top.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int AT_PIN = A0;
const int VT_PIN = A1;
LiquidCrystal_I2C lcd(0x27, 16, 2);
long peakMa = 0;
// The average of 16 readings, in millivolts.
long readMv(int pin) {
long sum = 0;
for (int i = 0; i < 16; i++) sum += analogRead(pin);
return sum * 5000L / 1023L / 16;
}
void setup() {
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: lamp power meter");
lcd.init();
lcd.backlight();
}
void loop() {
long mA = readMv(AT_PIN); // 1 mV on AT is 1 mA
long mV = readMv(VT_PIN) * 5; // VT is a fifth of the supply
long mW = mV * mA / 1000;
if (mA > peakMa) peakMa = mA;
lcd.setCursor(0, 0);
lcd.print(mV / 1000);
lcd.print('.');
lcd.print((mV % 1000) / 100);
lcd.print(" V ");
lcd.print(mA);
lcd.print(" mA ");
lcd.setCursor(0, 1);
lcd.print(mW);
lcd.print(" mW pk ");
lcd.print(peakMa);
lcd.print(" ");
Serial.print("V: ");
Serial.print(mV);
Serial.print(" mV I: ");
Serial.print(mA);
Serial.print(" mA P: ");
Serial.print(mW);
Serial.print(" mW peak: ");
Serial.println(peakMa);
delay(100);
}
Code walkthrough
The key functions of the sketch, and what each one does.
readMv sketch.ino
Takes 16 analogRead samples on a pin, adds them up, then scales the sum to millivolts on a 5 V reference and divides by 16. The average steadies the reading.
// The average of 16 readings, in millivolts.
long readMv(int pin) {
long sum = 0;
for (int i = 0; i < 16; i++) sum += analogRead(pin);
return sum * 5000L / 1023L / 16;
}setup sketch.ino
Opens serial at 115200, prints a hello line, starts the LCD and turns on its backlight.
void setup() {
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: lamp power meter");
lcd.init();
lcd.backlight();
}loop sketch.ino
Reads current in mA straight from AT, since 1 mV there is 1 mA. It multiplies the VT reading by 5 to get supply millivolts, then computes mW. It updates peakMa, writes two lines to the LCD, prints to serial, and waits 100 ms.
void loop() {
long mA = readMv(AT_PIN); // 1 mV on AT is 1 mA
long mV = readMv(VT_PIN) * 5; // VT is a fifth of the supply
long mW = mV * mA / 1000;
if (mA > peakMa) peakMa = mA;
lcd.setCursor(0, 0);
lcd.print(mV / 1000);
lcd.print('.');
lcd.print((mV % 1000) / 100);
lcd.print(" V ");
lcd.print(mA);
lcd.print(" mA ");
lcd.setCursor(0, 1);
lcd.print(mW);
lcd.print(" mW pk ");
lcd.print(peakMa);
lcd.print(" ");
Serial.print("V: ");
Serial.print(mV);
Serial.print(" mV I: ");
Serial.print(mA);
Serial.print(" mA P: ");
Serial.print(mW);
Serial.print(" mW peak: ");
Serial.println(peakMa);
delay(100);
// ... 1 more lines in the editorTroubleshooting
The usual mistakes with this circuit, and the fix for each.
- The peak does not show the true surge top. This project
That is expected. The meter samples about every tenth of a second, so the peak is the tail of the surge rather than its very top. - Voltage reads zero or current looks wrong. This project
Check the bench supply's minus, the lamp's other end and the Uno GND are all joined to the board's GND, and that the button is closed. - The current reading is wrong. Current and voltage sensor
Put the sensor in series with the supply, with the plus side toward the source. AT gives about 1 V per amp, so convert analogRead using your reference voltage (5 V for 1023). - The voltage reading is off. Current and voltage sensor
VT is one fifth of the input voltage, so multiply by 5. It works only up to about 25 V, and the maximum current is 3 A. - The input reads random HIGH and LOW when the button is not pressed. Pushbutton
A floating pin picks up noise. Add a 10 k pull-down or pull-up resistor, or use INPUT_PULLUP and wire the button between the pin and GND. Then pressed reads LOW. - The button seems always pressed, or never changes. Pushbutton
A 4-leg tactile switch has legs joined in pairs. Place it across the breadboard center gap so the pairs sit on different rows. Wired along one side, the legs are already connected. - The lamp is dim or does not light when driven from a board pin. Filament lamp
A lamp needs far more current than a pin gives (a pin is limited to about 20 mA). Switch it with a transistor or MOSFET from its own supply that matches the lamp's voltage rating. - The lamp's brightness lags or it burns out the switch when it first turns on. Filament lamp
A cold filament draws several times its running current at first. Size the switch for that surge, not just the steady current.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.