Hello friends, I hope you all are doing great. Today, I am going to share the Raspberry Pi Zero W Library for Proteus. The Raspberry Pi Zero W is the small one of the family - a 65 x 30 mm board with the BCM2835 at 1 GHz, 512 MB of RAM, Wi-Fi and Bluetooth, and the same 40-pin header as its big brothers. With this library the board runs your Python program against the circuit in Proteus 8.5, on our virtual Wi-Fi.
Raspberry Pi Zero 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 2 W · Pi 400 · Pi 2 · Pi 3 · Pi 4 · Zero W
Measurement modules: INA219 · Current Sensor WCS1600 · HX711 Load Cell · ADS1115 ADC
LED displays: MAX7219 Matrix · MAX7219 7-Segment · TM1637 · TM1638 · WS2812B NeoPixel
Helping Tools
- Laptop WiFi Monitor: a laptop on the Wi-Fi of your design: a browser, a TCP / UDP terminal and ping
- Mobile WiFi Monitor: a smartphone that opens the pages of your board and sends it commands
- LCD Library for Proteus V3.0: 16x2, 20x4 and I2C LCDs to show your readings
This is the ninth 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 W is a Wi-Fi kitchen scale: an HX711 reads a 5 kg load cell, a TM1637 4-digit display shows the grams, and a page on a laptop and a phone shows the weight in grams or ounces - and tares and calibrates the scale.
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 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 W Library for Proteus:
What is the Raspberry Pi Zero W?
The first Raspberry Pi Zero came out in 2015 at 5 dollars: the processor of the original Pi on a board the size of a stick of gum, with a mini-HDMI socket, two micro-USB sockets and the 40-pin header left unsoldered. In 2017 the Zero W followed at 10 dollars and added what the Zero missed most: 2.4 GHz Wi-Fi and Bluetooth 4.1 from a Cypress CYW43438, with a small antenna etched into the board.
Inside it is the BCM2835, a single ARM1176 core at 1 GHz, with 512 MB of RAM stacked right on top of the processor. It is not fast, but it is tiny, light and frugal, which makes it the Pi for things that sit somewhere and talk over Wi-Fi: sensors, cameras, smart gadgets - and kitchen scales. The header is the same 40-pin header as on every Pi since the B+, with the same numbers.
| Raspberry Pi Zero (2015) | Raspberry Pi Zero W (2017) | |
|---|---|---|
| Processor | BCM2835, one ARM1176 core at 1 GHz | the same |
| RAM | 512 MB | the same |
| Wireless | none | 2.4 GHz Wi-Fi and Bluetooth 4.1 (CYW43438) |
| Video | mini-HDMI | the same |
| USB | one micro-USB (OTG), one for power | the same |
| Camera | CSI connector (from v1.3) | CSI connector |
| Board | 65 x 30 mm, unpopulated 40-pin header | the same |
| Price at launch | 5 dollars | 10 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 and the Raspberry Pi 5 Library for Proteus, each with its own modules. The Zero W is the first small one: on Wi-Fi only, with a load cell and a 7-segment display.
Features of the Raspberry Pi Zero W Library for Proteus
- The board as it looks: the Zero W at its real size with the 40-pin header (drawn soldered in), the microSD slot with the card, the BCM2835 with its RAM on top, the CYW43438 and its 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 a 1 GHz single core, about 5 us a GPIO call.
- I2C, SPI, the UART, 1-Wire and the DHT sensors: smbus2, spidev, pyserial and the kernel's files, as on the earlier boards.
- Threads: a web server and a weighing 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.4 MB with the board, Python, the runtime, the HX711 / load cell, TM1637 and monitor libraries and the demo, without the source code of the models.
The Raspberry Pi Zero W in Proteus
Search RASPBERRY in Pick Devices; the device RASPBERRY PI ZERO W is in TEPRPI0W.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 W is on Wi-Fi from the start.
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
| Pins | Name | Pins | Name |
|---|---|---|---|
| 1 | 3V3 | 2 | 5V |
| 3 | GPIO2 (SDA) | 4 | 5V |
| 5 | GPIO3 (SCL) | 6 | GND |
| 7 | GPIO4 | 8 | GPIO14 (TXD) |
| 9 | GND | 10 | GPIO15 (RXD) |
| 11 | GPIO17 | 12 | GPIO18 |
| 13 | GPIO27 | 14 | GND |
| 15 | GPIO22 | 16 | GPIO23 |
| 17 | 3V3 | 18 | GPIO24 |
| 19 | GPIO10 (MOSI) | 20 | GND |
| 21 | GPIO9 (MISO) | 22 | GPIO25 |
| 23 | GPIO11 (SCLK) | 24 | GPIO8 (CE0) |
| 25 | GND | 26 | GPIO7 (CE1) |
| 27 | ID_SD | 28 | ID_SC |
| 29 | GPIO5 | 30 | GND |
| 31 | GPIO6 | 32 | GPIO12 |
| 33 | GPIO13 | 34 | GND |
| 35 | GPIO19 | 36 | GPIO16 |
| 37 | GPIO26 | 38 | GPIO20 |
| 39 | GND | 40 | GPIO21 |
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. 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 W Library for Proteus
Click the button below to download Raspberry-Pi-Zero-W-Library-for-Proteus-v1.0.zip (about 13.4 MB with Python included, without the source code of the models):
Raspberry Pi Zero 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:
TEPRPI0W.LIB(the Raspberry Pi Zero W) and the demo's parts:TEPHX711.LIB(the HX711 and the load cells),TEPTM1637.LIB(the display),TEPLAPTOP.LIBandTEPMOBILE.LIB. - Proteus Model Files:
TEPNET.DLL(the Pi, the laptop, the phone and the network), the parts'TEPHX711.DLLandTEPTM1637.DLL, and the TEPPi folder - Python 3.11 and the TEP Pi runtime. - Python Code:
blink.pyandwifi_scale.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 W Library for Proteus
- Close Proteus and extract the whole zip file, for example to your Desktop.
- Copy the files from Proteus Library Files into the LIBRARY folder of Proteus (usually
C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY). - 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 and Pi 5).
- Delete
TEPRPI0W.IDXfrom the LIBRARY folder if it is there. - 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 Kitchen Scale
Open Pi-Zero-W-WiFi-Scale.pdsprj. PI1 runs wifi_scale.py on Wi-Fi. The parts come from our own libraries, each with its article: the 5 kg load cell U1 and the HX711 U2 from the HX711 Load Cell Library for Proteus, the display TM1 from the TM1637 7-Segment Display Library for Proteus. The HX711 and the display 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.
A load cell is a metal bar with four strain gauges glued on it in a bridge: a weight bends the bar a little, and the bridge gives out a few millivolts - 1 mV for every volt of supply at the full 5 kg. The HX711 powers the bridge from its 4.3 V regulator and turns that tiny voltage into a 24-bit number, ten times a second. The TM1637 drives a 4-digit 7-segment display over two wires of its own. Net labels connect everything:
| Part pin | Net label | Pi pin | What it does |
|---|---|---|---|
| Load cell red, black | - | - | E+ and E- on the HX711: the bridge's supply |
| Load cell white, green | - | - | A- and A+ on the HX711: the bridge's output |
| HX711 VCC, GND | 3V3, GND | 1, 6 | the module's supply |
| HX711 DT | DT | 29 (GPIO5) | the data out - LOW when a result is ready |
| HX711 SCK | SCK | 31 (GPIO6) | the clock the Pi sends |
| TM1637 CLK, DIO | CLK, DIO | 16, 18 (GPIO23, GPIO24) | the 2-wire bus, open-drain |
| TM1637 VCC, GND | 3V3, GND | 1, 6 | the display's supply |
The HX711, Bit by Bit
The HX711 is not I2C or SPI: the Pi reads it with two GPIOs. DT is an input, SCK an output that starts LOW:
def __init__(self):
GPIO.setup(DT, GPIO.IN)
GPIO.setup(SCK, GPIO.OUT, initial=GPIO.LOW)
When DT goes LOW a result is ready. Each pulse on SCK shifts out the next bit, the most significant first; after 24 bits a 25th pulse chooses channel A with gain 128 for the next result. SCK must not stay HIGH for more than 60 us - that would power the chip down - and at about 5 us a GPIO call the Zero W keeps it far below that. The 24 bits are a signed number:
def read(self):
while GPIO.input(DT): # not ready yet (10 results a second)
time.sleep(0.005)
value = 0
for _ in range(24):
GPIO.output(SCK, 1)
value = value << 1 | GPIO.input(DT)
GPIO.output(SCK, 0)
GPIO.output(SCK, 1)
GPIO.output(SCK, 0) # the 25th clock: channel A, gain 128
return value - (1 << 24) if value & 0x800000 else value
The TM1637's Two Wires
CLK and DIO are open-drain lines with pull-up resistors on the module: a device either pulls a line LOW or lets it go, and the resistor makes it HIGH. So the program never drives them HIGH - it switches a pin to an output at LOW, or back to an input:
def pull_low(pin):
GPIO.setup(pin, GPIO.OUT, initial=GPIO.LOW)
@staticmethod
def let_go(pin):
GPIO.setup(pin, GPIO.IN)
A frame starts when DIO falls while CLK is HIGH and ends when DIO rises while CLK is HIGH:
def start(self):
self.pull_low(DIO) # DIO falls while CLK is HIGH
self.pull_low(CLK)
def stop(self):
self.pull_low(DIO)
self.let_go(CLK)
self.let_go(DIO) # DIO rises while CLK is HIGH
Bytes go out least significant bit first. On the 9th clock the program lets DIO go and the TM1637 answers by pulling it LOW - the ACK:
def byte(self, b):
for k in range(8):
if b >> k & 1:
self.let_go(DIO)
else:
self.pull_low(DIO)
self.let_go(CLK)
self.pull_low(CLK)
self.let_go(DIO) # the ACK clock: the chip answers on DIO
self.let_go(CLK)
ack = GPIO.input(DIO) == 0
self.pull_low(CLK)
return ack
Three frames update the display: 0x40 (write the RAM, address auto-increment), 0xC0 and the four digits from the leftmost one, then 0x88 plus the brightness to switch it on. The number is right-aligned, with OL when it does not fit:
def show(self, segments):
self.start(); self.byte(0x40); self.stop() # write the display RAM, auto-increment
self.start(); self.byte(0xC0) # from the leftmost digit
for s in segments:
self.byte(s)
self.stop()
self.start(); self.byte(0x88 | self.brightness); self.stop() # display on
def number(self, n):
"""n right-aligned (-999 .. 9999); 'OL' when it does not fit."""
if not -999 <= n <= 9999:
self.show([self.BLANK, self.BLANK, 0x3F, 0x38]) # " OL"
return
self.show([self.DIGITS[int(c)] if c.isdigit() else {' ': self.BLANK, '-': self.MINUS}[c] for c in str(n).rjust(4)])
Weighing
A thread weighs five times a second: the average of three results, minus the tare, divided by the counts per gram, on the display, and a line in the Pi Terminal when the weight changes by 2 g or more:
def weigh():
"""Five times a second: the average of 3 results, the grams on the display, a line when the weight changes."""
last = None
while True:
raw = scale.average(3)
with lock:
grams = (raw - state['offset']) / state['factor']
state['grams'], state['raw'] = grams, raw
shown = round(grams)
display.number(shown)
if last is None or abs(shown - last) >= 2:
print('%s %d g (raw %d)' % (time.strftime('%H:%M:%S'), shown, raw))
last = shown
time.sleep(0.2)
The Web Page
The page shows the weight, the raw reading, the tare and the factor, with three buttons in one row:
PAGE = """<html><head><title>Pi Zero W scale</title></head><body>
<p>Weight: <b>{weight}</b></p>
<p>Raw: {raw}</p>
<p>Tare: {offset}</p>
<p>Factor: {factor:.2f} per g</p>
<p>{note}</p>
<p><a href="/">REFRESH</a></p>
<p><a href="/tare">TARE</a> <a href="/cal">CAL 1 KG</a> <a href="/unit">G / OZ</a></p>
</body></html>"""
/tare takes the raw reading now as the new zero; /cal, with 1 kg on the scale, measures the counts per gram; /unit switches the page between grams and ounces:
def do_GET(self):
with lock:
if self.path == '/tare':
state['offset'] = state['raw']
state['note'] = 'tared'
elif self.path == '/cal':
if abs(state['raw'] - state['offset']) > 1000:
state['factor'] = (state['raw'] - state['offset']) / 1000.0
state['note'] = 'calibrated with 1 kg'
else:
state['note'] = 'put 1 kg on first'
elif self.path == '/unit':
state['oz'] = not state['oz']
grams = (state['raw'] - state['offset']) / state['factor']
weight = '%.2f oz' % (grams / GRAMS_PER_OZ) if state['oz'] else '%.0f g' % grams
body = PAGE.format(weight=weight, raw=int(state['raw']), offset=int(state['offset']), factor=state['factor'],
note=state['note']).encode()
At the start the program shows "----", tares the empty scale with five results, waits for Wi-Fi, starts the weighing thread and serves on port 8000:
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False) # (the TM1637 lines change between input and output)
scale = HX711()
display = TM1637()
display.show([TM1637.MINUS] * 4)
print('wifi_scale.py - Wi-Fi kitchen scale on the Raspberry Pi Zero W')
state['offset'] = scale.average(5) # the empty scale is zero
state['raw'] = state['offset']
print('HX711 on GPIO5 / GPIO6: tared at %d; TM1637 on GPIO23 / GPIO24' % state['offset'])
print('waiting for Wi-Fi ...')
while my_ip() == '0.0.0.0':
time.sleep(0.5)
threading.Thread(target=weigh, daemon=True).start()
print('serving on http://%s:%d/' % (my_ip(), PORT))
HTTPServer(('', PORT), Handler).serve_forever()
Run the Demo
Press Run. The program tares the empty scale - the 107359 counts are the load cell's own zero offset - and wlan0 joins TEP-WiFi; about 3 s after Run the page is served and the display shows 0:
pi@raspberrypi:~ $ python3 wifi_scale.py
wifi_scale.py - Wi-Fi kitchen scale on the Raspberry Pi Zero W
HX711 on GPIO5 / GPIO6: tared at 107359; TM1637 on GPIO23 / GPIO24
waiting for Wi-Fi ...
serving on http://192.168.1.51:8000/
15:41:41 0 g (raw 107377)
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:
Weigh Something
In the HX711's pop-up click the 500 g preset (the load cell's WEIGHT panel on the sheet does the same). The display shows 500, and REFRESH on the phone shows it too:
Calibrate and Switch Units
Click the 1 kg preset and tap CAL 1 KG on the phone: the program measures the counts per gram with the known weight. Then click 2.5 kg, and on the laptop click G / OZ - 2500 g are 88.19 oz - and TARE: what is on the scale now becomes the new zero:
The Pi Terminal logs every change. The line at 167 g comes from an average of three results that took in the moment the weight changed:
15:41:54 167 g (raw 178994)
15:41:55 500 g (raw 322108)
15:42:01 1000 g (raw 536865)
15:42:04 the page: /cal - 1000 g, calibrated with 1 kg
15:42:09 2500 g (raw 1181117)
15:42:12 the page: /unit - 88.19 oz, calibrated with 1 kg
15:42:14 the page: /tare - 0.00 oz, tared
15:42:15 0 g (raw 1181109)
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 - DT HIGH between results, SCK LOW, CLK and DIO let go to the module's pull-ups - the ACT LED and the supply pins, and RESTART PROGRAM starts the program again:
Properties of the Raspberry Pi Zero W
| Property | What it does |
|---|---|
| PROGRAM | the Python program (default blink.py; a name next to the project or a full path) |
| AUTOOPEN | the Pi Terminal at Run: YES (default) or NO |
| WIFISSID, WIFIPASS | the network wlan0 joins and its password (default TEP-WiFi, 12345678) |
| PYTHON, RUNTIME | a 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".
- The HX711 never gets ready or reads nonsense: DT on an input, SCK on an output and LOW between read-outs; SCK HIGH for more than 60 us powers the chip down - the pop-up shows every read-out bit by bit.
- The display stays dark: send the display-on command (0x88 plus the brightness) after the digits, and never drive CLK or DIO HIGH - let them go.
- The weight is off: calibrate with a known weight (CAL 1 KG) and tare the empty scale.
- 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 W
- The header: the Zero W comes without one - solder a 2 x 20 header, or buy the Zero WH with it fitted.
- The HX711: Linux can pause a Python program at any moment, and a pause with SCK HIGH longer than 60 us spoils a read-out; read a few times and drop the odd one out. Keep the load cell's wires short and away from the Wi-Fi antenna.
- The TM1637: most modules run on 3.3 V and have their own pull-ups, so CLK and DIO go straight to the Pi's GPIOs.
- Calibration: every load cell is a little different - calibrate with a known weight, and tare whenever the empty scale drifts.
- Wi-Fi: the Zero 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.
- 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.
- 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 30 % 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 W Library for Proteus. I hope it helps you try a small Wi-Fi gadget on the Pi before you touch the hardware - a load cell on an HX711 read bit by bit, a TM1637 driven over its two wires and a web page that tares and calibrates the scale 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!