Learning Examples | Foundations | Hacking | Links
full tutorial coming soon
/* qt401 demo
* ------------
*
* the qt401 from qprox http://www.qprox.com is a linear capacitive sensor
* that is able to read the position of a finger touching the sensor
* the surface of the sensor is divided in 128 positions
* the pin qt401_prx detects when a hand is near the sensor while
* qt401_det determines when somebody is actually touching the sensor
* these can be left unconnected if you are short of pins
*
* read the datasheet to understand the parametres passed to initialise the sensor
*
* Created January 2006
* Massimo Banzi http://www.potemkin.org
*
* based on C code written by Nicholas Zambetti
*/
// define pin mapping
int qt401_drd = 2; // data ready
int qt401_di = 3; // data in (from sensor)
int qt401_ss = 4; // slave select
int qt401_clk = 5; // clock
int qt401_do = 6; // data out (to sensor)
int qt401_det = 7; // detect
int qt401_prx = 8; // proximity
byte result;
void qt401_init() {
// define pin directions
pinMode(qt401_drd, INPUT);
pinMode(qt401_di, INPUT);
pinMode(qt401_ss, OUTPUT);
pinMode(qt401_clk, OUTPUT);
pinMode(qt401_do, OUTPUT);
pinMode(qt401_det, INPUT);
pinMode(qt401_prx, INPUT);
// initialise pins
digitalWrite(qt401_clk,HIGH);
digitalWrite(qt401_ss, HIGH);
}
//
// wait for the qt401 to be ready
//
void qt401_waitForReady(void)
{
while(!digitalRead(qt401_drd)){
continue;
}
}
//
// exchange a byte with the sensor
//
byte qt401_transfer(byte data_out)
{
byte i = 8;
byte mask = 0;
byte data_in = 0;
digitalWrite(qt401_ss,LOW); // select slave by lowering ss pin
delayMicroseconds(75); //wait for 75 microseconds
while(0 < i) {
mask = 0x01 << --i; // generate bitmask for the appropriate bit MSB first
// set out byte
if(data_out & mask){ // choose bit
digitalWrite(qt401_do,HIGH); // send 1
}
else{
digitalWrite(qt401_do,LOW); // send 0
}
// lower clock pin, this tells the sensor to read the bit we just put out
digitalWrite(qt401_clk,LOW); // tick
// give the sensor time to read the data
delayMicroseconds(75);
// bring clock back up
digitalWrite(qt401_clk,HIGH); // tock
// give the sensor some time to think
delayMicroseconds(20);
// now read a bit coming from the sensor
if(digitalRead(qt401_di)){
data_in |= mask;
}
// give the sensor some time to think
delayMicroseconds(20);
}
delayMicroseconds(75); // give the sensor some time to think
digitalWrite(qt401_ss,HIGH); // do acquisition burst
return data_in;
}
void qt401_calibrate(void)
{
// calibrate
qt401_waitForReady();
qt401_transfer(0x01);
delay(600);
// calibrate ends
qt401_waitForReady();
qt401_transfer(0x02);
delay(600);
}
void qt401_setProxThreshold(byte amount)
{
qt401_waitForReady();
qt401_transfer(0x40 & (amount & 0x3F));
}
void qt401_setTouchThreshold(byte amount)
{
qt401_waitForReady();
qt401_transfer(0x80 & (amount & 0x3F));
}
byte qt401_driftCompensate(void)
{
qt401_waitForReady();
return qt401_transfer(0x03);
}
byte qt401_readSensor(void)
{
qt401_waitForReady();
return qt401_transfer(0x00);
}
void setup() {
//setup the sensor
qt401_init();
qt401_calibrate();
qt401_setProxThreshold(10);
qt401_setTouchThreshold(10);
beginSerial(9600);
}
void loop() {
if(digitalRead(qt401_det)){
result = qt401_readSensor();
if(0x80 & result){
result = result & 0x7f;
printInteger(result);
printNewline();
}
}
}