Automation 2040w MicroPython PWM (#489)

Co-authored-by: ZodiusInfuser <christopher.parrott2@gmail.com>
This commit is contained in:
Gee Bartlett 2022-10-06 12:27:46 +01:00 committed by GitHub
parent 8280a6a720
commit 28b6698430
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 355 additions and 61 deletions

View File

@ -0,0 +1,49 @@
import time
from automation import Automation2040W, SWITCH_A
"""
Demonstrates how to toggle each of Automation 2040 W's output terminals.
Press "A" to exit the program.
"""
TIME_PER_TOGGLE = 0.5 # How much time to wait between each toggle (in seconds)
OUTPUT_NAMES = ("O1", "O2", "O3") # The friendly names to give each digital output
# Create a new Automation2040W
board = Automation2040W()
# Enable the LED of the switch used to exit the loop
board.switch_led(SWITCH_A, 50) # Half Brightness
toggle = True
index = 0
# Toggle the outputs until the user switch is pressed
while not board.switch_pressed(SWITCH_A):
# Toggle an output
for output_percentage in range(101):
if toggle is True:
board.output(index, output_percentage)
else:
board.output(index, 100.0 - output_percentage)
# Print the state of all outputs
for i in range(board.NUM_OUTPUTS):
print(OUTPUT_NAMES[i], " = ", board.output_percent(i), sep="", end=", ")
# Print a new line
print()
time.sleep(0.01)
index += 1 # Move on to the next output
if index >= board.NUM_OUTPUTS:
index = 0 # Go back to the first output
toggle = not toggle # Invert the toggle value
time.sleep(TIME_PER_TOGGLE)
# Put the board back into a safe state
board.reset()

View File

@ -1,5 +1,5 @@
import time
from automation import Automation2040W, SWITCH_A, NUM_ADCS
from automation import Automation2040W, SWITCH_A
"""
Shows how to read the 3 ADC terminals of Automation 2040 W.
@ -20,7 +20,7 @@ board.switch_led(SWITCH_A, 50) # Half Brightness
while not board.switch_pressed(SWITCH_A):
# Read each ADC in turn and print its voltage
for i in range(NUM_ADCS):
for i in range(board.NUM_ADCS):
voltage = board.read_adc(i)
print(ADC_NAMES[i], " = ", round(voltage, 3), sep="", end=", ")

View File

@ -1,5 +1,8 @@
import time
from automation import Automation2040W, SWITCH_A, NUM_INPUTS
from automation import Automation2040W, SWITCH_A
# Uncomment fo Automation2040W Mini and comment out above import
# from automation import Automation2040WMini, SWITCH_A
"""
Shows how to read the 3 Input terminals of Automation 2040 W.
@ -12,6 +15,8 @@ INPUT_NAMES = ("I1", "I2", "I3", "I4") # The friendly names to give each digita
# Create a new Automation2040W
board = Automation2040W()
# Uncomment fo Automation2040W Mini
# board = Automation2040WMini()
# Enable the LED of the switch used to exit the loop
board.switch_led(SWITCH_A, 50) # Half Brightness
@ -20,7 +25,7 @@ board.switch_led(SWITCH_A, 50) # Half Brightness
while not board.switch_pressed(SWITCH_A):
# Read each input in turn and print its value
for i in range(NUM_INPUTS):
for i in range(board.NUM_INPUTS):
value = board.read_input(i)
print(INPUT_NAMES[i], " = ", value, sep="", end=", ")

View File

@ -1,5 +1,5 @@
import time
from automation import Automation2040W, SWITCH_A, SWITCH_B, NUM_SWITCHES
from automation import Automation2040W, SWITCH_A, SWITCH_B
"""
An example of the user switches and LEDs on Automation 2040 W.
@ -22,7 +22,7 @@ led_brightnesses = [0.0, 0.0]
# Interact with the switches and LEDs until both are pressed simultaneously
while not board.switch_pressed(SWITCH_A) or not board.switch_pressed(SWITCH_B):
for i in range(NUM_SWITCHES):
for i in range(board.NUM_SWITCHES):
# Change the LED brightness based on switch's state
if board.switch_pressed(i):
print(SWITCH_NAMES[i], " = Pressed", sep="", end=", ")

View File

@ -1,5 +1,5 @@
import time
from automation import Automation2040W, SWITCH_A, NUM_OUTPUTS
from automation import Automation2040W, SWITCH_A
"""
Demonstrates how to toggle each of Automation 2040 W's output terminals.
@ -26,14 +26,14 @@ while not board.switch_pressed(SWITCH_A):
board.output(index, toggle)
# Print the state of all outputs
for i in range(NUM_OUTPUTS):
print(OUTPUT_NAMES[i], " = ", board.output(i), sep="", end=", ")
for i in range(board.NUM_OUTPUTS):
print(OUTPUT_NAMES[i], " = ", bool(board.output(i)), sep="", end=", ")
# Print a new line
print()
index += 1 # Move on to the next output
if index >= NUM_OUTPUTS:
if index >= board.NUM_OUTPUTS:
index = 0 # Go back to the first output
toggle = not toggle # Invert the toggle value

View File

@ -1,5 +1,5 @@
import time
from automation import Automation2040W, SWITCH_A, NUM_RELAYS
from automation import Automation2040W, SWITCH_A
"""
Demonstrates how to toggle the actuation state of each of Automation 2040 W's relays.
@ -12,6 +12,8 @@ RELAY_NAMES = ("R1", "R2", "R3") # The friendly names to give each relay
# Create a new Automation2040W
board = Automation2040W()
# Uncomment fo Automation2040W Mini
# board = Automation2040WMini()
# Enable the LED of the switch used to exit the loop
board.switch_led(SWITCH_A, 50) # Half Brightness
@ -23,17 +25,23 @@ index = 0
while not board.switch_pressed(SWITCH_A):
# Toggle a relay
board.relay(index, toggle)
if board.NUM_RELAYS == 1:
board.relay(toggle)
# Print the state of all relays
for i in range(NUM_RELAYS):
print(RELAY_NAMES[i], " = ", board.relay(i), sep="", end=", ")
# Print the state of the relay
print(RELAY_NAMES[0], " = ", board.relay(), sep="", end=", ")
else:
board.relay(index, toggle)
# Print the state of all relays
for i in range(board.NUM_RELAYS):
print(RELAY_NAMES[i], " = ", board.relay(i), sep="", end=", ")
# Print a new line
print()
index += 1 # Move on to the next relay
if index >= NUM_RELAYS:
if index >= board.NUM_RELAYS:
index = 0 # Go back to the first relay
toggle = not toggle # Invert the toggle value

View File

@ -14,7 +14,7 @@ def status_handler(mode, status, ip):
print("Network: {}".format(WIFI_CONFIG.SSID))
status_text = "Connecting..."
board.conn_led(20)
board.conn_led(20.0)
if status is not None:
if status:
status_text = "Connection successful!"
@ -119,12 +119,12 @@ class outputs:
def get(self, data):
if 'one' in data.keys():
board.output(0, int(data['one']))
board.output(0, bool(data['one']))
if 'two' in data.keys():
board.output(1, int(data['two']))
board.output(1, bool(data['two']))
if 'three' in data.keys():
board.output(2, int(data['three']))
return {"one": board.output(0), "two": board.output(1), "three": board.output(2)}, 201
board.output(2, bool(data['three']))
return {"one": bool(board.output(0)), "two": bool(board.output(1)), "three": bool(board.output(2))}, 201
def post(self, data):
if 'one' in data.keys():

View File

@ -8,6 +8,8 @@ This library offers convenient functions for interacting with your new [Pimoroni
- [Connectivity LED](#connectivity-led)
- [Actuating the Relays](#actuating-the-relays)
- [Setting the Outputs](#setting-the-outputs)
- [Reading as a percentage](#reading-as-a-percentage)
- [Changing the frequency](#changing-the-frequency)
- [Reading the Inputs](#reading-the-inputs)
- [Reading the ADCs](#reading-the-adcs)
- [Extra GPIOs](#extra-gpios)
@ -32,9 +34,9 @@ From here, all features of Automation 2040W can be accessed by calling functions
Automation 2040W has two handy switches onboard, with neighbouring LEDs, offering a tactile way to interact with your program and be notified of actions that need attention.
To read one of the switches, call `.switch_pressed(switch)`, where `switch` is a value from `0` to `NUM_SWITCHES - 1`. This returns `True` when the specified switch is pressed, and `False` otherwise.
To read one of the switches, call `.switch_pressed(switch)`, where `switch` is a value from `0` to `.NUM_SWITCHES - 1`. This returns `True` when the specified switch is pressed, and `False` otherwise.
To set a switch's neighbouring LED, call `.switch_led(switch, brightness)`, where `switch` is a value from `0` to `NUM_SWITCHES - 1`, and `brightness` is either `True`, `False`, or a number from `0.0` to `100.0`.
To set a switch's neighbouring LED, call `.switch_led(switch, brightness)`, where `switch` is a value from `0` to `.NUM_SWITCHES - 1`, and `brightness` is either `True`, `False`, or a number from `0.0` to `100.0`.
To make it easier to use a specific switch or it's LED, the `automation` module contains these handy constants:
@ -57,7 +59,7 @@ A relay can be actuated by calling `.actuate_relay(relay)`, or released by calli
The state of each relay can be read by calling `.relay(relay)`. This returns `True` if the relay is actuated, and `False` if it is released. The actuation state is also reflected by LEDs that neighbour each relay.
For all these functions, `relay` is a value from `0` to `NUM_RELAYS - 1`. To control a specific relay, the `automation` module contains these handy constants:
For all these functions, `relay` is a value from `0` to `.NUM_RELAYS - 1`. To control a specific relay, the `automation` module contains these handy constants:
* `RELAY_1` = `0`
* `RELAY_2` = `1`
* `RELAY_3` = `2`
@ -65,11 +67,11 @@ For all these functions, `relay` is a value from `0` to `NUM_RELAYS - 1`. To con
### Setting the Outputs
Three sourcing outputs, capable of 2A+, are present on Automation 2040W.
Three sourcing outputs, capable of PWM at up to 2A, are present on Automation 2040W.
An output can be controlled by calling `.output(output, value)`, where `output` is a value from `0` to `NUM_OUTPUTS - 1`, and `value` is `True` or `False`.
An output can be controlled by calling `.output(output, value)`, where `output` is a value from `0` to `.NUM_OUTPUTS - 1`, and `value` is `True`, `False` or a number between `0.0` and `100.0`
The state of an output can be read by calling `.output(output)`, where `output` is a value from `0` to `NUM_OUTPUTS - 1`. This returns `True` if the output is active, and `False` if it is inactive. The state is also reflected by LEDs that neighbour each output terminal.
The state of an output can be read by calling `.output(output)`, where `output` is a value from `0` to `.NUM_OUTPUTS - 1`. This returns `True` if the output is on by any percent, or `False` if it is off. The state is also reflected by LEDs that neighbour each output terminal.
To control a specific output, the `automation` module contains these handy constants:
* `OUTPUT_1` = `0`
@ -77,9 +79,19 @@ To control a specific output, the `automation` module contains these handy const
* `OUTPUT_3` = `2`
#### Reading as a percentage
If you prefer to know the current PWM setting of an output as a percentage, this can be accessed by calling `.output_precent(output)`, where `output` is a value from `0` to `.NUM_OUTPUTS - 1`. This will return a float between `0.0` and `100.0`.
#### Changing the frequency
The PWM frequency of the output can be set by calling `.change_output_freq(output, freq)`, where `output` is a value from `0` to `.NUM_OUTPUTS - 1` and `freq` is a frequency in Hz between `10.0` and `1000.0`. Values outside of this range will cause a `ValueError`.
### Reading the Inputs
Automation 2040W has four buffered digital inputs. These can be read by calling `.read_input(input)`, where `input` is a value from `0` to `NUM_INPUTS - 1`.
Automation 2040W has four buffered digital inputs. These can be read by calling `.read_input(input)`, where `input` is a value from `0` to `.NUM_INPUTS - 1`.
To read a specific input, the `automation` module contains these handy constants:
* `INPUT_1` = `0`
@ -90,7 +102,7 @@ To read a specific input, the `automation` module contains these handy constants
### Reading the ADCs
Automation 2040W has three analog inputs, capable of reading up to 40V. The voltage on these can be read by calling `.read_adc(adc)`, where `adc` is a value from `0` to `NUM_ADCS - 1`.
Automation 2040W has three analog inputs, capable of reading up to 40V. The voltage on these can be read by calling `.read_adc(adc)`, where `adc` is a value from `0` to `.NUM_ADCS - 1`.
To read a specific adc, the `automation` module contains these handy constants:
* `ADC_1` = `0`
@ -105,7 +117,7 @@ On the left hand side of Automation 2040W are three GPIO pins. These are 3.3V lo
* `GP1` = `1`
* `GP2` = `2`
There is also a `NUM_GPIOS` for times when any iteration needs to be performed.
There is also a `.NUM_GPIOS` for times when any iteration needs to be performed.
### Software Reset
@ -128,6 +140,8 @@ actuate_relay(relay)
release_relay(relay)
output(output)
output(output, value)
output_percent(output)
change_output_freq(output, freq)
read_input(input)
read_adc(adc)
reset()

View File

@ -29,14 +29,6 @@ INPUT_4 = 3
SWITCH_A = 0
SWITCH_B = 1
# Count Constants
NUM_GPIOS = 3
NUM_RELAYS = 3
NUM_OUTPUTS = 3
NUM_ADCS = 3
NUM_INPUTS = 4
NUM_SWITCHES = 2
class Automation2040W():
CONN_LED_PIN = 3
@ -50,6 +42,14 @@ class Automation2040W():
IN_BUFFERED_PINS = (19, 20, 21, 22)
ADC_PINS = (26, 27, 28)
# Count Constants
NUM_GPIOS = 3
NUM_RELAYS = 3
NUM_OUTPUTS = 3
NUM_ADCS = 3
NUM_INPUTS = 4
NUM_SWITCHES = 2
VOLTAGE_GAIN = 0.06 # 56 / (56 + 820)
VOLTAGE_OFFSET = -0.06
MAX_ADC_LED_VOLTAGE = 45.0
@ -63,25 +63,27 @@ class Automation2040W():
# Set up the relay pins
self.__relays = []
for i in range(NUM_RELAYS):
for i in range(self.NUM_RELAYS):
self.__relays.append(Pin(self.RELAY_PINS[i], Pin.OUT))
self.release_relay(i)
# Set up the output pins
# Set up outputs with pwm
self.__outputs = []
for i in range(NUM_OUTPUTS):
self.__outputs.append(Pin(self.OUTPUT_PINS[i], Pin.OUT))
self.output(i, False)
for i in range(self.NUM_OUTPUTS):
output = PWM(Pin(self.OUTPUT_PINS[i]))
output.freq(1000)
output.duty_u16(0)
self.__outputs.append(output)
# Set up the input pins
self.__inputs = []
for i in range(NUM_INPUTS):
for i in range(self.NUM_INPUTS):
self.__inputs.append(Pin(self.IN_BUFFERED_PINS[i], Pin.IN))
# Set up the adc pins and leds
self.__analogs = []
self.__adc_led_pwms = []
for i in range(NUM_ADCS):
for i in range(self.NUM_ADCS):
self.__analogs.append(Analog(self.ADC_PINS[i], self.VOLTAGE_GAIN, offset=self.VOLTAGE_OFFSET))
led_pwm = PWM(Pin(self.ADC_LED_PINS[i]))
led_pwm.freq(1000)
@ -91,7 +93,7 @@ class Automation2040W():
# Set up the user switches
self.__switches = []
self.__switch_led_pwms = []
for i in range(NUM_SWITCHES):
for i in range(self.NUM_SWITCHES):
self.__switches.append(Pin(self.USER_SW_PINS[i], Pin.IN, Pin.PULL_UP))
led_pwm = PWM(Pin(self.USER_LED_PINS[i]))
led_pwm.freq(1000)
@ -112,16 +114,16 @@ class Automation2040W():
raise ValueError("brightness out of range. Expected 0 to 100, or True or False")
else:
gamma = 2.8
value = int(pow(brightness / 100.0, gamma) * 65535 + 0.5)
value = int(pow(float(brightness) / 100.0, gamma) * 65535 + 0.5)
self.__conn_led_pwm.duty_u16(value)
def switch_pressed(self, switch):
if switch < 0 or switch > NUM_SWITCHES:
if switch < 0 or switch >= self.NUM_SWITCHES:
raise ValueError("switch out of range. Expected SWITCH_A (0) or SWITCH_B (1)")
return not self.__switches[switch].value()
def switch_led(self, switch, brightness):
if switch < 0 or switch > NUM_SWITCHES:
if switch < 0 or switch >= self.NUM_SWITCHES:
raise ValueError("switch out of range. Expected SWITCH_A (0) or SWITCH_B (1)")
if brightness is True:
@ -136,7 +138,7 @@ class Automation2040W():
self.__switch_led_pwms[switch].duty_u16(value)
def relay(self, relay, actuate=None):
if relay < 0 or relay > NUM_RELAYS:
if relay < 0 or relay >= self.NUM_RELAYS:
raise ValueError("relay out of range. Expected RELAY_1 (0), RELAY_2 (1), or RELAY_3 (2)")
if actuate is None:
@ -145,31 +147,59 @@ class Automation2040W():
self.__relays[relay].value(actuate)
def actuate_relay(self, relay):
if relay < 0 or relay > NUM_RELAYS:
if relay < 0 or relay >= self.NUM_RELAYS:
raise ValueError("relay out of range. Expected RELAY_1 (0), RELAY_2 (1), or RELAY_3 (2)")
self.__relays[relay].on()
def release_relay(self, relay):
if relay < 0 or relay > NUM_RELAYS:
if relay < 0 or relay >= self.NUM_RELAYS:
raise ValueError("relay out of range. Expected RELAY_1 (0), RELAY_2 (1), or RELAY_3 (2)")
self.__relays[relay].off()
def output(self, output, value=None):
if output < 0 or output > NUM_OUTPUTS:
if output < 0 or output >= self.NUM_OUTPUTS:
raise ValueError("output out of range. Expected OUTPUT_1 (0), OUTPUT_2 (1), or OUTPUT_3 (2)")
if value is None:
return self.__outputs[output].value()
return self.__outputs[output].duty_u16() != 0
self.__outputs[output].value(value)
if value is True:
value = 100.0
if value is False:
value = 0
try:
if value >= 0.0 and value <= 100.0:
self.__outputs[output].duty_u16(int((value / 100.0) * 65535))
return
except TypeError:
pass
raise ValueError("value out of range. Expected 0 to 100, or True or False")
def output_percent(self, output):
if output < 0 or output >= self.NUM_OUTPUTS:
raise ValueError("output out of range. Expected OUTPUT_1 (0), OUTPUT_2 (1), or OUTPUT_3 (2)")
return round((self.__outputs[output].duty_u16() / 65535) * 100.0, 1)
def change_output_freq(self, output, freq):
if output < 0 or output >= self.NUM_OUTPUTS:
raise ValueError("output out of range. Expected OUTPUT_1 (0), OUTPUT_2 (1), or OUTPUT_3 (2)")
if freq < 10 or freq > 1000.0:
raise ValueError("freq out of range. Expected 10Hz to 1000Hz")
self.__outputs[output].freq(freq)
def read_input(self, input):
if input < 0 or input > NUM_INPUTS:
if input < 0 or input >= self.NUM_INPUTS:
raise ValueError("input out of range. Expected INPUT_1 (0), INPUT_2 (1), INPUT_3 (2), or INPUT_4 (3)")
return self.__inputs[input].value()
def read_adc(self, adc):
if adc < 0 or adc > NUM_ADCS:
if adc < 0 or adc >= self.NUM_ADCS:
raise ValueError("adc out of range. Expected ADC_1 (0), ADC_2 (1), or ADC_3 (2)")
voltage = self.__analogs[adc].read_voltage()
@ -180,19 +210,207 @@ class Automation2040W():
def reset(self):
# Reset the relays
for i in range(NUM_RELAYS):
for i in range(self.NUM_RELAYS):
self.release_relay(i)
# Reset the outputs
for i in range(NUM_OUTPUTS):
for i in range(self.NUM_OUTPUTS):
self.output(i, False)
# Reset the adc LEDs
for i in range(NUM_ADCS):
for i in range(self.NUM_ADCS):
self.__adc_led_pwms[i].duty_u16(0)
# Reset the switch LEDs
for i in range(NUM_SWITCHES):
for i in range(self.NUM_SWITCHES):
self.__switch_led_pwms[i].duty_u16(0)
# Reset the connectivity LED
self.__conn_led_pwm.duty_u16(0)
class Automation2040WMini():
CONN_LED_PIN = 3
I2C_SDA_PIN = 4
I2C_SCL_PIN = 5
ADC_LED_PINS = (6, 7, 8)
RELAY_PIN = 9
USER_SW_PINS = (12, 13)
USER_LED_PINS = (14, 15)
OUTPUT_PINS = (16, 17)
IN_BUFFERED_PINS = (19, 20)
ADC_PINS = (26, 27, 28)
# Count Constants
NUM_GPIOS = 3
NUM_RELAYS = 1
NUM_OUTPUTS = 2
NUM_ADCS = 3
NUM_INPUTS = 2
NUM_SWITCHES = 2
VOLTAGE_GAIN = 0.06 # 56 / (56 + 820)
VOLTAGE_OFFSET = -0.06
MAX_ADC_LED_VOLTAGE = 45.0
def __init__(self):
# Free up hardware resources
gc.collect()
# Set up the i2c for Qw/st
self.i2c = PimoroniI2C(self.I2C_SDA_PIN, self.I2C_SCL_PIN, 100000)
# Set up the relay pins
self.__relay = Pin(self.RELAY_PIN, Pin.OUT)
# Set up outputs with pwm
self.__outputs = []
for i in range(self.NUM_OUTPUTS):
output = PWM(Pin(self.OUTPUT_PINS[i]))
output.freq(1000)
output.duty_u16(0)
self.__outputs.append(output)
# Set up the input pins
self.__inputs = []
for i in range(self.NUM_INPUTS):
self.__inputs.append(Pin(self.IN_BUFFERED_PINS[i], Pin.IN))
# Set up the adc pins and leds
self.__analogs = []
self.__adc_led_pwms = []
for i in range(self.NUM_ADCS):
self.__analogs.append(Analog(self.ADC_PINS[i], self.VOLTAGE_GAIN, offset=self.VOLTAGE_OFFSET))
led_pwm = PWM(Pin(self.ADC_LED_PINS[i]))
led_pwm.freq(1000)
led_pwm.duty_u16(0)
self.__adc_led_pwms.append(led_pwm)
# Set up the user switches
self.__switches = []
self.__switch_led_pwms = []
for i in range(self.NUM_SWITCHES):
self.__switches.append(Pin(self.USER_SW_PINS[i], Pin.IN, Pin.PULL_UP))
led_pwm = PWM(Pin(self.USER_LED_PINS[i]))
led_pwm.freq(1000)
led_pwm.duty_u16(0)
self.__switch_led_pwms.append(led_pwm)
# Set up the connectivity LED
self.__conn_led_pwm = PWM(Pin(self.CONN_LED_PIN))
self.__conn_led_pwm.freq(1000)
self.__conn_led_pwm.duty_u16(0)
def conn_led(self, brightness):
if brightness is True:
self.__conn_led_pwm.duty_u16(65535)
elif brightness is False:
self.__conn_led_pwm.duty_u16(0)
elif brightness > 0.0 or brightness > 100.0:
raise ValueError("brightness out of range. Expected 0 to 100, or True or False")
else:
gamma = 2.8
value = int(pow(brightness / 100.0, gamma) * 65535 + 0.5)
self.__conn_led_pwm.duty_u16(value)
def switch_pressed(self, switch):
if switch < 0 or switch >= self.NUM_SWITCHES:
raise ValueError("switch out of range. Expected SWITCH_A (0) or SWITCH_B (1)")
return not self.__switches[switch].value()
def switch_led(self, switch, brightness):
if switch < 0 or switch >= self.NUM_SWITCHES:
raise ValueError("switch out of range. Expected SWITCH_A (0) or SWITCH_B (1)")
if brightness is True:
self.__switch_led_pwms[switch].duty_u16(65535)
elif brightness is False:
self.__switch_led_pwms[switch].duty_u16(0)
elif brightness < 0.0 or brightness > 100.0:
raise ValueError("brightness out of range. Expected 0 to 100, or True or False")
else:
gamma = 2.8
value = int(pow(brightness / 100.0, gamma) * 65535 + 0.5)
self.__switch_led_pwms[switch].duty_u16(value)
def relay(self, actuate=None):
if actuate is None:
return self.__relay.value()
self.__relay.value(actuate)
def actuate_relay(self):
self.__relay.on()
def release_relay(self):
self.__relay.off()
def output(self, output, value=None):
if output < 0 or output >= self.NUM_OUTPUTS:
raise ValueError("output out of range. Expected OUTPUT_1 (0) or OUTPUT_2 (1)")
if value is None:
return self.__outputs[output].duty_u16() != 0
if value is True:
value = 100.0
if value is False:
value = 0
try:
if value >= 0.0 and value <= 100.0:
self.__outputs[output].duty_u16(int((value / 100.0) * 65535))
return
except TypeError:
pass
raise ValueError("value out of range. Expected 0 to 100, or True or False")
def output_percent(self, output):
if output < 0 or output >= self.NUM_OUTPUTS:
raise ValueError("output out of range. Expected OUTPUT_1 (0) or OUTPUT_2 (1)")
return round((self.__outputs[output].duty_u16() / 65535) * 100.0, 1)
def change_output_freq(self, output, freq):
if output < 0 or output >= self.NUM_OUTPUTS:
raise ValueError("output out of range. Expected OUTPUT_1 (0) or OUTPUT_2 (1)")
if freq < 10 or freq > 1000.0:
raise ValueError("freq out of range. Expected 10Hz to 1000Hz")
self.__outputs[output].freq(freq)
def read_input(self, input):
if input < 0 or input >= self.NUM_INPUTS:
raise ValueError("input out of range. Expected INPUT_1 (0) or INPUT_2 (1)")
return self.__inputs[input].value()
def read_adc(self, adc):
if adc < 0 or adc >= self.NUM_ADCS:
raise ValueError("adc out of range. Expected ADC_1 (0), ADC_2 (1), or ADC_3 (2)")
voltage = self.__analogs[adc].read_voltage()
gamma = 2.8
value = int(pow(voltage / self.MAX_ADC_LED_VOLTAGE, gamma) * 65535 + 0.5)
self.__adc_led_pwms[adc].duty_u16(value)
return voltage
def reset(self):
# Reset the relay
self.release_relay()
# Reset the outputs
for i in range(self.NUM_OUTPUTS):
self.output(i, False)
# Reset the adc LEDs
for i in range(self.NUM_ADCS):
self.__adc_led_pwms[i].duty_u16(0)
# Reset the switch LEDs
for i in range(self.NUM_SWITCHES):
self.__switch_led_pwms[i].duty_u16(0)
# Reset the connectivity LED