import micropython
# import machine
from machine import Pin, Timer, SoftI2C
from button_rgb import PushButtonRGB
import sys
# Buffer for interrupt error messages
micropython.alloc_emergency_exception_buf(100)
# Defines the PWM value for LED FULL ON
LED_FULL_ON = 100
# Defines the PWM value for LED FULL OFF
LED_FULL_OFF = 0
# Defines the Duty CYcle increment rate
DUTY_CYCLE_CHANGE_RATE = 2.5
# Defines if the LED is brightening
PWM_COUNT_DOWN = True
# Defines is the LED is dimming
PWM_COUNT_UP = False
# Defines PCF8574 don't pressed state
BUTTON_NOT_PRESSED = 0xFF
# Defines PCF8574 button pressed state
BUTTON_PRESSED = 0xFE
# Defines the maximum state supported by the pushbutton application
MAX_SYSTEM_STATE = 4
# Defines the address the I/O expander is ON
PCF8574_ADDRESS = 0x20
# List object that contains the duty cycle for RGB
# Valid values are 0 - 100. Due to the hardware.
# 0% provides a ground wich is full OFF to the LED's
# 100% is full voltage and LED is ON.
DutyCycle = 0
# Defines the pins used to drive the RGB duty cycle
# PinList = [Pin('X1'), Pin('X2'), Pin('X3')]
PinList = [Pin(4), Pin(16), Pin(17)]
# Defines the timers used to generate the PWM
TimerList = [2, 2, 2]
# Defines the timer frequency in Hz for the RGB
FrequencyList = [1000, 1000, 1000]
# Specifies the timer channels used to drive the RGB LEDs
TimerChList = [1, 2, 3]
# holds the button state based on how many times its been
# pressed
System_State = 0
# If 0, the duty cycle is counting down.
# If 1, the duty cycle is counting up.
PwmDirection = 0
# Holds the button state from the last time it was read.
# This is used to determine if the button has been released.
ButtonLastState = False
# Setup the MCU and application code to starting conditions
# The blue LED will start on, the yellow LED will be off
def system_init():
print("Initializing system ...")
print("Starting application ...")
############################################################
#
# Start script execution ...
#
############################################################
# Initialize the system
system_init()
try:
i2c = SoftI2C( scl=Pin(22), sda=Pin(21), freq = 100000)
I2C_List = i2c.scan()
if I2C_List:
print("I2C Slaves Present =", I2C_List)
else:
print("There are no I2C devices present! Exiting application.")
sys.exit(0)
except Exception as e:
sys.print_exception(e)
try:
RGB_Button = PushButtonRGB(PinList, TimerList, FrequencyList, TimerChList, i2c, PCF8574_ADDRESS)
except Exception as e:
sys.print_exception(e)
try:
# Make sure that the I2C device is present before proceeding.
RGB_Button.RGB.Write(LED_FULL_OFF, LED_FULL_OFF, LED_FULL_OFF)
except Exception as e:
sys.print_exception(e)
# Main application loop
while True:
# Make sure we have an I2C device to talk to, if so, try to read
#
try:
PushButton = RGB_Button.DeviceIO.Read()
except Exception as e:
sys.print_exception(e)
print("Existing application ...")
sys.exit(0)
# Check the Pushbutton to see if it has been presset and released.
# When released, move to the next system state.
if PushButton == BUTTON_NOT_PRESSED:
if ButtonLastState == True:
ButtonLastState = False
DutyCycle = LED_FULL_OFF
System_State += 1
if System_State >= MAX_SYSTEM_STATE:
System_State = 0
elif PushButton == BUTTON_PRESSED:
ButtonLastState = True
# The example application will toggle the LED from full on to
# full off and then back again.
if PwmDirection == PWM_COUNT_DOWN:
DutyCycle -= DUTY_CYCLE_CHANGE_RATE
if DutyCycle < LED_FULL_ON:
PwmDirection = PWM_COUNT_UP
else:
DutyCycle += DUTY_CYCLE_CHANGE_RATE
if DutyCycle >= LED_FULL_OFF:
PwmDirection = PWM_COUNT_DOWN
# This is a simple "State Machine" that will run different
# colors and patterns based on how many times the button
# has been pressed
try:
if System_State == 0:
RGB_Button.RGB.Write(DutyCycle, LED_FULL_OFF, LED_FULL_OFF)
elif System_State == 1:
RGB_Button.RGB.Write(LED_FULL_OFF, DutyCycle, LED_FULL_OFF)
elif System_State == 2:
RGB_Button.RGB.Write(DutyCycle, LED_FULL_OFF, DutyCycle)
elif System_State == 3:
RGB_Button.RGB.Write(DutyCycle, DutyCycle, DutyCycle)
except Exception as e:
sys.print_exception(e)
# This sets a periodic delay so that the DutyCycle doesn't
# change too fast
machine.delay(25)