Add configuration for semaphore signals and implement railway signal control

This commit is contained in:
Artem Kashaev
2026-01-22 10:30:31 +05:00
parent 7a455bd6ec
commit 5ae313defd
8 changed files with 638 additions and 111 deletions
+17 -66
View File
@@ -1,71 +1,22 @@
from machine import Pin
from time import ticks_ms, ticks_diff
from time import sleep_ms
from ir_pair import IRRxTxPollPair
# pin1 = Pin(16, Pin.IN)
pin2 = Pin(17, Pin.IN)
class Beam:
def __init__(self, id: int, pin: Pin):
self.id = id
self.pin = pin
self.prev_val = pin.value()
# --- Настройки пинов ---
# RX_PIN: выход ИК-приёмника (обычно TTL сигнал с модуля VS1838/TSOP*)
# TX_PIN: пин ИК-светодиода/ключа (на него подаётся 38кГц PWM во время окна опроса)
RX_PIN = 16
TX_PIN = 6
def check(self):
val = self.pin.value()
if val != self.prev_val:
self.prev_val = val
print(f"EVENT IK_MODULE {self.id} {val}")
# --- Тайминги опроса ---
POLL_PERIOD_MS = 500 # период опроса (как часто проверяем)
TX_ON_MS = 50 # сколько держим 38кГц включённым в каждом цикле
STATUS_PERIOD_MS = 1000
# --- Условия теста ---
# N влияет сразу на:
# - сколько раз "мигнуть" ИК-передатчиком за 1 цикл опроса
# - сколько фронтов (edges) нужно увидеть, чтобы считать луч НЕ перекрытым
N = 5
LED = Pin("LED", Pin.OUT)
def main():
pair = IRRxTxPollPair(
rx_pin=RX_PIN,
tx_pin=TX_PIN,
poll_period_ms=POLL_PERIOD_MS,
tx_on_ms=TX_ON_MS,
blinks_per_poll=N,
blink_off_ms=5,
freq_hz=38_000,
duty_percent=33,
min_edges=N,
# Считаем только FALLING: обычно на каждом включении carrier RX даёт 1 спад.
# Тогда 5 миганий ~= 5 edges (а при подсчёте обоих фронтов было бы ~10).
count_rising=False,
count_falling=True,
)
last_status = ticks_ms()
print("IR poll test started")
print("RX pin:", RX_PIN, "TX pin:", TX_PIN)
print("poll_period_ms:", POLL_PERIOD_MS, "tx_on_ms:", TX_ON_MS)
print("N:", N, "(blinks_per_poll and min_edges)")
try:
while True:
pair.poll_once() # результат и счетчики сохраняются внутри pair
LED.toggle()
now = ticks_ms()
if ticks_diff(now, last_status) >= STATUS_PERIOD_MS:
seen = bool(pair.last_seen)
print(
("BEAM NOT BLOCKED" if seen else "BEAM BLOCKED")
+ " | edges=%d" % pair.last_edges
)
last_status = now
finally:
pair.deinit()
main()
beam = Beam(1, pin2)
while True:
beam.check()
sleep_ms(50)