mpr121 - help reading filtered data

Dear davidb,

I'm encountering the same problem, but I think where we can find a solution.
However, trying to find a solution to this problem will just suck you deeper into the programming issue at hand.

It seems the MPR121 simply sends the touch status register data whenever the interrupt pin is high.
However, you want to read data from a different register, so you need to specifically request the data from a different register.

If you look at the datasheet, at section 6.4 'Read and Write Operation Format' you will see that a WRITE operation is fairly straightforward.

[ST][DeviceAddress][W] (AK) [RegisterAddress] (AK) [DATA] (AK) [SP]
where ST = Start Condition, W = Write (=0) and SP = Stop Condition.
straight brackets are master actions and curly brackets are slave operations

  1. You send a Start condition [ST] and the device address with Wire.beginTransmission( 0x5A );
  2. You send the register address you want to write to with Wire.write( 0xXX );
  3. You send the value you want to write with Wire.write( yourValue );
  4. You send a stop condition with Wire.endTransmission();

Now if we take a Byte Read operation, this has a somewhat different format.
[ST][DeviceAddress][W] (AK) [RegisterAddress] (AK) [SR][DeviceAddress][R] (AK)(Data) [NAK][SP]
where ST = Start Condition, SR = Start Condition Repeated, W = Write (=0), R = Read (=1) and SP = Stop Condition.
straight brackets are master actions and curly brackets are slave operations

With this operation, you run into the limitations of the Wire library as it is provided by the Arduino. (Or at least so it seems)

  1. You send a start condition [ST] and the device address with Wire.beginTransmission( 0x5A );
  2. You send the register address with Wire.write( 0xXX );
  3. Uh-oh, we have to send a Start Condition again with the device address (which would be Wire.beginTransmission( 0x5A ); ).

I've looked into the Wire library and the Wire.beginTransmission inherently sends a start condition [ST].
So, this would mean we again send Wire.beginTransmission( 0x5A ), but this time with a READ bit at the end (1 instead of 0).
The function Wire.requestFrom() does this, but internally taps from a different buffer (rxBuffer instead of txBuffer), thus we can't use this.

Another thing we could do is again use Wire.beginTransmission, and bitshift the device address to the left and add the READ bit to the end.
However, the beginTransmission() overwrites the information we had already entered there the first time. This is because the buffer is only send when using endTransmission().

What could be done is that we first send the device address and the register address, then end the transmission (so the buffer is cleared), then restart the transmission with the bitshifted device address (still following?!?). The problem with this is that the endTransmission internally sends a STOP condition.

As you see, there is not a simple solution to this issue. You need to be able to manually send a Start condition [SR] or be able to remove the STOP condition from the endTransmission in order to stick to the format of the MPR121.
Anyone with good suggestions/solutions is welcome to post them! :slight_smile: