philip d40ee50a8e Squashed commit of the following:
commit 2c7c3fc3985cc32866e8af496abea9971eaee90a
Merge: 9179dae 41022c3
Author: philip <philip@gladstonefamily.net>
Date:   Sun Feb 28 14:47:47 2016 -0500

    Merge remote-tracking branch 'upstream/dev' into rotary_2

commit 9179dae0824e6b35ad09e5113aacc26dc91692c0
Author: philip <philip@gladstonefamily.net>
Date:   Fri Feb 26 20:53:27 2016 -0500

    Review comments

commit 67741170e20ccb2b636e701f0664feff2aafbb4c
Author: philip <philip@gladstonefamily.net>
Date:   Fri Feb 26 20:59:49 2016 -0500

    Squashed commit of the following:

    commit 8c9a64731c4a8b9aedda18a399b433b173d2199f
    Merge: 085935f 19d3c1d
    Author: philip <philip@gladstonefamily.net>
    Date:   Fri Feb 26 20:58:10 2016 -0500

        Merge remote-tracking branch 'upstream/dev' into rotarymod

        Conflicts:
        	app/platform/platform.c

    commit 085935fc56986d607ff5e05d1663970331959c34
    Author: philip <philip@gladstonefamily.net>
    Date:   Fri Feb 26 20:53:27 2016 -0500

        Review comment

    commit 7732fd2d1044f28b8fcf5b0aa0f76d76fe80f449
    Author: philip <philip@gladstonefamily.net>
    Date:   Sat Feb 20 12:10:38 2016 -0500

        Module to handle rotary decoders

        Eliminate ROTARY_DEBUG

        Remove unused file

Eliminate a malloc call

Cleaned up the register code. Now 0x114 bytes

Fix bug with clearing bits in one case

Fix the type in the #define name
2016-02-29 08:21:12 -05:00

5.9 KiB

rotary Module

This module can read the state of cheap rotary encoder switches. These are available at all the standard places for a dollar or two. They are five pin devices where three are used for a gray code encoder for rotation, and two are used for the push switch. These switches are commonly used in car audio systems.

These switches do not have absolute positioning, but only encode the number of positions rotated clockwise / anticlockwise. To make use of this module, connect the common pin on the quadrature encoder to ground and the A and B phases to the nodemcu. One pin of the push switch should also be grounded and the other pin connected to the nodemcu.

Sources for parts

  • Amazon: This search shows a variety.
  • Ebay: Somewhat cheaper in this search
  • Adafruit: rotary encoder
  • Aliexpress: This search reveals all sorts of shapes and sizes.

There is also a switch mounted on a board with standard 0.1" pins. This is the KY-040, and can also be found at lots of places. Note that the pins are named somewhat eccentrically, and I suspect that it really does need the VCC connected.

Constants

  • rotary.PRESS = 1 The eventtype for the switch press.
  • rotary.LONGPRESS = 2 The eventtype for a long press.
  • rotary.RELEASE = 4 The eventtype for the switch release.
  • rotary.TURN = 8 The eventtype for the switch rotation.
  • rotary.CLICK = 16 The eventtype for a single click (after release)
  • rotary.DBLCLICK = 32 The eventtype for a double click (after second release)
  • rotary.ALL = 63 All event types.

rotary.setup()

Initialize the nodemcu to talk to a rotary encoder switch.

Syntax

rotary.setup(channel, 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.
  • longpress_time_ms (optional) The number of milliseconds (default 500) of press to be considered a long press.
  • dblclick_time_ms (optional) The number of milliseconds (default 500) between a release and a press for the next release to be considered a double click.

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)

rotary.on()

Sets a callback on specific events.

Syntax

rotary.on(channel, 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.

If the callback is None or omitted, then the registration is cancelled.

The callback will be invoked with three arguments when the event happens. The first argument is the current position of the rotary switch, the second is the eventtype, and the third is the time when the event happened.

The position is tracked and is represented as a signed 32-bit integer. Increasing values indicate clockwise motion. The time is the number of microseconds represented in a 32-bit integer. Note that this wraps every hour or so.

Example

rotary.on(0, rotary.ALL, function (pos, type, when) 
  print "Position=" .. pos .. " event type=" .. type .. " time=" .. when
end)

Notes

Events will be delivered in order, but there may be missing TURN events. If there is a long queue of events, then PRESS and RELEASE events may also be missed. Multiple pending TURN events are typically dispatched as one TURN callback with the final position as its parameter.

Some switches have 4 steps per detent. This means that, in practice, the application should divide the position by 4 and use that to determine the number of clicks. It is unlikely that a switch will ever reach 30 bits of rotation in either direction -- some are rated for under 50,000 revolutions.

The CLICK and LONGPRESS events are delivered on a timeout. The DBLCLICK event is delivered after a PRESS, RELEASE, PRESS, RELEASE sequence 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()

Gets the current position and press status of the switch

Syntax

pos, press, queue = rotary.getpos(channel)

Parameters

  • channel The rotary module supports three switches. The channel is either 0, 1 or 2.

Returns

  • pos The current position of the switch.
  • press A boolean indicating if the switch is currently pressed.
  • queue The number of undelivered callbacks (normally 0).

Example

print rotary.getpos(0)

rotary.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.

Example

rotary.close(0)