from machine import ADC, I2C, Pin
from machine_i2c_lcd import I2cLcd
import time
#lcd setup
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
adc = ADC(26)
# PULL_DOWN: pin reads 0 normally, goes to 1 when button is pressed
btn_left = Pin(10, Pin.IN, Pin.PULL_DOWN)
btn_right = Pin(11, Pin.IN, Pin.PULL_DOWN)
# Modes for menu
modes = ["Voltage", "Current", "Resistance", "Capacitance"]
current_mode = 0
# screen intro
lcd.clear()
lcd.putstr(" Multimeter ")
time.sleep(2)
# main loop
while True:
# left button - reads 1 when pressed
if btn_left.value() == 1:
if current_mode > 0:
current_mode = current_mode - 1
time.sleep(0.3) # debounce
# right button - reads 1 when pressed
if btn_right.value() == 1:
if current_mode < len(modes) - 1:
current_mode = current_mode + 1
time.sleep(0.3) # debounce
# Read the potentiometer
raw = adc.read_u16() # gives a number from 0 to 65535
volts = raw * 3.3 / 65535 # convert to volts (0.0 to 3.3)
# Work out what to display based on the selected mode
if modes[current_mode] == "Voltage":
reading = str(round(volts, 2)) + " V"
elif modes[current_mode] == "Current":
# Simulated: using 100 ohm, formula used is I = V / R
amps = volts / 100
reading = str(round(amps * 1000, 2)) + " mA"
elif modes[current_mode] == "Resistance":
# Voltage divider with known 1k resistor: R = R_known * V / (Vcc - V)
if volts >= 3.28:
reading = "Overload"
else:
ohms = 1000 * volts / (3.3 - volts)
reading = str(round(ohms, 1)) + " Ohm"
elif modes[current_mode] == "Capacitance":
# RC time constant formula: C = t / R
# The pot voltage (0 to 3.3V) maps to a simulated charge time (0 to 0.033 seconds)
# Fixed known resistor R = 10,000 ohms (10k)
# So C = t / R gives a range of 0 to 3.3 uF
R = 10000
t = (volts / 3.3) * 0.033 # simulated time in seconds (0 to 33ms)
C = t / R # capacitance in Farads
C_uf = C * 1000000 # convert to microfarads
reading = str(round(C_uf, 2)) + " uF"
#below is what is outputted on lcd
lcd.clear()
lcd.putstr(modes[current_mode])
lcd.move_to(0, 1)
lcd.putstr(reading)
time.sleep(0.3)