Chain PIR
PIRChain is the helper class for PIR (Passive Infrared) sensor devices on the Chain bus. It provides methods to read IR induction values, configure trigger delay, and monitor PIR trigger events.
Support the following products:
UiFlow2 Example
PIR motion detection
Open the m5core_chain_pir_basic_example.m5f2 project in UiFlow2.
This example demonstrates how to use trigger callbacks from the Chain PIR sensor to update motion status on screen. It enables trigger auto-send, configures trigger hold time, and counts the detected duration while motion is active.
UiFlow2 Code Block:
Example output:
None
MicroPython Example
PIR motion detection
This example demonstrates how to use trigger callbacks from the Chain PIR sensor to update motion status on screen. It enables trigger auto-send, configures trigger hold time, and counts the detected duration while motion is active.
MicroPython Code Block:
1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8from chain import PIRChain 9from chain import ChainBus 10import time 11 12 13title0 = None 14label_status = None 15label_count = None 16bus2 = None 17chain_pir_0 = None 18detected = None 19count = None 20last_time = None 21trigger_hold_time = None 22 23 24def chain_pir_0_motion_detected_event(args): 25 global \ 26 title0, \ 27 label_status, \ 28 label_count, \ 29 bus2, \ 30 chain_pir_0, \ 31 detected, \ 32 count, \ 33 last_time, \ 34 trigger_hold_time 35 print("detect motion") 36 detected = True 37 count = 0 38 label_status.setText(str("Status: detected")) 39 label_status.setColor(0x009900, 0x000000) 40 label_count.setVisible(True) 41 42 43def chain_pir_0_motion_ended_event(args): 44 global \ 45 title0, \ 46 label_status, \ 47 label_count, \ 48 bus2, \ 49 chain_pir_0, \ 50 detected, \ 51 count, \ 52 last_time, \ 53 trigger_hold_time 54 print("not detect") 55 detected = False 56 label_status.setText(str("Status: no detect")) 57 label_status.setColor(0xCCCCCC, 0x000000) 58 label_count.setVisible(False) 59 60 61def setup(): 62 global \ 63 title0, \ 64 label_status, \ 65 label_count, \ 66 bus2, \ 67 chain_pir_0, \ 68 detected, \ 69 count, \ 70 last_time, \ 71 trigger_hold_time 72 73 M5.begin() 74 Widgets.setRotation(1) 75 Widgets.fillScreen(0x000000) 76 title0 = Widgets.Title("Chain PIR Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu24) 77 label_status = Widgets.Label( 78 "Status: --", 20, 70, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.DejaVu24 79 ) 80 label_count = Widgets.Label( 81 "Count: --", 20, 165, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.DejaVu24 82 ) 83 84 bus2 = ChainBus(2, tx=21, rx=22) 85 chain_pir_0 = PIRChain(bus2, 1) 86 chain_pir_0.set_trigger_callback( 87 PIRChain.TRIGGER_MOTION_DETECTED, chain_pir_0_motion_detected_event 88 ) 89 chain_pir_0.set_trigger_callback(PIRChain.TRIGGER_MOTION_ENDED, chain_pir_0_motion_ended_event) 90 chain_pir_0.set_trigger(True) 91 chain_pir_0.set_trigger_hold_time(5, save=False) 92 trigger_hold_time = chain_pir_0.get_trigger_hold_time() 93 print((str("trigger hold time: ") + str(trigger_hold_time))) 94 detected = chain_pir_0.get_detect_status() 95 if detected: 96 label_status.setText(str("Status: detected")) 97 label_status.setColor(0x009900, 0x000000) 98 99 100def loop(): 101 global \ 102 title0, \ 103 label_status, \ 104 label_count, \ 105 bus2, \ 106 chain_pir_0, \ 107 detected, \ 108 count, \ 109 last_time, \ 110 trigger_hold_time 111 M5.update() 112 if detected: 113 if (time.ticks_diff((time.ticks_ms()), last_time)) >= 1000: 114 last_time = time.ticks_ms() 115 count = (count if isinstance(count, (int, float)) else 0) + 1 116 label_count.setText(str((str("Count: ") + str(count)))) 117 else: 118 pass 119 120 121if __name__ == "__main__": 122 try: 123 setup() 124 while True: 125 loop() 126 except (Exception, KeyboardInterrupt) as e: 127 try: 128 bus2.deinit() 129 from utility import print_error_msg 130 131 print_error_msg(e) 132 except ImportError: 133 print("please update to latest firmware")
Example output:
None
API
PIRChain
- class chain.pir.PIRChain(bus, device_id)
Bases:
KeyChainPIR Chain class for interacting with PIR (Passive Infrared) sensor devices over Chain bus.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
from chain import ChainBus from chain import PIRChain bus2 = ChainBus(2, tx=21, rx=22) chain_pir_0 = PIRChain(bus2, 1)
For other button and some general methods, please refer to the
ChainKeyclass.- get_detect_status()
Get the motion detection status.
- Returns:
Motion detection status. True means motion detected, False means motion ended. Returns False if failed.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
status = chain_pir_0.get_detect_status()
- set_trigger(enable)
Enable or disable PIR detection reporting.
- Parameters:
enable (bool) – True to enable PIR detection reporting, False to disable it.
- Returns:
True if the operation was successful, False otherwise.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
success = chain_pir_0.set_trigger(True)
- get_trigger()
Get whether PIR detection reporting is enabled.
- Returns:
True if PIR detection reporting is enabled, False if disabled. Returns False if failed.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
enabled = chain_pir_0.get_trigger()
- set_trigger_hold_time(seconds, save=False)
Set the hold time before triggering motion ended status.
- Parameters:
- Returns:
True if the operation was successful, False otherwise.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
success = chain_pir_0.set_trigger_hold_time(5, False)
- get_trigger_hold_time()
Get the hold time before triggering motion ended status.
- Returns:
Hold time in seconds, or None if failed.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
hold_time = chain_pir_0.get_trigger_hold_time()
- set_trigger_callback(trigger_type, callback)
Set callback for PIR motion detection events.
- Parameters:
trigger_type (int) – Trigger type to listen for. Use
PIRChain.TRIGGER_MOTION_DETECTED(1) for motion detected orPIRChain.TRIGGER_MOTION_ENDED(0) for motion ended.callback – Callback function that will be called when PIR motion detection changes.
- Return type:
None
Note
Chain related methods cannot be called in the callback function.
UiFlow2 Code Block:

MicroPython Code Block:
def motion_detected_callback(args): print("Motion detected") def motion_ended_callback(args): print("Motion ended") # Listen for motion detected only chain_pir_0.set_trigger_callback(PIRChain.TRIGGER_MOTION_DETECTED, motion_detected_callback) # Listen for motion ended only chain_pir_0.set_trigger_callback(PIRChain.TRIGGER_MOTION_ENDED, motion_ended_callback)

