# Esp32 - Drivers for 4 digit 7-segm display, NeoPixel leds and Potentiometer
#    implemented as functions
# provided by Anthony Vogelaar, Perth Scotland
# rev 0.10  2025-06-  initial release

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

# Implemented:
# npxInit(pin=25)
# npxShow(l0=NPX_OFF, l1=NPX_OFF, l2=NPX_OFF, l3=NPX_OFF, l4=NPX_OFF, l5=NPX_OFF)
# led7Init(pin_scl=22, pin_sda=21)
# led7Show(value=0, dp=None, hex=False)
# potmInit(pin=26)
# potmGet()         -->  float

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

npx_leds = None

# Basic colours for Neopixel LED's WS2812
NPX_OFF    = bytes.fromhex('00 00 00')
NPX_GREEN  = bytes.fromhex('FF 00 00')
NPX_RED    = bytes.fromhex('00 FF 00')
NPX_BLUE   = bytes.fromhex('00 00 FF')
NPX_YELLOW = bytes.fromhex('FF FF 00')
NPX_WHITE  = bytes.fromhex('FF FF FF')


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


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

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

i2c	= None

# Setup I2C channel for 4 digit 7-segment LED display
def led7Init(pin_scl=22, pin_sda=21):
    global i2c
    i2c = I2C(0, scl=Pin(pin_scl), sda=Pin(pin_sda), freq=400000)
    
       
# Display value on 4 digit 7-segment LED display
def led7Show(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 
    i2c.writeto(36, b'\x31')				# 0x24
    i2c.writeto(52, dig0.to_bytes())		# 0x34
    i2c.writeto(53, dig1.to_bytes())		# 0x35
    i2c.writeto(54, dig2.to_bytes())		# 0x36
    i2c.writeto(55, dig3.to_bytes())		# 0x37

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

potm = None

# Setup ADC channel potentiometer
def potmInit(pin=26):
    global potm
    potm = ADC(pin, atten=ADC.ATTN_11DB)
    

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

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

if __name__ == '__main__':
    
    import	time

    # Testing Neopixel LED's on FKS0001
    def test1():
        npxInit()
        while True:
            npxShow(NPX_GREEN);   time.sleep(1)
            npxShow(l1=NPX_RED);  time.sleep(1)
            npxShow(l2=NPX_BLUE); time.sleep(1)


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


    # print value of potentiometer in Volts
    def test3():
        potmInit()
        while True:
            print(potmGet(), 'Volt')
            time.sleep(1)


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