''' Created on 21 août 2022 @author: denis ''' import logging import os import threading logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) if os.getenv('BOARD_DEVICE') == 'RPI': print("found a RPI board") import RPi.GPIO as GPIO logger.info(GPIO.RPI_INFO) # @UndefinedVariable GPIO.setmode(GPIO.BOARD) # @UndefinedVariable elif os.getenv('BOARD_DEVICE') == 'RPI1B': print("found a RPI 1B board") import RPi.GPIO as GPIO # @Reimport logger.info(GPIO.RPI_INFO) # @UndefinedVariable GPIO.setmode(GPIO.BOARD) # @UndefinedVariable elif os.getenv('BOARD_DEVICE') == 'OPIWIN+': print("found an OPI WIN+ board") import orangepi.winplus from OPi import GPIO # @Reimport GPIO.setmode(orangepi.winplus.BOARD) elif os.getenv('BOARD_DEVICE') == 'OPIZERO': print("found an OPI ZERO board") import orangepi.zero from OPi import GPIO # @Reimport GPIO.setmode(orangepi.zero.BOARD) GPIO.setwarnings(False) # @UndefinedVariable IO_RISING = GPIO.RISING # @UndefinedVariable IO_FALLING = GPIO.FALLING # @UndefinedVariable IO_BOTH = GPIO.BOTH # @UndefinedVariable IO_LOW = GPIO.LOW # @UndefinedVariable IO_HIGH = GPIO.HIGH # @UndefinedVariable IO_INPUT = GPIO.IN # @UndefinedVariable IO_OUTPUT = GPIO.OUT # @UndefinedVariable IO_PULL_UP = GPIO.PUD_UP IO_PULL_DOWN = GPIO.PUD_DOWN IO_PULL_OFF = GPIO.PUD_OFF IO_CLEANUP = GPIO.cleanup # @UndefinedVariable lock = threading.Lock() def bitread(b, bitpos): return (b>>bitpos) & 0x1 class Pin: def __init__(self, channel, sens, initial=None, callback=None, edge=IO_FALLING, bouncetime=500, pull_up_down=GPIO.PUD_OFF): self.channel = channel self.sens = sens lock.acquire() if initial in [GPIO.LOW, GPIO.HIGH] and sens==GPIO.OUT: GPIO.setup(channel, sens, initial=initial, pull_up_down=pull_up_down) else: GPIO.setup(channel, sens, pull_up_down=pull_up_down) if callback is not None: self.set_interrupt(edge, callback, bouncetime) lock.release() logger.info(f'Channel {self.channel} sens: {sens} initial: {initial}') self.value = self.read() # initial value def cleanup(self): lock.acquire() GPIO.cleanup(self.channel) lock.release() def set_interrupt(self, edge, callback, bouncetime=None): if callable(callback) and edge in [IO_RISING, IO_FALLING, IO_BOTH]: GPIO.add_event_detect(self.channel, edge, callback=callback, bouncetime=bouncetime) def remove_interrupt(self): lock.acquire() GPIO.remove_event_detect(self.channel) lock.release() def state(self): return self.value def read(self): lock.acquire() self.value = GPIO.input(self.channel) lock.release() #logger.info(f'Read {self.channel} -> {self.value}') return self.value def write(self, value): lock.acquire() GPIO.output(self.channel, value) lock.release() #logger.info(f'Write {self.channel} <- {value}') return self.read() class ShiftInRegister74HC165(): lastState = 0; currentState = 0; def __init__(self, latch_pin, clock_pin, data_pin, number=1): self.datalen = number * 8 self.latch_pin = Pin(latch_pin, IO_OUTPUT, initial=IO_LOW, pull_up_down=IO_PULL_DOWN) self.clock_pin = Pin(clock_pin, IO_OUTPUT, initial=IO_LOW, pull_up_down=IO_PULL_DOWN) self.data_pin = Pin(data_pin, IO_INPUT, initial=IO_LOW, pull_up_down=IO_PULL_DOWN) threading.Event().wait(0.5) def read(self): self.lastState = self.currentState result = 0 self.latch_pin.write(IO_HIGH) for i in range(self.datalen): value = self.data_pin.read() result |= (value << ((self.datalen-1) - i)) self.clock_pin.write(IO_HIGH) self.clock_pin.write(IO_LOW) self.latch_pin.write(IO_LOW) self.currentState = result return result def state(self, idx): return bitread(self.currentState, idx) def last(self, idx): return bitread(self.lastState, idx) def update(self): return self.read()!=self.lastState def hasChanged(self, idx=None): return self.lastState!=self.currentState if idx is None else self.state(idx)!=self.last(idx) def pressed(self, idx): return not self.last(idx) and self.state(idx) def released(self, idx): return self.last(idx) and not self.state(idx) def cleanup(self): self.latch_pin.cleanup() self.clock_pin.cleanup() self.data_pin.cleanup() class ShiftOutRegister74HC595(): def __init__(self, latch_pin, clock_pin, data_pin, number=1): self.datalen = number * 8 self.latch_pin = Pin(latch_pin, IO_OUTPUT, initial=IO_LOW) self.clock_pin = Pin(clock_pin, IO_OUTPUT, initial=IO_LOW) self.data_pin = Pin(data_pin, IO_OUTPUT, initial=IO_LOW) self.set_low() threading.Event().wait(0.5) def set_low(self): self.registers = [0] * self.datalen self.write() def write(self): self.clock_pin.write(IO_LOW) self.latch_pin.write(IO_LOW) self.clock_pin.write(IO_HIGH) # #for i in range(self.datalen): for bit in self.registers: self.clock_pin.write(IO_LOW) self.data_pin.write(int(bit)) self.clock_pin.write(IO_HIGH) # self.clock_pin.write(IO_LOW) self.latch_pin.write(IO_HIGH) self.clock_pin.write(IO_HIGH) def set(self, index, state): self.registers[index] = int(state) self.write() return int(state) def get(self, index): return self.registers[index] def cleanup(self): self.set_low() self.latch_pin.cleanup() self.clock_pin.cleanup() self.data_pin.cleanup()