Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPR121 Touch IC Based Keypad Input Module #5103

Merged
merged 32 commits into from
Oct 21, 2024

Conversation

aussieklutz
Copy link
Contributor

For an upcoming meshtastic project, this implements an input driver utilising the MPR121 Touch IC and is compatible with common MPR121 keypad PCB's.

  • Implements a "candybar" phone style 12-key keypad
    • multiple taps to rotate through the character set
    • longpress for navigation keys
    • keymap to allow arbitrary routing of MPR121 pin to button configuration
    • extendable to other key functions
  • Integrates with the existing kbI2cBase implementation
  • Works with CannedMessageModule Freetext mode
  • Can be used with common MPR121 boards, such as https://www.amazon.com/MPR121-Capacitive-Keyboard-Buttons-Sensitive/dp/B083R89CHB/ref=sr_1_6
    • Note: These boards have the MPR121 configured to address 5A, which conflicts with an existing sensor. I made some patches around the configuration.h to resolve this, but welcome advice on the best approach.
  • Of use for PCB based radios, where some form of low surface area low component freetext input is required, but also without consuming too many IO pins.
  • Tested on a T3S3 connected to Wire1 (Second) interface.

For testing, uncommented the MRP121_USE_5A define in configuration.h, and add #define CANNED_MESSAGE_MODULE_ENABLE 1 to variant.h. Again, I expect that this is not an ideal approach and looking for input as to the best way to move forward.

@CLAassistant
Copy link

CLAassistant commented Oct 20, 2024

CLA assistant check
All committers have signed the CLA.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@fifieldt
Copy link
Contributor

Hi and welcome! Thanks for proving a great write-up.

I see the conflict with the MLX90614. Question - is there a register in the keyboard we can query that reliably returns something we can use to identify it? "Chip ID"/"model number/ etc. That way we can better disambiguate whether we have the sensor or the keyboard at that address.

@aussieklutz
Copy link
Contributor Author

aussieklutz commented Oct 20, 2024

And then write a special case scan, instead of using the simple scan macro, i.e instead of disambiguating in configuration.h, doing it in scani2c/scani2cwire?

@fifieldt
Copy link
Contributor

Ayesir!

@fifieldt
Copy link
Contributor

Couldn't see anything obvious in the data sheet. The 90614 appears to have an ID Number register so maybe we can search for that instead and make the keyboards the default :)

@fifieldt
Copy link
Contributor

By the way, are you familiar with the trunk linting tool? We use it to keep forgetting consistent and it looks like the files changed here need to be run through it.

@aussieklutz
Copy link
Contributor Author

I saw that. I'll lint it and give the detecttion approach a go. Cheers.

@aussieklutz
Copy link
Contributor Author

This will take some more thought... the MLX90614 ir temp sensor datasheet doesn't document the canonical id value, and it may be more a serial number than product id... this reference treats it as a 64 bit value... https://github.com/jfitter/MLX90614/blob/master/src%2FMLX90614.cpp

@aussieklutz
Copy link
Contributor Author

I think the most effective solution will be relying on the initial startup state of the MPR121:

Note: After completing power on reset (POR) or soft reset by command, MPR121 all registers are in default reset initial value (see Table 1). All the registers are cleared, except AFE Configuration Registers 0x5C (Default 0x10) and 0x5D (Default 0x24).

@Nestpebble
Copy link
Contributor

Nestpebble commented Oct 20, 2024

Here's how the dual addresses are done for the INA3221:

#define INA3221_ADDR 0x42

is the same as
#define DFROBOT_LARK_ADDR 0x42

So:

case INA3221_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue);
if (registerValue == 0x5449) {
LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address);
type = INA3221;
} else {
LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address);
type = DFROBOT_LARK;
}

@aussieklutz
Copy link
Contributor Author

I'll need to get someone with the IR temp sensor to test the detection when it's working, but I'll use the 0x5C (Default 0x10) value as I maintain that value in the setup. The other default value is changed to 0x20 during initialisation of the ic, so would be different on a warm reboot.

@aussieklutz
Copy link
Contributor Author

Okay, looks like a more complex soft reset process would be needed before reading from the MPR121, Instead looking to read the bus address register 0x0E from the MLX90614, which will contain 0x5A.

@thebentern thebentern requested a review from caveman99 October 21, 2024 00:26
Copy link
Member

@caveman99 caveman99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@fifieldt fifieldt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most excellent work

@fifieldt fifieldt merged commit 5ff8c90 into meshtastic:master Oct 21, 2024
47 checks passed
@fifieldt
Copy link
Contributor

Garn

@aussieklutz aussieklutz deleted the mpr121_v3 branch October 21, 2024 09:46
caveman99 pushed a commit that referenced this pull request Nov 3, 2024
Implements an input driver utilising the MPR121 Touch IC and is compatible with common MPR121 keypad PCB's.

- Implements a "candybar" phone style 12-key keypad
  - multiple taps to rotate through the character set
  - longpress for navigation keys
  - keymap to allow arbitrary routing of MPR121 pin to button configuration
  - extendable to other key functions
- Integrates with the existing kbI2cBase implementation
- Works with CannedMessageModule Freetext mode
- Can be used with common MPR121 boards, such as https://www.amazon.com/MPR121-Capacitive-Keyboard-Buttons-Sensitive/dp/B083R89CHB/ref=sr_1_6
- Of use for PCB based radios, where some form of low surface area low component freetext input is required, but also without consuming too many IO pins.
- Tested on a T3S3 connected to Wire1 (Second) interface.
  - Demonstration of functionality: https://youtu.be/UI6QP6nGvhY
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants