Added the rotary switch driver to the esp32 version
This commit is contained in:
parent
8fbbcd6f3d
commit
82b4c81484
|
@ -38,7 +38,7 @@ typedef struct {
|
|||
int last_recent_event_was_release : 1;
|
||||
int timer_running : 1;
|
||||
int possible_dbl_click : 1;
|
||||
uint8_t id;
|
||||
struct rotary_driver_handle *handle;
|
||||
int click_delay_us;
|
||||
int longpress_delay_us;
|
||||
uint32_t last_event_time;
|
||||
|
@ -46,7 +46,6 @@ typedef struct {
|
|||
esp_timer_handle_t timer_handle;
|
||||
} DATA;
|
||||
|
||||
static DATA *data[ROTARY_CHANNEL_COUNT];
|
||||
static task_handle_t tasknumber;
|
||||
static void lrotary_timer_done(void *param);
|
||||
static void lrotary_check_timer(DATA *d, uint32_t time_us, bool dotimer);
|
||||
|
@ -59,10 +58,8 @@ static void callback_free_one(lua_State *L, int *cb_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
static void callback_free(lua_State* L, unsigned int id, int mask)
|
||||
static void callback_free(lua_State* L, DATA *d, int mask)
|
||||
{
|
||||
DATA *d = data[id];
|
||||
|
||||
if (d) {
|
||||
int i;
|
||||
for (i = 0; i < CALLBACK_COUNT; i++) {
|
||||
|
@ -85,9 +82,8 @@ static int callback_setOne(lua_State* L, int *cb_ptr, int arg_number)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int callback_set(lua_State* L, int id, int mask, int arg_number)
|
||||
static int callback_set(lua_State* L, DATA *d, int mask, int arg_number)
|
||||
{
|
||||
DATA *d = data[id];
|
||||
int result = 0;
|
||||
|
||||
int i;
|
||||
|
@ -120,35 +116,16 @@ static void callback_call(lua_State* L, DATA *d, int cbnum, int arg, uint32_t ti
|
|||
}
|
||||
}
|
||||
|
||||
int platform_rotary_exists( unsigned int id )
|
||||
{
|
||||
return (id < ROTARY_CHANNEL_COUNT);
|
||||
}
|
||||
|
||||
// Lua: setup(id, phase_a, phase_b [, press])
|
||||
// Lua: setup(phase_a, phase_b [, press])
|
||||
static int lrotary_setup( lua_State* L )
|
||||
{
|
||||
unsigned int id;
|
||||
int nargs = lua_gettop(L);
|
||||
|
||||
id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( rotary, id );
|
||||
|
||||
if (rotary_close(id)) {
|
||||
return luaL_error( L, "Unable to close switch." );
|
||||
}
|
||||
callback_free(L, id, ROTARY_ALL);
|
||||
|
||||
if (!data[id]) {
|
||||
data[id] = (DATA *) calloc(1, sizeof(DATA));
|
||||
if (!data[id]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
DATA *d = data[id];
|
||||
DATA *d = (DATA *)lua_newuserdata(L, sizeof(DATA));
|
||||
if (!d) return luaL_error(L, "not enough memory");
|
||||
memset(d, 0, sizeof(*d));
|
||||
|
||||
d->id = id;
|
||||
luaL_getmetatable(L, "rotary.switch");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = lrotary_timer_done,
|
||||
|
@ -167,90 +144,83 @@ static int lrotary_setup( lua_State* L )
|
|||
d->click_delay_us = CLICK_DELAY_US;
|
||||
d->longpress_delay_us = LONGPRESS_DELAY_US;
|
||||
|
||||
int phase_a = luaL_checkinteger(L, 2);
|
||||
luaL_argcheck(L, platform_gpio_exists(phase_a) && phase_a > 0, 2, "Invalid pin");
|
||||
int phase_b = luaL_checkinteger(L, 3);
|
||||
luaL_argcheck(L, platform_gpio_exists(phase_b) && phase_b > 0, 3, "Invalid pin");
|
||||
int phase_a = luaL_checkinteger(L, 1);
|
||||
luaL_argcheck(L, platform_gpio_exists(phase_a) && phase_a > 0, 1, "Invalid pin");
|
||||
int phase_b = luaL_checkinteger(L, 2);
|
||||
luaL_argcheck(L, platform_gpio_exists(phase_b) && phase_b > 0, 2, "Invalid pin");
|
||||
int press;
|
||||
if (lua_gettop(L) >= 4) {
|
||||
press = luaL_checkinteger(L, 4);
|
||||
luaL_argcheck(L, platform_gpio_exists(press) && press > 0, 4, "Invalid pin");
|
||||
if (nargs >= 3) {
|
||||
press = luaL_checkinteger(L, 3);
|
||||
luaL_argcheck(L, platform_gpio_exists(press) && press > 0, 3, "Invalid pin");
|
||||
} else {
|
||||
press = -1;
|
||||
}
|
||||
|
||||
if (lua_gettop(L) >= 5) {
|
||||
d->longpress_delay_us = 1000 * luaL_checkinteger(L, 5);
|
||||
luaL_argcheck(L, d->longpress_delay_us > 0, 5, "Invalid timeout");
|
||||
if (nargs >= 4) {
|
||||
d->longpress_delay_us = 1000 * luaL_checkinteger(L, 4);
|
||||
luaL_argcheck(L, d->longpress_delay_us > 0, 4, "Invalid timeout");
|
||||
}
|
||||
|
||||
if (lua_gettop(L) >= 6) {
|
||||
d->click_delay_us = 1000 * luaL_checkinteger(L, 6);
|
||||
luaL_argcheck(L, d->click_delay_us > 0, 6, "Invalid timeout");
|
||||
if (nargs >= 5) {
|
||||
d->click_delay_us = 1000 * luaL_checkinteger(L, 5);
|
||||
luaL_argcheck(L, d->click_delay_us > 0, 5, "Invalid timeout");
|
||||
}
|
||||
|
||||
if (rotary_setup(id, phase_a, phase_b, press, tasknumber)) {
|
||||
d->handle = rotary_setup(phase_a, phase_b, press, tasknumber, d);
|
||||
if (!d->handle) {
|
||||
return luaL_error(L, "Unable to setup rotary switch.");
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: close( id )
|
||||
// Lua: close( )
|
||||
static int lrotary_close( lua_State* L )
|
||||
{
|
||||
unsigned int id;
|
||||
DATA *d = (DATA *)luaL_checkudata(L, 1, "rotary.switch");
|
||||
|
||||
id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( rotary, id );
|
||||
callback_free(L, id, ROTARY_ALL);
|
||||
if (d->handle) {
|
||||
callback_free(L, d, ROTARY_ALL);
|
||||
|
||||
DATA *d = data[id];
|
||||
if (d) {
|
||||
data[id] = NULL;
|
||||
free(d);
|
||||
if (rotary_close( d->handle )) {
|
||||
return luaL_error( L, "Unable to close switch." );
|
||||
}
|
||||
|
||||
if (rotary_close( id )) {
|
||||
return luaL_error( L, "Unable to close switch." );
|
||||
d->handle = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: on( id, mask[, cb] )
|
||||
// Lua: on( mask[, cb] )
|
||||
static int lrotary_on( lua_State* L )
|
||||
{
|
||||
unsigned int id;
|
||||
id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( rotary, id );
|
||||
DATA *d = (DATA *)luaL_checkudata(L, 1, "rotary.switch");
|
||||
|
||||
int mask = luaL_checkinteger(L, 2);
|
||||
|
||||
if (lua_gettop(L) >= 3) {
|
||||
if (callback_set(L, id, mask, 3)) {
|
||||
if (callback_set(L, d, mask, 3)) {
|
||||
return luaL_error( L, "Unable to set callback." );
|
||||
}
|
||||
} else {
|
||||
callback_free(L, id, mask);
|
||||
callback_free(L, d, mask);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: getpos( id ) -> pos, PRESS/RELEASE
|
||||
// Lua: getpos( ) -> pos, PRESS/RELEASE
|
||||
static int lrotary_getpos( lua_State* L )
|
||||
{
|
||||
unsigned int id;
|
||||
id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( rotary, id );
|
||||
DATA *d = (DATA *)luaL_checkudata(L, 1, "rotary.switch");
|
||||
|
||||
int pos = rotary_getpos(id);
|
||||
int pos = rotary_getpos(d->handle);
|
||||
|
||||
if (pos == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, (pos << 1) >> 1);
|
||||
lua_pushinteger(L, (pos & 0x80000000) ? MASK(PRESS) : MASK(RELEASE));
|
||||
lua_pushboolean(L, (pos & 0x80000000));
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
@ -264,7 +234,7 @@ static bool lrotary_dequeue_single(lua_State* L, DATA *d)
|
|||
// This chnnel is open
|
||||
rotary_event_t result;
|
||||
|
||||
if (rotary_getevent(d->id, &result)) {
|
||||
if (rotary_getevent(d->handle, &result)) {
|
||||
int pos = result.pos;
|
||||
|
||||
lrotary_check_timer(d, result.time_us, 0);
|
||||
|
@ -303,7 +273,8 @@ static bool lrotary_dequeue_single(lua_State* L, DATA *d)
|
|||
d->lastpos = pos;
|
||||
}
|
||||
|
||||
something_pending = rotary_has_queued_event(d->id);
|
||||
rotary_event_handled(d->handle);
|
||||
something_pending = rotary_has_queued_event(d->handle);
|
||||
}
|
||||
|
||||
lrotary_check_timer(d, esp_timer_get_time(), 1);
|
||||
|
@ -356,49 +327,28 @@ static void lrotary_check_timer(DATA *d, uint32_t time_us, bool dotimer)
|
|||
|
||||
static void lrotary_task(task_param_t param, task_prio_t prio)
|
||||
{
|
||||
(void) param;
|
||||
(void) prio;
|
||||
|
||||
uint8_t *task_queue_ptr = (uint8_t*) param;
|
||||
if (task_queue_ptr) {
|
||||
// Signal that new events may need another task post
|
||||
*task_queue_ptr = 0;
|
||||
}
|
||||
|
||||
int id;
|
||||
bool need_to_post = false;
|
||||
lua_State *L = lua_getstate();
|
||||
|
||||
for (id = 0; id < ROTARY_CHANNEL_COUNT; id++) {
|
||||
DATA *d = data[id];
|
||||
DATA *d = (DATA *) param;
|
||||
if (d) {
|
||||
if (lrotary_dequeue_single(L, d)) {
|
||||
need_to_post = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (need_to_post) {
|
||||
// If there is pending stuff, queue another task
|
||||
task_post_medium(tasknumber, 0);
|
||||
task_post_medium(tasknumber, param);
|
||||
}
|
||||
}
|
||||
|
||||
static int rotary_open(lua_State *L)
|
||||
{
|
||||
tasknumber = task_get_id(lrotary_task);
|
||||
if (rotary_driver_init() != ESP_OK) {
|
||||
return luaL_error(L, "Initialization fail");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Module function map
|
||||
LROT_BEGIN(rotary, NULL, 0)
|
||||
LROT_FUNCENTRY( setup, lrotary_setup )
|
||||
LROT_FUNCENTRY( close, lrotary_close )
|
||||
LROT_FUNCENTRY( on, lrotary_on )
|
||||
LROT_FUNCENTRY( getpos, lrotary_getpos )
|
||||
LROT_NUMENTRY( TURN, MASK(TURN) )
|
||||
LROT_NUMENTRY( PRESS, MASK(PRESS) )
|
||||
LROT_NUMENTRY( RELEASE, MASK(RELEASE) )
|
||||
|
@ -406,8 +356,22 @@ LROT_BEGIN(rotary, NULL, 0)
|
|||
LROT_NUMENTRY( CLICK, MASK(CLICK) )
|
||||
LROT_NUMENTRY( DBLCLICK, MASK(DBLCLICK) )
|
||||
LROT_NUMENTRY( ALL, ROTARY_ALL )
|
||||
|
||||
LROT_END(rotary, NULL, 0)
|
||||
|
||||
// Module function map
|
||||
LROT_BEGIN(rotary_switch, NULL, LROT_MASK_GC_INDEX)
|
||||
LROT_FUNCENTRY(__gc, lrotary_close)
|
||||
LROT_TABENTRY(__index, rotary_switch)
|
||||
LROT_FUNCENTRY(on, lrotary_on)
|
||||
LROT_FUNCENTRY(close, lrotary_close)
|
||||
LROT_FUNCENTRY(getpos, lrotary_getpos)
|
||||
LROT_END(rotary_switch, NULL, LROT_MASK_GC_INDEX)
|
||||
|
||||
static int rotary_open(lua_State *L) {
|
||||
luaL_rometatable(L, "rotary.switch",
|
||||
LROT_TABLEREF(rotary_switch)); // create metatable
|
||||
tasknumber = task_get_id(lrotary_task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NODEMCU_MODULE(ROTARY, "rotary", rotary, rotary_open);
|
||||
|
|
|
@ -40,20 +40,18 @@
|
|||
|
||||
#define STATUS_IS_PRESSED(x) (((x) & 0x80000000) != 0)
|
||||
|
||||
typedef struct {
|
||||
typedef struct rotary_driver_handle {
|
||||
int8_t phase_a_pin;
|
||||
int8_t phase_b_pin;
|
||||
int8_t press_pin;
|
||||
int8_t task_queued;
|
||||
uint32_t read_offset; // Accessed by task
|
||||
uint32_t write_offset; // Accessed by ISR
|
||||
uint32_t last_press_change_time;
|
||||
int tasknumber;
|
||||
rotary_event_t queue[QUEUE_SIZE];
|
||||
} DATA;
|
||||
|
||||
static DATA *data[ROTARY_CHANNEL_COUNT];
|
||||
|
||||
static uint8_t task_queued;
|
||||
void *callback_arg;
|
||||
} *rotary_driver_handle_t;
|
||||
|
||||
static void set_gpio_mode(int pin, gpio_int_type_t intr)
|
||||
{
|
||||
|
@ -61,6 +59,7 @@ static void set_gpio_mode(int pin, gpio_int_type_t intr)
|
|||
.pin_bit_mask = 1LL << pin,
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = intr
|
||||
};
|
||||
|
||||
|
@ -76,20 +75,12 @@ static void rotary_clear_pin(int pin)
|
|||
}
|
||||
|
||||
// Just takes the channel number. Cleans up the resources used.
|
||||
int rotary_close(uint32_t channel)
|
||||
int rotary_close(rotary_driver_handle_t d)
|
||||
{
|
||||
if (channel >= sizeof(data) / sizeof(data[0])) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DATA *d = data[channel];
|
||||
|
||||
if (!d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data[channel] = NULL;
|
||||
|
||||
rotary_clear_pin(d->phase_a_pin);
|
||||
rotary_clear_pin(d->phase_b_pin);
|
||||
rotary_clear_pin(d->press_pin);
|
||||
|
@ -102,7 +93,7 @@ int rotary_close(uint32_t channel)
|
|||
static void rotary_interrupt(void *arg)
|
||||
{
|
||||
// This function runs with high priority
|
||||
DATA *d = (DATA *) arg;
|
||||
rotary_driver_handle_t d = (rotary_driver_handle_t)arg;
|
||||
|
||||
uint32_t last_status = GET_LAST_STATUS(d).pos;
|
||||
|
||||
|
@ -165,9 +156,9 @@ static void rotary_interrupt(void *arg)
|
|||
|| STATUS_IS_PRESSED(last_status ^ GET_PREV_STATUS(d).pos)) {
|
||||
if (HAS_QUEUE_SPACE(d)) {
|
||||
QUEUE_STATUS(d, new_status);
|
||||
if (!task_queued) {
|
||||
if (task_post_medium(d->tasknumber, (task_param_t) &task_queued)) {
|
||||
task_queued = 1;
|
||||
if (!d->task_queued) {
|
||||
if (task_post_medium(d->tasknumber, (task_param_t) d->callback_arg)) {
|
||||
d->task_queued = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -179,27 +170,21 @@ static void rotary_interrupt(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
void rotary_event_handled(rotary_driver_handle_t d)
|
||||
{
|
||||
d->task_queued = 0;
|
||||
}
|
||||
|
||||
// The pin numbers are actual platform GPIO numbers
|
||||
int rotary_setup(uint32_t channel, int phase_a, int phase_b, int press, task_handle_t tasknumber )
|
||||
{
|
||||
if (channel >= sizeof(data) / sizeof(data[0])) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data[channel]) {
|
||||
if (rotary_close(channel)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
DATA *d = (DATA *) calloc(1, sizeof(DATA));
|
||||
rotary_driver_handle_t rotary_setup(int phase_a, int phase_b, int press,
|
||||
task_handle_t tasknumber, void *arg) {
|
||||
rotary_driver_handle_t d = (rotary_driver_handle_t )calloc(1, sizeof(*d));
|
||||
if (!d) {
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data[channel] = d;
|
||||
|
||||
d->tasknumber = tasknumber;
|
||||
d->callback_arg = arg;
|
||||
|
||||
set_gpio_mode(phase_a, GPIO_INTR_ANYEDGE);
|
||||
gpio_isr_handler_add(phase_a, rotary_interrupt, d);
|
||||
|
@ -215,17 +200,11 @@ int rotary_setup(uint32_t channel, int phase_a, int phase_b, int press, task_han
|
|||
}
|
||||
d->press_pin = press;
|
||||
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
bool rotary_has_queued_event(uint32_t channel)
|
||||
bool rotary_has_queued_event(rotary_driver_handle_t d)
|
||||
{
|
||||
if (channel >= sizeof(data) / sizeof(data[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DATA *d = data[channel];
|
||||
|
||||
if (!d) {
|
||||
return false;
|
||||
}
|
||||
|
@ -234,16 +213,9 @@ bool rotary_has_queued_event(uint32_t channel)
|
|||
}
|
||||
|
||||
// Get the oldest event in the queue and remove it (if possible)
|
||||
bool rotary_getevent(uint32_t channel, rotary_event_t *resultp)
|
||||
{
|
||||
bool rotary_getevent(rotary_driver_handle_t d, rotary_event_t *resultp) {
|
||||
rotary_event_t result = { 0 };
|
||||
|
||||
if (channel >= sizeof(data) / sizeof(data[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DATA *d = data[channel];
|
||||
|
||||
if (!d) {
|
||||
return false;
|
||||
}
|
||||
|
@ -263,22 +235,10 @@ bool rotary_getevent(uint32_t channel, rotary_event_t *resultp)
|
|||
return status;
|
||||
}
|
||||
|
||||
int rotary_getpos(uint32_t channel)
|
||||
{
|
||||
if (channel >= sizeof(data) / sizeof(data[0])) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DATA *d = data[channel];
|
||||
|
||||
int rotary_getpos(rotary_driver_handle_t d) {
|
||||
if (!d) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return GET_LAST_STATUS(d).pos;
|
||||
}
|
||||
|
||||
esp_err_t rotary_driver_init()
|
||||
{
|
||||
return gpio_install_isr_service(ESP_INTR_FLAG_LOWMED);
|
||||
}
|
||||
|
|
|
@ -6,23 +6,23 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ROTARY_CHANNEL_COUNT 3
|
||||
|
||||
typedef struct {
|
||||
uint32_t pos;
|
||||
uint32_t time_us;
|
||||
} rotary_event_t;
|
||||
|
||||
int rotary_setup(uint32_t channel, int phaseA, int phaseB, int press, task_handle_t tasknumber);
|
||||
struct rotary_driver_handle *rotary_setup(int phaseA,
|
||||
int phaseB, int press,
|
||||
task_handle_t tasknumber, void *arg);
|
||||
|
||||
bool rotary_getevent(uint32_t channel, rotary_event_t *result);
|
||||
bool rotary_getevent(struct rotary_driver_handle *handle, rotary_event_t *result);
|
||||
|
||||
bool rotary_has_queued_event(uint32_t channel);
|
||||
bool rotary_has_queued_event(struct rotary_driver_handle *handle);
|
||||
|
||||
int rotary_getpos(uint32_t channel);
|
||||
int rotary_getpos(struct rotary_driver_handle *handle);
|
||||
|
||||
int rotary_close(uint32_t channel);
|
||||
int rotary_close(struct rotary_driver_handle *handle);
|
||||
|
||||
int rotary_driver_init();
|
||||
void rotary_event_handled(struct rotary_driver_handle *handle);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,10 +32,9 @@ Note that the pins are named somewhat eccentrically, and I suspect that it reall
|
|||
Initialize the nodemcu to talk to a rotary encoder switch.
|
||||
|
||||
#### Syntax
|
||||
`rotary.setup(channel, pina, pinb[, pinpress[, longpress_time_ms[, dblclick_time_ms]]])`
|
||||
`switch = rotary.setup(pina, pinb[, pinpress[, longpress_time_ms[, dblclick_time_ms]]])`
|
||||
|
||||
#### Parameters
|
||||
- `channel` The rotary module supports three switches. The channel is either 0, 1 or 2.
|
||||
- `pina` This is a GPIO number (excluding 0) and connects to pin phase A on the rotary switch.
|
||||
- `pinb` This is a GPIO number (excluding 0) and connects to pin phase B on the rotary switch.
|
||||
- `pinpress` (optional) This is a GPIO number (excluding 0) and connects to the press switch.
|
||||
|
@ -45,20 +44,18 @@ Initialize the nodemcu to talk to a rotary encoder switch.
|
|||
#### Returns
|
||||
Nothing. If the arguments are in error, or the operation cannot be completed, then an error is thrown.
|
||||
|
||||
For all API calls, if the channel number is out of range, then an error will be thrown.
|
||||
|
||||
#### Example
|
||||
|
||||
rotary.setup(0, 5,6, 7)
|
||||
switch = rotary.setup(5, 6, 7)
|
||||
|
||||
## rotary.on()
|
||||
## switch:on()
|
||||
Sets a callback on specific events.
|
||||
|
||||
#### Syntax
|
||||
`rotary.on(channel, eventtype[, callback])`
|
||||
`switch:on(eventtype[, callback])`
|
||||
|
||||
#### Parameters
|
||||
- `channel` The rotary module supports three switches. The channel is either 0, 1 or 2.
|
||||
- `eventtype` This defines the type of event being registered. This is the logical or of one or more of `PRESS`, `LONGPRESS`, `RELEASE`, `TURN`, `CLICK` or `DBLCLICK`.
|
||||
- `callback` This is a function that will be invoked when the specified event happens.
|
||||
|
||||
|
@ -73,8 +70,8 @@ in a 32-bit integer. Note that this wraps every hour or so.
|
|||
|
||||
#### Example
|
||||
|
||||
rotary.on(0, rotary.ALL, function (type, pos, when)
|
||||
print "Position=" .. pos .. " event type=" .. type .. " time=" .. when
|
||||
switch:on(rotary.ALL, function (type, pos, when)
|
||||
print("Position=" .. pos .. " event type=" .. type .. " time=" .. when)
|
||||
end)
|
||||
|
||||
#### Notes
|
||||
|
@ -94,14 +91,11 @@ where this is a short time gap between the middle `RELEASE` and `PRESS`.
|
|||
#### Errors
|
||||
If an invalid `eventtype` is supplied, then an error will be thrown.
|
||||
|
||||
## rotary.getpos()
|
||||
## switch:getpos()
|
||||
Gets the current position and press status of the switch
|
||||
|
||||
#### Syntax
|
||||
`pos, press = rotary.getpos(channel)`
|
||||
|
||||
#### Parameters
|
||||
- `channel` The rotary module supports three switches. The channel is either 0, 1 or 2.
|
||||
`pos, press = switch:getpos()`
|
||||
|
||||
#### Returns
|
||||
- `pos` The current position of the switch.
|
||||
|
@ -109,18 +103,15 @@ Gets the current position and press status of the switch
|
|||
|
||||
#### Example
|
||||
|
||||
print rotary.getpos(0)
|
||||
print(switch:getpos())
|
||||
|
||||
## rotary.close()
|
||||
## switch:close()
|
||||
Releases the resources associated with the rotary switch.
|
||||
|
||||
#### Syntax
|
||||
`rotary.close(channel)`
|
||||
|
||||
#### Parameters
|
||||
- `channel` The rotary module supports three switches. The channel is either 0, 1 or 2.
|
||||
`switch:close()`
|
||||
|
||||
#### Example
|
||||
|
||||
rotary.close(0)
|
||||
switch:close()
|
||||
|
||||
|
|
Loading…
Reference in New Issue