Hello friends, I hope you all are doing great. Today, I am going to share the Raspberry Pi Zero 2 W Library for Proteus. The Raspberry Pi Zero 2 W keeps the tiny 65 x 30 mm board of the Zero W but puts a quad-core Cortex-A53 at 1 GHz on it - the RP3A0, with 512 MB of RAM inside the same package - together with Wi-Fi, Bluetooth and the usual 40-pin header. With this library the board runs your Python program against the circuit in Proteus 8.5, on our virtual Wi-Fi.

Updates

Raspberry Pi Zero 2 W Library for Proteus

Latest version: V1.0 (October 2026, this tutorial)

Other Raspberry Pi boards: Pico · Pico W · Pico 2 W · Pi Model B · Pi 1 B+ · Pi 2 Model B · Pi 3 Model B · Pi 3 Model B+ · Pi 3 Model A+ · Pi 4 Model B · Pi 5 · Pi Zero W · Pi 400 · Pi 2 · Pi 3 · Pi 4 · Zero W

Measurement modules: INA219 · Current Sensor WCS1600 · HX711 Load Cell · ADS1115 ADC

Other displays: OLED · Nokia 5110 · LCD 128x64 · ST7735 · ST7789 · ILI9341 · TFT Shield 2.4 inch · TFT Shield 3.5 inch · E-Paper

Helping Tools

This is the tenth library of our Raspberry Pi series, and every library of the series connects the Pi to a different module and serves a web page. This time the Zero 2 W is a Wi-Fi power meter: an INA219 current sensor measures the voltage, the current and the power going to a DC load, a Nokia 5110 LCD shows them, and a page on a laptop and a phone shows them too - with the energy used so far, a current limit and the LCD's backlight.

NOTICE: this library does not run Raspberry Pi OS. It runs your Python program, with the same Python libraries a Pi uses for its pins, its buses and its network, in step with the simulation. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the Raspberry Pi Zero 2 W board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the Raspberry Pi Zero 2 W Library for Proteus:

Figure: The Raspberry Pi Zero 2 W Library for Proteus: PI1 runs power_meter.py - 800 mA through the INA219, over the 500 mA limit, so the Nokia 5110 is inverse, and the phone's page says OVER LIMIT.

What is the Raspberry Pi Zero 2 W?

The Raspberry Pi Zero W of 2017 was small and cheap, but slow: one ARM1176 core, the processor of the very first Pi. In October 2021 the Zero 2 W arrived at 15 dollars with the same size, the same connectors in the same places and the same mounting holes, so it fits the Zero cases - and with about five times the speed on work that uses all its cores.

The trick is the RP3A0, a system-in-package made by Raspberry Pi: the BCM2710A1 - the four Cortex-A53 cores of the Pi 3 - and 512 MB of LPDDR2 RAM stacked together in one square package. Next to it a metal shield can covers the wireless chip, a CYW43438 for 2.4 GHz Wi-Fi and Bluetooth 4.2, with the antenna etched into the board by the camera connector. The 40-pin header is the same as on every Pi since the B+, and it comes unsoldered, as on the other Zeros.

The Raspberry Pi Zero W and the Raspberry Pi Zero 2 W
Raspberry Pi Zero W (2017)Raspberry Pi Zero 2 W (2021)
ProcessorBCM2835, one ARM1176 core at 1 GHzRP3A0 (BCM2710A1), four Cortex-A53 cores at 1 GHz
RAM512 MB, stacked on the processor512 MB LPDDR2 inside the RP3A0
Wireless2.4 GHz Wi-Fi, Bluetooth 4.12.4 GHz Wi-Fi, Bluetooth 4.2 and BLE (in a shielded module)
64-bitnoyes
Video, USB, cameramini-HDMI, micro-USB OTG, CSIthe same
Board65 x 30 mm, unpopulated 40-pin headerthe same
Price at launch10 dollars15 dollars

In Proteus, our Raspberry Pi Model B Library for Proteus covers how the board runs a Python program: the program and Proteus work in lockstep, every sleep, pin wait and bus transfer moves the simulation clock, and the Python libraries for the pins answer as on a Pi. Then came the Raspberry Pi 1 Model B+ Library for Proteus, the Raspberry Pi 2 Model B Library for Proteus, the Raspberry Pi 3 Model B Library for Proteus, the Raspberry Pi 3 Model B+ Library for Proteus, the Raspberry Pi 3 Model A+ Library for Proteus, the Raspberry Pi 4 Model B Library for Proteus, the Raspberry Pi 5 Library for Proteus and the Raspberry Pi Zero W Library for Proteus, each with its own modules. The Zero 2 W is the faster small one: on Wi-Fi only, with a current sensor on I2C and a graphic LCD on SPI.

Features of the Raspberry Pi Zero 2 W Library for Proteus

  • The board as it looks: the Zero 2 W at its real size with the 40-pin header (drawn soldered in), the microSD slot with the card, the RP3A0, the wireless module under its shield can, the antenna, the camera connector, the mini-HDMI and the two micro-USB sockets, and the green ACT LED.
  • Wi-Fi only: wlan0 joins the network in the WIFISSID and WIFIPASS properties - our router TEP-WiFi by default - and gets 192.168.1.51; sockets and http.server work on it.
  • Your Python program: any .py file in the PROGRAM property; Python 3.11 and its standard library are included.
  • RPi.GPIO and gpiozero: outputs, inputs, pull-ups and pull-downs, edges with callbacks, software PWM, and gpiozero's devices - with the timing of the Zero 2 W, about 3.5 us a GPIO call.
  • I2C and SPI side by side: smbus2 for the INA219 and spidev for the LCD, as on a real Pi - plus pyserial, 1-Wire and the DHT sensors, as on the earlier boards.
  • Threads: a web server and a measuring loop run side by side, every wait in simulation time.
  • The Pi Terminal: the output, the errors, a line for input(), and a Board tab with the GPIOs, the LED and the supply pins - with our TEP header, no Windows title bar.
  • A complete package: about 13.5 MB with the board, Python, the runtime, the INA219 / DC load, Nokia 5110 and monitor libraries and the demo, without the source code of the models.

The Raspberry Pi Zero 2 W in Proteus

Figure: The part as the library draws it: the 40-pin header along the top edge with a colour-coded tag on each pin, the microSD card out of the left edge, the RP3A0, the Wi-Fi module's shield can, the antenna and the camera connector, the ACT LED lit, and the mini-HDMI and the two micro-USB sockets along the bottom.

Search RASPBERRY in Pick Devices; the device RASPBERRY PI ZERO 2 W is in TEPRPI02W.LIB (Microprocessor ICs, Raspberry Pi), with the prefix PI. The 40 pins leave the top edge as one comb, each pin above its column of the header, with a tag in the colour of its kind: 5V red, 3V3 orange, GND black, GPIO green, I2C blue, SPI pink, UART purple and the ID pins grey. Click the mini-HDMI socket or the processor to open the Pi Terminal. There is no RJ45 and no ETHERNET property: the Zero 2 W is on Wi-Fi from the start.

Figure: PI1 in the demo: ten header pins go up to net labels - 3V3 and GND, SDA and SCL for the INA219, and BL, DC, RST, DIN, CLK and CE for the LCD.

Wi-Fi

At Run the board boots for half a second and wlan0 joins the network named in its WIFISSID property with the password in WIFIPASS - by default our router TEP-WiFi with 12345678, the network of our other Wi-Fi parts and of the Laptop WiFi Monitor and the Mobile WiFi Monitor. 2.3 to 3.5 s after Run the Pi has 192.168.1.51 and the name raspberrypi.local. A wrong name or password shows up in the simulation log, and the program simply waits.

The 40-Pin Header

The 40 pins with their BCM numbers
PinsNamePinsName
13V325V
3GPIO2 (SDA)45V
5GPIO3 (SCL)6GND
7GPIO48GPIO14 (TXD)
9GND10GPIO15 (RXD)
11GPIO1712GPIO18
13GPIO2714GND
15GPIO2216GPIO23
173V318GPIO24
19GPIO10 (MOSI)20GND
21GPIO9 (MISO)22GPIO25
23GPIO11 (SCLK)24GPIO8 (CE0)
25GND26GPIO7 (CE1)
27ID_SD28ID_SC
29GPIO530GND
31GPIO632GPIO12
33GPIO1334GND
35GPIO1936GPIO16
37GPIO2638GPIO20
39GND40GPIO21

The GPIOs work at 3.3 V; GPIO2 and GPIO3 have the Pi's 1.8 k pull-ups. The 5V and 3V3 pins power the modules wired to them - in Proteus as logic levels, so a module that measures its own supply reads 5 V on either of them. ID_SD and ID_SC are kept for a HAT's ID EEPROM, so leave them free, as on a real Pi.

Download Raspberry Pi Zero 2 W Library for Proteus

Click the button below to download Raspberry-Pi-Zero-2-W-Library-for-Proteus-v1.0.zip (about 13.5 MB with Python included, without the source code of the models):

Raspberry Pi Zero 2 W Library for Proteus V1.0
  • README.txt: the device, Wi-Fi, installation, the demo, the header, the properties, troubleshooting and the limits.
  • Proteus Library Files: TEPRPI02W.LIB (the Raspberry Pi Zero 2 W) and the demo's parts: TEPINA219.LIB (the INA219 and the DC load), TEPNOKIA5110.LIB (the LCD), TEPLAPTOP.LIB and TEPMOBILE.LIB.
  • Proteus Model Files: TEPNET.DLL (the Pi, the laptop, the phone and the network), the parts' TEPINA219.DLL and TEPNOKIA5110.DLL, and the TEPPi folder - Python 3.11 and the TEP Pi runtime.
  • Python Code: blink.py and power_meter.py.
  • Proteus Simulation: the demo project, its program and copies of the DLLs.

No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.

How to Install Raspberry Pi Zero 2 W Library for Proteus

  1. Close Proteus and extract the whole zip file, for example to your Desktop.
  2. Copy the files from Proteus Library Files into the LIBRARY folder of Proteus (usually C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY).
  3. Copy everything from Proteus Model Files - the DLLs and the TEPPi folder - into the MODELS folder, replacing an older TEPNET.DLL and TEPPi folder (these are the newest; they also run our Model B, Model B+, Pi 2, Pi 3, Pi 3 B+, Pi 3 A+, Pi 4, Pi 5 and Zero W).
  4. Delete TEPRPI02W.IDX from the LIBRARY folder if it is there.
  5. Start Proteus, press P and search for RASPBERRY.

There is nothing else to install: Python comes in the TEPPi folder, so you need no Python on your PC.

Demo: a Wi-Fi Power Meter

Open Pi-Zero-2-W-Power-Meter.pdsprj. PI1 runs power_meter.py on Wi-Fi. The parts come from our own libraries, each with its article: the INA219 module U1 and the DC electronic load LD1 from the INA219 Current Sensor Library for Proteus, the LCD LCD1 from the Nokia 5110 LCD Library for Proteus. The INA219 and the LCD are the Advance versions: each opens a pop-up window at Run that shows what the Pi does with it. PC1 is the Laptop WiFi Monitor and MOB1 the Mobile WiFi Monitor, both on the same Wi-Fi as the Pi.

Figure: The whole demo: the titles, PI1 with ten header pins going to net labels, the INA219 between the 5 V supply and the DC load, the Nokia 5110, and the laptop and the phone.

The INA219 sits on the high side: its 0.1 ohm shunt is in series between the supply (VIN+) and the load (VIN-), so the whole current of the load flows through it. The chip measures the small voltage across the shunt - 10 uV a step - and the bus voltage from VIN- to GND - 4 mV a step - and with a calibration value it works out the current and the power by itself. The DC load is a constant-current sink: it draws whatever current it is set to, here 250 mA from the 5 V supply at the start.

The Nokia 5110 is the 84 x 48 graphic LCD of the old Nokia phones, driven by a PCD8544. It listens on SPI only - there is no read - and a DC pin tells it whether a byte is a command or picture data. Net labels connect everything:

The wiring of the Wi-Fi power meter
Part pinNet labelPi pinWhat it does
INA219 VCC, GND3V3, GND1, 6the module's supply
INA219 SDA, SCLSDA, SCL3, 5 (GPIO2, GPIO3)I2C bus 1, address 0x40
INA219 VIN+--the 5 V supply (a power terminal)
INA219 VIN---the DC load's +, whose - goes to ground
LCD RSTRST18 (GPIO24)the reset pulse
LCD CECE24 (GPIO8, CE0)chip enable, driven by the SPI driver
LCD DCDC16 (GPIO23)LOW = a command, HIGH = data
LCD DIN, CLKDIN, CLK19, 23 (GPIO10, GPIO11)SPI0 MOSI and SCLK
LCD BLBL12 (GPIO18)the backlight, with PWM
LCD VCC, GND3V3, GND1, 6the LCD's supply

The INA219 on smbus2

The INA219 has six 16-bit registers, sent the most significant byte first. The program resets the chip, writes the configuration 0x399F - the 32 V range, +-320 mV across the shunt, 12-bit results, both measured continuously - and the calibration 4096, which with the 0.1 ohm shunt makes the Current register count 0.1 mA and the Power register 2 mW:

    def __init__(self, address=0x40):
        self.bus = SMBus(1)
        self.address = address
        self.write(self.CONFIG, 0x8000)                         # reset
        self.write(self.CONFIG, 0x399F)                         # 32 V range, +-320 mV, 12-bit, shunt and bus continuous
        self.write(self.CAL, 4096)

Each read sends the register number and reads two bytes back. The shunt and the current are signed; the bus voltage sits in the top 13 bits of its register, with a flag for an overflow in bit 0:

    def read(self, reg, signed=False):
        hi, lo = self.bus.read_i2c_block_data(self.address, reg, 2)
        value = hi << 8 | lo
        return value - 0x10000 if signed and value & 0x8000 else value

    def measure(self):
        bus = self.read(self.BUS)
        return {'volts': (bus >> 3) * 0.004, 'overflow': bool(bus & 1), 'shunt_mv': self.read(self.SHUNT, True) * 0.01,
                'ma': self.read(self.CURRENT, True) * 0.1, 'mw': self.read(self.POWER) * 2.0}

The Nokia 5110 on spidev

SPI0 with CE0 drives the LCD at 4 MHz, mode 0. Every PCD8544 needs a reset pulse after power-on; then the extended instruction set (0x21) sets the LCD voltage - Vop 55 - and the bias, and the basic set (0x20) and DISPLAY NORMAL (0x0C) switch the picture on:

    def __init__(self, contrast=55):
        GPIO.setup(DC, GPIO.OUT, initial=GPIO.LOW)
        GPIO.setup(RST, GPIO.OUT, initial=GPIO.HIGH)
        self.spi = spidev.SpiDev()
        self.spi.open(0, 0)
        self.spi.max_speed_hz = 4000000                         # (the PCD8544 takes up to 4 Mbit/s)
        self.spi.mode = 0
        GPIO.output(RST, 0)                                     # the reset pulse every PCD8544 needs after power-on
        time.sleep(0.01)
        GPIO.output(RST, 1)
        self.command(0x21, 0x80 | contrast, 0x04, 0x14, 0x20, 0x0C)   # extended set: Vop, TC 0, bias 4; basic set, normal
        self.ram = bytearray(504)

The picture is 504 bytes: six banks of 84 columns, one byte for 8 pixels down. The program keeps a copy and sends all of it in one SPI transfer, with DC LOW for the commands and HIGH for the data. DISPLAY INVERSE (0x0D) flips every pixel - that is the over-limit warning:

    def command(self, *cmds):
        GPIO.output(DC, 0)
        self.spi.xfer2(list(cmds))
    def show(self, inverse=False):
        self.command(0x0D if inverse else 0x0C, 0x40, 0x80)    # normal / inverse, Y 0, X 0
        GPIO.output(DC, 1)
        self.spi.xfer2(list(self.ram))

The text uses a 5 x 7 font. For the big current every font pixel becomes 2 x 2 pixels, spread over two banks, and the decimal point is drawn narrow so that 3200.0 still fits next to "mA":

    def big(self, right, bank, s):
        """Twice-size text over two banks, its right edge at x = right (the '.' is narrow)."""
        cols = []
        for ch in s:
            glyph = [c for c in FONT.get(ch, FONT[' ']) if c] if ch == '.' else list(FONT.get(ch, FONT[' ']))
            for c in glyph + [0]:
                wide = 0
                for k in range(7):
                    if c >> k & 1:
                        wide |= 3 << 2 * k
                cols += [wide, wide]
        x = right - len(cols)
        for wide in cols:
            if 0 <= x < 84:
                self.ram[bank * 84 + x] = wide & 0xFF
                self.ram[(bank + 1) * 84 + x] = wide >> 8
            x += 1

Measuring

A thread measures twice a second: it reads the INA219, adds the power times the time since the last reading to the energy, checks the limit and redraws the LCD - inverse when the current is over the limit. A line goes to the Pi Terminal when the current changes by more than 5 mA or the limit is crossed:

def meter():
    """Twice a second: read the INA219, add up the energy, redraw the LCD; a line when the current changes or the limit is crossed."""
    last_ma, last_over, t0 = None, None, time.monotonic()
    while True:
        m = ina.measure()
        now = time.monotonic()
        with lock:
            state.update(m)
            state['mwh'] += m['mw'] * (now - t0) / 3600.0
            state['over'] = m['ma'] > state['limit']
            s = dict(state)
        t0 = now
        lcd.clear()
        lcd.text(0, 0, 'OVER LIMIT !' if s['over'] else 'ZERO 2 W METER')
        lcd.big(70, 1, '%.1f' % s['ma'])
        lcd.text(72, 2, 'mA')
        lcd.text(0, 3, 'BUS %7.3f V' % s['volts'])
        lcd.text(0, 4, 'PWR %7.0f mW' % s['mw'])
        lcd.text(0, 5, 'E %7.2f mWh' % s['mwh'])
        lcd.show(inverse=s['over'])
        if last_ma is None or abs(s['ma'] - last_ma) > 5 or s['over'] != last_over:
            print('%s  %.3f V  %.1f mA  %.0f mW  %.2f mWh%s' % (time.strftime('%H:%M:%S'), s['volts'], s['ma'], s['mw'], s['mwh'],
                                                              '  OVER LIMIT (%d mA)' % s['limit'] if s['over'] else ''))
            last_ma, last_over = s['ma'], s['over']
        time.sleep(0.5)

The Web Page

The page shows the readings, the energy since the last reset, the limit and the backlight, with REFRESH and two rows of three links:

PAGE = """<html><head><title>Pi Zero 2 W power meter</title></head><body>
<p>Bus: <b>{volts:.3f} V</b></p>
<p>Current: <b>{ma:.1f} mA</b></p>
<p>Power: <b>{mw:.0f} mW</b></p>
<p>Energy: {mwh:.2f} mWh in {secs:.0f} s</p>
<p>Limit: {limit} mA - {verdict}</p>
<p>Backlight: {light} %</p>
<p><a href="/">REFRESH</a></p>
<p><a href="/reset">RESET ENERGY</a> <a href="/limit?ma=500">LIMIT 500 MA</a> <a href="/limit?ma=2000">LIMIT 2 A</a></p>
<p><a href="/light?pc=100">LIGHT 100 %</a> <a href="/light?pc=25">LIGHT 25 %</a> <a href="/light?pc=0">LIGHT OFF</a></p>
</body></html>"""

/reset starts the energy again, /limit sets the current limit, and /light changes the duty cycle of the backlight's PWM on GPIO18:

    def do_GET(self):
        url = urlparse(self.path)
        q = parse_qs(url.query)
        with lock:
            if url.path == '/reset':
                state['mwh'], state['since'] = 0.0, time.monotonic()
            elif url.path == '/limit' and q.get('ma', [''])[0].isdigit():
                state['limit'] = int(q['ma'][0])
                state['over'] = state['ma'] > state['limit']
            elif url.path == '/light' and q.get('pc', [''])[0].isdigit():
                state['light'] = min(100, int(q['pc'][0]))
                backlight.ChangeDutyCycle(state['light'])
            s = dict(state)
        verdict = 'OVER LIMIT' if s['over'] else 'OK'
        body = PAGE.format(volts=s['volts'], ma=s['ma'], mw=s['mw'], mwh=s['mwh'], secs=time.monotonic() - s['since'], limit=s['limit'],
                           verdict=verdict, light=s['light']).encode()

At the start the program lights the backlight, shows "WAITING FOR WI-FI ..." on the LCD, sets up the INA219, waits for Wi-Fi, starts the measuring thread and serves on port 8000:

GPIO.setmode(GPIO.BCM)
GPIO.setup(BL, GPIO.OUT)
backlight = GPIO.PWM(BL, 1000)                                  # the backlight: 1 kHz PWM, 100 % = fully lit
backlight.start(100)
lcd = Nokia5110()
lcd.text(0, 0, 'ZERO 2 W METER')
lcd.text(0, 3, 'WAITING FOR')
lcd.text(0, 4, 'WI-FI ...')
lcd.show()
ina = INA219()
print('power_meter.py - Wi-Fi power meter on the Raspberry Pi Zero 2 W')
print('INA219 at 0x40 on I2C1 (32 V, 0.1 mA a step); Nokia 5110 on SPI0 CE0, DC GPIO23, RST GPIO24, backlight GPIO18')
print('waiting for Wi-Fi ...')
while my_ip() == '0.0.0.0':
    time.sleep(0.5)
state['since'] = time.monotonic()
threading.Thread(target=meter, daemon=True).start()
print('serving on http://%s:%d/' % (my_ip(), PORT))
HTTPServer(('', PORT), Handler).serve_forever()

Run the Demo

Press Run. The LCD asks for Wi-Fi, wlan0 joins TEP-WiFi and 2.5 s after Run the page is served. The first reading is the DC load at 250 mA: 25.00 mV across the shunt, 4.976 V left for the load, 1242 mW:

Figure: The demo running: PI1 on Wi-Fi, the INA219 and the DC load at 0.250 A, the Nokia 5110 with the readings, the laptop and the phone.
pi@raspberrypi:~ $ python3 power_meter.py
power_meter.py - Wi-Fi power meter on the Raspberry Pi Zero 2 W
INA219 at 0x40 on I2C1 (32 V, 0.1 mA a step); Nokia 5110 on SPI0 CE0, DC GPIO23, RST GPIO24, backlight GPIO18
waiting for Wi-Fi ...
serving on http://192.168.1.51:8000/
16:33:06  4.976 V  250.0 mA  1242 mW  0.00 mWh
Figure: The Pi Terminal: the program's first lines - the INA219, the LCD's pins, the Wi-Fi and the address of the page.
Figure: Closer: the INA219 with VIN+ on the 5 V power terminal and VIN- on the DC load, which shows 0.250 A; SDA, SCL, 3V3 and GND go to the labels.
Figure: The INA219's pop-up: the load presets, the circuit with 25.00 mV across the R100 shunt, the readings, the six registers (Configuration 0x399F, Calibration 0x1000) and the last read byte by byte.
Figure: Closer: the Nokia 5110 - the current in big digits, then the bus, the power and the energy.
Figure: The LCD's pop-up: the glass, DISPLAY NORMAL, Vop 55 (GOOD), bias 4, the RAM as stored and the latest transfers - a frame of 504 bytes every half second. It notes VCC 5.00 V: in Proteus the Pi's 3V3 pin is a logic level.

Open the Page

On the laptop click Browser, check the address http://192.168.1.51:8000/ and click Go; on the phone the same. The laptop shows the links as text, the phone as buttons:

Figure: The laptop: the bus, 250.0 mA, the power, the energy, the limit 1000 mA - OK, the backlight at 100 %, and the links.
Figure: The phone: the same page; RESET ENERGY, the limits and the backlight are buttons.

Over the Limit

Tap LIMIT 500 MA on the phone, then click the MOTOR 800 mA preset in the INA219's pop-up (the DC load's panel on the sheet does the same). Now 800 mA flow through the shunt: the LCD turns inverse with "OVER LIMIT !" on top, and REFRESH on the phone shows OVER LIMIT:

Figure: The phone after LIMIT 500 MA: still 250.0 mA, the limit 500 mA - OK.
Figure: Closer: the Nokia 5110 in inverse mode - OVER LIMIT !, 800.1 mA, 4.924 V, 3938 mW.
Figure: The phone after REFRESH: 800.0 mA, 3932 mW, the limit 500 mA - OVER LIMIT.
Figure: The LCD's pop-up: DISPLAY INVERSE - the transfers show the command 0D before the frame; the RAM itself is unchanged.

Dim the Backlight, Raise the Limit

On the laptop click LIGHT 25 %: the PWM on GPIO18 drops to a quarter and the LCD's glass gets darker. Then LIMIT 2 A: 800 mA is fine again and the picture turns back to normal:

Figure: The laptop after LIGHT 25 %: still over the 500 mA limit, the backlight at 25 %.
Figure: The laptop after LIMIT 2 A: 800.1 mA, the limit 2000 mA - OK.

A Bigger Load and a Fresh Count

Click the LAMP 1.5 A preset: 150 mV across the shunt, 4.852 V left for the load, 7272 mW. On the laptop click RESET ENERGY - the energy starts again from zero, at about 2 mWh a second with this load:

Figure: Closer: 1500.2 mA on the LCD, with the backlight at 25 %.
Figure: The laptop after RESET ENERGY and REFRESH: 1499.9 mA, 7270 mW, and the energy counted from the reset.
Figure: The INA219's pop-up with LAMP 1.5 A: 150 mV across the shunt and the registers to match.
Figure: The LCD's pop-up: BACKLIGHT 25 % (PWM), measured from GPIO18.

The Pi Terminal logs every change and every click on the page:

16:33:22  the page: /limit?ma=500 - 250.0 mA, limit 500 mA OK, backlight 100 %
16:33:24  4.920 V  800.1 mA  3932 mW  6.45 mWh  OVER LIMIT (500 mA)
16:33:32  the page: /light?pc=25 - 800.0 mA, limit 500 mA OVER LIMIT, backlight 25 %
16:33:35  the page: /limit?ma=2000 - 800.1 mA, limit 2000 mA OK, backlight 25 %
16:33:35  4.916 V  800.0 mA  3932 mW  18.55 mWh
16:33:37  4.852 V  1499.9 mA  7272 mW  21.76 mWh
16:33:40  the page: /reset - 1499.9 mA, limit 2000 mA OK, backlight 25 %

The Pi Terminal

The Pi Terminal opens at Run, in the look of our TEP Serial Monitor Advance for Proteus - our own TEP header, no Windows title bar. Its Monitor tab shows the program's output (OUT), errors (ERR) and the lines you type for input() (IN). The Board tab shows the board live - GPIO2 and GPIO3 pulled up, CE0 HIGH between transfers, the backlight's PWM on GPIO18, DC and RST HIGH - the ACT LED and the supply pins, and RESTART PROGRAM starts the program again:

Figure: The Pi Terminal after the run: a line for every change of the current and every action from the page.
Figure: The Board tab: the BCM2710A1 at 1 GHz, the GPIOs by BCM number, the ACT LED, 5V and 3V3, power_meter.py and the speed.

Properties of the Raspberry Pi Zero 2 W

Double-click the Pi to change them
PropertyWhat it does
PROGRAMthe Python program (default blink.py; a name next to the project or a full path)
AUTOOPENthe Pi Terminal at Run: YES (default) or NO
WIFISSID, WIFIPASSthe network wlan0 joins and its password (default TEP-WiFi, 12345678)
PYTHON, RUNTIMEa python.exe and a runtime folder of your own (empty: the TEPPi folder)

Your own programs go next to your project; set PROGRAM to the file's name. The default blink.py blinks an LED on GPIO17:

from time import sleep
from gpiozero import LED

led = LED(17)
while True:
    led.on()
    print('LED on')
    sleep(0.5)
    led.off()
    print('LED off')
    sleep(0.5)

Troubleshooting

  • The program waits for Wi-Fi forever: check WIFISSID and WIFIPASS - the simulation log says "not found" or "wrong password".
  • OSError [Errno 121] Remote I/O error from the INA219: SDA and SCL swapped or not wired, no power on VCC, or another address - the pop-up logs every transaction.
  • The current and the power stay 0: the calibration register was never written; the demo writes 4096 after the reset.
  • The LCD stays blank: check CE, DC and RST, and send the reset pulse and the extended set before 0x20 and 0x0C - the LCD's pop-up (Tests, Init check) checks the start-up byte by byte.
  • The current stops at 3200.0 mA: that is the INA219's +-320 mV range on the 0.1 ohm shunt; HEATER 3.5 A is over it.
  • The page does not open: the address is http://192.168.1.51:8000/ and the program must have printed "serving on". A monitor sometimes needs Go a second time. Use the page's REFRESH link - the monitors' Reload repeats the last link.
  • The TEPPi folder was not found: copy it from Proteus Model Files into MODELS, or next to your project.

Things to Know Before Using a Real Raspberry Pi Zero 2 W

  • The header: the Zero 2 W comes without one - solder a 2 x 20 header, or buy the Zero 2 WH with it fitted.
  • Power: four cores need more than the old Zero; use a good 5 V supply of at least 2.5 A, and a small heatsink on the RP3A0 if it works hard for long.
  • The INA219: power the module from the Pi's 3V3 pin, so that its own pull-ups on SDA and SCL stay at 3.3 V. The inputs take up to 26 V; with the 0.1 ohm shunt the range ends at 3.2 A. Keep the grounds of the supply, the load and the Pi together.
  • The Nokia 5110: the PCD8544 is a 3.3 V chip, and so are the Pi's GPIOs - no level shifter is needed. The best contrast differs from module to module, and some modules light up with BL HIGH, others with BL LOW.
  • Wi-Fi: the Zero 2 W uses the 2.4 GHz band only; a phone on the same router opens the page as here.

Limitations of the Simulation

  • The board does not run Raspberry Pi OS: there is no desktop, no shell commands and no apt. It runs one Python program; its threads take turns, so the four cores are not modelled.
  • Bluetooth and Wi-Fi scanning are not modelled; the network is the same TEP network.
  • The mini-HDMI socket, the camera connector, USB and its gadget modes, the microSD card's files and the RUN pads are drawn but not simulated; GPIO18 makes software PWM, not hardware PWM.
  • The 5V and 3V3 pins are logic levels: a module that reads its own supply - like the Nokia 5110's pop-up - sees 5 V on 3V3.
  • C programs and Python packages with C code do not run. Pure Python code takes no simulation time; only the pin, bus, sleep and network calls move the clock.
  • The router, the board's address, the boot time and the Pi Terminal are TEP additions.
  • Raspberry Pi is a trademark of Raspberry Pi Ltd; this library is not made or endorsed by Raspberry Pi Ltd or Labcenter.
  • Tested in Proteus 8.5 in October 2026 (the demo as shipped, about 40 % of real time on our PC with the two pop-ups, the two monitors and the Pi Terminal open). Proteus 7 is not supported.

So, that was all about the Raspberry Pi Zero 2 W Library for Proteus. I hope it helps you try a small Wi-Fi gadget on the Pi before you touch the hardware - an INA219 read over I2C, a Nokia 5110 driven over SPI and a web page that watches the power, sets a limit and dims the backlight from a laptop or a phone. The next boards of our Raspberry Pi series bring other modules and more web pages. If you use the library in a project, please share it in the comments or in our forum, and if you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!