• @n00b, sorry to be not clear enough in my initial post.

    The watch is not on a virtual pin made visible through the available driver (module). The watch is on an Espruino pin(s) connected to one(both) of the interrupt pin(s) INTA (and INTB) of the MCP23017 Portexpander.

    You still need to do some scanning similar you did with the interval, but you do only when a press happens and you do less. You do less because the you get already row (or col) by reading the register that loads the pin states at interrupt time.

    The current module is more for predictable/'static' behavior... When I came across the MCP23017 Portexpander, I tried to write a module that supports all options. But there are too many to generalize, and the module would become too fat. Therefore, I gave up and decided to go custom for the particular application when using it.

    The general logic for time multiplexed reading of up to 64 buttons is:

    Setup for watching press event:

    • reset
    • configure 8 pins out, 8 pins input pull-up
    • configure an interrupt on the 8 input pins
    • set watch for press
    • enable interrupt

    On watch (interrupt) press event:

    • disable interrupt (if it not already happened automatically)
    • read the capture register (which gives you the row (or col))
    • loop through 8 output pins:
      • set only the 1 pin on high
      • read the 8 input pins
      • if any of the 8 input pins is low, then
        • the current output pin that is high denotes the col (or row)
        • you can exit (break the loop)

    Setup for release event:

    • put all outputs back to high
    • set watch for release
    • enable interrupt

    On watch (interrupt) release event:

    • disable interrupt (if it not already happened automatically)
    • read the capture register (which gives you the row (or col))
      • if any of the 8 bits is still low,
        • then there is still a button pressed and you resume with 'Setup for release event:'
        • else all buttons are released and you resume with
        • set watch for press event
        • enable interrupt

    The above pseudo code does not talk about how to preset the register for detecting the interrupt. In the setup for watch press, it is all high. For the preset of release detection, you have to determine empirically (may what was read by the interrupt capture register). Also, no cover all corner cases are covered, such as things already changed again since the interrupt. This happens especially with bouncing (and this bouncing may have to be captured differently than in the bounce option of the watches). To capture/overcome switch bouncing is not a trivial thing... see conversation about Problems with setWatch.

About

Avatar for allObjects @allObjects started