This is a Toit driver for the MPR121 is a capacitive touch sensor controller, made by NXP Semiconductors. It detects when a finger (or any conductive object) approaches or touches one of the pads. There are versions of this chipset made by Seeedstudio and others. Check pinouts as not all pins from the MPR121 are exposed in all cases.
Warning
This driver is functional but still under development.
For a quick overview and to get started, see the examples
The MPR121 uses a constant DC current capacitance sensing scheme. It can measure capacitances ranging from 10 pF to over 2000 pF with a resolution up to 0.01 pF. The device does this by varying the amount of charge current and charge time applied to the sensing inputs.
-
Proximity Sensor
This uses a number of the original pins, combining them to increase sensitivity to make a proximity sensor. This is a virtual 13th channel.
-
GPIO and LED Driver function (Not yet implemented.)
Among the 12 electrode inputs, 8 inputs are designed as multifunctional pins (D0 - D7 bits in the register correspond to GPIO and LED functions on ELE4 - ELE11). When these pins are not configured as electrodes, they may be used to drive LEDs or used for general purpose input or output. For more details on this feature, please refer to application note AN3894.
Note: The number of touch sensing electrodes, and therefore the number of GPIO ports left available is configured by the ECR (0x5E) and GPIO Enable Register (0x77). ECR has higher priority and overrides the GPIO enabled in 0x77 - that is, when a pin is enabled as GPIO but is also selected as electrode by ECR, the GPIO function is disabled immediately and it becomes an electrode during Run Mode.
Note: Be aware that the channels/electrodes cannot be turned on or off without following the 'total number of touch channels enabled' sequence. This means that using the first 6 channels for touch and wanting to use the second channel for GPIO, won't work. This means that using the higher end channels for GPIO might need to be done first, and then to start reducing the number of channels for touch one by one.
- Most functions specified in the datasheet are featured in the driver,
Mpr121. - 'Callback'/Event handler feature has been added,
Mpr121Events.
- Combinations (eg, hold 3, and tap 4)
- Proximity feature hasn't been implemented in
Mpr121Events - GPIO function has not been implemented.
- LED driver function has not yet been implemented.
A starter pattern for the driver is shown in this example.
After getting started, to simply see that something is being sensed/recognised by the driver, the interrupt pin could be wired to an LED and used. In addition, the driver also has a rudimentary feature to print the binary mask of what is being touched, shown in the example. This example does not require an interrupt pin be configured.
// I2C setup omitted.
// Start touch debugger.
mpr121-driver.debug-touched
// Stop touch debugger.
mpr121-driver.stop-all-tasksAn event handler class has been written such that a Toit Lambda can be assigned to a button. The lambda will be executed on touch (or release) of the chosen sensor channel. This version requires the use of a wired interrupt pin (pin 18 shown in this example) - similar operation to the debug mechanism is possible, but not implemented in this code.
// I2C setup Omitted (see files in ./examples/).
// Start the MPR121 device/driver:
mpr121-device := bus.device Mpr121.I2C-ADDRESS
mpr121-driver := Mpr121 mpr121-device --logger=logger
// Start the event driver, supplying the mpr121-driver:
event-driver = Mpr121Events mpr121-driver --intrpt-pin=(gpio.Pin 18)
mpr121-driver.on-touch Mpr121Events.CHANNEL-03 --callback=(:: print "touch channel 03")
mpr121-driver.on-release Mpr121Events.CHANNEL-04 --callback=(:: print "touch channel 04")
// Remove all tasks for Channel 03:
mpr121-driver.remove Mpr121Events.CHANNEL-03Note: Assigning Lambdas to a combinations of channel/touches, is not implemented yet.
If there are any issues, changes, or any other kind of feedback, please raise an issue. Feedback is welcome and appreciated!
- This driver has been written and tested with an unbranded INA226 module.
- All trademarks belong to their respective owners.
- No warranties for this work, express or implied.
- Several works were pivotal in understanding the device and how it works.
- Florian for the tireless help and encouragement
- The wider Toit developer team (past and present) for a truly excellent product
- AI has been used for code and text reviews, analysing and compiling data and results, and assisting with ensuring accuracy.
One would assume you are here because you know what Toit is. If you dont:
Toit is a high-level, memory-safe language, with container/VM technology built specifically for microcontrollers (not a desktop language port). It gives fast iteration (live reloads over Wi-Fi in seconds), robust serviceability, and performance that’s far closer to C than typical scripting options on the ESP32. [link]
