Adafruit 2340 Capacitative Touch Hat Raspberry Pi too sensitive - how can I change it?


#1

HI,

I am using the Adadfruit Capacitative Touch board 2340 - most of the useful docs are for the MPR121 & indeed the software supplied is for that.

I am using one pin, a wire connected to a Bare Conductive Paint area - quite large.
Unfortunately it is constantly triggering making the project unusable.

The documented set_thresholds method doesn’t change the behaviour (& this is reported in a number of online questions).
The answer seems to be to edit MPR121.py and change the thresholds in the source - however I believe this is inside an egg file.

Would any of you know
a) how to change this behaviour so that the pin isnt so sensitive or
b) how to edit the MPR121.py held in the egg file so that I can change the parameters

If there are no good options then I may create my own version of the soft reset _reset reproducing the version in MPR121.py so that I can make it perform all the same functions with different sets of threshold values - from within my own program.

Any help & guidance would be very much appreciated.
Thanks,
Regards
David


#2

It looks like the library just calls set_thresholds(12, 6) internally: https://github.com/adafruit/Adafruit_Python_MPR121/blob/master/Adafruit_MPR121/MPR121.py#L106 so I’m not sure what you could fix by modifying it. Insofar as I can tell by reading the datasheet, it’s writing the correct values to the correct registers.

You might find that no threshold is suitable for your particular application given the default settings in MPR121.py. However, the chip has some features that might help mitigate your problem- https://www.sparkfun.com/datasheets/Components/MPR121.pdf

While none of the configuration features are available in MPR121.py, you should be able to manipulate the configuration registers, without modifying the library, by calling:

mpr121._device.write8(0x00, 0x01)

Where mpr121 is your instance of the MPR library, 0x00 is the register to tweak, and 0x01 is the value.

You might want to try poking the auto-reconfig bit to see what happens:

conf = mpr121._device.read8(0x7b)
mpr121._device.write8(0x7b, conf | 2)

I don’t think there’s a silver bullet for your particular application, but if you trawl through the datasheet and try some of the settings you may arrive at a workable solution through trial and error.


#3

Hi Phil,
Thanks.
I would alter the library but it’s in an egg file (save a copy, rename to zip, unpack, edit file, rezip, rename to egg, test?).

Otherwise what you suggest is exactly where I am - so I think unless someone comes up with more, I shall reproduce the soft reset routine from the MPR121.py library, _reset, in my program and try different threshold settings.

Certainly calling set_thresholds from within the program changes nothing at all.

I would suggest Pi is not a priority for Adafruit in favour of Arduino but this isn’t the case, because the Arduino folks report it not working there either. Just amazing that it hasn’t been sorted by Adafruit. I guess most people are connections by it to bananas!

I see barefoot conductive have release a capacitative board but it’s more expensive.

The MPR121 docs suggest using a virtual pin 13 which takes account of all the pin readings - however the Python library does have this. I may take a look at the Arduino library and see if there is useful code to transfer into my program. Then I can connect all 12 pins to my conductive paint strip.

Other things I can try

  • smaller activation area
  • screened cable
  • use a button instead (also known as giving in to what I could have done quickly in the first place.

Regards David


#4

You could grab the library from GitHub, and potentially install it as “devel” and work on it from there.

I don’t know if this will work with Adafruit’s Python libraries, but:

git clone https://github.com/adafruit/Adafruit_Python_MPR121
cd Adafruit_Python_MPR121
sudo python setup.py devel

Now any changes made to the source will be reflected as if the library were installed.

Alternatively just stick your user script in this directory and it will import the local “Adafruit_MPR121” rather than your installed one, allowing you to make changes in the same way.

Python is very flexible anyway, so you can poke at registers in the way I suggested. I don’t believe you need the baggage of _setup if you’re just poking some settings. You can simply overwrite the one you want to change. Some pertain to autoconfiguration, so you’d have to make sure to trigger AUTO_RECONFIG after changing them.


#5

Cheers Phil.

Regards David


#6

Hi Phil,
this code made a difference. Its basically a local copy of the soft reset procedure that wraps either side of the set_thresholds call in the MPR121.py library.

It definitely changes behaviour in a way that calling set_thresholds only, on its own, doesn’t.
Now I am finding it tricky to get a t_threshold value that triggers when I touch it but doesnt occasionally fire on its own.
Best regards
David

Adafruit MPR121 Capacitative Touch Support

import Adafruit_MPR121.MPR121 as MPR121
t_threshold=42 # touch threshold value - original default was 12
r_threshold=12 # release threshold value - original default was 6

Register addresses.

MPR121_I2CADDR_DEFAULT = 0x5A
MPR121_TOUCHSTATUS_L = 0x00
MPR121_TOUCHSTATUS_H = 0x01
MPR121_FILTDATA_0L = 0x04
MPR121_FILTDATA_0H = 0x05
MPR121_BASELINE_0 = 0x1E
MPR121_MHDR = 0x2B
MPR121_NHDR = 0x2C
MPR121_NCLR = 0x2D
MPR121_FDLR = 0x2E
MPR121_MHDF = 0x2F
MPR121_NHDF = 0x30
MPR121_NCLF = 0x31
MPR121_FDLF = 0x32
MPR121_NHDT = 0x33
MPR121_NCLT = 0x34
MPR121_FDLT = 0x35
MPR121_TOUCHTH_0 = 0x41
MPR121_RELEASETH_0 = 0x42
MPR121_DEBOUNCE = 0x5B
MPR121_CONFIG1 = 0x5C
MPR121_CONFIG2 = 0x5D
MPR121_CHARGECURR_0 = 0x5F
MPR121_CHARGETIME_1 = 0x6C
MPR121_ECR = 0x5E
MPR121_AUTOCONFIG0 = 0x7B
MPR121_AUTOCONFIG1 = 0x7C
MPR121_UPLIMIT = 0x7D
MPR121_LOWLIMIT = 0x7E
MPR121_TARGETLIMIT = 0x7F
MPR121_GPIODIR = 0x76
MPR121_GPIOEN = 0x77
MPR121_GPIOSET = 0x78
MPR121_GPIOCLR = 0x79
MPR121_GPIOTOGGLE = 0x7A
MPR121_SOFTRESET = 0x80

MAX_I2C_RETRIES = 5

def Touch_Softreset(self):
# Soft reset of device.
self._i2c_retry(self._device.write8, MPR121_SOFTRESET, 0x63)
time.sleep(0.001) # This 1ms delay here probably isn’t necessary but can’t hurt.
# Set electrode configuration to default values.
self._i2c_retry(self._device.write8, MPR121_ECR, 0x00)
# Check CDT, SFI, ESI configuration is at default values.
c = self._i2c_retry(self._device.readU8, MPR121_CONFIG2)
if c != 0x24:
return False
#
#Set threshold for touch and release to default values.
#
self.set_thresholds(t_threshold, r_threshold)
#
# Configure baseline filtering control registers.
self._i2c_retry(self._device.write8, MPR121_MHDR, 0x01)
self._i2c_retry(self._device.write8, MPR121_NHDR, 0x01)
self._i2c_retry(self._device.write8, MPR121_NCLR, 0x0E)
self._i2c_retry(self._device.write8, MPR121_FDLR, 0x00)
self._i2c_retry(self._device.write8, MPR121_MHDF, 0x01)
self._i2c_retry(self._device.write8, MPR121_NHDF, 0x05)
self._i2c_retry(self._device.write8, MPR121_NCLF, 0x01)
self._i2c_retry(self._device.write8, MPR121_FDLF, 0x00)
self._i2c_retry(self._device.write8, MPR121_NHDT, 0x00)
self._i2c_retry(self._device.write8, MPR121_NCLT, 0x00)
self._i2c_retry(self._device.write8, MPR121_FDLT, 0x00)
# Set other configuration registers.
self._i2c_retry(self._device.write8, MPR121_DEBOUNCE, 0)
self._i2c_retry(self._device.write8, MPR121_CONFIG1, 0x10) # default, 16uA charge current
self._i2c_retry(self._device.write8, MPR121_CONFIG2, 0x20) # 0.5uS encoding, 1ms period
# Enable all electrodes.
self._i2c_retry(self._device.write8, MPR121_ECR, 0x8F) # start with first 5 bits of baseline tracking
# All done, everything succeeded!
return True