Capacitive Sensor Visualization With Processing

Introduction: Capacitive Sensor Visualization With Processing

About: Sophia Brueckner, born in Detroit, MI, is an artist, designer, and engineer. Inseparable from computers since the age of two, she believes she is a cyborg. She recently graduated from the MIT Media Lab and the…

To test and demo the e-textile capacitive wheel I worked on with Rachel Freire, we visualized the sensors' responsiveness with Processing. It was much easier to see what was going on using a visualization rather than just looking at the Serial Monitor in the Arduino IDE.

We used fabric to make our sensors along with a Teensy 3.2, but you could adapt this to work with other sensors and boards. See Rachel's instructable on how to make an e-textile capacitive wheel here.

Step 1: Tools and Materials


Arduino IDE

Processing IDE


Teensy 3.2 (or similar)

Capacitive sensors

Step 2: Arduino Code


// List of pins that are used for the touch
// sensors. const int touchPin1 = 15; const int touchPin2 = 17; const int touchPin3 = 18; const int touchPin4 = 19; const int touchPin5 = 16; const int touchPin6 = 22; void setup(void) { Serial.begin(9600); } void loop(void) { // JSON is a way to structure data that is easy to work with in // Processing. String json; // I assigned a lowercase letter to each touch sensor. // In our case, we had 6 sensors that I named a-f. We read // from each sensor and then assemble the JSON from concatenated // strings. The JSON for this example looks like: // {a:1000,b:1,c:1200,d:3000,e:4000,f:2000} json = "{\"a\":"; json = json + touchRead(touchPin1); json = json + ",\"b\":"; json = json + touchRead(touchPin2); json = json + ",\"c\":"; json = json + touchRead(touchPin3); json = json + ",\"d\":"; json = json + touchRead(touchPin4); json = json + ",\"e\":"; json = json + touchRead(touchPin5); json = json + ",\"f\":"; json = json + touchRead(touchPin6); json = json + "}"; // This gets printed to Serial, which Processing will read. Serial.println(json); delay(200); }

After uploading this to your board, you can test that it outputs the correct JSON by opening the Serial Monitor in the Arduino IDE (see screenshot). Make note of the biggest values being read from your sensors for your Processing program.

Step 3: Processing Code


import processing.serial.*;


Serial port_; JSONObject json_; float[] pinValues_; int maxPinInput_ = 9000; // UPDATE THIS TO THE MAX VALUE YOU READ FROM YOUR SENSORS

void setup() { size(400, 400); // The code below will print out all your ports to your console. // MAKE A NOTE of which port is the first listing for /dev/tty.usbmodem#####. for (int i = 0; i < Serial.list().length; i++) { println(Serial.list()[i]); } // CHANGE 2 TO BE WHICHEVER PORT WAS /DEV/TTY.USBMODEM#######. // You start counting with 0. Ours was the third listing, so we put 2. String portName = Serial.list()[2]; port_ = new Serial(this, portName, 9600); pinValues_ = new float[numPins_]; for (int i = 0; i < numPins_; i++) { pinValues_[i] = 0; } }

void draw() { if (getData()) { background(255); // clears background // The value read from each sensor gets mapped to the range [0, Screen Width]. // This value becomes the length of the rectangle associated with that sensor. float rh = height / pinValues_.length; float maxRw = width; fill(255, 0, 0); for (int i = 0; i < pinValues_.length; i++) { float rw = map(pinValues_[i], 0, maxPinInput_, 0, maxRw); rect(0, i * rh, rw, rh); } } }

boolean getData() { if (port_.available() > 0) { // If data is available, json_ = parseJSONObject(port_.readString()); // println(json_); if (json_ != null) { pinValues_[0] = json_.getInt("a"); // IF YOU HAVE MORE OR LESS SENSORS, UPDATE THIS pinValues_[1] = json_.getInt("b"); pinValues_[2] = json_.getInt("c"); pinValues_[3] = json_.getInt("d"); pinValues_[4] = json_.getInt("e"); pinValues_[5] = json_.getInt("f"); // println(pinValues_); return true; } } // println("INVALID JSON"); return false; }

Step 4: Run

After uploading the .ino file to your board, compile and run your processing sketch.

NOTE: You cannot have the Arduino Serial Monitor and the Processing sketch running at the same time.

In the Processing code, you can adjust maxPinInput_ at the top of the file to make the visualization more or less responsive.

1 Person Made This Project!


  • Build a Tool Contest

    Build a Tool Contest
  • Colors of the Rainbow Contest

    Colors of the Rainbow Contest
  • Remote Control Contest

    Remote Control Contest



Question 2 years ago on Step 4

I have successfully drafted the Ardunio code for capacitive sensing. The serial Monitor shows right values.
Also, I have successful drafted the processing code which shows the exact same values from Arduino’s serial monitor on processing’s console.
However, on processing the drawing function is not doing by desired drawing when reading values. Moreover, both codes are working fine independently.
Please help.
Moreover, my processing code works fine with other ardunio example code. That is drawings change.
Thank you for helping

#include /*
* CapitiveSense Library Demo Sketch
* Paul Badger 2008
* Uses a high value resistor e.g. 10 megohm between send pin and receive pin
* Resistor effects sensitivity, experiment with values, 50 kilohm - 50 megohm. Larger resistor values yield larger sensor values.
* Receive pin is the sensor pin - try different amounts of foil/metal on this pin
* Best results are obtained if sensor foil and wire is covered with an insulator such as paper or plastic sheet
CapacitiveSensor cs_4_2 = CapacitiveSensor(A4,A2); // 10 megohm resistor between pins 4 & 2, pin 2 is sensor pin, add wire, foilvoid setup()

cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate on channel 1 - just as an example


void loop()
long start = millis();
long total1 = cs_4_2.capacitiveSensor(30);

//Serial.println(millis() - start); // check on performance in milliseconds//Serial.println("\t"); // tab character for debug window spacing

Serial.println(total1); // print sensor output 1
delay(1000); // arbitrary delay to limit data to serial port

import processing.serial.*;
import processing.serial.*; // import the Processing serial library
Serial myPort; // The serial portint sensor1;
int sensor2;
int sensor3;
float mappedSensor1;
float mappedSensor2;
float mappedSensor3;
PImage Gifimg;
PImage firstimg;
PImage secondimg;
PImage Frontimg; // Declare variable "a" of type PImage// Declare variable "a" of type PImagevoid setup() {
size(1080, 800);
// List all the available serial ports in the console
Gifimg = loadImage("secondsmall.png"); // Load the image into the program
Frontimg = loadImage("Frontsmall.png"); // Load the image into the program
secondimg = loadImage("finalsmall.png"); // Load the image into the program // Change the 0 to the appropriate number of the serial port// that your microcontroller is attached to.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
// read incoming bytes to a buffer// until you get a linefeed (ASCII 10):
void draw() {

if (sensor1 == 0) {
image(secondimg, 0, 0);
image(Gifimg, 0, 0);
else {
image(Frontimg, 0, 0);


void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
if (myString != null) {
// println(myString);
myString = trim(myString);

// split the string at the commas// and convert the sections into integers:int sensors[] = int(split(myString, ','));
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
// add a linefeed at the end:
sensor1 = sensors[0];

mappedSensor1 = map(sensor1, 0, 1023, height, 0);