Hello friends, I hope you all are doing great. Today, I am going to share the new PIR Sensor Library for Proteus V4.0. The HC-SR501 is a very popular PIR motion sensor module: a green board with a white dome that switches its OUT pin HIGH when a person or an animal moves in front of it. You find it in motion-activated lights, alarms and automatic doors. With this PIR Sensor Library for Proteus, a person or a cat walks through a room on your schematic, and your Arduino reads the OUT pin exactly as it reads a real HC-SR501.

Version 4.0 is the next version of our PIR sensor library. You get two devices: HC-SR501 Simple, with a room scene on the schematic, and HC-SR501 Advance, with a pop-up window and four measured sensor test tools. The model has the time delay, the H / L jumper, the block time and the warm-up of the real module, the board is animated, and the new PIR sensor Arduino Proteus demo runs on two Arduino UNOs with a motion lamp and a warm-up guard, shown in the compact Simple interface of our TEP Serial Monitor.

NOTICE: This library is very special to our team. Our HC-SR501 model has the BISS0001's trigger logic with the time delay, jumper H and L, the block time and the warm-up with its false pulses, and a PIR that sees only a moving warm body inside its 110 degree cone and its range. It took our team a lot of hard work, many test runs and many design changes. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the PIR Sensor Library board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the PIR Sensor Library for Proteus:

Figure: The PIR sensor demo in Proteus 8.5: NODE 1 (Simple) and NODE 2 (Advance), U2's Room page (OUT HIGH, Last HIGH 20.2 s, Response 0.10 s) and U4 printing "Motion detected! #14 at 367.4 s".

What is a PIR Sensor (HC-SR501)?

PIR stands for passive infrared. Every warm body gives off infrared light (heat radiation) that our eyes cannot see. A PIR sensor sends nothing out, which is why it is called passive; it only watches this light. Inside the HC-SR501 sits a pyroelectric sensor with two elements, under a white plastic Fresnel lens: the dome. The lens splits the room into zones. When a warm body moves from one zone to the next, the two elements see a change of heat, and the sensor gives a small signal.

The module's controller chip, the BISS0001, turns that signal into a clean digital output: it switches the OUT pin HIGH for a set time. Two small pots set that time (TIME) and the range (SENS), and a jumper decides what happens when the motion goes on (H or L). Your Arduino needs one digital pin and no library.

The HC-SR501 at a Glance

HC-SR501 in numbers (the real module)
FeatureValue
SensorA dual-element pyroelectric sensor under a white Fresnel dome
ControllerBISS0001 PIR signal processor
OutputOUT, digital: HIGH = 3.3 V (motion was seen), LOW = 0 V
Supply4.5 to 20 V (5 V from the Arduino is fine)
Time delay (TIME pot)About 3 s to 5 minutes
Range (SENS pot)About 3 to 7 m
Field of viewA cone of about 110 degrees
Trigger jumperH = repeat trigger, L = single trigger
Block timeAbout 2.5 s after OUT falls, not adjustable on the board
Warm-up30 to 60 s after power-on, with false pulses
PinsVCC, OUT, GND (three pins)

PIR Terms You Will See in This Article

PIR terms
TermMeaning
PIRPassive infrared: the sensor only receives heat radiation
Fresnel lensThe white dome; it splits the view into zones
BISS0001The chip that turns the PIR signal into the OUT pulse
Trigger (PIR pulse)One "I saw motion" signal from the PIR to the BISS0001
Time delayHow long OUT stays HIGH after a trigger (the TIME pot)
Repeat trigger (H)Every new trigger restarts the time delay
Single trigger (L)OUT stays HIGH for the time delay only, then falls
Block timeAfter OUT falls, the sensor ignores motion for a short time
Warm-upThe settling time after power-on; OUT can give false pulses
ResponseThe time from the moment the PIR first sees the body to OUT going HIGH

How the HC-SR501 Decides When OUT Goes HIGH

Only a Moving Warm Body Counts

A PIR sees changes of heat, not heat itself. A person who walks across the room gives trigger pulses; the same person standing still gives none. So the HC-SR501 is a motion sensor, not a presence sensor: OUT falls after the time delay even when someone is still in the room.

The Time Delay and the Jumper

On the first trigger, OUT goes HIGH for the time delay. On the real board, the TIME pot sets it from about 3 s to 5 minutes; our model starts at 5 s to keep the demo fast. The jumper decides what a new trigger does while OUT is HIGH:

  • H, repeat trigger: every new trigger restarts the time delay. OUT stays HIGH while you keep moving and falls one time delay after the last trigger. Most projects use H.
  • L, single trigger: OUT stays HIGH for exactly the time delay and then falls, even if you keep moving.

The Block Time and the Warm-Up

When OUT falls, the BISS0001 ignores every trigger for about 2.5 s, the block time. So with jumper L, a person who keeps walking makes pulses of exactly the time delay, with a gap of the block time between them.

After power-on, a real HC-SR501 needs 30 to 60 s to settle, and OUT may give false pulses meanwhile, which a sketch cannot tell from real motion. Our model gives two false pulses, at 20 % and 55 % of the warm-up; that is an approximation, because real modules vary. The demo skips the warm-up (WARMUP = SKIP); click REAL 60 s on the panel or run the Warm-up test to see it.

How Our Model Watches the Room

In our model, the PIR looks at the room every 100 ms while the body moves. The body counts as seen when it moves inside the 110 degree cone and within the range. The second look in a row that sees it gives the first trigger, and then one trigger comes every 0.5 s while the body stays seen. So OUT goes HIGH 0.2 s after the motion starts, which is 0.1 s after the PIR first sees the body: the response. A cat counts only up to half of the SENS range, because it is smaller and warms fewer zones.

What's New in PIR Sensor Library for Proteus V4.0

Our PIR sensor library had earlier versions, up to V3.0. Version 4.0 is the next one, and it brings:

  • Two devices in TEPHCSR501.LIB: HC-SR501 Simple (HCSR501TEP) and HC-SR501 Advance (HCSR501ADVTEP), both run by TEPHCSR501.DLL.
  • The BISS0001 behaviour: the time delay, jumper H and L, the block time and the warm-up.
  • A live board with PWR, OUT and TRIG LEDs (a TEP addition), turning pots, a moving jumper cap, a glowing dome and an animated PIR VIEW screen.
  • A room scene: a person or a cat walks in, paces, stands still or walks out.
  • An event log with measured times and four measured test tools on the Advance.
  • A two-UNO demo with the TEP Serial Monitor instead of the Virtual Terminal, with a lamp on A0 and five commands.
  • A fast sheet: the panels animate at 10 Hz and redraw only what changes. In our Proteus run, the whole demo runs at about 0.71 x real time (22.0 s simulated in 30.8 s, with the pop-up open, U1 animating and both monitors running); our first V4.0 build reached only about 0.35 x.
  • A small package: about 1.52 MB, without the C++ source code.

PIR Sensor Library for Proteus: Simple vs Advance

Both devices run the same model with the same properties; only the panel differs:

PIR sensor Simple vs Advance
FeatureSimpleAdvance
Full HC-SR501 model (BISS0001 timing, jumper, block time, warm-up, 110 degree cone, range)✔✔
Green board: PWR / OUT / TRIG LEDs, turning pots, jumper, glowing dome, PIR VIEW screen✔✔
PIR ROOM SCENE panel on the schematic (the room, the OUT timeline, scene and module buttons)✔✘
Pop-up window you can move, resize and minimise✘✔
Room page with THE SENSOR card (measured times) and the EVENT LOG✘✔
OUT check, Retrigger H / L, Warm-up & block and Range sweep✘✔
TEP Dark / Light theme, text size, Help page with Copy diagnostics✘✔
Close the panel and open it again from the board✔✔

Choose Simple when you want to see the room next to your circuit, and Advance when your sheet is full or you want measured numbers about your sensor. The demo has one of each.

Download PIR Sensor Library for Proteus

Click the button below to download PIR-Sensor-Library-for-Proteus-v4.0.zip (about 1.52 MB, without the C++ source code):

PIR Sensor Library for Proteus V4.0
  • README.txt: a detailed guide to the files, the wiring, the model, the test tools and real hardware.
  • Proteus Library Files: TEPHCSR501.LIB (both devices), TEPSERIALMON.LIB and our Arduino UNO library ArduinoV3TEP.LIB / ArduinoV3TEP.IDX.
  • Proteus Model Files: TEPHCSR501.DLL and TEPSERIALMON.DLL.
  • Proteus Simulation: HCSR501-PIR-ArduinoUnoV3.pdsprj, HCSR501_Motion.hex (both UNOs run it) and copies of both DLLs.
  • Arduino Code: HCSR501_Motion.ino, the demo sketch. It needs no Arduino library.

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 PIR Sensor Library for Proteus

  1. Close Proteus and extract the whole zip file.
  2. Copy the four files from Proteus Library Files into the LIBRARY folder, usually C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY (on some PCs C:\ProgramData\Labcenter Electronics\Proteus 8 Professional\LIBRARY).
  3. Copy TEPHCSR501.DLL and TEPSERIALMON.DLL into the MODELS folder.
  4. Start Proteus, press P and search for HC-SR501 or PIR. You get the Simple and the Advance device (category Sensors > Motion).

Updating from an earlier version? Replace its LIB and DLL files, and delete TEPHCSR501.IDX if there is one in the LIBRARY folder. Tested in Proteus 8.5; Proteus 7 is not supported.

The HC-SR501 Board in Proteus

We drew the sensor as a clean TEP board in the green of the real module: the white faceted Fresnel dome in the middle, the orange TIME and SENS pots, the BISS0001 chip, the L / H jumper with its yellow cap and the VCC OUT GND header. The real module has the dome on one side and the parts on the other; we put them all on one face, so you see everything at once. Here is U1, the Simple device, right after Run:

Figure: U1 (Simple) after Run: the person stands still at MID 3.5 m, so OUT stays LOW: "NO MOTION - A STILL BODY IS INVISIBLE TO THE PIR".

The PIR VIEW Screen

Above the board, on two posts, sits the PIR VIEW - TOP screen. It shows the sensor's cone from above with the zone arcs at 1.5, 3.5 and 6 m, the detection range as an arc in the state's colour (green = ready, orange = OUT HIGH, violet = blocked, amber = warming up) and the warm body as a dot. While the PIR sees the body, a halo and heat ripples run from the body to the sensor.

Pinout

The three pins have the real order, left to right with the dome up and the header at the bottom: VCC, OUT and GND. Some clones swap them, so on a real board, check the print under the dome.

HC-SR501 pins in Proteus (VCC OUT GND)
PinWhat it doesDemo connection
VCCPower (4.5 to 20 V on the real module)Power terminal
OUTDigital output: HIGH while motion was seen, LOW when the time delay is overArduino D2
GNDGroundGround

LEDs and Indicators

Board animations (the same on both devices)
IndicatorWhat it shows
PWR LED (red)Lit while the board has power
OUT LED (green)Lit while OUT is HIGH
TRIG LED (amber)Lights for 0.3 s on every trigger pulse from the PIR, also on the ones the BISS0001 ignores
Dome ringGrey when idle, amber blinking while warming up, orange-red while OUT is HIGH, a yellow flash on each accepted trigger, violet while blocked
TIME and SENS potsTheir slots turn with the settings
Jumper capSits on H or on L
PIR VIEW screenThe cone, the range in the state's colour, the body, the halo and the heat ripples
PANEL / OPEN PANEL, SIMPLE / ADVANCEThe panel button and the device badge

The PWR, OUT and TRIG LEDs are a TEP addition: the real HC-SR501 has no LED at all. The board also reacts to the mouse: click the jumper to move its cap, and click the left or right half of a pot to turn it down or up.

Component Properties

HC-SR501 properties (double-click the sensor > Edit Properties)
PropertyMeaningDefault
TRIGGERThe jumper: H (repeat) or L (single)H
TIMEDELAYThe time delay in s (the TIME pot: 3 to 300 on the real board; 1 to 600 accepted)5
SENSITIVITYThe range in m (the SENS pot), 3 to 75
BLOCKTIMEThe block time after OUT falls, in s, 0 to 102.5
WARMUPSKIP, REAL (60 s) or a number of seconds, 0 to 300SKIP
BODYPERSON or CATPERSON
ZONENEAR (1.5 m), MID (3.5 m) or FAR (6 m)MID
STARTThe body at Run: STILL, WALKING, OUTSIDE or AUTOSTILL
PANELSimple only: the panel at Run, OPEN or CLOSEDOPEN

A bad value is written to the Simulation Log, and the default is used. The panel style comes from the device (Simple or Advance), not from a property; the Advance window has its own "open at Run" setting. There is one more property, for emergencies: if a part of a panel ever looks stale in your Proteus, add REDRAW=FULL under Edit Properties > Other Properties. The sensor then redraws everything on every frame, like our first V4.0 build. It is slower, but it is the fallback.

HC-SR501 Simple: The PIR Room Scene on the Sheet

Beside the Simple board sits the HC-SR501 PIR ROOM SCENE panel (on the right of the image above). On its left, a room of 9.1 x 8.2 m seen from above: the sensor in the bottom wall, its cone, the detection area cut at the SENS range (RANGE 5 m), the zone arcs NEAR 1.5 m, MID 3.5 m and FAR 6 m, a sofa, a plant and the door in the right wall. On its right:

The HC-SR501 Simple room scene panel
PartWhat it does
Header, red XHC-SR501 PIR ROOM SCENE; the X closes the panel
BannerThe state in words and in its colour
OUT, TIME LEFT, BLOCK LEFT, DETECTIONSOUT now, the time delay and the block time still to run, and the detections since power-on (without the warm-up's false pulses)
OUT TIMELINE - LAST 30 sGreen = OUT HIGH, violet = blocked, amber = warm-up, ticks = PIR pulses
PERSON (OR CAT)WALK IN, STAND STILL, WALK OUT, AUTO DEMO
WARM BODY, DISTANCE ZONEPERSON or CAT; NEAR 1.5 m, MID 3.5 m or FAR 6 m
SENSITIVITY POT (3 - 7 m), TIME DELAY POT (3 s - 5 min)The SENS and TIME pots with - / +
TRIGGER JUMPERL SINGLE or H REPEAT
WARM-UP AFTER POWER ONSKIP, or REAL 60 s
HOW A PIR SENSOR SEESSix short tips on how a PIR works
The scene buttons
ButtonWhat the warm body does
WALK INWalks from the door to the zone, then paces across the cone
STAND STILLStops where it is (from outside: walks in and stops)
WALK OUTWalks back to the door and out
AUTO DEMOOutside 4 s, in and pacing 6 s, still 12 s, out, and again
PERSON / CATA cat is seen only up to half of the SENS range
NEAR / MID / FARThe pacing zone: 1.5, 3.5 or 6 m from the sensor

At Run: Standing Still Is Invisible

Look at the image above again. The demo starts with START = STILL: the person stands at MID 3.5 m, inside the cone and the range, and yet the banner says NO MOTION - A STILL BODY IS INVISIBLE TO THE PIR. OUT is LOW, DETECTIONS is 0, and only the PWR LED is lit, just like a real PIR.

WALK IN: Motion Detected

Figure: WALK IN: MOTION DETECTED - OUT HIGH, TIME LEFT 4.9 s, DETECTIONS 1; all three LEDs are lit.

Click WALK IN. The person walks in and paces across the cone at MID 3.5 m, and 0.2 s after the motion starts, OUT goes HIGH. The banner turns green, MOTION DETECTED - OUT HIGH, the detection area turns orange and the person gets an orange halo. On the board, all three LEDs are lit, the dome's ring flashes yellow with the accepted trigger, and the PIR VIEW shows heat ripples running to the sensor.

TIME LEFT says 4.9 s: with jumper H, every new trigger restarts the 5 s time delay. Now click STAND STILL: the banner says OUT HIGH - TIME DELAY RUNNING, NO MOTION NOW, and 5 s after the last trigger, OUT falls. The area turns violet for the 2.5 s block, then green again, and U3 prints the "Motion ended" line with the HIGH time.

Jumper L: OUT Drops While You Keep Walking

Figure: L SINGLE while the person keeps walking: BLOCKED (RE-ARMING) - OUT LOW, MOTION IGNORED, BLOCK LEFT 0.3 s.

Now click L SINGLE while the person keeps pacing, and the jumper cap on the board moves to L. New triggers no longer restart the time delay, so OUT falls when it runs out, although the person is still walking. Then the sensor is blocked: the banner turns violet, BLOCKED (RE-ARMING) - OUT LOW, MOTION IGNORED, BLOCK LEFT shows 0.3 s, and the dome ring and the detection area are violet.

The PIR still sees the person: the ticks on the timeline go on, and the TRIG LED still flashes. But the BISS0001 ignores those triggers until the block ends. This is why a light with jumper L can switch off while you are still in the room.

A Cat at MID 3.5 m: Too Far

Figure: CAT at MID 3.5 m with SENS 5 m: NO MOTION SEEN - TOO FAR FOR THE SENSITIVITY; the PIR VIEW's range arc moves in to 2.5 m.

Click CAT. A cat is smaller and warms fewer zones, so our model sees it only up to half of the SENS range: 2.5 m with SENS 5 m. At MID 3.5 m, the cat walks and walks, but OUT stays LOW, and the banner turns orange: NO MOTION SEEN - TOO FAR FOR THE SENSITIVITY. On the PIR VIEW screen, the green range arc has moved in to half the distance, with the cat's dot beyond it. The timeline still shows the person's two detections, each followed by the violet block.

To catch the cat, click NEAR 1.5 m, or press SENS + twice: at 7 m, a cat counts up to 3.5 m.

Closing the Panel

Click the red X in the panel's header: the panel disappears, the board button says PANEL: CLOSED, and the sensor keeps running. The PIR VIEW screen stays, so you still see what the sensor sees; here, the cat beyond its range. Click PANEL to bring the panel back. The PANEL property decides whether the panel is open at Run.

Figure: The panel closed: PANEL: CLOSED; the PIR VIEW still shows the cat beyond its 2.5 m range.

HC-SR501 Advance: The Pop-Up Room Window

The Advance device keeps only the board on the schematic. Here is U2:

Figure: U2 (Advance) with OPEN PANEL and the ADVANCE badge; the person stands inside the 5 m range.

At Run, the "TEP HC-SR501 Advance" pop-up opens with the look of our TEP Serial Monitor and no Windows title bar: move it by its header, resize or minimise it, and open it again with OPEN PANEL after you close it. The header shows the state (for example U2 · OUT HIGH), the Room and Test tabs, and the palette (theme), gear (Settings) and ? (Help) icons.

The Room Page

Figure: The Room page: OUT HIGH, Last HIGH 20.2 s, After last pulse 5.0 s (= the TIME pot), Response 0.10 s; the EVENT LOG newest first.
  • Toolbar chips: OUT HIGH, Jumper H, TIME 5 s, Range 5 m and Detections 12.
  • ROOM - TOP VIEW: the same room with the cone, the range in the state's colour and the person with the halo.
  • THE SENSOR: the state, OUT "HIGH (3.3 V)", time left 5.0 s of 5 s, Detections 12 (208 PIR pulses), the measured Last HIGH 20.2 s, After last pulse 5.0 s, Last block 2.5 s and Response 0.10 s, the jumper, the range and the warm body: person at 3.5 m, -11 degrees.
  • SCENE AND MODULE SETTINGS and OUT - THE LAST 30 SECONDS: the buttons and the timeline of the Simple panel.
  • EVENT LOG - NEWEST FIRST: every event with its simulation time.

Read the event log from the bottom up. At 272.554 s, the person stopped. At 277.501 s: "OUT LOW - HIGH for 20.2 s, 5.0 s after the last trigger", and at 280.001 s: "Ready again - blocked for 2.5 s". Then the person started moving at 367.301 s, the PIR saw it at 3.5 m at 367.401 s, and at 367.501 s came "OUT HIGH - motion #12 at 3.5 m, 0.10 s after it was seen". The model measures these times itself, so they are exactly what OUT did.

The Test Page: Four Measured Sensor Test Tools

The four tools on the Test tab only move the warm body, set the jumper or restart the warm-up, and then read the model's event log. So every time they show is what OUT really did, measured with the simulation clock. Each tool ends with a bold "Good for:" line and puts the scene back when it ends. A tool refuses to start, with the reason, when the sensor has no power, is warming up, another test runs, or (for Retrigger and Warm-up) TIME is above 30 s. All results below come from U2 in our Proteus run.

1. OUT Check: Does OUT Stay HIGH for the TIME Pot?

Figure: OUT check, 40 s, Walk in + out: 3 pulses, HIGH 11.0 and 12.5 s, every fall 5.0 s after the last pulse, block 2.5 s, response 0.10 s.

Good for: "checking that OUT stays HIGH for the TIME pot after the last motion - what your sketch reads on D2." Choose 20, 40 or 60 s and the motion: As set (the scene as it is), Walk in + out (in, pace 4 s, out, 3 s outside, and again) or Auto demo. Then click Run test. The chart shows the body moving (blue), the PIR pulses (the green tick started OUT) and OUT (green HIGH, violet block).

OUT check, 40 s, Walk in + out (U2, jumper H, TIME 5 s)
#RiseFallHIGH forAfter last pulseRestartsResponse
10.20 s11.20 s11.0 s5.0 s120.10 s
217.00 s29.50 s12.5 s5.0 s150.10 s
335.35 sstill HIGH--90.10 s

Every pulse is longer than 5 s, because each PIR pulse restarts the time delay (12 and 15 restarts). But every pulse ends exactly 5.0 s after its last trigger: the TIME pot. After each fall, the sensor is blind for 2.5 s, and every pulse started 0.10 s after the PIR first saw the body. The third pulse was still HIGH when the 40 s ended.

2. Retrigger H / L: Why Does OUT Drop While I Keep Moving?

Figure: Retrigger H / L, 1 burst: jumper L gives 2 pulses of 5.0 s, 2.5 s apart; jumper H gives one HIGH of 15.0 s.

Good for: "seeing why OUT drops while you keep moving (jumper L) or stays HIGH all along (jumper H)." The tool makes the same motion twice, first with jumper L and then with jumper H: 10.5 s of moving in place at 3.0 m (60 % of the range), which is TIME 5 s + block 2.5 s + 3 s. Choose 1 or 3 bursts; each burst starts after a flat lead-in (OUT LOW and the sensor ready for 1 s).

Retrigger H / L, 1 burst (U2, TIME 5 s, block 2.5 s)
JumperPulsesHIGH timesGaps (block)OUT fell after the motion
L25.0 s, 5.0 s2.5 s2.2 s later
H115.0 s-4.7 s later

With jumper L, OUT is HIGH for exactly 5.0 s and falls although the body keeps moving, stays blind for the 2.5 s block, and then the next trigger starts a second pulse of 5.0 s. With jumper H, every PIR pulse restarts the time. The first trigger came 0.2 s after the motion started and the last one 0.3 s before it ended, so OUT was HIGH from 0.2 s to 15.2 s: one pulse of 15.0 s, falling 4.7 s after the motion, which is 5.0 s after the last trigger. For a light that must stay on while people move, use H.

3. Warm-Up & Block: How Long Is the Sensor Blind?

Figure: Warm-up & block, 30 s: 2 false pulses of 1.8 s, 60 triggers ignored, the first detection at 30.20 s, block 2.5 s.

Good for: "knowing how long to wait after power-on, and how long the sensor is blind after OUT falls." Choose a warm-up of 10 s, 30 s or 60 s (real); the tool reminds you that "a real HC-SR501 needs 30 - 60 s". It restarts the warm-up like a fresh power-on while the person keeps moving. After the first detection, the person stands still until OUT falls and then moves again at once.

Warm-up & block, 30 s (U2)
TimeEvent (as the tool lists it)
0.00 swarm-up 30 s starts (like a fresh power-on)
6.00 sOUT HIGH - false pulse 1 (the sketch would see motion!)
7.80 sOUT LOW - the false pulse lasted 1.8 s
16.50 sOUT HIGH - false pulse 2 (the sketch would see motion!)
18.30 sOUT LOW - the false pulse lasted 1.8 s
30.00 swarm-up over after 30.0 s (60 triggers ignored)
30.20 sOUT HIGH - motion detected
35.20 sOUT LOW after 5.0 s HIGH - the block starts
37.70 sready again after a 2.5 s block (5 pulses ignored)
37.90 sOUT HIGH - motion detected

The two false pulses come at 20 % and 55 % of the warm-up (6.0 and 16.5 s of 30 s), and to your sketch they look exactly like motion. The person moved all through the warm-up, but all 60 triggers were ignored; the first real detection came 0.2 s after the warm-up ended. Then the block: OUT fell at 35.20 s, the sensor ignored 5 pulses for 2.5 s, and the next detection came at 37.90 s, so OUT was LOW for 2.7 s between two detections. The demo sketch has the cure for the false pulses: the GUARD command.

4. Range Sweep: Where Does the Sensor See You?

Figure: Range sweep, both directions, person, SENS 5 m: seen up to 5.0 m ahead, not from 5.5 m; the cone -55 .. +55 deg; the first pulse after 0.20 s.

Good for: "finding where the sensor sees a moving body - the SENS range straight ahead and the 110 deg cone." Choose Straight ahead, Across the cone or Both. At each point, the body stands still for 0.3 s and then moves in place for 0.8 s; a point counts when the PIR gives a pulse. Straight ahead, the points go from 0.5 to 8 m; across the cone, from -70 to +70 degrees at 60 % of the range (3.0 m here).

  • Seen up to 5.0 m straight ahead and not seen from 5.5 m: the SENS pot.
  • Cone -55 .. +55 degrees: 110 degrees in total; at -60 and +60 degrees, nothing.
  • The first pulse 0.20 s after the motion started, at every point that was seen.

On the map, green dots are points with pulses, grey rings are points without, and the orange arc and lines are the range and the cone you set. For a cat, the range is half as far.

Settings and Help

The gear opens Settings: theme (TEP Dark or Light), text size (Small, Normal or Large), open the panel at Run, and the window size, saved for your Windows user.

Figure: Settings, saved under HKCU\Software\TheEngineeringProjects\TEP HC-SR501 Advance.

The ? icon opens Help & Support: eight cards with their links (the PIR sensor forum board for bugs and ideas, this article, updates, donate, our website and the forum), Check for updates, and Copy diagnostics, which copies the scene, the counts, the measured values, the events and the test results for a bug report.

Figure: Help & Support: every card shows its link; TEP HC-SR501 Advance v4.0, build 2026-10-09, TEPHCSR501.DLL.

PIR Motion Sensor with Arduino in Proteus

Open HCSR501-PIR-ArduinoUnoV3.pdsprj from the Proteus Simulation folder, with HCSR501_Motion.hex and both DLLs beside it. Its two Arduino UNOs from our Arduino Library for Proteus V3.0 run the same HEX file:

  • NODE 1 - SIMPLE: UNO 1 (ARD1) with the HC-SR501 Simple (U1), the lamp LED D1 with R1 (220 Ω) on A0, and Serial Monitor U3.
  • NODE 2 - ADVANCE: UNO 2 (ARD2) with the HC-SR501 Advance (U2), the lamp LED D2 with R2 on A0, and Serial Monitor U4.
Figure: The whole circuit running, without the pop-up windows: right after Run, both OUT pins are LOW, both lamps are off, and U3 and U4 show the start lines.

Wiring

Demo wiring (the same on both UNOs)
FromToWhy
HC-SR501 VCC / GNDPower terminal / groundPower (the PWR LED lights)
HC-SR501 OUTArduino D2Read with digitalRead(): HIGH = motion
LED + 220 Ω (the lamp)A0 to GNDThe motion lamp
Serial Monitor RXD / TXD / GNDArduino D1 / D0 / groundShows what the Arduino prints, sends what you type
Serial Monitor RXD2Not connectedOUT is one logic line, and the sketch prints what it sees

On the real module, OUT is 3.3 V when HIGH, and an UNO at 5 V reads anything above 3.0 V as HIGH, so no level shifter is needed (see our Introduction to Arduino UNO). The sketch also lights the UNO's own LED on D13 ("L") while OUT is HIGH.

The Arduino Code

The sketch needs no library. It reads D2 every 10 ms and prints a line only when something happens. First the pins:

const int PIR_PIN = 2;          // HC-SR501 OUT
const int LED_PIN = 13;         // the UNO's built-in LED
const int LAMP_PIN = A0;        // the lamp (LED + 220R)

In setup(), D2 is a plain input, because the sensor drives OUT itself, and the sketch prints its three start lines:

void setup() {
  pinMode(PIR_PIN, INPUT);      // the sensor drives OUT itself, no pull-up needed
  pinMode(LED_PIN, OUTPUT);
  pinMode(LAMP_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  setLamp(false);
  Serial.begin(9600);
  Serial.println("HC-SR501 PIR Motion Sensor demo - The Engineering Projects");
  Serial.println("Move in front of the sensor (Proteus: WALK IN on the panel)...");
  Serial.println("PIR Sensor Library for Proteus V4.0 - type HELP for the commands.");
}

The loop reads OUT, lets the UNO's LED follow it, and reads the commands from the Serial Monitor:

  int state = digitalRead(PIR_PIN);      // HIGH = motion, LOW = no motion
  digitalWrite(LED_PIN, state);          // the LED simply follows OUT
  unsigned long now = millis();
  readCommands();

A rising edge, where OUT was LOW and is HIGH now, is a new motion. The counter goes up, the time is stored, the lamp goes on, and the sketch prints the motion number and the time since the Arduino started:

  if (state == HIGH && lastState == LOW) {          // OUT just went HIGH: motion started
    motionCount++;
    highSince = now;
    setLamp(true);
    Serial.print("Motion detected!  #");
    Serial.print(motionCount);
    Serial.print(" at ");
    printSeconds(highSince);
    Serial.println();
  }

A falling edge means that the time delay is over. The sketch measures how long OUT was HIGH and keeps the shortest and the longest time for STATUS:

  if (state == LOW && lastState == HIGH) {          // OUT just went LOW: motion ended (time delay over)
    lowSince = now;
    lastHigh = now - highSince;
    if (shortestHigh == 0 || lastHigh < shortestHigh) shortestHigh = lastHigh;
    if (lastHigh > longestHigh) longestHigh = lastHigh;
    Serial.print("Motion ended      #");
    Serial.print(motionCount);
    Serial.print(" at ");
    printSeconds(now);
    Serial.print(" (OUT was HIGH for ");
    printSeconds(now - highSince);
    Serial.println(")");
  }

printSeconds() prints milliseconds as seconds with one decimal, rounded to 0.1 s. The panels round their times the same way, so both show the same numbers:

void printSeconds(unsigned long ms) {
  ms += 50;
  Serial.print(ms / 1000);
  Serial.print('.');
  Serial.print((ms % 1000) / 100);
  Serial.print(" s");
}

The lamp on A0 stays on for LAMP seconds after OUT goes LOW, like a motion-activated light in a corridor. With LAMP 0, the start value, it simply follows OUT:

  if (lampOn && state == LOW && now - lowSince >= lampSeconds * 1000UL) {
    setLamp(false);                                  // no motion for LAMP seconds (LAMP 0: at once)
    if (lampSeconds > 0) {
      Serial.print("Lamp OFF after ");
      Serial.print(lampSeconds);
      Serial.println(" s without motion.");
    }
  }

GUARD is the answer to the warm-up's false pulses. While the guard runs, the sketch counts the OUT changes but ignores them; when it ends, it says how many it ignored and starts watching OUT:

  if (guarding && (long)(now - guardUntil) >= 0) {   // the guard time is over
    guarding = false;
    Serial.print("Guard over - watching OUT (");
    Serial.print(guardIgnored);
    Serial.println(" changes ignored).");
    if (state == HIGH) highSince = now;
    lastState = state;
  }
  if (guarding) {                                    // sitting out the warm-up: no counting, no lamp
    if (state != lastState) guardIgnored++;
    lastState = state;
    delay(10);
    return;
  }

The GUARD command takes 0 to 300 seconds; 0 switches the guard off:

    if (s == 0) {
      guarding = false;
      Serial.println("Guard off - watching OUT.");
    } else {
      guarding = true;
      guardUntil = millis() + (unsigned long)s * 1000UL;
      Serial.print("Guard: OUT ignored for the next ");
      Serial.print(s);
      Serial.println(" s (warm-up).");
    }

HELP prints three short lines, so they fit the Serial Monitor's Simple interface:

void printHelp() {
  Serial.println("Commands: HELP, STATUS, RESET, LAMP s, GUARD s");
  Serial.println("  LAMP s: the A0 lamp stays on s s after the motion (0-600)");
  Serial.println("  GUARD s: ignore OUT for s s - sit out the warm-up (0-300)");
}

The loop ends with a short pause; 100 looks a second are plenty for a PIR:

  lastState = state;
  delay(10);                    // look 100 times a second - plenty for a PIR

To change the sketch, export a new HEX file and load it into both UNOs; see How to get the HEX file from Arduino. New to Arduino? Start with our Arduino Tutorial for Beginners.

Serial Monitor Commands

Commands of the demo sketch, upper or lower case (quick buttons: U3 STATUS, LAMP 10, RESET, HELP; U4 STATUS, GUARD 30, LAMP 0, HELP)
CommandWhat it doesThe sketch answers
HELPThe command listThree lines, from "Commands: HELP, STATUS, RESET, LAMP s, GUARD s"
STATUSOUT now, the motions counted, how long ago the last one ended; the last, shortest and longest HIGH time, the lamp and the guardTwo lines, "Status: ..." and " HIGH: ..."
RESETThe motion counter back to 0"Counter reset: 0 motions."
LAMP sThe A0 lamp stays on s seconds after OUT goes LOW (0 to 600; 0 = it follows OUT)"Lamp: A0 stays on 10 s after the motion." for LAMP 10
GUARD sIgnore OUT for s seconds (0 to 300; 0 = off)"Guard: OUT ignored for the next 30 s (warm-up)." for GUARD 30

Any other text gets "Unknown command: FOO - type HELP" (with your text in place of FOO). The README shows what STATUS prints after one motion with a HIGH time of 7.5 s:

Status: OUT LOW, 1 motion, last ended 4.2 s ago
  HIGH: last 7.5 s, shortest 7.5 s, longest 7.5 s; lamp 0 s; guard off

How to Run the Demo

  1. Press Run. Both Serial Monitors (9600 baud) and U2's pop-up open, U3 and U4 print the three start lines, and the PWR LEDs light.
  2. On U1's panel, click WALK IN (the lamp D1 lights, U3 prints "Motion detected!"), then STAND STILL (5 s after the last trigger, U3 prints "Motion ended").
  3. Try CAT, FAR 6 m (press SENS + twice), L SINGLE, AUTO DEMO and WARM-UP REAL 60 s, whose two false pulses the sketch counts as motions.
  4. Use the quick buttons: STATUS, LAMP 10 (the lamp stays on 10 s after the motion), RESET and HELP on U3; STATUS, GUARD 30 (sit out the warm-up), LAMP 0 and HELP on U4.
  5. On U2, watch THE SENSOR card and the EVENT LOG on the Room page, then try the four tools on the Test tab.
  6. Close U2's window and open it again with OPEN PANEL; close U1's panel with its red X and open it with PANEL.

PIR Sensor Proteus Simulation Results

The Serial Monitor in Its Simple Interface

Both monitors in this demo run in the Simple interface of our TEP Serial Monitor, as in every monitor screenshot here. Only the log, the send box and one slim toolbar row stay visible (baud rate, follow, pause, search and clear), so the window stays small.

  • Switch to it: right-click the log and choose Simple interface, or press Ctrl+Shift+U.
  • Back to the full view: click the corner button (the expand arrows at the top right), press Esc or Ctrl+Shift+U, or right-click and choose Full interface.
  • Your choice is remembered.

Type commands such as STATUS or LAMP 10 in the send box and press Enter; the quick buttons come back with the full view. Every line of the sketch is shorter than 80 characters (the longest has 71), so it fits this small window. Read all about the monitor in TEP Serial Monitor Advance for Proteus.

Start-Up

After Run, U3 prints its three lines, and then nothing until OUT changes: the sketch never prints anything periodically.

Figure: U3 in the Simple interface: the three start lines, then silence until OUT changes.
HC-SR501 PIR Motion Sensor demo - The Engineering Projects
Move in front of the sensor (Proteus: WALK IN on the panel)...
PIR Sensor Library for Proteus V4.0 - type HELP for the commands.

The Motion Log

Figure: U4 after the tests: #8 and #9 are the warm-up's false pulses (1.8 s each); #13 was HIGH for 20.2 s, as the Room page measured.
Motion detected!  #8 at 182.9 s
Motion ended      #8 at 184.7 s (OUT was HIGH for 1.8 s)
Motion detected!  #9 at 193.4 s
Motion ended      #9 at 195.2 s (OUT was HIGH for 1.8 s)
Motion detected!  #10 at 207.1 s
Motion ended      #10 at 212.1 s (OUT was HIGH for 5.0 s)
Motion detected!  #11 at 214.8 s
Motion ended      #11 at 221.5 s (OUT was HIGH for 6.7 s)
Motion detected!  #12 at 236.3 s
Motion ended      #12 at 251.7 s (OUT was HIGH for 15.4 s)
Motion detected!  #13 at 257.2 s
Motion ended      #13 at 277.4 s (OUT was HIGH for 20.2 s)
Motion detected!  #14 at 367.4 s

These lines come from U4 in our run, after the four tests. Look at #8 and #9: two pulses of 1.8 s, 10.5 s apart. They are the two false pulses of the Warm-up & block test, at 6.00 and 16.50 s of its warm-up. #10 at 207.1 s is that test's first real detection, 30.2 s after its warm-up started; it was HIGH for 5.0 s while the person stood still, and #11 followed 2.7 s after it ended: the 2.5 s block plus the 0.2 s response.

The sketch counts every rising edge of OUT, the false pulses too, while the model's Detections counter leaves them out. That is why U2 says Detections 12 while U4 is at #14: a warm-up guard matters in a real project. And look at #13: HIGH for 20.2 s. The Room page measured the same, "OUT LOW - HIGH for 20.2 s, 5.0 s after the last trigger", so the sketch and the model agree.

Troubleshooting

  • Nothing is printed while the person stands in the room: correct; a PIR sees only moving warm bodies. Click WALK IN.
  • "Motion detected!" right after Run without anyone moving: the warm-up's false pulses (WARMUP REAL or a number). Use GUARD in the sketch, or wait.
  • OUT goes LOW although the person keeps walking: jumper L (single trigger), or the person is too far (FAR 6 m with SENS 5 m) or outside the cone.
  • No new detection right after OUT went LOW: the block time (2.5 s).
  • A cat at MID 3.5 m is not detected with SENS 5 m: correct; try NEAR 1.5 m or SENS 7 m.
  • The part is not simulated, no panel or no monitor window: TEPHCSR501.DLL or TEPSERIALMON.DLL is missing from MODELS and the project folder; click OPEN MONITOR on a closed monitor.
  • The Advance pop-up does not appear: click OPEN PANEL on the board, use Proteus's Debug menu, or turn "Open the panel at Run" back on in Settings.
  • The red X does not close the Simple panel: the design holds an older symbol; replace TEPHCSR501.LIB, delete TEPHCSR501.IDX and re-pick the part.
  • A part of a panel looks stale: add REDRAW=FULL to the sensor (Edit Properties > Other Properties), and please tell us in the forum.

Things to Know Before Using a Real HC-SR501

The demo sketch uses no library, so it runs unchanged on a real UNO and HC-SR501. Keep in mind:

  • Supply: 4.5 to 20 V; 5 V from the UNO is fine. OUT is 3.3 V when HIGH, which an UNO reads as HIGH.
  • Pins: some clones swap VCC, OUT and GND: check the print under the dome.
  • Jumper: its factory position varies; most projects use H.
  • Warm-up: wait 30 to 60 s after power-on (or use GUARD 60 in the demo) before you trust OUT.
  • What it sees: a body moving across its zones is seen best, a body walking straight at it is seen later (not simulated), and glass blocks it.

Limitations of the Simulation

  • Not modelled: the analog signal of the pyroelectric element, the direction of motion (motion towards the sensor is seen as well as motion across it), temperature effects, the board's pads for a daylight sensor (LDR) and a thermistor, the retrigger glitches of real boards, and the exact false-pulse pattern of a real warm-up (it varies).
  • The model is our own implementation, written from the published BISS0001 and HC-SR501 data; it contains no third-party code. The way the PIR looks every 100 ms, the cat's half range and the two false pulses are model choices.
  • Licences: the demo sketch uses no Arduino library. The HEX file contains the Arduino AVR core 1.8.6, which includes LGPL-licensed code; its source code is on GitHub.
  • Tested in Proteus 8.5 in October 2026: the demo on two UNOs, both panels, the four tools, the fixes after the first run (re-checked the same day) and every screenshot here; and with 1,435 automatic PC checks, all passed, 29 of them with the real demo sketch on two UNOs. Proteus 7 is not supported.

Want to know how far away the person is? See our Ultrasonic Sensor Library for Proteus V2.0. For short-range obstacles, try our Infrared Sensor Library for Proteus V2.0, and to switch your motion lamp on only at night, add our LDR Sensor Library for Proteus. To send a motion alarm to another Arduino by radio, add our HC-12 Library for Proteus.

So, that was all about the PIR Sensor Library for Proteus V4.0. I hope the walking person, the H / L jumper, the block time, the warm-up guard and the four test tools make the HC-SR501 much easier to understand, so your motion project works the first time you wire a real module. If you use the PIR Sensor Library for Proteus in a project, please share your feedback 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!