Did anybody use CAP1188?

Andy Belov

Well-known member
I just found out that MPR121 (12 capacitive sensors in one chip) is no longer made and has been replaces with CAP1188 (same thing, only 8 sensors).
Did anybody try it yet with Teensy?

I'm going to buy and try it, but if somebody did already, please let me know if I should bother.

Thanks.
 
Just got 3 of these: https://learn.adafruit.com/adafruit-cap1188-breakout/wiring
Put them on the breadboard, ran I2C scanner and says that it found all 3, but the Adafruit example says "CAP1188 not found".
I did try all 3 addresses.
Did anybody get it working?

Here is the example from Adafruit in their library:
Code:
/*************************************************** 
  This is a library for the CAP1188 I2C/SPI 8-chan Capacitive Sensor

  Designed specifically to work with the CAP1188 sensor from Adafruit
  ----> [url]https://www.adafruit.com/products/1602[/url]

  These sensors use I2C/SPI to communicate, 2+ pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/
 
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_CAP1188.h>

// Reset Pin is used for I2C or SPI
#define CAP1188_RESET  9

// CS pin is used for software or hardware SPI
#define CAP1188_CS  10

// These are defined for software SPI, for hardware SPI, check your 
// board's SPI pins in the Arduino documentation
#define CAP1188_MOSI  11
#define CAP1188_MISO  12
#define CAP1188_CLK  13

// For I2C, connect SDA to your Arduino's SDA pin, SCL to SCL pin
// On UNO/Duemilanove/etc, SDA == Analog 4, SCL == Analog 5
// On Leonardo/Micro, SDA == Digital 2, SCL == Digital 3
// On Mega/ADK/Due, SDA == Digital 20, SCL == Digital 21

// Use I2C, no reset pin!
//Adafruit_CAP1188 cap = Adafruit_CAP1188();

// Or...Use I2C, with reset pin
Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_RESET);

// Or... Hardware SPI, CS pin & reset pin 
// Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_CS, CAP1188_RESET);

// Or.. Software SPI: clock, miso, mosi, cs, reset
//Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_CLK, CAP1188_MISO, CAP1188_MOSI, CAP1188_CS, CAP1188_RESET);

void setup() {
  Serial.begin(9600);
  Serial.println("CAP1188 test!");

  // Initialize the sensor, if using i2c you can pass in the i2c address
  if (!cap.begin(0x28)) {
    Serial.println("CAP1188 not found");
    while (1);
  }
  Serial.println("CAP1188 found!");
}

void loop() {
  uint8_t touched = cap.touched();

  if (touched == 0) {
    // No touch detected
    return;
  }
  
  for (uint8_t i=0; i<8; i++) {
    if (touched & (1 << i)) {
      Serial.print("C"); Serial.print(i+1); Serial.print("\t");
    }
  }
  Serial.println();
  delay(50);
}
 
Last edited by a moderator:
Might help to have additional information, like what Teensy? What pins are you hooked up to? Pictures are good as it helps find things like, if someone put their Teensy on a breadboard, but the pins are not soldered to the Teensy or ...

And what addresses did yours show up as? i.e. what resistor... did you use to set address? That is did address 0x28 show up in the list of scan? As I think that is the one you are trying to use in the example app...
 
Looking at that library's code, I see the begin() function is supposed to print a few lines to the serial monitor.

Code:
  // Useful debugging info

  Serial.print("Product ID: 0x");
  Serial.println(readRegister(CAP1188_PRODID), HEX);
  Serial.print("Manuf. ID: 0x");
  Serial.println(readRegister(CAP1188_MANUID), HEX);
  Serial.print("Revision: 0x");
  Serial.println(readRegister(CAP1188_REV), HEX);

In setup(), add this line so it will wait for you to open the serial monitor:

Code:
  while (!Serial) ; // wait

With that added, you should always see at least "CAP1188 test!" printed. Do those 3 other lines from within the begin() function print anything?
 
Sorry, forgot the connections and the monitor output.
I just thought that the fact that the I2C scanner finds all boards proves that the connections are good.
I use I2C on pins 18 and 19.

Here is the board:
20191012_185729.jpg


This is what I see in the serial monitor in the test:
CAP1188 test!
Product ID: 0x50
Manuf. ID: 0x1
Revision: 0x1
CAP1188 not found


This is the I2C scanner output:
I2C Scanner
Scanning...
I2C device found at address 0x28 !
I2C device found at address 0x29 !
I2C device found at address 0x2A !
done

I tried with and without the reset pin, tried all addresses.

Appreciate you looking into this.
 
Which version of Teensyduino are you using?

Version 1.48 (the latest) fixed a bug in the Wire library. If you're using 1.47 or older, please update to 1.48.
 
Yesterday I downloaded the latest of everything.
Checking now.
Adduino help says Adruino 1.8.10 and Teensyduino 1.48
The Adafruit library I downloaded today.
 
Can you confirm whether the problem happens with only 1 of these boards, or if 2 or 3 are needed.

I will order 1, 2 or 3 from Adafruit for testing, depending on your answer.
 
Looks like the register values are not reading back what it expects, the product ID is right but the revision and Manufacturer ID are not. Here is what the library expects the values to be:
Code:
   if ((readRegister(CAP1188_PRODID) != 0x50) ||
      (readRegister(CAP1188_MANUID) != 0x5D) ||
      (readRegister(CAP1188_REV) != 0x83)) {
    return false;
  }

You can change those values in this if statement to the values that Serial monitor shows and see if it works after that. This is located in the begin function directly after the Serial prints so this is what is causing it to say not detected even though it is reading from the chips.
 
Tried to change the "if" like below. Still see the "?????" in the monitor. Don't understand how it can print "0x1" and fail to compare to it.
Anyway, I commented the "if" out and can see the touches, but they never go away after I stop touching. Once touched, it stays "touched" until I power it down.
And sensor 1 is "touched" on power up, even though I never touch it.
Tried with 1 and 3 chips, same thing.

/*if ((readRegister(CAP1188_PRODID) != 0x50) ||
(readRegister(CAP1188_MANUID) != 0x1) ||
(readRegister(CAP1188_REV) != 0x1)) {
Serial.println("?????");
return false;
}*/

I'll keep digging and adding serial outputs in the Adafruit library to see if I can find something.

Thanks for all the help.
 
I've ordered 1 from Adafruit. It will probably take about 1 week to arrive, since they can't ship until Tuesday and it has to go from New York to Oregon.
 
For what it is worth, I did order one which arrived today, and can verify...
Code:
Product ID: 0x50
Manuf. ID: 0x1
Revision: 0x1
CAP1188 not found


I believe it is a timing issue. As if I edit the area that prints out the registers:
Code:
  readRegister(CAP1188_PRODID);
  delay(2); //////

  // Useful debugging info

  Serial.print("Product ID: 0x");
  Serial.println(readRegister(CAP1188_PRODID), HEX);
  delay(2); //////
  Serial.print("Manuf. ID: 0x");
  Serial.println(readRegister(CAP1188_MANUID), HEX);
  delay(2); //////
  Serial.print("Revision: 0x");
  Serial.println(readRegister(CAP1188_REV), HEX);
  delay(2); //////

  if ((readRegister(CAP1188_PRODID) != 0x50) ||
      (readRegister(CAP1188_MANUID) != 0x5D) ||
      (readRegister(CAP1188_REV) != 0x83)) {
    return false;
  }
  // allow multiple touches
I now get:
Code:
Product ID: 0x50
Manuf. ID: 0x5D
Revision: 0x83
CAP1188 not found
 
Actually if I remove those delays and put a delay(1) in readRegister like:
Code:
uint8_t Adafruit_CAP1188::readRegister(uint8_t reg) {
  if (_i2c) {
[COLOR="#FF0000"]    delay(1);[/COLOR]
    _wire->beginTransmission(_i2caddr);
    i2cwrite(reg);
    _wire->endTransmission();
    _wire->requestFrom(_i2caddr, 1);
    return (_wire->read());
  } else {

I now get
Code:
CAP1188 test!
Product ID: 0x50
Manuf. ID: 0x5D
Revision: 0x83
CAP1188 found!
 
Thanks, Kurt.

I have no idea how you figured it out, but that was the first half of the solution.
Addind the "delay(1);" in readRegister fixes the reading.

What I also found that it fixes the writing as well.
Before, if you touched a sensor, it would stay "touched" until you power off.
After I added the same delay in writeRegister, the sensors show as "touched" only when I touch them.

Code:
void Adafruit_CAP1188::writeRegister(uint8_t reg, uint8_t value) {
  if (_i2c) {
    delay(1); // I added this to "clear" the touch
    _wire->beginTransmission(_i2caddr);
Well, it's all good, but one thing I still miss from MPR121 is it's "analog" touch: it would give you the initial (base) capacity and the current one.
Then I can use it for "expression" in my musical instrument. Or, you could do a "slide" sensor out of two triangles next to each other.

I guess I'll try to see what registers the CAP1188 has. Maybe it's easy to read the capacity value.

Thanks again for your help.
 
Last edited:
Glad it is working.

I tried the delay as I first looked at it with Logic Analyzer and it looked like the I2C Speed was within spec... And the first register read returned what appeared to be correct. So wondered it I put a delay in between them would do anything and ...

What I have not done yet is to see how little of a delay may work. That is currently I put in 1ms (1000us). Might try reducing this, like would
delayMicroseconds(100); work.. If so would 50...

Also maybe @Paul will have other suggestions as I don't use I2C very often and know all of the ins and outs, like this device might support clock stretching, but not sure of if/how the T4 handles this and/or if the library does not, is there something that can or should be enabled...
 
Wow, that's advanced. I need to start learning about all this Logic Analyzer thingy. Which one do you use? Hope it's not too expansive.

My guess is that Teensy 4.0 is so much fast than anything out there, that we may see more bugs like this one, related to the timing.
 
Wow, that's advanced. I need to start learning about all this Logic Analyzer thingy. Which one do you use? Hope it's not too expansive.

I've not used it, but the author of Gamedunio3 has come out with two devices, one that analyzes i2c bus protocol and the other spi bus protocol:

Since I2C is a relatively slow protocol, I would imagine you don't need extremely high speed analysis tools.

My guess is that Teensy 4.0 is so much fast than anything out there, that we may see more bugs like this one, related to the timing.

I would have hoped even the Teensy 3.x and similar ARM M4 Adafruit/Arduino/Sparkfun boards would have already exposed a lot of these slow devices that were only made for AVR 328p (i.e. Arduino Uno) speeds. But yes, if you need to insert delays because of the device, it can be a pain.
 
Last edited:
I have some Logic Analyzers from Saleae: https://www.saleae.com/ which are not cheap. I currently actually have 3 of them. I have one of their old 16 bit ones, then when they had the equivalent of a Kickstarter, I ordered one of their new 8 bit ones, which is great. But when I started doing more stuff with higher speed devices, I then purchased one of their 8 bit pro units.

If you are just a hobbyist like me, you can get a discounted price on them: https://blog.saleae.com/saleae-discounts/

There are some knockoffs of their earlier boards out there. Some of which hopefully get squashed as they point their users to use the software from Saleae... But others use some open source code which is fine.

Also you can use a Teensy as a Logic Analyzer. There is a good setup: https://github.com/LAtimes2/TeensyLogicAnalyzer
I have not tried it in awhile, wonder how it would work with T4?

And as @MichaelMeissner mentioned I would have thought some issues like this would have been hit with some other chips as well.

Note: I don't see any open/closed issues or Pull requests that mention anything like this. Maybe should boil this down and report it and/or propse update to them...
 
Thanks, Michael.
This is as affordable as it gets: $29 for each.
I still hope for the other people to do the tedious work for me (he-he).

Maybe I need to start looking for an alternative to Adafruit's CAP1188.
I expect things just to work if they are sold. Well, maybe with a little effort.
 
Was a resolution ever found for this problem?

I'm sitting here with an Adafruit CAP1188, also purchased for musical instrument design. When I run the Adafruit example for the CAP1188, my Teensy3.6 shows no response. Going to the Adafruit forum link in the last message, I see there was no response to the post there.
 
Back
Top