piripherals.mpr121 module

a sane and complete interface to the MPR121 touch sensor

This is thought to be a replacement of the incomplete and undocumented Adafruit.MPR121 library.

Note

To fully understand this device, please read the datasheet.

Wiring the MPR121 to the RaspberryPi

Connect the pins of the MPR121 to the RaspberryPi according to the following table. In this doc and in the code, all Pi pin numbers are BCM pin numbers, physical pin numbers are set in round braces.

MPR121 RaspberryPi
3.3V 3.3V (1)
GND GND (6)
SDA BCM 2 (3)
SCL BCM 3 (5)
IRQ* BCM 4 (7)

Connecting the IRQ line is optional but highly recommended to avoid unneccessary bus traffic and CPU load due to polling. To be able to use the IRQ, you need to have RPi.GPIO installed (apt-get install python-rpi.gpio or pip install RPi.GPIO). You may use a different pin, adjust the number accordingly.

If you want to connect multiple MPR121s to the same bus, you can change their address with the address pin. Refer to the datasheet on how to do this.

Enable I2C access

The MPR121 uses I2C for communication. On the RaspberryPi running Raspbian Stretch, you need to enable the I2C bus. To /boot/config.txt add the lines:

dtparam=i2c_arm=on
dtparam=i2c1=on

and to /etc/modules add:

i2c-dev

This should enable the /dev/i2c-1 (bus=1) device on boot. Install i2c-tools with:

apt-get install i2c-tools

and list the addresses of connected devices:

i2cdetect -y 1

For MPR121 being able to access the I2C bus, you need to have a Python smbus implementation installed. Use python-smbus from the distro or smbus2 (apt-get install python-smbus or pip install smbus2). Other implementations may work, too.

Using MPR121

Attach the MPR121 to the Pi as described above and use it like:

from piripherals import MPR121

# MPR121 should come up and be running with 12 channels
mpr = MPR121(irq=4)
for i in range(12): # print status on touch and release
    mpr.on_touch(i, lambda *x: print(x))

Simply instanciante it and assign touch handlers. For fine tuning and to userthe GPIO functionality, see the doc below.

Tip

Use the mpr121-dump script to examine the MPR121’s response and to tune the settings.

class piripherals.mpr121.MPR121(bus=1, addr=90, irq=0, handlers=1, setup=1, reset=1, **kwargs)[source]

Bases: object

MPR121 capacitive touch sensor and GPIO/LED controller.

It will be configured with sane defaults and started immediately.

Parameters:
  • bus (int) – I2C bus, 1 = /dev/i2c-1
  • addr (int) – I2C address of the device
  • irq (int) – BCM pin # that is connect to interrupt line, 0 disables IRQ, uses polling instead
  • handlers (bool) – enable IRQ handler/polling, if disabled update_touch_state() has to be called explicitly
  • setup (bool) – configure with (sane) defaults
  • reset (bool) – reset on initialization
  • **kwargs – arguments to setup()
auto_config(ace=1, are=1, bva=3, retry=2, afes=1, scts=0, acfie=1, arfie=1, oorie=1, usl=200, lsl=130, tl=180)[source]

Configure automatic adjustment eletrode change current and time.

Parameters:
  • ace (bool) – enable auto configuration
  • are (bool) – enable auto reconfiguration
  • bva (int) – baseline adjustment after current and time have been set: 0 = no change, 1 = set to zero, 2 = set 5MSBs to measured value, 3 = set to measured value.
  • retry (int) – # of retries for auto configuration: 0-3 (0,2,4,8)
  • afes (int) – # of AFE sample during search process, set to values as filter(ffi): 0-3 (6,10,18,34)
  • scts (bool) – skip charge time search
  • acfie (bool) – enable IRQ on auto config failure
  • arfie (bool) – enable IRQ on auto reconfig failure
  • oorie (bool) – enable IRQ on out of range event
baseline(rft=-1, mhd=0, nhd=0, ncl=0, fdl=0, prox=0)[source]

Get raw baslines or configure baseline tracking.

Parameters:
  • rft (int) – scenario to set the values for: 0 = rising, raw eletrode data > current baseline, 1 = falling, raw eletrode data < current baseline, 2 = touched, eletrode in touch status.
  • mhd (int) – max. half delta 0-63 (for rft=0 or 1 only), largest magnitude of variation to pass through the baseline filter.
  • nhd (int) – noise half delta 0-63, incremental change when non-noise drift is detected.
  • ncl (int) – noise count limit 0-255, number of samples consecutively greater than mhd necessary before if can be determined that it is non-noise.
  • fdl (int) – filter delay count limit 0-255, rate of operation of the filer, greater values makes it operate slower.
  • prox (bool) – if True set values for proximity mode.
Returns:

raw 10 bit baseline values per eletrode, if invoked with no args.

Return type:

list of ints

charge(channel, cdc=0, cdt=0)[source]

Configure change current and time per channel.

These values are determined automatically when auto_config() is activated.

Parameters:
  • channel (int) – channel to configure 0-11
  • cdc (int) – charge-discharge-current 0-63 (uA)
  • cdt (int) – charge-discharge-time 0-7 (0.5*2**(cdt-1) us)
configure(cl=3, prox=0, touch=12)[source]

activate/deactivate measurement.

Measurement is activated when setting prox>0 or touch>0 (run mode). Deactivate measurement with prox=0 and touch=0 (stop mode).

Parameters:
  • cl (int) – calibration lock: 0 = baseline tracking enabled, 1 = baseline tracking disabled, 2 = baseline tracking enabled, init 5MSBs with initial measurement, 3 = baseline tracking enabled, init with initial measurement.
  • prox (int) – proximity detection: 0 = disabled, 1 = enabled on electrodes 0-1, 2 = enabled on electrodes 0-3, 3 = enabled on electrodes 0-11.
  • touch (int) – enable electrodes: 0 = disabled, 1 = enable electrode 0, 2 = enable electrodes 0-1, 3 = enable electrodes 0-2, …, 12 = enable electrodes 0-11.
debounce(touch=0, release=-1)[source]

Configure debouncing.

# of consecutiv measurements with same result needed to trigger state change.

Parameters:
  • touch (int) – for touch 0-7
  • release (int) – for release 0-7, if ommited release=touch
dump(regs=1, up=1, loop=1)[source]

Dump raw values, baseline and touch status to console.

Uses this repeatedly to adjust the configuration.

Parameters:
  • regs (bool) – dump register values
  • up (bool) – move cursor up after dump
  • loop (int) – run in loop for given # of rounds
electrode_data()[source]

Get raw eletrode measurement data.

Returns:raw 10 bit eletrode measurement per eletrode
Return type:list of int
filter(cdc=16, cdt=1, ffi=0, sfi=0, esi=4)[source]

Settings for global eletrode charging, sampling and filtering.

Effective measurement cycle period is sfi*esi.

Parameters:
  • cdc (int) – charge-discharge-current 0-63 (uA)
  • cdt (int) – charge-discharge-time 0-7 (0.5*2**(cdt-1) us)
  • ffi (int) – first filter iterations 0-3 (6,10,18,34)
  • sfi (int) – second filter iterations 0-3 (4,6,10,18)
  • esi (int) – eletrode sample interval 0-7 (2**esi ms)
gpio_set(channel, value)[source]

Set GPIO channel.

Parameters:
  • channel (int) – channel to set 4-11
  • value (bool) – set 1=HIGH or 0=LOW
gpio_setup(channel, output, mode=0, enable=1)[source]

Setup GPIO configuration.

If the channel is configured as touch eletrode with configure(), then this GPIO setting has not effect. Sensing eletrode have precedence.

Parameters:
  • channel (int) – channel to configure (4-11)
  • output (bool) – configure as 1=output or 0=input
  • mode (int) – pin mode, when output: 0 = CMOS output, 2 = open drain output, low side MOS only, 3 = open drain output, high side MOS only, when input: 0 = input, 2 = input with pull-down, 3 = input with pull-up.
  • enable (bool) – enable/disbale GPIO functionality
gpio_status()[source]

Get GPIO status bits.

Returns:GPIO status byte for channels 4-11
is_touched(channel)[source]

Get touch status.

Parameters:channel (int) – channel to get status for, 0-12
Returns:True if touched
Return type:bool
on_touch(channel, handler)[source]

Register touch handler, invoked on state change.

Parameters:
  • channel (int) – channel to attach the handler to (0-12, 12=proximity)
  • handler (callable(boolean, [channel])) – handler, it gets passed a channel number [optional] and a boolean (True=touched), Pass None to remove any assigned handler.
out_of_range(raise_on_failure=1)[source]

get out of range status.

Returns:first 12 bits contain oor status.
Return type:int
Parameters:raise_on_failure (bool) – raise if failure bits are set
Raises:Exception – if auto (re)config has failed
reset()[source]

Perform soft reset.

setup(reset=1, channels=12, prox=0, threshold=50, debounce=2, auto_config=1)[source]

Configure the device with sane defaults.

Parameters:
  • reset (bool) – perform soft reset
  • channels (int) – number of channels to activate 0-12
  • threshold (int) – touch threshold 0-255
  • debounce (int) – debounce count 0-7
  • auto_config (bool) – enable charge auto config
threshold(touch, release=-1, channel=-1)[source]

Set touch and release thresholds.

Usually touch > release for hysteresis.

Parameters:
  • touch (int) – touch threshold 0-255
  • release (int) – release threshold 0-255 if ommited release=0.6*touch
  • channel (int) – channel to set thresholds for 0-12 (12=proximity) if ommited apply thresholds to all channels
touched(raise_on_failure=1)[source]

Get touch status bits to the device.

Returns:first 12 bits contain touch status, 1=touched
Return type:int
Parameters:raise_on_failure (bool) – raise if failure bits are set
Raises:Exception – on overcurrent and out of range
update_touch_state()[source]

Update touch state, calls touched()