Automatic pet feeder ・ 自动喂宠
Core2コントローラー、2チャンネルリレーでモーター駆動、RTCで時刻管理する自動給餌器。
この構成をエディタで開く・編集する →| 部品 | 役割 | ポート | リンク・価格 |
|---|---|---|---|
| M5Stack Core2 | Controller | grove_i2c, grove_analog, grove_uart, mbus | official page — $46.9 |
| Unit PaHub2 | I2C Hub | grove_i2c | official page — $7.95 |
| Unit 2Relay (2-Channel Relay Unit) | Motor Driver (2-Channel Relay) | grove_i2c | official page — $6.5 |
| Unit RTC | Real-Time Clock | grove_i2c | official page — $4.95 |
M5Stack Core2とPaHub2、2チャンネルリレーユニット、RTCユニットを使って作る、自動ペットフーダーです。決まった時間にリレーでモーターを動かし、フードを自動で出します。Core2がRTCで現在時刻を取得し、設定した給餌時刻になるとリレーをONにしてモーターを回します。
# M5Stack Core2 + PaHub2 + 2Relay + RTC (Automatic Pet Feeder)
# Wiring:
# Core2 Port.A (red) -> PaHub2 IN
# PaHub2 CH0 -> 2Relay (I2C address 0x26)
# PaHub2 CH1 -> RTC (I2C address 0x51)
import time
from machine import Pin, I2C
from m5stack import lcd
from m5stack_ui import M5Screen
# Initialize I2C on Core2 Port.A
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=100000)
# PaHub2 (TCA9548A) I2C address: 0x70
PAHUB_ADDR = 0x70
def select_channel(ch):
"""Select a channel on PaHub2 (0-5)."""
i2c.writeto(PAHUB_ADDR, bytes([1 << ch]))
# 2Relay I2C address: 0x26
RELAY_ADDR = 0x26
def relay_on(channel):
"""Turn on a relay channel (0 or 1)."""
select_channel(0) # 2Relay is on CH0
if channel == 0:
i2c.writeto(RELAY_ADDR, bytes([0x01])) # Relay1 ON
else:
i2c.writeto(RELAY_ADDR, bytes([0x02])) # Relay2 ON
def relay_off(channel):
"""Turn off a relay channel."""
select_channel(0)
if channel == 0:
i2c.writeto(RELAY_ADDR, bytes([0x00])) # Relay1 OFF
else:
i2c.writeto(RELAY_ADDR, bytes([0x00])) # Relay2 OFF (same command)
# RTC (HYM8563) I2C address: 0x51
RTC_ADDR = 0x51
def read_rtc():
"""Read time from RTC, return (hour, minute, second)."""
select_channel(1) # RTC is on CH1
# Read 7 bytes from register 0x02 (seconds, minutes, hours, ...)
data = i2c.readfrom_mem(RTC_ADDR, 0x02, 7)
sec = (data[0] & 0x7F) + ((data[0] >> 4) & 0x07) * 10 # BCD to decimal
minute = (data[1] & 0x7F) + ((data[1] >> 4) & 0x07) * 10
hour = (data[2] & 0x3F) + ((data[2] >> 4) & 0x03) * 10
return hour, minute, sec
def set_rtc(hour, minute, second):
"""Set RTC time (24h format)."""
select_channel(1)
# Convert decimal to BCD
sec_bcd = (second // 10) << 4 | (second % 10)
min_bcd = (minute // 10) << 4 | (minute % 10)
hour_bcd = (hour // 10) << 4 | (hour % 10)
# Write to registers 0x02 (seconds), 0x03 (minutes), 0x04 (hours)
i2c.writeto_mem(RTC_ADDR, 0x02, bytes([sec_bcd, min_bcd, hour_bcd]))
# Set initial time (adjust as needed)
# set_rtc(12, 0, 0) # Uncomment and set to current time once
# Feeding schedule: list of times in "HH:MM" format
FEED_TIMES = ["08:00", "18:00"]
FEED_DURATION = 3 # seconds
def parse_time(t_str):
h, m = map(int, t_str.split(':'))
return h, m
last_feed_day = -1 # to avoid multiple feeds per day
while True:
hour, minute, second = read_rtc()
current_time = "{:02d}:{:02d}:{:02d}".format(hour, minute, second)
lcd.clear()
lcd.print("Time: " + current_time, 10, 20)
# Check if current time matches any feed time
for t in FEED_TIMES:
feed_h, feed_m = parse_time(t)
if hour == feed_h and minute == feed_m and second < 5: # within 5 sec window
# Check if already fed today (using day of month, simplified)
# For simplicity, we use a flag that resets at midnight
if last_feed_day != hour * 60 + minute: # crude unique check
lcd.print("Feeding...", 10, 60)
relay_on(0) # Relay1 controls motor
time.sleep(FEED_DURATION)
relay_off(0)
last_feed_day = hour * 60 + minute
break
time.sleep(1)
この作り方はAIが構成から生成したものです(未検証)。通電前に配線とコードをご確認ください。
この構成はAIが実在するM5Stack部品から設計し、ポート互換をサーバで検証したものです。編集・共有できます。
エディタで開く →UnitKit は M5Stack® 製品向けの非公式ツール。作りたいものを書くと、部品リストと配線図が出ます。