# Esp32 - Drivers for 4 digit 7-segm display, NeoPixel leds and Potentiometer
# provided by Anthony Vogelaar, Perth Scotland
# rev 0.10  2025-06-19  initial release
# rev 0.11  2025-06-20  converted to classes

from 	machine 	import 	Pin, I2C, ADC, freq;		freq(240_000_000)
import	neopixel	as		npx

# Implemented:
# Npx(pin=25)
# 	Npx.show(l0=OFF, l1=OFF, l2=OFF, l3=OFF, l4=OFF, l5=OFF)
# Led7(pin_scl=22, pin_sda=21)
# 	Led7.show(value=0, dp=None, hex=False)
# Potm(pin=26)
# 	Potm.get()         -->  float

# ========================= Neo Pixel Leds ===========================

class Npx:
    # Basic colours for Neopixel LED's WS2812
    OFF    = bytes.fromhex('00 00 00')
    GREEN  = bytes.fromhex('FF 00 00')
    RED    = bytes.fromhex('00 FF 00')
    BLUE   = bytes.fromhex('00 00 FF')
    YELLOW = bytes.fromhex('FF FF 00')
    WHITE  = bytes.fromhex('FF FF FF')


    # Setup of NeoPixel LED output
    def __init__(self, pin=25):
        self.leds = npx.NeoPixel(Pin(pin), 6)		# Setup for 6 leds on pin


    # Set the colours of the 6 NeoPixel LED's
    def show(self, l0=OFF, l1=OFF, l2=OFF, l3=OFF, l4=OFF, l5=OFF):
        self.leds[0] = l0; self.leds[1] = l1; self.leds[2] = l2
        self.leds[3] = l3; self.leds[4] = l4; self.leds[5] = l5
        self.leds.write()

# ===================== 4 digit 7 segment LED ==========================

class  Led7:
    
    # Setup I2C channel for 4 digit 7-segment LED display
    def __init__(self, pin_scl=22, pin_sda=21, i2c_bus=0):
        self.i2c = I2C(i2c_bus, scl=Pin(pin_scl), sda=Pin(pin_sda), freq=400000)
    
       
    # Display value on 4 digit 7-segment LED display
    def show(self, value=0, dp=None, hex=False):
        CHARS    = b' 0123456789ABCDEF'
        PATTERNS = bytes.fromhex('00 3F 06 5B 4F 66 6D 7D 07 7F 6F 77 7C 39 5E 79 71')

        if value is None: b4=b'    '
        elif hex: b4 = bytes(f'{value:04X}', 'ascii')
        else    : b4 = bytes(f'{value:4}', 'ascii')
        dig0 = PATTERNS[CHARS.index(b4[0].to_bytes())];
        dig1 = PATTERNS[CHARS.index(b4[1].to_bytes())]
        dig2 = PATTERNS[CHARS.index(b4[2].to_bytes())]
        dig3 = PATTERNS[CHARS.index(b4[3].to_bytes())]
        if   dp == 4: dig0 += 0x80 
        elif dp == 3: dig1 += 0x80 
        elif dp == 2: dig2 += 0x80 
        elif dp == 1: dig3 += 0x80 
        self.i2c.writeto(36, b'\x31')				# 0x24
        self.i2c.writeto(52, dig0.to_bytes())		# 0x34
        self.i2c.writeto(53, dig1.to_bytes())		# 0x35
        self.i2c.writeto(54, dig2.to_bytes())		# 0x36
        self.i2c.writeto(55, dig3.to_bytes())		# 0x37

# ====================== Potmeter ADC ==========================

class Potm:
    
    def __init__(self, pin=26):
        self.potm = ADC(pin, atten=ADC.ATTN_11DB)
    

    # get potentiometer voltage 0.128 .. 3.126 Volt
    def get(self):
        return round(self.potm.read_uv()/1_000_000, 3)

# ===================== Tests ========================

if __name__ == '__main__':
    
    import	time

    # Testing Neopixel LED's on FKS0001
    def test1():
        npx = Npx()
        while True:
            npx.show(Npx.GREEN);   time.sleep(1)
            npx.show(l1=Npx.RED);  time.sleep(1)
            npx.show(l2=Npx.BLUE); time.sleep(1)


    # Testing 4 digit 7-segment LED's on FKS0001
    def test2():
        led7 = Led7()
        while True:
            led7.show(1000, 3);        time.sleep(2)		# 10.00
            led7.show(1000, hex=True); time.sleep(2)
            led7.show(None);           time.sleep(2)


    # testing potentiometer adc
    def test3():
        potm = Potm()
        while True:
            print(potm.get(), 'Volt')
            time.sleep(1)


    test3()
    
# ===================== End =========================
