# mPy - 6 pc of one wire 2-aspect signals and 5 IR train detectors
#    signals set by detectors IRQ
# by Anthony Vogelaar, Perth Scotland
# rev 0.10  2024-10-24  initial release

from	machine_sim	import	Pin
import	time
from	ve_rw2050	import	portA, portB

# =========================== Hardware set-up =============================

RED   = 0
GREEN = 1

pins_signal   = portA[0:6]							# PA0..PA5 outputs
pins_detector = portB[3:8]							# PB3..PB7 inputs
signals		  = [Pin(p, Pin.OUT, value=RED)  for p in pins_signal]
detectors     = [Pin(p, Pin.IN, Pin.PULL_UP) for p in pins_detector]

# ============================== main ====================================

class Main:

    # instantiate required io objects and setup
    def __init__(self):
        self.ptrn_last = [0, 0, 0, 0, 0, 0] # all RED
        self.dir       = 'ab'
        self.irq       = None				# object of last IRQ
        for detector in detectors:			# enable detector IRQ
            detector.irq(self.onSensor, Pin.IRQ_FALLING)
        self.task()
        

    # set 6 signals according pattern
    def setPattern(self, pattern):
        for signal, aspect, aspect_last in zip(signals, pattern, self.ptrn_last):
            if aspect_last != aspect:
                signal.value(aspect)    
        self.ptrn_last = pattern


    # background task, handling detector flags
    def task(self):
        while True:
            for _ in range(10):									# @ 100 mSec
                if self.irq:
                    idx = detectors.index(self.irq)				# convert flag to index
                    if idx == 0:								# if at A
                        self.setPattern([1, 1, 1, 0, 0, 0])
                        self.dir = 'ab'
                    elif idx == 4:								# if at B
                        self.setPattern([0, 0, 0, 1, 1, 1])
                        self.dir = 'ba'
                    else:
                        idx_s = idx-1 if self.dir == 'ab' else 6-idx
                        pattern        = self.ptrn_last.copy()
                        pattern[idx_s] = RED
                        self.setPattern(pattern)
                    self.irq = None
                Pin.qtExe()				                        # background task - GPIO simulator
                time.sleep(0.1)
            print('*', end='', flush=True)									# @ 1 Sec

        
    # save detected irq object
    def onSensor(self, obj):
        self.irq = obj
 
 
Main()

# ================================ end ================================
