Last active
March 8, 2024 01:42
-
-
Save TatsukiIshijima/95f733337a3e762bc4305ad462f6dfdc to your computer and use it in GitHub Desktop.
PIRセンサーで人を検知した時にサーボモータを動かすスクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import machine | |
import utime | |
# Servoモータの電源は単3電池x3から | |
# PIR センサーはPicoの5Vピンから | |
# 同じ電源から取ってServoを動かすとOFFからすぐにONになるような挙動になる | |
servo = machine.PWM(machine.Pin(2)) | |
servo.freq(50) | |
# サーボが動作可能な範囲 | |
ANGLE_RANGE = 180 | |
# サーボに指定するPWMの時間の範囲 | |
TIME_RANGE = 1.9 | |
# サーボに指定できる最小の時間 | |
MIN_TIME = 0.5 | |
# サーボのPWMの周期時間 | |
CYCLE_TIME = 20.0 | |
motion_sensor = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_UP) | |
led = machine.Pin(25, machine.Pin.OUT) | |
# ライト点灯中かのフラグ | |
is_light_on = False | |
# 最後に検知した時刻 | |
last_detection_time = 0 | |
# サーボ角度 | |
servo_angle = 0 | |
def get_local_time(): | |
current_time = utime.time() | |
local_time = utime.localtime(current_time) | |
year = local_time[0] | |
month = local_time[1] | |
day = local_time[2] | |
hour = local_time[3] | |
minute = local_time[4] | |
second = local_time[5] | |
return "{}/{}/{} {}:{}:{}".format(year, month, day, hour, minute, second) | |
def turn_on(): | |
print(f"{get_local_time()} turn on") | |
global is_light_on | |
led.value(1) | |
is_light_on = True | |
def turn_off(): | |
print(f"{get_local_time()} turn off") | |
global is_light_on | |
led.value(0) | |
is_light_on = False | |
# ref: https://tech-and-investment.com/raspberrypi-picow-12-servo/ | |
def move_servo(angle): | |
print(f"{get_local_time()} move_servo({angle})") | |
global servo_angle | |
if angle < -90 or angle > 90 : | |
return | |
servo_angle = angle | |
angle = angle + 90 | |
percent = angle / ANGLE_RANGE | |
addTime = TIME_RANGE * percent | |
time = MIN_TIME + addTime | |
ratio = time / CYCLE_TIME | |
ratio = (int)(65535 * ratio) | |
servo.duty_u16(ratio) | |
def on_detect(Pin): | |
print( f"{get_local_time()} on_detect") | |
global last_detection_time | |
last_detection_time = utime.ticks_ms() | |
if not is_light_on: | |
turn_on() | |
if servo_angle != 60: | |
move_servo(60) | |
motion_sensor.irq(trigger = machine.Pin.IRQ_RISING, handler = on_detect) | |
def main(): | |
global last_detection_time | |
while True: | |
# 最後に検知された時間から5秒以上経過していれば消灯させる | |
if utime.ticks_diff(utime.ticks_ms(), last_detection_time) >= 5000: | |
if is_light_on: | |
turn_off() | |
if servo_angle != -30: | |
move_servo(-30) | |
utime.sleep_ms(1500) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment