by jamie allen Feb, 2007

Code sample for timing the 'throw' of a mercury or ball tilt switch to infer force of an impact. The tilt switch is arranged such that it is 'open' when stationary, and switches when force (acceleration) is incident on a given axis of the circuit assembly. The momentum given to the 'ball' or mercury of the switch is proportional to the incident force, as is, resultantly, the time that the switch is 'closed'. Further described in the code comments below.

With some averaging and/or thresholding, this technique can be quite useful.



/* Tilt switch timimng force sensing
 * 
 * This is an alternate way of using a tilt sensor, stably mounted
 * on a given axis through which you're trying to measure force. If
 * mounted in such a way as the angle of the tilt switch inside your
 * object is fairly stable, this method gives consistent relative
 * force measurments.
 *
 * The below code was adapted most notably from
 * Tod E. Kurt's <tod@todbot.com> code for timing a standard piezo buzzer
 * to allow for inference of 'force'.
 * 
 * Jamie Allen for ITP Sensor Workshop class, 2007
 *
 * I've used this idea with 3-tilt switches, which, when arranged 
 * perpendicularly to one another, gives you force vectors in three axes.
 * Consider using these redundantly with an accelerometer, for example,
 * to trigger finer force measurements or handle out-of-scale acceleration conditions.
 */

int ledPin = 13;
int tiltPin = 7;

int THRESHOLD = 100;  // set minimum value that indicates a knock

int val = 0;       // variable to store the value coming from the tilt switch
int t = 0;         // the "time" measured for how long the knock lasts

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(tiltPin, INPUT);
  digitalWrite(tiltPin, HIGH);
  Serial.begin(9600); 
  //Serial.println("ready");      // indicate we're waiting
}

void loop() {
  digitalWrite(ledPin,LOW);     // indicate we're waiting

  val = digitalRead(tiltPin);   // read piezo
  if( val == LOW) {      // did it switch?
    digitalWrite(ledPin, HIGH); // tell the world
    t = 0;
    while(digitalRead(tiltPin) == LOW) {
      t++;  //this will contain a 'relative' timing value, proportional to the force of the hit 
    }
    if(t!=0) 
      Serial.println(t,DEC);
  }
}