diff --git a/java/libraries/io/examples/Touch_I2C_MPR121/MPR121.pde b/java/libraries/io/examples/Touch_I2C_MPR121/MPR121.pde new file mode 100644 index 000000000..0ef023820 --- /dev/null +++ b/java/libraries/io/examples/Touch_I2C_MPR121/MPR121.pde @@ -0,0 +1,112 @@ +import processing.io.I2C; + +// MPR121 is a capacitive-touch sensor controller with 12 channels +// datasheet: https://www.nxp.com/docs/en/data-sheet/MPR121.pdf + +class MPR121 extends I2C { + int address; + int touched; + + // registers used (there are more) + static final int EFD0LB = 0x04; // ELE0 Electrode Filtered Data LSB + static final int E0TTH = 0x41; // ELE0 Touch Threshold + static final int E0RTH = 0x42; // ELE0 Release Threshold + static final int E0BV = 0x1e; // ELE0 Baseline Value + static final int MHDR = 0x2b; // MHD Rising + static final int NHDR = 0x2c; // NHD Amount Rising + static final int NCLR = 0x2d; // NCL Rising + static final int MHDF = 0x2f; // MHD Falling + static final int NHDF = 0x30; // NHD Amount Falling + static final int NCLF = 0x31; // NCL Falling + static final int CDT = 0x5d; // Filter/Global CDT Configuration + static final int ECR = 0x5e; // Electrode Configuration + static final int SRST = 0x80; // Soft Reset + + // there can be more than one device connected to the bus + // as long as they have different addresses + // possible addresses: 0x5a (default) - 0x5d + MPR121(String dev, int address) { + super(dev); + this.address = address; + reset(); + } + + void update() { + beginTransmission(address); + write(0x00); + byte[] in = read(2); + // & 0xff makes sure the byte is not interpreted as a negative value + touched = (in[1] & 0xff) << 8 | (in[0] & 0xff); + } + + boolean touched(int channel) { + if (channel < 0 || 11 < channel) { + return false; + } + if ((touched & (1 << channel)) != 0) { + return true; + } else { + return false; + } + } + + void threshold(int touch, int release) { + for (int i=0; i < 12; i++) { + threshold(touch, release, i); + } + } + + void threshold(int touch, int release, int channel) { + if (channel < 0 || 11 < channel) { + return; + } + touch = constrain(touch, 0, 255); + release = constrain(release, 0, 255); + writeRegister(E0TTH + 2*channel, touch); + writeRegister(E0RTH + 2*channel, release); + } + + int analogRead(int channel) { + if (channel < 0 || 11 < channel) { + return 0; + } + beginTransmission(address); + write(EFD0LB + 2*channel); + byte[] in = read(2); + return (in[1] & 0xff) << 8 | (in[0] & 0xff); + } + + int analogReadBaseline(int channel) { + if (channel < 0 || 11 < channel) { + return 0; + } + beginTransmission(address); + write(E0BV + channel); + byte[] in = read(1); + return (in[0] & 0xff) << 2; + } + + void reset() { + writeRegister(SRST, 0x63); + delay(1); + threshold(12, 6); + // set baseline filtering control registers (see p. 12) + writeRegister(MHDR, 0x01); + writeRegister(NHDR, 0x01); + writeRegister(NCLR, 0x0e); + writeRegister(MHDF, 0x01); + writeRegister(NHDF, 0x05); + writeRegister(NCLF, 0x01); + // change sample interval to 1ms period from default 16ms + writeRegister(CDT, 0x20); + // start sampling + writeRegister(ECR, 0x8f); + } + + void writeRegister(int register, int value) { + beginTransmission(address); + write(register); + write(value); + endTransmission(); + } +} diff --git a/java/libraries/io/examples/Touch_I2C_MPR121/Touch_I2C_MPR121.pde b/java/libraries/io/examples/Touch_I2C_MPR121/Touch_I2C_MPR121.pde new file mode 100644 index 000000000..58f69ad1c --- /dev/null +++ b/java/libraries/io/examples/Touch_I2C_MPR121/Touch_I2C_MPR121.pde @@ -0,0 +1,26 @@ +import processing.io.*; +MPR121 touch; + +// see setup.png in the sketch folder for wiring details + +void setup() { + size(600, 200); + //printArray(I2C.list()); + touch = new MPR121("i2c-1", 0x5a); +} + +void draw() { + background(204); + noStroke(); + + touch.update(); + + for (int i=0; i < 12; i++) { + if (touch.touched(i)) { + fill(255, 0, 0); + } else { + fill(255, 255, 255); + } + ellipse((width/12) * (i+0.5), height/2, 20, 20); + } +}