Hello friends, I hope you all are doing great. Today, I am going to share the Raspberry Pi 1 Model B+ Library for Proteus. The Model B+ is the 2014 redesign of the first Raspberry Pi: the same BCM2835 and 512 MB of RAM, but the 40-pin GPIO header every Pi since has kept, four USB ports, a microSD slot and the shape and mounting holes of today's boards. With this library the board runs your Python program against the circuit in Proteus 8.5.
Raspberry Pi 1 Model B+ 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 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 Zero 2 W · Pi 400 · Pi 2 · Pi 3 · Pi 4 · Zero W
Other displays: OLED · Nokia 5110 · LCD 128x64 · ST7735 · ST7789 · ILI9341 · TFT Shield 2.4 inch · TFT Shield 3.5 inch · E-Paper
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 second library of our Raspberry Pi series, and every library of the series connects the Pi to a different module. This time it is a 2.8" ILI9341 SPI TFT with a touch screen: a Python program draws a colour dashboard on it and reads the touch controller, and two buttons on the glass switch an LED - with nothing but spidev and RPi.GPIO.
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, 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 1 Model B+ 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 1 Model B+ Library for Proteus:
What is the Raspberry Pi 1 Model B+?
The Raspberry Pi 1 Model B+ came out in July 2014 at 35 dollars, as the final form of the first-generation Pi. Its processor did not change - a Broadcom BCM2835 with a 700 MHz ARM11 core and 512 MB of RAM - but almost everything around it did. The board kept its 85 x 56 mm size and got rounded corners and four mounting holes in a rectangle, the layout every Model B since has used, and that HAT add-on boards are made for.
The 26-pin P1 header of the Model B became a 40-pin header. Its first 26 pins are the same as before, so old add-ons still fit; the 14 new pins give nine more GPIOs and the ID_SD / ID_SC pair for a HAT's ID EEPROM. The SMSC LAN9514 gives four USB ports instead of two, the SD card became a push-push microSD, switching regulators replaced the old linear ones and cut the power use, and the composite video moved into the 4-pole 3.5 mm audio jack.
| Raspberry Pi Model B (2012) | Raspberry Pi 1 Model B+ (2014) | |
|---|---|---|
| Processor, RAM | BCM2835 at 700 MHz, 512 MB | the same |
| GPIO header | P1, 26 pins, 17 GPIOs | 40 pins, 26 GPIOs, ID_SD / ID_SC |
| USB, network | 2 USB ports, 10/100 Ethernet (LAN9512) | 4 USB ports, 10/100 Ethernet (LAN9514) |
| Storage | SD card | microSD card |
| Video and audio | HDMI, RCA composite, 3.5 mm audio | HDMI, composite and audio in one 4-pole jack |
| LEDs | PWR, ACT, FDX, LNK, 100 | PWR and ACT; the link LEDs moved onto the RJ45 jack |
| Shape | square corners, two holes | rounded corners, four holes |
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. The B+ works the same way, with its 40-pin header and its own LEDs.
Features of the Raspberry Pi 1 Model B+ Library for Proteus
- The board as it looks: the green B+ at its real size with the 40-pin header, the four mounting holes, PWR and ACT under pin 1, the two USB pairs and the RJ45 with its own LEDs, micro-USB, HDMI, the camera and display connectors, the black A/V jack and the microSD card.
- 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 LED, Button, CPUTemperature and the rest.
- The buses: I2C with smbus2, SPI0 with spidev in modes 0 to 3 on CE0 and CE1, the UART with pyserial, 1-Wire and the DHT sensors.
- Ethernet: sockets and http.server on eth0, the cable clickable on the RJ45 jack.
- The clock follows the simulation: time.time(), time.strftime() and datetime.now() move with Proteus.
- The Pi Terminal: the output, the errors, a line for input(), and a Board tab with all 28 GPIOs, the LEDs and the supply pins - with our TEP header, no Windows title bar.
- A complete package: about 13.1 MB with the board, Python, the runtime, the TFT library and the demo, without the source code of the models.
The Raspberry Pi 1 Model B+ in Proteus
Search RASPBERRY in Pick Devices; the device RASPBERRY PI 1 MODEL B+ is in TEPRPIBP.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 HDMI socket or the processor to open the Pi Terminal, and the RJ45 jack to pull the Ethernet cable out or plug it back in.
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. 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 1 Model B+ Library for Proteus
Click the button below to download Raspberry-Pi-1-Model-B-Plus-Library-for-Proteus-v1.0.zip (about 13.1 MB with Python included, without the source code of the models):
Raspberry Pi 1 Model B+ Library for Proteus V1.0- README.txt: the device, installation, the demo, the header, the properties, troubleshooting and the limits.
- Proteus Library Files:
TEPRPIBP.LIB(the Raspberry Pi 1 Model B+) andTEPILI9341.LIB(the demo's TFT). - Proteus Model Files:
TEPNET.DLL(the Pi and the network),TEPILI9341.DLL(the TFT) and the TEPPi folder - Python 3.11 and the TEP Pi runtime. - Python Code:
blink.pyandtft_dashboard.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 1 Model B+ 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).
- Delete
TEPRPIBP.IDXandTEPILI9341.IDXfrom the LIBRARY folder if they are 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 Touch Dashboard on a 2.8" ILI9341 TFT
Open Pi-1-Model-B-Plus-TFT-Dashboard.pdsprj. PI1 runs tft_dashboard.py. TFT1 is the red 2.8" SPI TFT from our TFT ILI9341 Library for Proteus: a 320 x 240 ILI9341 display with an XPT2046 touch controller under a resistive film, both on one 14-pin header. D1 is an LED on GPIO27 through R1 220R.
The TFT and the touch controller share SPI0: the TFT is on chip select CE0, the touch controller on CE1, and the TFT's SDO and the touch controller's T_DO both go to MISO - each one lets go of the line while its chip select is high. Net labels connect everything:
| TFT pin | Net label | Pi pin | What it does |
|---|---|---|---|
| VCC, GND | 3V3, GND | 1, 6 | power from the Pi's header |
| CS | CE0 | 24 (GPIO8) | the TFT's chip select |
| RESET | RST | 18 (GPIO24) | a hardware reset at the start |
| DC | DC | 22 (GPIO25) | LOW = a command, HIGH = data |
| SDI, T_DIN | MOSI | 19 (GPIO10) | the Pi sends |
| SDO, T_DO | MISO | 21 (GPIO9) | the TFT and the touch answer |
| SCK, T_CLK | SCLK | 23 (GPIO11) | the SPI clock |
| LED | BL | 12 (GPIO18) | the backlight, with PWM |
| T_CS | CE1 | 26 (GPIO7) | the touch controller's chip select |
| T_IRQ | T_IRQ | 11 (GPIO17) | LOW while the film is pressed |
Driving the ILI9341 from Python
There is no TFT library in this program - the ILI9341 is simple enough to drive with spidev and RPi.GPIO alone. The pins first:
DC, RST, BL, T_IRQ, LED = 25, 24, 18, 17, 27
The TFT works with 16-bit colours, five bits of red, six of green and five of blue:
def colour(r, g, b): # RGB to the TFT's 16-bit 565 colour
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
The set-up is a list of commands with their parameters - the power, VCOM and gamma values that Adafruit's library sends, MADCTL 0xE8 for the landscape picture and COLMOD 0x55 for 16-bit colour:
INIT = [ # the ILI9341 set-up: power, VCOM, gamma (the values Adafruit's library sends), landscape (MADCTL E8), 16-bit colour
(0xEF, [0x03, 0x80, 0x02]), (0xCF, [0x00, 0xC1, 0x30]), (0xED, [0x64, 0x03, 0x12, 0x81]), (0xE8, [0x85, 0x00, 0x78]),
(0xCB, [0x39, 0x2C, 0x00, 0x34, 0x02]), (0xF7, [0x20]), (0xEA, [0x00, 0x00]), (0xC0, [0x23]), (0xC1, [0x10]),
(0xC5, [0x3E, 0x28]), (0xC7, [0x86]), (0x36, [0xE8]), (0x3A, [0x55]), (0xB1, [0x00, 0x18]), (0xB6, [0x08, 0x82, 0x27]),
(0xF2, [0x00]), (0x26, [0x01]),
(0xE0, [0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00]),
(0xE1, [0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F])]
The TFT class resets the controller with its RESET pin, sends the list, takes it out of sleep (SLPOUT, then 120 ms) and switches the display on (DISPON). SPI runs at 8 MHz:
class TFT:
"""The ILI9341 on SPI0 CE0: 320 x 240 in landscape, 16-bit colour."""
def __init__(self):
self.spi = spidev.SpiDev(0, 0)
self.spi.max_speed_hz = 8000000 # (the ILI9341 takes up to 10 MHz)
GPIO.setup([DC, RST], GPIO.OUT, initial=GPIO.HIGH)
GPIO.output(RST, GPIO.LOW) # a hardware reset, then the 150 ms the controller needs
time.sleep(0.001)
GPIO.output(RST, GPIO.HIGH)
time.sleep(0.15)
for cmd, data in INIT:
self.command(cmd, data)
self.command(0x11) # SLPOUT: out of sleep, 120 ms
time.sleep(0.12)
self.command(0x29) # DISPON
Every byte goes out with the DC pin telling the controller what it is: LOW for a command, HIGH for its parameters or the pixels. spidev's writebytes2 takes a buffer of any length and sends it in 4096-byte pieces, as on a Pi:
def command(self, cmd, data=None):
GPIO.output(DC, GPIO.LOW) # DC low: a command byte
self.spi.writebytes([cmd])
if data:
GPIO.output(DC, GPIO.HIGH) # DC high: its parameters, or the pixels
self.spi.writebytes2(data)
Drawing is always the same three commands: CASET and PASET set a window, RAMWR fills it with pixels. A filled rectangle is just a window full of one colour:
def area(self, x, y, w, h, pixels):
self.command(0x2A, [x >> 8, x & 255, (x + w - 1) >> 8, (x + w - 1) & 255]) # CASET: the columns
self.command(0x2B, [y >> 8, y & 255, (y + h - 1) >> 8, (y + h - 1) & 255]) # PASET: the rows
self.command(0x2C, pixels) # RAMWR: the pixels, left to right, top to bottom
def fill(self, x, y, w, h, c):
self.area(x, y, w, h, c.to_bytes(2, 'big') * (w * h))
Text uses an 8 x 14 font stored in the program (rasterised from Cascadia Mono). A whole string becomes one window, built row by row, and can be drawn two or three times bigger:
def text(self, x, y, s, fg, bg, size=1):
f, b = fg.to_bytes(2, 'big') * size, bg.to_bytes(2, 'big') * size
glyphs = [FONT[(ord(ch) - 32) * 14:(ord(ch) - 31) * 14] if ' ' <= ch <= '~' else bytes(14) for ch in s]
pixels = bytearray()
for r in range(14):
line = b''.join(f if g[r] & (0x80 >> k) else b for g in glyphs for k in range(8))
pixels += line * size
self.area(x, y, 8 * size * len(s), 14 * size, pixels)
Reading the XPT2046 Touch Controller
The touch controller is on the same bus, on CE1, at 1 MHz. It pulls T_IRQ low while the film is pressed; then each control byte (0x90 for X, 0xD0 for Y) starts a conversion and the next two bytes bring the 12-bit result back. Three readings are averaged and mapped to the screen - this film reads X 3855 at the left edge and 240 at the right, Y 3805 at the top and 290 at the bottom:
class Touch:
"""The XPT2046 on SPI0 CE1: T_IRQ goes LOW while the film is pressed."""
def __init__(self):
self.spi = spidev.SpiDev(0, 1)
self.spi.max_speed_hz = 1000000 # (the XPT2046 clocks up to 2.5 MHz)
GPIO.setup(T_IRQ, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def raw(self, control):
r = self.spi.xfer2([control, 0, 0])
return ((r[1] << 8) | r[2]) >> 3 # the 12-bit result
def point(self):
if GPIO.input(T_IRQ):
return None
x = sum(self.raw(0x90) for _ in range(3)) // 3 # X: along the long side
y = sum(self.raw(0xD0) for _ in range(3)) // 3 # Y: along the short side
# this film reads X 3855 at the left edge and 240 at the right, Y 3805 at the top and 290 at the bottom
sx = min(319, max(0, round((3855 - x) * 319 / 3615)))
sy = min(239, max(0, round((3805 - y) * 239 / 3515)))
return sx, sy, x, y
The Dashboard
The program sets up the pins, starts the backlight's PWM at zero and creates the TFT, the touch controller and gpiozero's CPUTemperature:
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup([LED, BL], GPIO.OUT, initial=GPIO.LOW)
backlight = GPIO.PWM(BL, 500)
backlight.start(0)
tft, touch, cpu = TFT(), Touch(), CPUTemperature()
A TFT's memory is random at power-up, so the whole screen is cleared once; then the fixed parts are drawn, and the backlight fades in:
tft.fill(0, 0, 320, 240, DARK) # the whole screen once: a TFT's memory is random at power-up
tft.fill(0, 0, 320, 30, NAVY)
tft.text(8, 1, 'Pi 1 Model B+', WHITE, NAVY, 2)
tft.text(8, 40, 'CPU TEMPERATURE', GREY, DARK)
tft.fill(8, 106, 200, 66, GREY)
tft.fill(9, 107, 198, 64, DARK)
for label, y in (('ADDRESS', 40), ('UPTIME', 84), ('LED', 128)):
tft.text(216, y, label, GREY, DARK)
set_led(False)
for duty in range(0, 101, 20): # the backlight fades in (PWM on GPIO18)
backlight.ChangeDutyCycle(duty)
time.sleep(0.05)
print('TFT ready: 320 x 240 on CE0, touch on CE1 - touch LED ON / LED OFF')
The buttons are drawn by one function: the active one gets a white frame, and the LED's state is written next to them:
def buttons(on): # the active button gets a white frame
tft.fill(8, 182, 148, 50, WHITE if on else DARK)
tft.fill(11, 185, 142, 44, GREEN)
tft.text(34, 193, 'LED ON', WHITE, GREEN, 2)
tft.fill(164, 182, 148, 50, DARK if on else WHITE)
tft.fill(167, 185, 142, 44, RED)
tft.text(182, 193, 'LED OFF', WHITE, RED, 2)
tft.text(216, 146, ' ON' if on else 'OFF', AMBER if on else GREY, DARK, 2)
The main loop checks the touch every 50 ms. A press on a button switches the LED, and the loop waits for the release:
while True:
p = touch.point()
if p:
x, y, rx, ry = p
print('touch at x %d, y %d (raw %d, %d)' % p)
if 182 <= y < 232 and 8 <= x < 156:
set_led(True)
elif 182 <= y < 232 and 164 <= x < 312:
set_led(False)
while not GPIO.input(T_IRQ): # wait for the release
time.sleep(0.02)
Twice a second it updates the clock, the temperature (only when the shown value changes), one bar of the chart - a sweep from left to right with an amber cursor - the uptime and the address, and every two seconds it prints a line in the terminal.
Run the Demo
Press Run. The board boots for half a second, the program sets the TFT up and draws the dashboard, and the backlight fades in. eth0 gets 192.168.1.51 from the router 1.2 s after Run, and the address appears on the screen:
Now click LED ON on the TFT's glass and keep the mouse button down for a moment - the program checks the touch every 50 ms. The touch controller reports the point, the LED on GPIO27 lights, LED ON gets its frame and the screen says ON:
The Pi Terminal shows the touch - the screen point and the raw values of the film - and the readings:
pi@raspberrypi:~ $ python3 tft_dashboard.py
TFT ready: 320 x 240 on CE0, touch on CE1 - touch LED ON / LED OFF
07:36:35 CPU 44.3 C LED off 192.168.1.51
07:36:37 CPU 44.7 C LED off 192.168.1.51
07:36:39 CPU 45.1 C LED off 192.168.1.51
07:36:41 CPU 45.3 C LED off 192.168.1.51
touch at x 81, y 208 (raw 2936, 744)
07:36:43 CPU 45.4 C LED on 192.168.1.51
Click LED OFF and the LED goes out again:
touch at x 233, y 204 (raw 1209, 807)
07:36:51 CPU 45.0 C LED off 192.168.1.51
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 - on the B+ all 28 GPIOs, the PWR, ACT, LNK and 100 LEDs and the supply pins - and RESTART PROGRAM starts the program again:
Properties of the Raspberry Pi 1 Model B+
| 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 |
| ETHERNET | the cable to the router at Run: IN (default) or OUT |
| 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 TFT stays white: it is still asleep or never set up - send SLPOUT (0x11), wait 120 ms, then DISPON (0x29). The TFT's STATUS panel under the board names the problem.
- Garbage on the screen: keep DC low for a command byte and high for its parameters and the pixels.
- The picture is mirrored or on its side: MADCTL (0x36) sets the rotation; 0xE8 is landscape and upright here.
- A touch lands in the wrong place: calibrate with the raw values the program prints at the edges of the glass.
- No touch at all: T_IRQ must be wired, T_DO shares MISO, and the mouse button must stay down long enough for the program's poll.
- OverflowError: Argument list size exceeds 4096 bytes: split xfer / xfer2 transfers, or use writebytes2.
- 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
- Turn SPI on: SPI is off in a fresh Raspberry Pi OS - enable it with
sudo raspi-config. - 3.3 V: the red ILI9341 module has its own regulator; feed it from the Pi and keep every signal at 3.3 V.
- Speed: a real ILI9341 often takes SPI faster than its 10 MHz rating; start at 8 MHz and try more.
- Libraries: on a real Pi you can also use luma.lcd or Adafruit's CircuitPython ILI9341 driver, or the kernel's fbtft driver to make the TFT a Linux screen; this program shows what those libraries do underneath.
- Calibration: every touch film is a little different - read the raw values at the edges of your module.
Limitations of the Simulation
- The board does not run Raspberry Pi OS: there is no desktop, no shell commands, no apt and no fbtft. It runs one Python program.
- HDMI, the A/V jack, the camera and display connectors, USB, the microSD card's files and a HAT's ID EEPROM are drawn but not simulated; GPIO18's PWM is software PWM here.
- 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 to 60 % of real time on our PC with the TFT and the Pi Terminal open). Proteus 7 is not supported.
So, that was all about the Raspberry Pi 1 Model B+ Library for Proteus. I hope it helps you try a Pi project with a colour touch screen before you touch the hardware - the 40-pin header, SPI with two devices on one bus, and a dashboard drawn from pure Python. The next boards of our Raspberry Pi series bring other modules. 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!