Tilt sensor

Nettigo offers tilt sensors with 30° and 60° (exactly from -30° to +30°) operating range.
Tilt sensor is a kind of switch. The difference between it and regular switches is that the current starts to flow through it when it’s tilted. Such a sensors are commonly user in car alarm system They are monitoring car’s position and triggering the alarm when the car is dragged by a wrecker truck, for example.
It looks like this:

Hardware

Utilizing the sensor isn’t difficult. It’s similiar to every ordinary switch. Only a free Arduino digital pin is needed. When the pin is in input mode, its state remains unknown (random) until a certain voltage is applied to it. Applying a “GND” sets it into “LOW” state, and providing 5V causes “HIGH” state.

If we have the sensor wired to a digital pin and “GND”, we know the state will switch to “LOW” when the current will begin to flow. When the current doesn’t flow, the state is going to be reversed – “HIGH”. Presently, the state is undefined. Thus, to define the state we will use built-in “Pull Up” resistor. It causes setting a pin into “HIGH” state when no voltage is applied to it.

Software

We’re taking advantage of the sensor reading the state of a selected digital pin. First, we must set the pin as “INPUT” in “setup” section.

pinMode(pin_number, INPUT);

And activate internal “Pull Up” resistor.

digitalWrite(pin_number, HIGH);

After that, in “loop” function you can read pin’s state and thus the sensor’s position with “digitalRead” function.

variable = digitalRead(pin_number);

Example program, lighting the “L” diode up during a tilt.

// Defining a pin for the tilt sensor
#define SENSOR_PIN 2
// Defining a pin for the LED diode
#define LED_PIN 13

void setup()
{
	// Setting sensor's pin as input
  pinMode(SENSOR_PIN, INPUT);
  // Turning internal Pull Up resistor on
  digitalWrite(SENSOR_PIN, HIGH);
  pinMode(LED_PIN, OUTPUT);
}

void loop()
{
	// Checking sensor's state
  if (digitalRead(SENSOR_PIN) == HIGH)
  {
  	// Action if off
    digitalWrite(LED_PIN, HIGH); // Turning the LED on
  }
  else
  {
  	// Action if on
    digitalWrite(LED_PIN, LOW); // Turning the LED off
  }
}

Assembled module

A task

As every man well knows, a woman holds in her purse only treasures. These are so valuable, that no-one is allowed to browse it. In order to protect poor ladies from nosy people I resolved to build a purse alarm.

Elements

The following parts will be needed:

  • Tilt sensor for sensing the position of the purse
  • Piezo buzzer for alarming

I assembled the elements as on the following schematic. I used pin 2 as sensor’s input, pin 3 as output for piezo buzzer and pin 13 for LED diode.

The code isn’t much different from the previous, except from additional sound procedures.

First of them is “tone”, turning the sound on.

tone(speaker_pin_number, frequency);

The second – “noTone”, turning it off.

noTone(speaker_pin_number);
// Defining a pin for the tilt sensor
#define SENSOR_PIN 2
// Defining a pin for the LED diode
#define LED_PIN 13
// Defining a pin for the piezo buzzer
#define PIEZO_PIN 3

void setup()
{
  // Setting sensor's pin as input
  pinMode(SENSOR_PIN, INPUT);
  // Turning internal Pull Up resistor on
  digitalWrite(SENSOR_PIN, HIGH);
  pinMode(LED_PIN, OUTPUT);
}

void loop()
{
  // Checking sensor's state
  if (digitalRead(SENSOR_PIN) == HIGH)
  {
    // Action if on
    digitalWrite(LED_PIN, HIGH); // Turning the LED on
    tone(PIEZO_PIN, 600); // Alarm sound
  }
  else
  {
    // Action if off
    digitalWrite(LED_PIN, LOW); // Turning the LED off
    noTone(PIEZO_PIN); // Turning alarm sound off
  }
}

It’s easily noticeable that the alarm is too sensitive and every shock (even foot stamping) causes “screeching” of the buzzer. This would not appeal to the purse’s owner.

What is the difference between shocks and poking around in a purse?

The easiest way to distinguish them is switching speed of sensor. Shakes are switching it in thousandths of a second, while moves caused by a lifter – from tenths of a second to a few seconds. So, the time in which the sensor turns on must be counted and, if it’s longer than 0.1 s (moving the purse), the alarm should be triggered.

For this case, I used “millis” function, which returns how many miliseconds have elapsed from turning Arduino on. It could be applicated to storing the time from turning the sensor on. When a previously set value is reached, the alarm is turned on.

// Defining a pin for the tilt sensor
#define SENSOR_PIN 2
// Defining a pin for the LED diode
#define LED_PIN 13
// Defining a pin for the piezo
#define PIEZO_PIN 3
// Defining sensitivity time
#define SENSOR_TIME 100

// Variable storing the switching time
unsigned long sensor_time;

// Function invoked, when the alarm is on
void alarm_on()
{
	digitalWrite(LED_PIN, HIGH); // LED on
  tone(PIEZO_PIN, 600); // Alarm sound
}

//  Function invoked, when the alarm is off
void alarm_off()
{
  digitalWrite(LED_PIN, LOW); // LED off
  noTone(PIEZO_PIN); // Turning alarm sound off
}

// Function checking sensor's state
void check_sensor()
{
  // Checking sensor's state
  if (digitalRead(SENSOR_PIN) == HIGH)
  {
    // Action if off

    if (sensor_time == 0) // Checking if the state was changed
    {
      sensor_time = millis(); // Storing the sensor's activation time
    }
    // Checking if the state of sensor has been lasting for a specified time
    else if (millis() - sensor_time > SENSOR_TIME)
    {
      alarm_on();
    }
  }
  else
  {
    // Action if on
    sensor_time = 0;
    alarm_off();
  }
}

void setup()
{
  // Setting the sensor's pin as input
  pinMode(SENSOR_PIN, INPUT);
  // Turning internal Pull Up resistor on
  digitalWrite(SENSOR_PIN, HIGH);
  pinMode(LED_PIN, OUTPUT);
}

void loop()
{
  check_sensor();
}

Real alarm

Our purse alarm has one more disadvantage. It turns off immediately when the purse returns to its position. This is not a way real alarm works!
Professional alarm systems also have varied sounds. Here we will use “millis” function again. In the first place we are going to count, how much time was elapsed since triggering the alarm. It will be set off only when a certain amount of time will elapse, in order to deter and attract attention more effectively.
In the second place I employed time measuring to check the duration of signal tone, so as to switch it cyclically between high and low pitches. This way our purse alarm will be better distinguished from other noises.

// Defining a pin for the tilt sensor
#define SENSOR_PIN 2
// Defining a pin for the LED diode
#define LED_PIN 13
// Defining a pin for the piezo
#define PIEZO_PIN 3
// Defining sensitivity time [ms]
#define SENSOR_TIME 100
// Defining alarm duration time [ms] (5000 ms = 5 s)
#define ALARM_TIME 5000

// variable storing sensor's switching time
unsigned long sensor_time;
// variable storing alarm duration
unsigned long alarm_time;
// variable storing pitch change time
unsigned long signal_time = 0;
// variable storing the pitch value
// 0 - no sound
// 1 - first tone
// > 1 - second tone
byte sound_tone = 0;

// alarm siren function
void alarm_signal()
{
  if (sound_tone != 0) // checking if the siren should be turned on
  {
    if (millis() - signal_time > 750) // checking tone duration
    {
      signal_time = millis(); // storing the time when the tone was turned on
      sound_tone = ~sound_tone; // turning on the second tone
    }

    if (sound_tone == 1) // first tone
    {
      tone(PIEZO_PIN, 600);
    }
    else // second tone
    {
      tone(PIEZO_PIN, 1200);
    }
  }
  else
  {
    noTone(PIEZO_PIN); // Sound off
  }
}

// Function invoked when the alarm is off
void alarm_on()
{
  alarm_time = millis(); // storing the time when the tone was turned on
  digitalWrite(LED_PIN, HIGH); // LED on
  sound_tone = 1; // Turning alarm siren on
}

// Function invoked when the alarm is off
void alarm_off()
{
  if (millis() - alarm_time > ALARM_TIME) // checking alarm duration
  {
    digitalWrite(LED_PIN, LOW); // LED off
    sound_tone = 0; // Turning alarm siren off
  }
}

// function checking sensor's state
void check_sensor()
{
  // checking sensor's state
  if (digitalRead(SENSOR_PIN) == HIGH)
  {
    // Action if off

    if (sensor_time == 0) // checking if the state was changed
    {
      sensor_time = millis(); // storing sensor's activation time
    }
    // Condition, if sensor's state lasts for a specified time
    else if (millis() - sensor_time > SENSOR_TIME)
    {
      alarm_on();
    }
  }
  else
  {
    // Action if off
    sensor_time = 0;
    alarm_off();
  }
}

void setup()
{
  // Setting the sensor's pin as input
  pinMode(SENSOR_PIN, INPUT);
  // Turning internal Pull Up resistor on
  digitalWrite(SENSOR_PIN, HIGH);
  pinMode(LED_PIN, OUTPUT);
}

void loop()
{
  check_sensor();
  alarm_signal();
}

This is only one of many applications of tilt sensor. If you have any ideas or questions – leave a comment or use the mail.

Source codes: