kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Initial support for Encoder wheel breakout
rodzic
56dba370c6
commit
59d57a193b
|
@ -2,6 +2,7 @@ add_subdirectory(hershey_fonts)
|
|||
add_subdirectory(bitmap_fonts)
|
||||
add_subdirectory(breakout_dotmatrix)
|
||||
add_subdirectory(breakout_encoder)
|
||||
add_subdirectory(breakout_encoder_wheel)
|
||||
add_subdirectory(breakout_ioexpander)
|
||||
add_subdirectory(breakout_ltr559)
|
||||
add_subdirectory(breakout_rgbmatrix5x5)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
include(breakout_encoder_wheel.cmake)
|
|
@ -0,0 +1,11 @@
|
|||
set(LIB_NAME breakout_encoder_wheel)
|
||||
add_library(${LIB_NAME} INTERFACE)
|
||||
|
||||
target_sources(${LIB_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib ioexpander is31fl3731)
|
|
@ -0,0 +1,89 @@
|
|||
#include "breakout_encoder_wheel.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
bool BreakoutEncoderWheel::init(bool skip_chip_id_check) {
|
||||
bool success = false;
|
||||
if(ioe.init(skip_chip_id_check)) {
|
||||
|
||||
if(interrupt_pin != PIN_UNUSED) {
|
||||
ioe.enable_interrupt_out(true);
|
||||
}
|
||||
|
||||
ioe.setup_rotary_encoder(ENC_CHANNEL, ENC_TERM_A, ENC_TERM_B);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
i2c_inst_t* BreakoutEncoderWheel::get_i2c() const {
|
||||
return ioe.get_i2c();
|
||||
}
|
||||
|
||||
int BreakoutEncoderWheel::get_ioe_address() const {
|
||||
return ioe.get_address();
|
||||
}
|
||||
|
||||
int BreakoutEncoderWheel::get_led_address() const {
|
||||
return led_ring.get_address();
|
||||
}
|
||||
|
||||
int BreakoutEncoderWheel::get_sda() const {
|
||||
return ioe.get_sda();
|
||||
}
|
||||
|
||||
int BreakoutEncoderWheel::get_scl() const {
|
||||
return ioe.get_scl();
|
||||
}
|
||||
|
||||
int BreakoutEncoderWheel::get_int() const {
|
||||
return ioe.get_int();
|
||||
}
|
||||
|
||||
void BreakoutEncoderWheel::set_ioe_address(uint8_t address) {
|
||||
ioe.set_address(address);
|
||||
}
|
||||
|
||||
bool BreakoutEncoderWheel::get_interrupt_flag() {
|
||||
return ioe.get_interrupt_flag();
|
||||
}
|
||||
|
||||
void BreakoutEncoderWheel::clear_interrupt_flag() {
|
||||
ioe.clear_interrupt_flag();
|
||||
}
|
||||
|
||||
BreakoutEncoderWheel::Direction BreakoutEncoderWheel::get_encoder_direction() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
void BreakoutEncoderWheel::set_encoder_direction(Direction direction) {
|
||||
this->direction = direction;
|
||||
}
|
||||
|
||||
void BreakoutEncoderWheel::set_pixel(uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
|
||||
RGBLookup rgb = lookup_table[index];
|
||||
led_ring.set(rgb.r, r);
|
||||
led_ring.set(rgb.g, g);
|
||||
led_ring.set(rgb.b, b);
|
||||
}
|
||||
|
||||
bool BreakoutEncoderWheel::wheel_available() {
|
||||
return (ioe.get_interrupt_flag() > 0);
|
||||
}
|
||||
|
||||
int16_t BreakoutEncoderWheel::read_wheel() {
|
||||
int16_t count = ioe.read_rotary_encoder(ENC_CHANNEL);
|
||||
if(direction != DIRECTION_CW)
|
||||
count = 0 - count;
|
||||
|
||||
ioe.clear_interrupt_flag();
|
||||
return count;
|
||||
}
|
||||
|
||||
void BreakoutEncoderWheel::clear_wheel() {
|
||||
ioe.clear_rotary_encoder(ENC_CHANNEL);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
#pragma once
|
||||
|
||||
#include "drivers/ioexpander/ioexpander.hpp"
|
||||
#include "drivers/is31fl3731/is31fl3731.hpp"
|
||||
#include "common/pimoroni_common.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
class BreakoutEncoderWheel {
|
||||
struct RGBLookup {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
//--------------------------------------------------
|
||||
// Enums
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
enum Direction : bool {
|
||||
DIRECTION_CW = true,
|
||||
DIRECTION_CCW = false
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Constants
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
static const uint8_t DEFAULT_IOE_I2C_ADDRESS = 0x13;
|
||||
static const uint8_t DEFAULT_LED_I2C_ADDRESS = 0x77;
|
||||
static const uint8_t LED_I2C_ADDRESS_ALTERNATE = 0x74;
|
||||
|
||||
static const Direction DEFAULT_DIRECTION = DIRECTION_CW;
|
||||
static const uint32_t DEFAULT_TIMEOUT = 1;
|
||||
|
||||
private:
|
||||
static const uint8_t SWITCH_CENTRE = 1;
|
||||
static const uint8_t SWITCH_UP = 13;
|
||||
static const uint8_t SWITCH_LEFT = 11;
|
||||
static const uint8_t SWITCH_DOWN = 4;
|
||||
static const uint8_t SWITCH_RIGHT = 2;
|
||||
|
||||
static const uint8_t ENC_TERM_A = 12;
|
||||
static const uint8_t ENC_TERM_B = 3;
|
||||
|
||||
static const uint8_t ENC_CHANNEL = 1;
|
||||
|
||||
// This wonderful lookup table maps the LEDs on the encoder wheel
|
||||
// from their 3x24 (remember, they're RGB) configuration to
|
||||
// their specific location in the 144 pixel buffer.
|
||||
static constexpr RGBLookup lookup_table[24] = {
|
||||
{128, 32, 48},
|
||||
{129, 33, 49},
|
||||
{130, 17, 50},
|
||||
{131, 18, 34},
|
||||
{132, 19, 35},
|
||||
{133, 20, 36},
|
||||
{134, 21, 37},
|
||||
{112, 80, 96},
|
||||
{113, 81, 97},
|
||||
{114, 82, 98},
|
||||
{115, 83, 99},
|
||||
{116, 84, 100},
|
||||
{117, 68, 101},
|
||||
{118, 69, 85},
|
||||
{127, 47, 63},
|
||||
{121, 41, 57},
|
||||
{122, 25, 58},
|
||||
{123, 26, 42},
|
||||
{124, 27, 43},
|
||||
{125, 28, 44},
|
||||
{126, 29, 45},
|
||||
{15, 95, 111},
|
||||
{8, 89, 105},
|
||||
{9, 90, 106},
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
IOExpander ioe;
|
||||
IS31FL3731 led_ring;
|
||||
Direction direction = DEFAULT_DIRECTION;
|
||||
uint interrupt_pin = PIN_UNUSED; // A local copy of the value passed to the IOExpander, used in initialisation
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Constructors/Destructor
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
BreakoutEncoderWheel(uint8_t ioe_address = DEFAULT_IOE_I2C_ADDRESS, uint8_t led_address = DEFAULT_LED_I2C_ADDRESS)
|
||||
: BreakoutEncoderWheel(new I2C(), ioe_address, led_address) {}
|
||||
|
||||
BreakoutEncoderWheel(I2C *i2c, uint8_t ioe_address = DEFAULT_IOE_I2C_ADDRESS, uint8_t led_address = DEFAULT_LED_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT, bool debug = false)
|
||||
: ioe(i2c, ioe_address, interrupt, timeout, debug), led_ring(i2c, led_address) {}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Methods
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
bool init(bool skip_chip_id_check = false);
|
||||
|
||||
// For print access in micropython
|
||||
i2c_inst_t* get_i2c() const;
|
||||
int get_ioe_address() const;
|
||||
int get_led_address() const;
|
||||
int get_sda() const;
|
||||
int get_scl() const;
|
||||
int get_int() const;
|
||||
|
||||
// Calls through to IOExpander class
|
||||
void set_ioe_address(uint8_t address);
|
||||
bool get_interrupt_flag();
|
||||
void clear_interrupt_flag();
|
||||
|
||||
// Encoder breakout specific
|
||||
Direction get_encoder_direction();
|
||||
void set_encoder_direction(Direction direction);
|
||||
|
||||
void set_pixel(uint8_t index, uint8_t r, uint8_t g, uint8_t b);
|
||||
//void update(uint8_t frame = 0);
|
||||
//void clear();
|
||||
|
||||
bool wheel_available();
|
||||
int16_t read_wheel();
|
||||
void clear_wheel();
|
||||
bool read_switch();
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
import time
|
||||
from pimoroni_i2c import PimoroniI2C
|
||||
from breakout_ioexpander import BreakoutIOExpander
|
||||
from adafruit_is31fl3731 import IS31FL3731
|
||||
import sys
|
||||
|
||||
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
|
||||
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}
|
||||
|
||||
s1_pin = 1
|
||||
s2_pin = 13
|
||||
s3_pin = 11
|
||||
s4_pin = 4
|
||||
s5_pin = 2
|
||||
|
||||
ENC_TERM_A = 3
|
||||
ENC_TERM_B = 12
|
||||
|
||||
ENC_CHANNEL = 1
|
||||
|
||||
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
|
||||
ioe = BreakoutIOExpander(i2c, address=0x18)
|
||||
|
||||
ioe.set_mode(s1_pin, BreakoutIOExpander.PIN_IN_PU)
|
||||
ioe.set_mode(s2_pin, BreakoutIOExpander.PIN_IN_PU)
|
||||
ioe.set_mode(s3_pin, BreakoutIOExpander.PIN_IN_PU)
|
||||
ioe.set_mode(s4_pin, BreakoutIOExpander.PIN_IN_PU)
|
||||
ioe.set_mode(s5_pin, BreakoutIOExpander.PIN_IN_PU)
|
||||
|
||||
ioe.setup_rotary_encoder(ENC_CHANNEL, ENC_TERM_A, ENC_TERM_B, 6, count_microsteps=True)
|
||||
#ioe.set_mode(ENC_TERM_A, BreakoutIOExpander.PIN_IN_PU)
|
||||
#ioe.set_mode(ENC_TERM_B, BreakoutIOExpander.PIN_IN_PU)
|
||||
|
||||
display = IS31FL3731(i2c, address=0x77)
|
||||
#display.fill(10)
|
||||
|
||||
mapping = ((128, 32, 48),
|
||||
(129, 33, 49),
|
||||
(130, 17, 50),
|
||||
(131, 18, 34),
|
||||
(132, 19, 35),
|
||||
(133, 20, 36),
|
||||
(134, 21, 37),
|
||||
(112, 80, 96),
|
||||
(113, 81, 97),
|
||||
(114, 82, 98),
|
||||
(115, 83, 99),
|
||||
(116, 84, 100),
|
||||
(117, 68, 101),
|
||||
(118, 69, 85),
|
||||
(127, 47, 63),
|
||||
(121, 41, 57),
|
||||
(122, 25, 58),
|
||||
(123, 26, 42),
|
||||
(124, 27, 43),
|
||||
(125, 28, 44),
|
||||
(126, 29, 45),
|
||||
(15, 95, 111),
|
||||
(8, 89, 105),
|
||||
(9, 90, 106))
|
||||
|
||||
|
||||
def hsv_to_rgb(h, s, v):
|
||||
if s == 0.0:
|
||||
return v, v, v
|
||||
i = int(h * 6.0)
|
||||
f = (h * 6.0) - i
|
||||
p = v * (1.0 - s)
|
||||
q = v * (1.0 - s * f)
|
||||
t = v * (1.0 - s * (1.0 - f))
|
||||
i = i % 6
|
||||
if i == 0:
|
||||
return v, t, p
|
||||
if i == 1:
|
||||
return q, v, p
|
||||
if i == 2:
|
||||
return p, v, t
|
||||
if i == 3:
|
||||
return p, q, v
|
||||
if i == 4:
|
||||
return t, p, v
|
||||
if i == 5:
|
||||
return v, p, q
|
||||
|
||||
'''
|
||||
while True:
|
||||
for x in range(0, 24):
|
||||
single = mapping[x]
|
||||
display.pixel(single[0], 0, 255)
|
||||
display.pixel(single[1], 0, 255)
|
||||
display.pixel(single[2], 0, 255)
|
||||
print(x)
|
||||
time.sleep(0.05)
|
||||
display.pixel(single[0], 0, 0)
|
||||
display.pixel(single[1], 0, 0)
|
||||
display.pixel(single[2], 0, 0)
|
||||
'''
|
||||
|
||||
last_s1 = True
|
||||
last_s2 = True
|
||||
last_s3 = True
|
||||
last_s4 = True
|
||||
last_s5 = True
|
||||
last_count = -1
|
||||
|
||||
last_enc_a = False
|
||||
last_enc_b = False
|
||||
|
||||
|
||||
while True:
|
||||
s1 = bool(ioe.input(s1_pin))
|
||||
s2 = bool(ioe.input(s2_pin))
|
||||
s3 = bool(ioe.input(s3_pin))
|
||||
s4 = bool(ioe.input(s4_pin))
|
||||
s5 = bool(ioe.input(s5_pin))
|
||||
if s1 is not last_s1:
|
||||
if s1:
|
||||
print("Centre (S1) has been released")
|
||||
else:
|
||||
print("Centre (S1) has been pressed")
|
||||
last_s1 = s1
|
||||
|
||||
if s2 is not last_s2:
|
||||
if s2:
|
||||
print("Up (S2) has been released")
|
||||
else:
|
||||
print("Up (S2) has been pressed")
|
||||
last_s2 = s2
|
||||
|
||||
if s3 is not last_s3:
|
||||
if s3:
|
||||
print("Left (S3) has been released")
|
||||
else:
|
||||
print("Left (S3) has been pressed")
|
||||
last_s3 = s3
|
||||
|
||||
if s4 is not last_s4:
|
||||
if s4:
|
||||
print("Down (S4) has been released")
|
||||
else:
|
||||
print("Down (S4) has been pressed")
|
||||
last_s4 = s4
|
||||
|
||||
if s5 is not last_s5:
|
||||
if s5:
|
||||
print("Right (S5) has been released")
|
||||
else:
|
||||
print("Right (S5) has been pressed")
|
||||
last_s5 = s5
|
||||
|
||||
count = ioe.read_rotary_encoder(ENC_CHANNEL) // 2
|
||||
if count != last_count:
|
||||
if count - last_count > 0:
|
||||
print("Clockwise, Count = ", count)
|
||||
else:
|
||||
print("Counter Clockwise, Count = ", count)
|
||||
|
||||
last_single = mapping[last_count % 24]
|
||||
display.pixel(last_single[0], 0, 0)
|
||||
display.pixel(last_single[1], 0, 0)
|
||||
display.pixel(last_single[2], 0, 0)
|
||||
single = mapping[count % 24]
|
||||
r, g, b = hsv_to_rgb(count / 24, 1.0, 1.0)
|
||||
display.pixel(single[0], 0, int(255 * r))
|
||||
display.pixel(single[1], 0, int(255 * g))
|
||||
display.pixel(single[2], 0, int(255 * b))
|
||||
last_count = count
|
||||
|
||||
'''
|
||||
enc_a = bool(ioe.input(ENC_TERM_A))
|
||||
enc_b = bool(ioe.input(ENC_TERM_B))
|
||||
|
||||
if enc_a is not last_enc_a:
|
||||
if enc_a:
|
||||
print("ENC A high")
|
||||
else:
|
||||
print("ENC A low")
|
||||
last_enc_a = enc_a
|
||||
|
||||
if enc_b is not last_enc_b:
|
||||
if enc_b:
|
||||
print("ENC B high")
|
||||
else:
|
||||
print("ENC B low")
|
||||
last_enc_b = enc_b
|
||||
'''
|
||||
|
||||
time.sleep(0.005)
|
|
@ -0,0 +1,69 @@
|
|||
#include "breakout_encoder_wheel.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// BreakoutEncoderWheel Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***** Methods *****/
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutEncoderWheel_set_address_obj, 2, BreakoutEncoderWheel_set_address);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_get_interrupt_flag_obj, BreakoutEncoderWheel_get_interrupt_flag);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_clear_interrupt_flag_obj, BreakoutEncoderWheel_clear_interrupt_flag);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_get_direction_obj, BreakoutEncoderWheel_get_direction);
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutEncoderWheel_set_direction_obj, 2, BreakoutEncoderWheel_set_direction);
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutEncoderWheel_set_brightness_obj, 2, BreakoutEncoderWheel_set_brightness);
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutEncoderWheel_set_led_obj, 4, BreakoutEncoderWheel_set_led);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_available_obj, BreakoutEncoderWheel_available);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_read_obj, BreakoutEncoderWheel_read);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_clear_obj, BreakoutEncoderWheel_clear);
|
||||
|
||||
/***** Binding of Methods *****/
|
||||
STATIC const mp_rom_map_elem_t BreakoutEncoderWheel_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_address), MP_ROM_PTR(&BreakoutEncoderWheel_set_address_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_interrupt_flag), MP_ROM_PTR(&BreakoutEncoderWheel_get_interrupt_flag_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_clear_interrupt_flag), MP_ROM_PTR(&BreakoutEncoderWheel_clear_interrupt_flag_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_direction), MP_ROM_PTR(&BreakoutEncoderWheel_get_direction_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_direction), MP_ROM_PTR(&BreakoutEncoderWheel_set_direction_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_brightness), MP_ROM_PTR(&BreakoutEncoderWheel_set_brightness_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_led), MP_ROM_PTR(&BreakoutEncoderWheel_set_led_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_available), MP_ROM_PTR(&BreakoutEncoderWheel_available_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&BreakoutEncoderWheel_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&BreakoutEncoderWheel_clear_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DIRECTION_CW), MP_ROM_INT(1) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DIRECTION_CCW), MP_ROM_INT(0) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(BreakoutEncoderWheel_locals_dict, BreakoutEncoderWheel_locals_dict_table);
|
||||
|
||||
/***** Class Definition *****/
|
||||
const mp_obj_type_t breakout_encoder_wheel_BreakoutEncoderWheel_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_BreakoutEncoderWheel,
|
||||
.make_new = BreakoutEncoderWheel_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&BreakoutEncoderWheel_locals_dict,
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// breakout_encoder_wheel Module
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***** Globals Table *****/
|
||||
STATIC const mp_map_elem_t breakout_encoder_wheel_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_breakout_encoder_wheel) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_BreakoutEncoderWheel), (mp_obj_t)&breakout_encoder_wheel_BreakoutEncoderWheel_type },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_breakout_encoder_wheel_globals, breakout_encoder_wheel_globals_table);
|
||||
|
||||
/***** Module Definition *****/
|
||||
const mp_obj_module_t breakout_encoder_wheel_user_cmodule = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&mp_module_breakout_encoder_wheel_globals,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if MICROPY_VERSION <= 70144
|
||||
MP_REGISTER_MODULE(MP_QSTR_breakout_encoder_wheel, breakout_encoder_wheel_user_cmodule, MODULE_BREAKOUT_ENCODER_ENABLED);
|
||||
#else
|
||||
MP_REGISTER_MODULE(MP_QSTR_breakout_encoder_wheel, breakout_encoder_wheel_user_cmodule);
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
@ -0,0 +1,168 @@
|
|||
#include "libraries/breakout_encoder_wheel/breakout_encoder_wheel.hpp"
|
||||
#include "micropython/modules/util.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
extern "C" {
|
||||
#include "breakout_encoder_wheel.h"
|
||||
#include "pimoroni_i2c.h"
|
||||
|
||||
/***** Variables Struct *****/
|
||||
typedef struct _breakout_encoder_wheel_BreakoutEncoderWheel_obj_t {
|
||||
mp_obj_base_t base;
|
||||
BreakoutEncoderWheel *breakout;
|
||||
_PimoroniI2C_obj_t *i2c;
|
||||
} breakout_encoder_wheel_BreakoutEncoderWheel_obj_t;
|
||||
|
||||
|
||||
/***** Constructor *****/
|
||||
mp_obj_t BreakoutEncoderWheel_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = nullptr;
|
||||
|
||||
enum { ARG_i2c, ARG_address, ARG_interrupt };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} },
|
||||
{ MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutEncoderWheel::DEFAULT_I2C_ADDRESS} },
|
||||
{ MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} },
|
||||
};
|
||||
|
||||
// Parse args.
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
self = m_new_obj(breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
self->base.type = &breakout_encoder_wheel_BreakoutEncoderWheel_type;
|
||||
|
||||
self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj);
|
||||
|
||||
self->breakout = m_new_class(BreakoutEncoderWheel, (pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int, args[ARG_interrupt].u_int);
|
||||
|
||||
if(!self->breakout->init()) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, "BreakoutEncoderWheel: breakout not found when initialising");
|
||||
}
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
/***** Methods *****/
|
||||
mp_obj_t BreakoutEncoderWheel_set_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_self, ARG_address };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
|
||||
self->breakout->set_address(args[ARG_address].u_int);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_get_interrupt_flag(mp_obj_t self_in) {
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
return mp_obj_new_bool(self->breakout->get_interrupt_flag());
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_clear_interrupt_flag(mp_obj_t self_in) {
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
self->breakout->clear_interrupt_flag();
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_get_direction(mp_obj_t self_in) {
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
return mp_obj_new_bool(self->breakout->get_direction());
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_set_direction(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_self, ARG_clockwise };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_clockwise, MP_ARG_REQUIRED | MP_ARG_BOOL },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
|
||||
self->breakout->set_direction(args[ARG_clockwise].u_bool ? BreakoutEncoderWheel::DIRECTION_CW : BreakoutEncoderWheel::DIRECTION_CCW);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_set_brightness(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_self, ARG_brightness };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_brightness, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
|
||||
float brightness = mp_obj_get_float(args[ARG_brightness].u_obj);
|
||||
if(brightness < 0 || brightness > 1.0f)
|
||||
mp_raise_ValueError("brightness out of range. Expected 0.0 to 1.0");
|
||||
else
|
||||
self->breakout->set_brightness(brightness);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_set_led(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_self, ARG_r, ARG_g, ARG_b, ARG_w };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_r, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_g, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_b, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
|
||||
int r = args[ARG_r].u_int;
|
||||
int g = args[ARG_g].u_int;
|
||||
int b = args[ARG_b].u_int;
|
||||
|
||||
if(r < 0 || r > 255)
|
||||
mp_raise_ValueError("r out of range. Expected 0 to 255");
|
||||
else if(g < 0 || g > 255)
|
||||
mp_raise_ValueError("g out of range. Expected 0 to 255");
|
||||
else if(b < 0 || b > 255)
|
||||
mp_raise_ValueError("b out of range. Expected 0 to 255");
|
||||
else
|
||||
self->breakout->set_led(r, g, b);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_available(mp_obj_t self_in) {
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
return mp_obj_new_bool(self->breakout->available());
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_read(mp_obj_t self_in) {
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
return mp_obj_new_int(self->breakout->read());
|
||||
}
|
||||
|
||||
mp_obj_t BreakoutEncoderWheel_clear(mp_obj_t self_in) {
|
||||
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
|
||||
self->breakout->clear();
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// Include MicroPython API.
|
||||
#include "py/runtime.h"
|
||||
|
||||
/***** Extern of Class Definition *****/
|
||||
extern const mp_obj_type_t breakout_encoder_wheel_BreakoutEncoderWheel_type;
|
||||
|
||||
/***** Extern of Class Methods *****/
|
||||
extern mp_obj_t BreakoutEncoderWheel_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
|
||||
extern mp_obj_t BreakoutEncoderWheel_set_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
extern mp_obj_t BreakoutEncoderWheel_get_interrupt_flag(mp_obj_t self_in);
|
||||
extern mp_obj_t BreakoutEncoderWheel_clear_interrupt_flag(mp_obj_t self_in);
|
||||
extern mp_obj_t BreakoutEncoderWheel_get_direction(mp_obj_t self_in);
|
||||
extern mp_obj_t BreakoutEncoderWheel_set_direction(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
extern mp_obj_t BreakoutEncoderWheel_set_brightness(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
extern mp_obj_t BreakoutEncoderWheel_set_led(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
extern mp_obj_t BreakoutEncoderWheel_available(mp_obj_t self_in);
|
||||
extern mp_obj_t BreakoutEncoderWheel_read(mp_obj_t self_in);
|
||||
extern mp_obj_t BreakoutEncoderWheel_clear(mp_obj_t self_in);
|
|
@ -0,0 +1,21 @@
|
|||
set(MOD_NAME breakout_encoder_wheel)
|
||||
string(TOUPPER ${MOD_NAME} MOD_NAME_UPPER)
|
||||
add_library(usermod_${MOD_NAME} INTERFACE)
|
||||
|
||||
target_sources(usermod_${MOD_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../libraries/${MOD_NAME}/${MOD_NAME}.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/ioexpander/ioexpander.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/is31fl3731/is31fl3731.cpp
|
||||
)
|
||||
|
||||
target_include_directories(usermod_${MOD_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(usermod_${MOD_NAME} INTERFACE
|
||||
-DMODULE_${MOD_NAME_UPPER}_ENABLED=1
|
||||
)
|
||||
|
||||
target_link_libraries(usermod INTERFACE usermod_${MOD_NAME})
|
|
@ -1,5 +1,6 @@
|
|||
include(breakout_dotmatrix/micropython)
|
||||
include(breakout_encoder/micropython)
|
||||
include(breakout_encoder_wheel/micropython)
|
||||
include(breakout_ioexpander/micropython)
|
||||
include(breakout_ltr559/micropython)
|
||||
include(breakout_as7262/micropython)
|
||||
|
|
Ładowanie…
Reference in New Issue