Loading...

Learning   Examples | Foundations | Hacking | Links

qt401 sensor

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();

    }
  }

}