Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

MLX90614 IR thermometer with Raspberry Pi Pico W — MicroPython

Read object and ambient temperature from an MLX90614 (GY-906) on Pico W I2C0 at 100 kHz in MicroPython with SMBus word reads, no library.

MicroPythonVerified — micropython (mpy-cross v1.29.0), 3 Nov 2026Compile-only

Community draft — report a mistake

The MLX90614 measures the temperature of whatever it points at, without touching it — handy for motors, cooking surfaces and contactless thermometer projects. Over I2C it behaves like an SMBus device: one word read per temperature.

Wire the GY-906 to 3V3 and I2C0 (GP4/GP5) at 100 kHz. The script prints object and ambient temperature twice a second.

Wiring

Raspberry Pi Pico WOnly the pins used are shown · 3.3 V logicMLX90614 IR thermometer (GY-906)GNDGP4GP53V3VINGNDSCLSDA
Every connection
Raspberry Pi Pico WMLX90614 IR thermometer (GY-906)WireNotes
3V3VINred3V3 is pin 36. Safe for both 3 V (BAA) and regulator boards.
GNDGNDblack
GP5SCLyellowGP5 is physical pin 7 (I2C0 SCL).
GP4SDAblueGP4 is physical pin 6 (I2C0 SDA).

3.3 V (5 V versions with regulator) part, 3.3 V board. Check the chip marking: MLX90614BAA is a 3 V part, MLX90614AAA is 5 V. Most GY-906 boards with a regulator accept 3.3–5 V; power 3 V-only boards from 3.3 V.

Board quirks

  • The MLX90614 is an SMBus device: keep the bus at 100 kHz. At 400 kHz it often drops off the bus.
  • readfrom_mem(0x5A, 0x07, 3) returns the object temperature (low byte, high byte, PEC); register 0x06 is the sensor’s own (ambient) temperature. Each bit is 0.02 K.
  • The field of view is about 90° on the GY-906: at 10 cm it averages a circle about 20 cm wide. Get close to measure a small spot.
  • It reads skin a degree or two below body temperature — fine for a project, not a medical thermometer.

Code

main.pyMicroPython
# MLX90614 (GY-906) non-contact IR thermometer on a Raspberry Pi Pico W (MicroPython, no library).
# Wiring: VIN -> 3V3 (pin 36), GND -> GND, SCL -> GP5 (pin 7), SDA -> GP4 (pin 6). I2C0, 100 kHz.
from machine import Pin, I2C
import time

ADDR = 0x5A
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100_000)  # SMBus device - keep it at 100 kHz
if ADDR not in i2c.scan():
    raise SystemExit("No MLX90614 at 0x5A - found {}".format([hex(a) for a in i2c.scan()]))


def read_temp(ram_addr):
    lo, hi, _pec = i2c.readfrom_mem(ADDR, ram_addr, 3)  # data word + SMBus PEC byte
    raw = (hi << 8) | lo
    if raw & 0x8000:
        raise OSError("error flag set")
    return raw * 0.02 - 273.15  # 0.02 K per bit


print("MLX90614 at 0x5A")
while True:
    try:
        ambient = read_temp(0x06)
        obj = read_temp(0x07)
        print("Object {:.2f} C  Ambient {:.2f} C".format(obj, ambient))
    except OSError as e:
        print("Read failed:", e)
    time.sleep_ms(500)

Expected serial output

REPL / Thonny shellOutput
MLX90614 at 0x5A
Object 33.84 C  Ambient 28.12 C
Object 61.02 C  Ambient 28.14 C

Common errors

No MLX90614 at 0x5A

Drop the bus to 100 kHz, check SDA (GP4, pin 6) and SCL (GP5, pin 7). A 5 V-only (AAA) chip on 3.3 V may not answer.

Object temperature of shiny metal is far too low

Polished metal reflects IR instead of emitting it. Put a piece of matt black tape on the surface and measure the tape.

↑↓ to move · Enter to open