# BEAPER Nano I/O Test project
# October 8, 2024

# Functionality test program for on-board BEAPER Nano I/O devices. Press
# each pushbutton to light LEDs. SW3 makes tones. Analog values converted
# from the ambient light sensor, temperature sensor and potentiometers
# are displayed in the terminal.

# Import machine and time functions
from machine import Pin, PWM, ADC
import time

# Configure Educational Starter I/O devices
SW2 = Pin(44, Pin.IN, Pin.PULL_UP)
SW3 = Pin(43, Pin.IN, Pin.PULL_UP)
SW4 = Pin(5, Pin.IN, Pin.PULL_UP)
SW5 = Pin(6, Pin.IN, Pin.PULL_UP)
LED2 = Pin(7, Pin.OUT)
LED3 = Pin(8, Pin.OUT)
LED4 = Pin(9, Pin.OUT)
LED5 = Pin(10, Pin.OUT)
BEEPER = Pin(17, Pin.OUT)

# Configure built-in Arduino Nano ESP32 LEDs
LED_BUILTIN = Pin(48, Pin.OUT, value = 0)   # Active High
LED_BLUE = Pin(45, Pin.OUT, value = 1)      # Active Low
LED_GREEN = Pin(0, Pin.OUT, value = 1)      # Active Low
LED_RED = Pin(46, Pin.OUT, value = 0)       # Active Low

# Configure analog input devices
Q1 = Q4 = ADC(1, atten = ADC.ATTN_11DB)
Q2 = U4 = ADC(2, atten = ADC.ATTN_11DB)
Q3 = RV1 = ADC(3, atten = ADC.ATTN_11DB)
VDIV = RV2 = ADC(4, atten = ADC.ATTN_11DB)

# Define toggle button variables
SW4IsPressed = False
LED4State = 0

# Tone functions
def tone(frequency,duration=None):
    beeperPin = PWM(Pin(17), duty_u16 = 32768)
    beeperPin.freq(frequency)
    if duration is not None:
        time.sleep(duration)
        noTone()

def noTone(duration=None):
    beeperPin = PWM(Pin(17))
    beeperPin.deinit()
    if duration is not None:
        time.sleep(duration)

# Start-up sound
tone(4000,0.1)

while True:
    # Chase LEDs
    if SW2.value() == 0:
        LED2.value(1)
        time.sleep(0.1)
        LED3.value(1)
        time.sleep(0.1)
        LED4.value(1)
        time.sleep(0.1)
        LED5.value(1)
        time.sleep(0.1)
        
        LED2.value(0)
        time.sleep(0.1)
        LED3.value(0)
        time.sleep(0.1)
        LED4.value(0)
        time.sleep(0.1)
        LED5.value(0)
        time.sleep(0.1)

    # Beep, boop, with momentary button
    if SW3.value() == 0:
        LED3.value(1)
        tone(700, 0.16)
        noTone(0.05)
        tone(600, 0.16)
        noTone()
        while SW3.value() == 0:
            time.sleep_ms(10)
    else:
        LED3.value(0)
    
    # Toggle button
    if SW4.value() == 0 and SW4IsPressed == False:
        SW4IsPressed = True
        if LED4State == 0:
            LED4State = 1
        else:
            LED4State = 0
            
    LED4.value(LED4State)
    
    if SW4.value() == 1:
        SW4IsPressed = False
    
    # Cycle through the rainbow on the Arduino Nano ESP32 RGB LED
    if SW5.value() == 0:
        for brightness in range(255, 0, -1):
            LED_RED.value(0)
            LED_GREEN.value(1)
            LED_BLUE.value(1)
            for step in range (255):
                if step == brightness:
                    LED_RED.value(1)
                    LED_GREEN.value(0)
                time.sleep_us(10)
        for brightness in range(255, 0, -1):
            LED_RED.value(1)
            LED_GREEN.value(0)
            LED_BLUE.value(1)
            for step in range (255):
                if step == brightness:
                    LED_GREEN.value(1)
                    LED_BLUE.value(0)
                time.sleep_us(10)
        for brightness in range(255, 0, -1):
            LED_RED.value(1)
            LED_GREEN.value(1)
            LED_BLUE.value(0)
            for step in range (255):
                if step == brightness:
                    LED_BLUE.value(1)
                    LED_RED.value(0)
                time.sleep_us(10)

    # Display analog input levels
    lightLevel = Q4.read_u16()
    rawTemp = U4.read_u16()
    pos1 = RV1.read_u16()
    pos2 = RV2.read_u16()
    print("")
    print("Light level: ", lightLevel)
    print("Temp level: ", rawTemp)
    print("RV1 position: ", pos1)
    print("RV2 position: ", pos2)

    time.sleep_ms(100)
