Touch Sliders With A Softpot + Arduino

Monday, November 26 th , 2012

You all know the potentiometer, you turn it, and you can read on your arduino where it was turned to. Well 3M makes a product called the softpot that is a linear touch potentiometer. So instead of turning a knob, you touch it.

The really nice thing about these is that they are great for prototypes because you can tell where someone touched it. So if you place a piece of paper with some printed buttons over it, you can mock up surface touch buttons. Or if you need to prototype a rotary touch wheel like the old ipods, but don’t want to get involved with complex capitative sensors, you can do that too.

There are a million uses for these, and they come in a few sizes, shapes, and even offer high temperature versions.

Hooking it up

The softpot sensors change their resistance depending on where they are touched. And because they work just like potentiometers you don’t need any extra parts to use them with your arduino. We can just plug in the middle pin to an analog in pin on the arduino and we are ready to go.

The arduino analogRead will vary between 0 and 1023 depending on where you touch it, (1023 when not being touched) and is linear, so it will be about 512 if touched in the middle.

WARNING!!!!!

If you touch the softpot at the top and the bottom at the same time, it will get really hot, really quick, and if you leave it for more than a second, you may burn it up. I have no clue why. But beware!

This is especially an issue on the round version. If you press down dead center on the bottom (where the straight parts come off of), you will be pressing on both sides of the pot and it will again get super hot and melt. SO DONT PRESS IT IN THE MIDDLE BOTTOM

Code

The arduino code for this just could not be easier. We are adding some serial prints and delays to it just so you can easily see the readings, but they dont need to be there if you dont need them.

int softpotPin = A0; //analog pin 0

void setup(){
digitalWrite(softpotPin, HIGH); //enable pullup resistor
Serial.begin(9600);
}

void loop(){
int softpotReading = analogRead(softpotPin);

Serial.println(softpotReading);
delay(250); //just here to slow down the output for easier reading
}

Get Touchy – Nintendo DS Touch Screen + Arduino

Monday, June 13 th , 2011

It seems like touch screens are plastered on every consumer electronic device from your phone to your refrigerator. And why not right? Well, even though those beautiful multitouch hi-res screens are a little pricy and crazy hard to develop with, doesn’t mean we cant still add a touch panel to our project. The touch panel from the Nintendo DS provides a very simple, inexpensive solution to allow us to do just that.

The Nintendo DS panel is a resistive panel making it very easy to hook it up to our Arduino, but it only recognizes a single input at a time and is a little imprecise.

Hooking It Up

If you are going to use this, I highly recommend using the breakout board with it because it is a little hard soldering directly to the ribbon cable. If you are using the breakout board: The ribbon from the panel it too thin to be used with the breakout board, and it will just fall out (weird I know). To fix this I stuck 2 layers of scotch tape over the back and cut off the excess with an x-acto blade – just make sure not to cut the ribbon. The brown plastic part of the breakout-board connector pulls out so you can slide the ribbon in it (pins side up). Once you have the ribbon in, and aligned nicely, make sure to slide the connector close to lock it into place.

Now that the panel is connected to the breakout, just note… the panel is actually now upside down (again… weird). I just flipped the panel over and to right so the ribbon was just bent at a 45ยบ angle, but you can do whatever works best for you.

If you are wondering where the [[VCC|+]]/[[-|GND]] & [[resistors]] are… don’t worry about it. Just connect the 4 pins into the Arduino as shown and you are ready for the code. This really is how it goes, it gets power and ground from the pins based on how the code works.

Code

This code may look a little funky at first, so just hold on. If you didn’t know, the analog pins can be used as digital pins if needed and can be written to. The pins we are using need to act as digital pins at points and analog pins at others. Some people refer to the analog pins as pins 14-19 when using them as digital pins, and the Arduino will understand that. But that always confused the crud out of me when I was new to this so I will be referring to them as A0, A1, A2 & A3 because it does the same thing, and is much less confusing. Also, on the Arduino Mega, there is a digital pin 14, making things even weirder, so this takes that into consideration as well.

If you are still confused:

If you tell your arduino to do an analogRead on pin 0, it knows to read from analog pin 0. If you tell the arduino to do a digitalWrite on pin 0 it uses digital 0. We need to do a digitalWrite on analog 0, then an analogRead on analog 0 as well. So if we just said 0 for both, the Arduino would be confused and write to the digital 0 then read from analog 0. So we are saying A0 so it knows that whether we are reading or writing to that pin, we mean analog 0.

This code will just output the coordinates in the serial terminal when you touch it. The top left should be 0,0 and should move to about 800,770 in the bottom right. I shouldn’t output anything when it is not being touched.

If it does not respond when you touch the panel, try the other side, it is a little hard to tell just by looking at it, what the sensitive side is. If you tried both sides and it still does not respond, try repositioning the ribbon cable in the connector and try again.

[code lang=”arduino”]

int y1 = A0;
int x2 = A1;
int y2 = A2;
int x1 = A3;

void setup() {
Serial.begin(9600);
}

int readX(){
pinMode(y1, INPUT);
pinMode(x2, OUTPUT);
pinMode(y2, INPUT);
pinMode(x1, OUTPUT);

digitalWrite(x2, LOW);
digitalWrite(x1, HIGH);

delay(5); //pause to allow lines to power up

return analogRead(y1);
}

int readY(){

pinMode(y1, OUTPUT);
pinMode(x2, INPUT);
pinMode(y2, OUTPUT);
pinMode(x1, INPUT);

digitalWrite(y1, LOW);
digitalWrite(y2, HIGH);

delay(5); //pause to allow lines to power up

return analogRead(x2);
}

void loop()
{
int x = readX();
int y = readY();

if(x < 1000 & y < 1000){ Serial.print("x: "); Serial.print(x-100); Serial.print(" - y: "); Serial.println(y- 130); } delay(100); //just to slow this down so it is earier to read in the terminal - Remove if wanted } [/code]

Sensing Capacitive Touch – MPR121 + Arduino

Tuesday, May 31 st , 2011

Every now and then you get sick of the typical push buttons and you want something cooler. And what is cooler than touch sensitive things? Remember that old lamp in your Grandma’s that changed brightness just by touching the base? Yeah, that’s right… We are talking THAT cool! The [[Capacitive_Touch_Sensor_-_MPR121 |MPR121 capitative touch sensor]] gives you 12 of such inputs that we can use with our Arduino, and you can get it in several forms from SparkFun – Im using the basic breakout board.

How? Well… Capacitive sensing is pretty simple in concept. Every object has [[capacitance]], (in laymen’s terms capacitance is just an objects ability to hold a charge), and when you come in contact with something you change its capacitance. Well the [[Capacitive_Touch_Sensor_-_MPR121 |MPR121]] just looks for these changes, and tells us when it happens.

Hooking It Up

Hooking it up to your Arduino is pretty simple, the [[Capacitive_Touch_Sensor_-_MPR121 |MPR121]] is an [[I2C]] device. [[I2C]] is a 2-wire [[serial]] connection, so you just need to connect the SDA (Data) and SCL (Clock) lines to your Arduino for communication. On your Arduino (everything but the [[Arduino Mega|mega]]) SDA is on analog pin 4, and SCL is on analog pin 5. On an [[Arduino Mega]], SDA is digital 20, and SCL is digital 21.

When the MPR121 senses a change, it pulls an interrupt pin LOW. Now if we were ninja’s we would use this oppertunity to create an interrupt on our Arduino and deal with changed immediately. However, to simplify things for us non-ninjas, we are just going to check that pin to see if it is LOW during our loop. To do this, this sensor also needs access to another digital pin, and in this case we are using digital 2.

Electrodes

This is a touch sensor, so we need something to touch right? We call these electrodes. Typically, electrodes can just be some piece of metal, or a wire, or my favorite, metal tape (just make sure you have at least 1/2in of bare wire in contact with the sticky part of the tape for good contact). But some times depending on the length of our wire, or the material the electrode is on, it can make triggering the sensor difficult. For this reason, the MPR121 allows you to configure what is needed to trigger and untrigger an electrode. So if you are getting false or no positives, you may need to change that.

Proximity Sensing

There is a small change in capacitance even as you approach an electrode, just through the air. So if you set the touch threshold, or release threshold too low you may notice it trigger even a few inches away. If you want it to trigger from a decent distance away, the MPR121 supports aggregating all of the electrodes together to use it as a single large proximity sensor – But you will need to read the doc sheet to figure that one out, sorry.

Code

You may have noticed that SparkFun has example code for this sensor already – Actually, this code is slightly based off of theirs. But this setup and code is not limited to sensing one electrode at a time like their’s is. Also this is using the Wire Library to simplify the code to only 2 files. And… We can also sense when one of the electrodes is let go as well.

I know this code looks complicated, but most of it is just configuring the sensor (part based off of sparkFun’s code). All it does is output in the serial terminal when one of the electrodes is touched or untouched. You can touch all of them at once if you want, and it will show that, then just let go of one, and only that one will show as let go.

Feel free to change the setup values in section C to adjust the sensitivity of the electrodes. You will see constants used in the code such as TOU_THRESH, these values are defined in mpr121.h incase you need to change them.

If you want to trigger individual functions based on the electrode touched, you could do something like this and just add the call to your function under where it says “//X was touched”
[code lang=”arduino”]

if(touchStates[i] == 0){
//pin i was just touched
Serial.print(“pin “);
Serial.print(i);
Serial.println(” was just touched”);

switch (i) {
case 0:
//0 was touched

break;
case 1:
//1 was touched

break;
case 2:
//2 was touched

break;
case 3:
//3 was touched
}

}

[/code]

I hope this was helpful in getting your MPR121 up and running with your Arduino, and if you have any questions, please use the discussion link.

Video