kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Libraries and examples for Automation 2040 W (#418)
* Libraries and examples for Automation 2040 W * Fix for initialisation errorpull/420/head
rodzic
93e1da21b2
commit
d9d8f4417a
|
@ -45,6 +45,7 @@ add_subdirectory(pico_wireless)
|
||||||
|
|
||||||
add_subdirectory(inky_pack)
|
add_subdirectory(inky_pack)
|
||||||
|
|
||||||
|
add_subdirectory(automation2040w)
|
||||||
add_subdirectory(plasma2040)
|
add_subdirectory(plasma2040)
|
||||||
add_subdirectory(badger2040)
|
add_subdirectory(badger2040)
|
||||||
add_subdirectory(tufty2040)
|
add_subdirectory(tufty2040)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
include(automation2040w_read_adcs.cmake)
|
||||||
|
include(automation2040w_read_inputs.cmake)
|
||||||
|
include(automation2040w_switches_and_leds.cmake)
|
||||||
|
include(automation2040w_toggle_outputs.cmake)
|
||||||
|
include(automation2040w_toggle_relays.cmake)
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Automation 2040 W C++ Examples <!-- omit in toc -->
|
||||||
|
|
||||||
|
- [Function Examples](#function-examples)
|
||||||
|
- [Read ADCs](#read-adcs)
|
||||||
|
- [Read Inputs](#read-inputs)
|
||||||
|
- [Toggle Relays](#toggle-relays)
|
||||||
|
- [Toggle Outputs](#toggle-outputs)
|
||||||
|
- [Switches and LEDs](#switches-and-leds)
|
||||||
|
|
||||||
|
|
||||||
|
## Function Examples
|
||||||
|
|
||||||
|
### Read ADCs
|
||||||
|
[automation2040w_read_adcs.cpp](automation2040w_read_adcs.cpp)
|
||||||
|
|
||||||
|
Shows how to read the 3 ADC terminals of Automation 2040 W.
|
||||||
|
|
||||||
|
|
||||||
|
### Read Inputs
|
||||||
|
[automation2040w_read_inputs.cpp](automation2040w_read_inputs.cpp)
|
||||||
|
|
||||||
|
Shows how to read the 3 Input terminals of Automation 2040 W.
|
||||||
|
|
||||||
|
|
||||||
|
### Toggle Relays
|
||||||
|
[automation2040w_toggle_relays.cpp](automation2040w_toggle_relays.cpp)
|
||||||
|
|
||||||
|
Demonstrates how to toggle the actuation state of each of Automation 2040 W's relays.
|
||||||
|
|
||||||
|
|
||||||
|
### Toggle Outputs
|
||||||
|
[automation2040w_toggle_outputs.cpp](automation2040w_toggle_outputs.cpp)
|
||||||
|
|
||||||
|
Demonstrates how to toggle each of Automation 2040 W's output terminals.
|
||||||
|
|
||||||
|
|
||||||
|
### Switches and LEDs
|
||||||
|
[automation2040w_switches_and_leds.cpp](automation2040w_switches_and_leds.cpp)
|
||||||
|
|
||||||
|
An example of the user switches and LEDs on Automation 2040 W.
|
|
@ -0,0 +1,14 @@
|
||||||
|
set(OUTPUT_NAME automation2040w_read_adcs)
|
||||||
|
add_executable(${OUTPUT_NAME} automation2040w_read_adcs.cpp)
|
||||||
|
|
||||||
|
# Pull in pico libraries that we need
|
||||||
|
target_link_libraries(${OUTPUT_NAME}
|
||||||
|
pico_stdlib
|
||||||
|
automation
|
||||||
|
)
|
||||||
|
|
||||||
|
# enable usb output
|
||||||
|
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||||
|
|
||||||
|
# create map/bin/hex file etc.
|
||||||
|
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include <cstdio>
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
#include "automation.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Shows how to read the 3 ADC terminals of Automation 2040 W.
|
||||||
|
|
||||||
|
Press "A" to exit the program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace automation;
|
||||||
|
|
||||||
|
// How many times to update per second
|
||||||
|
const uint UPDATES = 10;
|
||||||
|
|
||||||
|
// The friendly names to give each ADC input
|
||||||
|
const char* ADC_NAMES[] = {"A1", "A2", "A3"};
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new Automation2040W
|
||||||
|
Automation2040W board;
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
|
||||||
|
// Attempt to initialise the board
|
||||||
|
if(board.init()) {
|
||||||
|
|
||||||
|
// Enable the LED of the switch used to exit the loop
|
||||||
|
board.switch_led(SWITCH_A, 50.0f); // Half Brightness
|
||||||
|
|
||||||
|
// Read the ADCs until user switch is pressed
|
||||||
|
while(!board.switch_pressed(SWITCH_A)) {
|
||||||
|
|
||||||
|
// Read each ADC in turn and print its voltage
|
||||||
|
for(uint i = 0; i < NUM_ADCS; i++) {
|
||||||
|
float voltage = board.read_adc(i);
|
||||||
|
printf("%s = %f, ", ADC_NAMES[i], voltage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print a new line
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
sleep_ms(1000 / UPDATES);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the board back into a safe state
|
||||||
|
board.reset();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
set(OUTPUT_NAME automation2040w_read_inputs)
|
||||||
|
add_executable(${OUTPUT_NAME} automation2040w_read_inputs.cpp)
|
||||||
|
|
||||||
|
# Pull in pico libraries that we need
|
||||||
|
target_link_libraries(${OUTPUT_NAME}
|
||||||
|
pico_stdlib
|
||||||
|
automation
|
||||||
|
)
|
||||||
|
|
||||||
|
# enable usb output
|
||||||
|
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||||
|
|
||||||
|
# create map/bin/hex file etc.
|
||||||
|
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include <cstdio>
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
#include "automation.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Shows how to read the 3 Input terminals of Automation 2040 W.
|
||||||
|
|
||||||
|
Press "A" to exit the program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace automation;
|
||||||
|
|
||||||
|
// How many times to update per second
|
||||||
|
const uint UPDATES = 10;
|
||||||
|
|
||||||
|
// The friendly names to give each digital input
|
||||||
|
const char* INPUT_NAMES[] = {"I1", "I2", "I3", "I4"};
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new Automation2040W
|
||||||
|
Automation2040W board;
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
|
||||||
|
// Attempt to initialise the board
|
||||||
|
if(board.init()) {
|
||||||
|
|
||||||
|
// Enable the LED of the switch used to exit the loop
|
||||||
|
board.switch_led(SWITCH_A, 50.0f); // Half Brightness
|
||||||
|
|
||||||
|
// Read the inputs until user switch is pressed
|
||||||
|
while(!board.switch_pressed(SWITCH_A)) {
|
||||||
|
|
||||||
|
// Read each input in turn and print its voltage
|
||||||
|
for(uint i = 0; i < NUM_INPUTS; i++) {
|
||||||
|
bool value = board.read_input(i);
|
||||||
|
printf("%s = %d, ", INPUT_NAMES[i], (int)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print a new line
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
sleep_ms(1000 / UPDATES);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the board back into a safe state
|
||||||
|
board.reset();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
set(OUTPUT_NAME automation2040w_switches_and_leds)
|
||||||
|
add_executable(${OUTPUT_NAME} automation2040w_switches_and_leds.cpp)
|
||||||
|
|
||||||
|
# Pull in pico libraries that we need
|
||||||
|
target_link_libraries(${OUTPUT_NAME}
|
||||||
|
pico_stdlib
|
||||||
|
automation
|
||||||
|
)
|
||||||
|
|
||||||
|
# enable usb output
|
||||||
|
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||||
|
|
||||||
|
# create map/bin/hex file etc.
|
||||||
|
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include <cstdio>
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
#include "automation.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
An example of the user switches and LEDs on Automation 2040 W.
|
||||||
|
|
||||||
|
Press "A" and "B" together to exit the program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace automation;
|
||||||
|
|
||||||
|
// How many times to update per second
|
||||||
|
const uint UPDATES = 10;
|
||||||
|
|
||||||
|
// The friendly names to give each user input
|
||||||
|
const char* SWITCH_NAMES[] = {"SW_A", "SW_B"};
|
||||||
|
|
||||||
|
// How much to change a LED's brightess each update
|
||||||
|
const uint LED_INCREMENT = 2;
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new Automation2040W
|
||||||
|
Automation2040W board;
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
|
||||||
|
// Attempt to initialise the board
|
||||||
|
if(board.init()) {
|
||||||
|
|
||||||
|
// Enable the Conn LED
|
||||||
|
board.conn_led(true); // Full Brightness
|
||||||
|
|
||||||
|
float led_brightnesses[] = {0.0f, 0.0f};
|
||||||
|
|
||||||
|
// Interact with the switches and LEDs until both are pressed simultaneously
|
||||||
|
while(!board.switch_pressed(SWITCH_A) || !board.switch_pressed(SWITCH_B)) {
|
||||||
|
|
||||||
|
for(uint i = 0; i < NUM_SWITCHES; i++) {
|
||||||
|
// Change the LED brightness based on switch's state
|
||||||
|
if(board.switch_pressed(i)) {
|
||||||
|
printf("%s = Pressed, ", SWITCH_NAMES[i]);
|
||||||
|
led_brightnesses[i] = MIN(led_brightnesses[i] + LED_INCREMENT, 100.0f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("%s = Released, ", SWITCH_NAMES[i]);
|
||||||
|
led_brightnesses[i] = MAX(led_brightnesses[i] - LED_INCREMENT, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the new brightnesses to the LEDs
|
||||||
|
board.switch_led(i, led_brightnesses[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print a new line
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
sleep_ms(1000 / UPDATES);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the board back into a safe state
|
||||||
|
board.reset();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
set(OUTPUT_NAME automation2040w_toggle_outputs)
|
||||||
|
add_executable(${OUTPUT_NAME} automation2040w_toggle_outputs.cpp)
|
||||||
|
|
||||||
|
# Pull in pico libraries that we need
|
||||||
|
target_link_libraries(${OUTPUT_NAME}
|
||||||
|
pico_stdlib
|
||||||
|
automation
|
||||||
|
)
|
||||||
|
|
||||||
|
# enable usb output
|
||||||
|
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||||
|
|
||||||
|
# create map/bin/hex file etc.
|
||||||
|
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,63 @@
|
||||||
|
#include <cstdio>
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
#include "automation.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Demonstrates how to toggle each of Automation 2040 W's output terminals.
|
||||||
|
|
||||||
|
Press "A" to exit the program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace automation;
|
||||||
|
|
||||||
|
// How much time to wait between each toggle (in milliseconds)
|
||||||
|
const uint TIME_PER_TOGGLE_MS = 500;
|
||||||
|
|
||||||
|
// The friendly names to give each digital output
|
||||||
|
const char* OUTPUT_NAMES[] = {"O1", "O2", "O3"};
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new Automation2040W
|
||||||
|
Automation2040W board;
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
|
||||||
|
// Attempt to initialise the board
|
||||||
|
if(board.init()) {
|
||||||
|
|
||||||
|
// Enable the LED of the switch used to exit the loop
|
||||||
|
board.switch_led(SWITCH_A, 50.0f); // Half Brightness
|
||||||
|
|
||||||
|
bool toggle = true;
|
||||||
|
uint index = 0;
|
||||||
|
|
||||||
|
// Toggle the outputs until the user switch is pressed
|
||||||
|
while(!board.switch_pressed(SWITCH_A)) {
|
||||||
|
|
||||||
|
// Toggle an output
|
||||||
|
board.output(index, toggle);
|
||||||
|
|
||||||
|
// Print the state of all outputs
|
||||||
|
for(uint i = 0; i < NUM_OUTPUTS; i++) {
|
||||||
|
printf("%s = %d, ", OUTPUT_NAMES[i], (int)board.output(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print a new line
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
index++; // Move on to the next output
|
||||||
|
if(index >= NUM_OUTPUTS) {
|
||||||
|
index = 0; // Go back to the first output
|
||||||
|
toggle = !toggle; // Invert the toggle value
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep_ms(TIME_PER_TOGGLE_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the board back into a safe state
|
||||||
|
board.reset();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
set(OUTPUT_NAME automation2040w_toggle_relays)
|
||||||
|
add_executable(${OUTPUT_NAME} automation2040w_toggle_relays.cpp)
|
||||||
|
|
||||||
|
# Pull in pico libraries that we need
|
||||||
|
target_link_libraries(${OUTPUT_NAME}
|
||||||
|
pico_stdlib
|
||||||
|
automation
|
||||||
|
)
|
||||||
|
|
||||||
|
# enable usb output
|
||||||
|
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||||
|
|
||||||
|
# create map/bin/hex file etc.
|
||||||
|
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,63 @@
|
||||||
|
#include <cstdio>
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
#include "automation.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Demonstrates how to toggle the actuation state of each of Automation 2040 W's relays.
|
||||||
|
|
||||||
|
Press "A" to exit the program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace automation;
|
||||||
|
|
||||||
|
// How much time to wait between each toggle (in milliseconds)
|
||||||
|
const uint TIME_PER_TOGGLE_MS = 500;
|
||||||
|
|
||||||
|
// The friendly names to give each relay
|
||||||
|
const char* RELAY_NAMES[] = {"R1", "R2", "R3"};
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new Automation2040W
|
||||||
|
Automation2040W board;
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
|
||||||
|
// Attempt to initialise the board
|
||||||
|
if(board.init()) {
|
||||||
|
|
||||||
|
// Enable the LED of the switch used to exit the loop
|
||||||
|
board.switch_led(SWITCH_A, 50.0f); // Half Brightness
|
||||||
|
|
||||||
|
bool toggle = true;
|
||||||
|
uint index = 0;
|
||||||
|
|
||||||
|
// Toggle the relays until the user switch is pressed
|
||||||
|
while(!board.switch_pressed(SWITCH_A)) {
|
||||||
|
|
||||||
|
// Toggle a relay
|
||||||
|
board.relay(index, toggle);
|
||||||
|
|
||||||
|
// Print the state of all relays
|
||||||
|
for(uint i = 0; i < NUM_RELAYS; i++) {
|
||||||
|
printf("%s = %d, ", RELAY_NAMES[i], (int)board.relay(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print a new line
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
index++; // Move on to the next relay
|
||||||
|
if(index >= NUM_RELAYS) {
|
||||||
|
index = 0; // Go back to the first relay
|
||||||
|
toggle = !toggle; // Invert the toggle value
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep_ms(TIME_PER_TOGGLE_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the board back into a safe state
|
||||||
|
board.reset();
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ add_subdirectory(pico_explorer)
|
||||||
add_subdirectory(pico_motor_shim)
|
add_subdirectory(pico_motor_shim)
|
||||||
add_subdirectory(pico_rgb_keypad)
|
add_subdirectory(pico_rgb_keypad)
|
||||||
add_subdirectory(pico_wireless)
|
add_subdirectory(pico_wireless)
|
||||||
|
add_subdirectory(automation2040w)
|
||||||
add_subdirectory(plasma2040)
|
add_subdirectory(plasma2040)
|
||||||
add_subdirectory(badger2040)
|
add_subdirectory(badger2040)
|
||||||
add_subdirectory(tufty2040)
|
add_subdirectory(tufty2040)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
include(automation.cmake)
|
|
@ -0,0 +1,12 @@
|
||||||
|
add_library(automation INTERFACE)
|
||||||
|
|
||||||
|
target_sources(automation INTERFACE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/automation.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(automation INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
#include(${PIMORONI_PICO_PATH}/drivers/analog/analog.cmake)
|
||||||
|
|
||||||
|
# Pull in pico libraries that we need
|
||||||
|
target_link_libraries(automation INTERFACE pico_stdlib hardware_pwm hardware_i2c pimoroni_i2c analog)
|
|
@ -0,0 +1,178 @@
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "automation.hpp"
|
||||||
|
|
||||||
|
namespace automation {
|
||||||
|
|
||||||
|
const uint Automation2040W::ADC_LED_PINS[] = {6, 7, 8};
|
||||||
|
const uint Automation2040W::RELAY_PINS[] = {9, 10, 11};
|
||||||
|
const uint Automation2040W::USER_SW_PINS[] = {12, 13};
|
||||||
|
const uint Automation2040W::USER_LED_PINS[] = {14, 15};
|
||||||
|
const uint Automation2040W::OUTPUT_PINS[] = {16, 17, 18};
|
||||||
|
const uint Automation2040W::IN_BUFFERED_PINS[] = {19, 20, 21, 22};
|
||||||
|
const uint Automation2040W::ADC_PINS[] = {26, 27, 28};
|
||||||
|
|
||||||
|
|
||||||
|
Automation2040W::Automation2040W()
|
||||||
|
: i2c(I2C_SDA_PIN, I2C_SCL_PIN, 100000)
|
||||||
|
, analogs{Analog(ADC_PINS[0], VOLTAGE_GAIN, 0.0f, VOLTAGE_OFFSET),
|
||||||
|
Analog(ADC_PINS[1], VOLTAGE_GAIN, 0.0f, VOLTAGE_OFFSET),
|
||||||
|
Analog(ADC_PINS[2], VOLTAGE_GAIN, 0.0f, VOLTAGE_OFFSET)} {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Automation2040W::init() {
|
||||||
|
// Set up the relay pins
|
||||||
|
for(auto i = 0u; i < NUM_RELAYS; i++) {
|
||||||
|
gpio_set_function(RELAY_PINS[i], GPIO_FUNC_SIO);
|
||||||
|
gpio_set_dir(RELAY_PINS[i], GPIO_OUT);
|
||||||
|
release_relay(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the output pins
|
||||||
|
for(auto i = 0u; i < NUM_OUTPUTS; i++) {
|
||||||
|
gpio_set_function(OUTPUT_PINS[i], GPIO_FUNC_SIO);
|
||||||
|
gpio_set_dir(OUTPUT_PINS[i], GPIO_OUT);
|
||||||
|
output(i, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the input pins
|
||||||
|
for(auto i = 0u; i < NUM_INPUTS; i++) {
|
||||||
|
gpio_set_function(IN_BUFFERED_PINS[i], GPIO_FUNC_SIO);
|
||||||
|
gpio_set_dir(IN_BUFFERED_PINS[i], GPIO_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the adc leds
|
||||||
|
for(auto i = 0u; i < NUM_ADCS; i++) {
|
||||||
|
gpio_put(ADC_LED_PINS[i], false);
|
||||||
|
pwm_config cfg = pwm_get_default_config();
|
||||||
|
pwm_set_wrap(pwm_gpio_to_slice_num(ADC_LED_PINS[i]), 65535);
|
||||||
|
pwm_init(pwm_gpio_to_slice_num(ADC_LED_PINS[i]), &cfg, true);
|
||||||
|
gpio_set_function(ADC_LED_PINS[i], GPIO_FUNC_PWM);
|
||||||
|
pwm_set_gpio_level(ADC_LED_PINS[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the user switches and LEDs
|
||||||
|
for(auto i = 0u; i < NUM_SWITCHES; i++) {
|
||||||
|
gpio_set_function(USER_SW_PINS[i], GPIO_FUNC_SIO);
|
||||||
|
gpio_set_dir(USER_SW_PINS[i], GPIO_IN);
|
||||||
|
gpio_pull_up(USER_SW_PINS[i]);
|
||||||
|
|
||||||
|
gpio_put(USER_LED_PINS[i], false);
|
||||||
|
pwm_config cfg = pwm_get_default_config();
|
||||||
|
pwm_set_wrap(pwm_gpio_to_slice_num(USER_LED_PINS[i]), 65535);
|
||||||
|
pwm_init(pwm_gpio_to_slice_num(USER_LED_PINS[i]), &cfg, true);
|
||||||
|
gpio_set_function(USER_LED_PINS[i], GPIO_FUNC_PWM);
|
||||||
|
pwm_set_gpio_level(USER_LED_PINS[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the connectivity LED
|
||||||
|
gpio_put(CONN_LED_PIN, false);
|
||||||
|
pwm_config cfg = pwm_get_default_config();
|
||||||
|
pwm_set_wrap(pwm_gpio_to_slice_num(CONN_LED_PIN), 65535);
|
||||||
|
pwm_init(pwm_gpio_to_slice_num(CONN_LED_PIN), &cfg, true);
|
||||||
|
gpio_set_function(CONN_LED_PIN, GPIO_FUNC_PWM);
|
||||||
|
pwm_set_gpio_level(CONN_LED_PIN, 0);
|
||||||
|
|
||||||
|
return true; // We just return true for now, but could expand in the future
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::conn_led(bool on) {
|
||||||
|
pwm_set_gpio_level(CONN_LED_PIN, on ? 65535 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::conn_led(float brightness) {
|
||||||
|
brightness = CLAMP(brightness, 0.0f, 100.0f);
|
||||||
|
const float gamma = 2.8f;
|
||||||
|
uint16_t value = (uint16_t)(powf(brightness / 100.0f, gamma) * 65535.0f + 0.5f);
|
||||||
|
pwm_set_gpio_level(CONN_LED_PIN, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Automation2040W::switch_pressed(uint sw) {
|
||||||
|
assert(sw < NUM_SWITCHES);
|
||||||
|
return !gpio_get(USER_SW_PINS[sw]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::switch_led(uint sw, bool on) {
|
||||||
|
assert(sw < NUM_SWITCHES);
|
||||||
|
pwm_set_gpio_level(USER_LED_PINS[sw], on ? 65535 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::switch_led(uint sw, float brightness) {
|
||||||
|
assert(sw < NUM_SWITCHES);
|
||||||
|
|
||||||
|
brightness = CLAMP(brightness, 0.0f, 100.0f);
|
||||||
|
const float gamma = 2.8f;
|
||||||
|
|
||||||
|
uint16_t value = (uint16_t)(powf(brightness / 100.0f, gamma) * 65535.0f + 0.5f);
|
||||||
|
pwm_set_gpio_level(USER_LED_PINS[sw], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Automation2040W::relay(uint relay) {
|
||||||
|
assert(relay < NUM_RELAYS);
|
||||||
|
return gpio_get(RELAY_PINS[relay]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::relay(uint relay, bool actuate) {
|
||||||
|
assert(relay < NUM_RELAYS);
|
||||||
|
gpio_put(RELAY_PINS[relay], actuate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::actuate_relay(uint relay) {
|
||||||
|
assert(relay < NUM_RELAYS);
|
||||||
|
gpio_put(RELAY_PINS[relay], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::release_relay(uint relay) {
|
||||||
|
assert(relay < NUM_RELAYS);
|
||||||
|
gpio_put(RELAY_PINS[relay], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Automation2040W::output(uint output) {
|
||||||
|
assert(output < NUM_OUTPUTS);
|
||||||
|
return gpio_get(OUTPUT_PINS[output]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::output(uint output, bool value) {
|
||||||
|
assert(output < NUM_OUTPUTS);
|
||||||
|
gpio_put(OUTPUT_PINS[output], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Automation2040W::read_input(uint input) {
|
||||||
|
assert(input < NUM_INPUTS);
|
||||||
|
return gpio_get(IN_BUFFERED_PINS[input]);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Automation2040W::read_adc(uint adc) {
|
||||||
|
assert(adc < NUM_ADCS);
|
||||||
|
float voltage = analogs[adc].read_voltage();
|
||||||
|
const float gamma = 2.8f;
|
||||||
|
uint16_t value = (uint16_t)(powf(voltage / MAX_ADC_LED_VOLTAGE, gamma) * 65535.0f + 0.5f);
|
||||||
|
pwm_set_gpio_level(ADC_LED_PINS[adc], value);
|
||||||
|
return voltage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Automation2040W::reset() {
|
||||||
|
// Reset the relays
|
||||||
|
for(auto i = 0u; i < NUM_RELAYS; i++) {
|
||||||
|
release_relay(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the outputs
|
||||||
|
for(auto i = 0u; i < NUM_OUTPUTS; i++) {
|
||||||
|
output(i, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the adc leds
|
||||||
|
for(auto i = 0u; i < NUM_ADCS; i++) {
|
||||||
|
pwm_set_gpio_level(ADC_LED_PINS[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the switch LEDs
|
||||||
|
for(auto i = 0u; i < NUM_SWITCHES; i++) {
|
||||||
|
pwm_set_gpio_level(USER_LED_PINS[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the connectivity LED
|
||||||
|
pwm_set_gpio_level(CONN_LED_PIN, 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
#pragma once
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "hardware/pwm.h"
|
||||||
|
|
||||||
|
#include "analog.hpp"
|
||||||
|
#include "pimoroni_i2c.hpp"
|
||||||
|
|
||||||
|
using namespace pimoroni;
|
||||||
|
|
||||||
|
|
||||||
|
namespace automation {
|
||||||
|
// IO Pin Constants
|
||||||
|
const uint GP0 = 0;
|
||||||
|
const uint GP1 = 1;
|
||||||
|
const uint GP2 = 2;
|
||||||
|
|
||||||
|
|
||||||
|
// Index Constants
|
||||||
|
const uint RELAY_1 = 0;
|
||||||
|
const uint RELAY_2 = 1;
|
||||||
|
const uint RELAY_3 = 2;
|
||||||
|
|
||||||
|
const uint OUTPUT_1 = 0;
|
||||||
|
const uint OUTPUT_2 = 1;
|
||||||
|
const uint OUTPUT_3 = 2;
|
||||||
|
|
||||||
|
const uint ADC_1 = 0;
|
||||||
|
const uint ADC_2 = 1;
|
||||||
|
const uint ADC_3 = 2;
|
||||||
|
|
||||||
|
const uint INPUT_1 = 0;
|
||||||
|
const uint INPUT_2 = 1;
|
||||||
|
const uint INPUT_3 = 2;
|
||||||
|
const uint INPUT_4 = 3;
|
||||||
|
|
||||||
|
const uint SWITCH_A = 0;
|
||||||
|
const uint SWITCH_B = 1;
|
||||||
|
|
||||||
|
|
||||||
|
// Count Constants
|
||||||
|
const uint NUM_GPIOS = 3;
|
||||||
|
const uint NUM_RELAYS = 3;
|
||||||
|
const uint NUM_OUTPUTS = 3;
|
||||||
|
const uint NUM_ADCS = 3;
|
||||||
|
const uint NUM_INPUTS = 4;
|
||||||
|
const uint NUM_SWITCHES = 2;
|
||||||
|
|
||||||
|
|
||||||
|
class Automation2040W {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
//--------------------------------------------------
|
||||||
|
public:
|
||||||
|
static const uint CONN_LED_PIN = 3;
|
||||||
|
static const uint I2C_SDA_PIN = 4;
|
||||||
|
static const uint I2C_SCL_PIN = 5;
|
||||||
|
static const uint ADC_LED_PINS[];
|
||||||
|
static const uint RELAY_PINS[];
|
||||||
|
static const uint USER_SW_PINS[];
|
||||||
|
static const uint USER_LED_PINS[];
|
||||||
|
static const uint OUTPUT_PINS[];
|
||||||
|
static const uint IN_BUFFERED_PINS[];
|
||||||
|
static const uint ADC_PINS[];
|
||||||
|
|
||||||
|
static constexpr float VOLTAGE_GAIN = 0.06f; // 56 / (56 + 820)
|
||||||
|
static constexpr float VOLTAGE_OFFSET = -0.06f;
|
||||||
|
static constexpr float MAX_ADC_LED_VOLTAGE = 45.0f;
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// Variables
|
||||||
|
//--------------------------------------------------
|
||||||
|
public:
|
||||||
|
I2C i2c;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Analog analogs[NUM_ADCS];
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// Constructors/Destructor
|
||||||
|
//--------------------------------------------------
|
||||||
|
public:
|
||||||
|
Automation2040W();
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
public:
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
void conn_led(bool on);
|
||||||
|
void conn_led(float brightness);
|
||||||
|
bool switch_pressed(uint sw);
|
||||||
|
void switch_led(uint sw, bool on);
|
||||||
|
void switch_led(uint sw, float brightness);
|
||||||
|
|
||||||
|
bool relay(uint relay);
|
||||||
|
void relay(uint relay, bool actuate);
|
||||||
|
void actuate_relay(uint relay);
|
||||||
|
void release_relay(uint relay);
|
||||||
|
|
||||||
|
bool output(uint output);
|
||||||
|
void output(uint output, bool value);
|
||||||
|
|
||||||
|
bool read_input(uint input);
|
||||||
|
float read_adc(uint adc);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Automation 2040 W Micropython Examples <!-- omit in toc -->
|
||||||
|
|
||||||
|
- [Function Examples](#function-examples)
|
||||||
|
- [Read ADCs](#read-adcs)
|
||||||
|
- [Read Inputs](#read-inputs)
|
||||||
|
- [Toggle Relays](#toggle-relays)
|
||||||
|
- [Toggle Outputs](#toggle-outputs)
|
||||||
|
- [Switches and LEDs](#switches-and-leds)
|
||||||
|
- [Reset Automation](#reset-automation)
|
||||||
|
|
||||||
|
|
||||||
|
## Function Examples
|
||||||
|
|
||||||
|
### Read ADCs
|
||||||
|
[read_adcs.py](read_adcs.py)
|
||||||
|
|
||||||
|
Shows how to read the 3 ADC terminals of Automation 2040 W.
|
||||||
|
|
||||||
|
|
||||||
|
### Read Inputs
|
||||||
|
[read_inputs.py](read_inputs.py)
|
||||||
|
|
||||||
|
Shows how to read the 3 Input terminals of Automation 2040 W.
|
||||||
|
|
||||||
|
|
||||||
|
### Toggle Relays
|
||||||
|
[toggle_relays.py](toggle_relays.py)
|
||||||
|
|
||||||
|
Demonstrates how to toggle the actuation state of each of Automation 2040 W's relays.
|
||||||
|
|
||||||
|
|
||||||
|
### Toggle Outputs
|
||||||
|
[toggle_outputs.py](toggle_outputs.py)
|
||||||
|
|
||||||
|
Demonstrates how to toggle each of Automation 2040 W's output terminals.
|
||||||
|
|
||||||
|
|
||||||
|
### Switches and LEDs
|
||||||
|
[switches_and_leds.py](switches_and_leds.py)
|
||||||
|
|
||||||
|
An example of the user switches and LEDs on Automation 2040 W.
|
||||||
|
|
||||||
|
|
||||||
|
### Reset Automation
|
||||||
|
[reset_automation.py](reset_automation.py)
|
||||||
|
|
||||||
|
A simple program that resets Automation 2040 W, turning off its Relays, Outputs, and LEDs.
|
|
@ -0,0 +1,33 @@
|
||||||
|
import time
|
||||||
|
from automation import Automation2040W, SWITCH_A, NUM_ADCS
|
||||||
|
|
||||||
|
"""
|
||||||
|
Shows how to read the 3 ADC terminals of Automation 2040 W.
|
||||||
|
|
||||||
|
Press "A" to exit the program.
|
||||||
|
"""
|
||||||
|
|
||||||
|
UPDATES = 10 # How many times to update per second
|
||||||
|
ADC_NAMES = ("A1", "A2", "A3") # The friendly names to give each ADC input
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Read the ADCs until the user switch is pressed
|
||||||
|
while not board.switch_pressed(SWITCH_A):
|
||||||
|
|
||||||
|
# Read each ADC in turn and print its voltage
|
||||||
|
for i in range(NUM_ADCS):
|
||||||
|
voltage = board.read_adc(i)
|
||||||
|
print(ADC_NAMES[i], " = ", round(voltage, 3), sep="", end=", ")
|
||||||
|
|
||||||
|
# Print a new line
|
||||||
|
print()
|
||||||
|
|
||||||
|
time.sleep(1.0 / UPDATES)
|
||||||
|
|
||||||
|
# Put the board back into a safe state
|
||||||
|
board.reset()
|
|
@ -0,0 +1,33 @@
|
||||||
|
import time
|
||||||
|
from automation import Automation2040W, SWITCH_A, NUM_INPUTS
|
||||||
|
|
||||||
|
"""
|
||||||
|
Shows how to read the 3 Input terminals of Automation 2040 W.
|
||||||
|
|
||||||
|
Press "A" to exit the program.
|
||||||
|
"""
|
||||||
|
|
||||||
|
UPDATES = 10 # How many times to update per second
|
||||||
|
INPUT_NAMES = ("I1", "I2", "I3", "I4") # The friendly names to give each digital input
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Read the inputs until the user switch is pressed
|
||||||
|
while not board.switch_pressed(SWITCH_A):
|
||||||
|
|
||||||
|
# Read each input in turn and print its value
|
||||||
|
for i in range(NUM_INPUTS):
|
||||||
|
value = board.read_input(i)
|
||||||
|
print(INPUT_NAMES[i], " = ", value, sep="", end=", ")
|
||||||
|
|
||||||
|
# Print a new line
|
||||||
|
print()
|
||||||
|
|
||||||
|
time.sleep(1.0 / UPDATES)
|
||||||
|
|
||||||
|
# Put the board back into a safe state
|
||||||
|
board.reset()
|
|
@ -0,0 +1,8 @@
|
||||||
|
from automation import Automation2040W
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple program that resets Automation 2040 W,
|
||||||
|
turning off its Relays, Outputs, and LEDs.
|
||||||
|
"""
|
||||||
|
|
||||||
|
board = Automation2040W()
|
|
@ -0,0 +1,43 @@
|
||||||
|
import time
|
||||||
|
from automation import Automation2040W, SWITCH_A, SWITCH_B, NUM_SWITCHES
|
||||||
|
|
||||||
|
"""
|
||||||
|
An example of the user switches and LEDs on Automation 2040 W.
|
||||||
|
|
||||||
|
Press "A" and "B" together to exit the program.
|
||||||
|
"""
|
||||||
|
|
||||||
|
UPDATES = 10 # How many times to update per second
|
||||||
|
SWITCH_NAMES = ("SW_A", "SW_B") # The friendly names to give each user switch
|
||||||
|
LED_INCREMENT = 2 # How much to change a LED's brightess each update
|
||||||
|
|
||||||
|
# Create a new Automation2040W
|
||||||
|
board = Automation2040W()
|
||||||
|
|
||||||
|
# Enable the Conn LED
|
||||||
|
board.conn_led(True) # Full Brightness
|
||||||
|
|
||||||
|
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):
|
||||||
|
# Change the LED brightness based on switch's state
|
||||||
|
if board.switch_pressed(i):
|
||||||
|
print(SWITCH_NAMES[i], " = Pressed", sep="", end=", ")
|
||||||
|
led_brightnesses[i] = min(led_brightnesses[i] + LED_INCREMENT, 100)
|
||||||
|
else:
|
||||||
|
print(SWITCH_NAMES[i], " = Released", sep="", end=", ")
|
||||||
|
led_brightnesses[i] = max(led_brightnesses[i] - LED_INCREMENT, 0)
|
||||||
|
|
||||||
|
# Apply the new brightnesses to the LEDs
|
||||||
|
board.switch_led(i, led_brightnesses[i])
|
||||||
|
|
||||||
|
# Print a new line
|
||||||
|
print()
|
||||||
|
|
||||||
|
time.sleep(1.0 / UPDATES)
|
||||||
|
|
||||||
|
# Put the board back into a safe state
|
||||||
|
board.reset()
|
|
@ -0,0 +1,43 @@
|
||||||
|
import time
|
||||||
|
from automation import Automation2040W, SWITCH_A, NUM_OUTPUTS
|
||||||
|
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
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=", ")
|
||||||
|
|
||||||
|
# Print a new line
|
||||||
|
print()
|
||||||
|
|
||||||
|
index += 1 # Move on to the next output
|
||||||
|
if index >= 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()
|
|
@ -0,0 +1,43 @@
|
||||||
|
import time
|
||||||
|
from automation import Automation2040W, SWITCH_A, NUM_RELAYS
|
||||||
|
|
||||||
|
"""
|
||||||
|
Demonstrates how to toggle the actuation state of each of Automation 2040 W's relays.
|
||||||
|
|
||||||
|
Press "A" to exit the program.
|
||||||
|
"""
|
||||||
|
|
||||||
|
TIME_PER_TOGGLE = 0.5 # How much time to wait between each toggle (in seconds)
|
||||||
|
RELAY_NAMES = ("R1", "R2", "R3") # The friendly names to give each relay
|
||||||
|
|
||||||
|
# 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 relays until the user switch is pressed
|
||||||
|
while not board.switch_pressed(SWITCH_A):
|
||||||
|
|
||||||
|
# Toggle a relay
|
||||||
|
board.relay(index, toggle)
|
||||||
|
|
||||||
|
# Print the state of all relays
|
||||||
|
for i in range(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:
|
||||||
|
index = 0 # Go back to the first relay
|
||||||
|
toggle = not toggle # Invert the toggle value
|
||||||
|
|
||||||
|
time.sleep(TIME_PER_TOGGLE)
|
||||||
|
|
||||||
|
# Put the board back into a safe state
|
||||||
|
board.reset()
|
|
@ -0,0 +1,199 @@
|
||||||
|
import gc
|
||||||
|
from machine import Pin, PWM
|
||||||
|
from pimoroni_i2c import PimoroniI2C
|
||||||
|
from pimoroni import Analog
|
||||||
|
|
||||||
|
# IO Pin Constants
|
||||||
|
GP0 = 0
|
||||||
|
GP1 = 1
|
||||||
|
GP2 = 2
|
||||||
|
|
||||||
|
# Index Constants
|
||||||
|
RELAY_1 = 0
|
||||||
|
RELAY_2 = 1
|
||||||
|
RELAY_3 = 2
|
||||||
|
|
||||||
|
OUTPUT_1 = 0
|
||||||
|
OUTPUT_2 = 1
|
||||||
|
OUTPUT_3 = 2
|
||||||
|
|
||||||
|
ADC_1 = 0
|
||||||
|
ADC_2 = 1
|
||||||
|
ADC_3 = 2
|
||||||
|
|
||||||
|
INPUT_1 = 0
|
||||||
|
INPUT_2 = 1
|
||||||
|
INPUT_3 = 2
|
||||||
|
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
|
||||||
|
I2C_SDA_PIN = 4
|
||||||
|
I2C_SCL_PIN = 5
|
||||||
|
ADC_LED_PINS = (6, 7, 8)
|
||||||
|
RELAY_PINS = (9, 10, 11)
|
||||||
|
USER_SW_PINS = (12, 13)
|
||||||
|
USER_LED_PINS = (14, 15)
|
||||||
|
OUTPUT_PINS = (16, 17, 18)
|
||||||
|
IN_BUFFERED_PINS = (19, 20, 21, 22)
|
||||||
|
ADC_PINS = (26, 27, 28)
|
||||||
|
|
||||||
|
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.__relays = []
|
||||||
|
for i in range(NUM_RELAYS):
|
||||||
|
self.__relays.append(Pin(self.RELAY_PINS[i], Pin.OUT))
|
||||||
|
self.release_relay(i)
|
||||||
|
|
||||||
|
# Set up the output pins
|
||||||
|
self.__outputs = []
|
||||||
|
for i in range(NUM_OUTPUTS):
|
||||||
|
self.__outputs.append(Pin(self.OUTPUT_PINS[i], Pin.OUT))
|
||||||
|
self.output(i, False)
|
||||||
|
|
||||||
|
# Set up the input pins
|
||||||
|
self.__inputs = []
|
||||||
|
for i in range(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):
|
||||||
|
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(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 > 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:
|
||||||
|
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, relay, actuate=None):
|
||||||
|
if relay < 0 or relay > NUM_RELAYS:
|
||||||
|
raise ValueError("relay out of range. Expected RELAY_1 (0), RELAY_2 (1), or RELAY_3 (2)")
|
||||||
|
|
||||||
|
if actuate is None:
|
||||||
|
return self.__relays[relay].value()
|
||||||
|
|
||||||
|
self.__relays[relay].value(actuate)
|
||||||
|
|
||||||
|
def actuate_relay(self, relay):
|
||||||
|
if relay < 0 or relay > 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:
|
||||||
|
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:
|
||||||
|
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()
|
||||||
|
|
||||||
|
self.__outputs[output].value(value)
|
||||||
|
|
||||||
|
def read_input(self, input):
|
||||||
|
if input < 0 or input > 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:
|
||||||
|
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 relays
|
||||||
|
for i in range(NUM_RELAYS):
|
||||||
|
self.release_relay(i)
|
||||||
|
|
||||||
|
# Reset the outputs
|
||||||
|
for i in range(NUM_OUTPUTS):
|
||||||
|
self.output(i, False)
|
||||||
|
|
||||||
|
# Reset the adc LEDs
|
||||||
|
for i in range(NUM_ADCS):
|
||||||
|
self.__adc_led_pwms[i].duty_u16(0)
|
||||||
|
|
||||||
|
# Reset the switch LEDs
|
||||||
|
for i in range(NUM_SWITCHES):
|
||||||
|
self.__switch_led_pwms[i].duty_u16(0)
|
||||||
|
|
||||||
|
# Reset the connectivity LED
|
||||||
|
self.__conn_led_pwm.duty_u16(0)
|
Ładowanie…
Reference in New Issue