let me first say that I'm somewhat of a noob when it comes to i2c and serial communication. I've been trying for 2 days now to grasp it, reading datasheets, youtube videos etc. And I'm having a hard time grasping some concepts. I'm working within the node.js i2c library and referencing some python i2c projects.

1). my biggest struggle is understanding what the data means. I'm using the MPR121 sensor. The response is a buffer which is has a length of 32. I'm not sure what to do with these 32 pieces of info and what they mean. I'm not sure how to use the data sheet to tell me. if I convert my buffer to JSON it looks something like... [2,0,0,0,154,0,103,0,148,0,151,0,151,0,150,0,150,0,151,0,148,0,143,0,139,0,149,0,0,0,38,35] but again, I'm not sure what to do with that.

2). The node.js i2c library requires length for readByteData, where the python version doesn't. I'm not sure how I find that info besides using trial and error, like I did before to discover it was 32.

3). Other examples (node.js + i2c) use buffer functions like readInt16BE(2*1) and so on but node's documentation doesn't really explain what that is used for and why or why I shouldn't use it in my project.

I understand I'm probably over-ambitious and biting off more than I can chew. I also know that I should prob learn some basics first but I can't really find anything that teaches the basics. I guess I'm just looking for those few small answers to help make it click. Thanks.

  • 2
    This question appears to be off-topic because it is about i2c and had almost nothing about Raspberry Pi. You might get better luck trying Electronics Exchange or some other electronics related stackexchange site. – lenik Oct 1 '13 at 23:29

I've only used the i2c-dev C API so I can't comment much about how your python and js modules are supposed to work (although they must be built on top of the C API and should be pretty simple).

1). my biggest struggle is understanding what the data means. I'm using the MPR121 sensor. The response is a buffer which is has a length of 32.

Including some code here would make things clearer, but this is probably all 32 8-bit registers listed on page 10 of the data sheet.

The general idea is you are reading and writing to the registers described in the data sheet by address. For example, at the top of page 11 there are two "Touch Status" registers referred to, at addresses 0x00 and 0x01. Notice the addresses are 8-bit numbers,1 and so are the default values on page 10. This implies the registers themselves are 8-bits, and indeed, the little chart at the top of page 11 shows the meaning of the eight bits in each of the two registers. These ones are evidently read-only, since the "Write" rows are grayed out.

[If you do not know what a bit field is, or what bitwise AND, OR, etc., refer to, you need to do some reading.]

Each bit indicates some kind of state is either set (1) or unset (0). If you want to find the state of a bit in the first touch status register, you would read one byte (eight bits) from address 0x00 and then AND that with a one byte mask whose value is the bit you want to check (so, e.g., to check the third bit you'd AND with a mask value of 4).

To set a bit for writable registers, you need to write a whole byte. That means you first need to get the value in the register and OR it against a mask with that bit set, and write the OR'd value. To unset a bit, you'd AND with a mask that has all bits except that one set (so to unset the third bit, you'd AND with a mask value of 255 - 4 = 251).

In C, you would be dealing with the literal 1 byte (8-bit) value. A js or python library may provide some related convenience functions, but really there is not much for them to do beyond wrap the read and write calls. Note that all three languages use the same bitwise operators.

1 Because 0x00 is a hexadecimal number with two digits (the '0x' prefix is convention), and the range of two hexadecimal digits is 16 * 16, 0-ff, just as the range of two decimal digits is 10 * 10, 0-99. 16 * 16 = 256, which is the range of an 8-bit number (2^8 = 256), 0-255 in decimal. Each value represents a unique combination of bits and in one byte there are 256 possible unique combinations.

| improve this answer | |
  • goldilocks, I really appreciate it and your explanation was great. I do definetly need to read up on bit field and bitwise. I attached a git link in the other answers response... github.com/thegregthomp/working-MPR121/blob/master/server.js. I did see that the operators are the same. and also the py equivalent of what I'm trying to do.. github.com/scottgarner/BeetBox/blob/master/mpr121.py. If my response is strictly "Buffer", In C, how would I translate that to usable data. What I'd like to know is the status of each of the 12 sensors. – G Thompson Oct 1 '13 at 17:10

Based on the data and the data sheet, the values appear to be the register values, starting from address 0.

If you look at page 5 of the datasheet (found here), this would mean the values by index are:

0:  8 single bit flags for touch status
1:  Some more bit flags for touch status and some other flags
2:  8 single bit flags for out-of-range errors
3:  Some more bit flags for out-of-range errors and some other flags
4:  Lower 8 bits of the reading for electrode 0
5:  Upper 2 bits of the reading for electrode 0
6:  Lower 8 bits of the reading for electrode 1
7:  Upper 2 bits of the reading for electrode 1
26: Lower 8 bits of the reading for electrode 11
27: Upper 2 bits of the reading for electrode 11
26: Lower 8 bits of the reading for the aggregate (based on all readings)
27: Upper 2 bits of the reading for the aggregate (based on all readings)
28: Baseline for electrode 0
29: Baseline for electrode 1
30: Baseline for electrode 2
31: Baseline for electrode 3

The question seems to be what are you trying to achieve, for example if you wanted the raw reading for electrode 0, you can read if from the byte array as:

rawElectrode[0] = (rawData[5] << 8) | rawData[4];

then you may want to remove the baseline value using:

electrode[0] = rawElectrode[0] - (rawData[28] << 2);


Assuming you are just trying to detect that a touch has happened the same way the example in Python does:

function readData(address){
    wire.readBytes(address, 2, function(err, res) {
        if (!err) {
            MSB = res[0];
            LSB = res[1];
            touchData = MSB;
        } else {
            return console.log(err+',read failed');
            console.log(res); //Returns <bytes>

excuse my javascript, I do not use it so I am guessing syntax, but it should help you understand what is happening a bit better.

| improve this answer | |
  • Pi, thank you so much for your time. I put up a quick git to show what I'm doing. I'd basically just like to detect the status of a sensor on an interval... here's a link... github.com/thegregthomp/working-MPR121/blob/master/server.js I'm working off of... github.com/scottgarner/BeetBox/blob/master/mpr121.py which is a working py library. – G Thompson Oct 1 '13 at 16:49
  • Thanks, syntax looks good, but curious why you'd use 2 as the length? This i2c Package requires length for the call – G Thompson Oct 1 '13 at 19:55
  • The Python code you are starting from actually only reads two values in, that is where the 2 came from. Reading more should not hurt. – PiBorg Oct 1 '13 at 22:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.