Tilt alarm on an Arduino Uno
Tip the tilt switch and a buzzer and a lamp sound off until the arcade button on pin 3 resets them. Half-size board. The whole build, an Arduino Uno and 5 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Beginner About 15 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $32. On Mokxi they're free.
Step by step, with the wiring and the common mistakes: Arduino Tilt Sensor (SW-520D): Wiring and Code
What you'll learn
- Debouncing a noisy switch with a settle time
- Latching an alarm until it is reset
- Blinking without
delayusingmillis - Two
INPUT_PULLUPinputs to ground
- Difficulty: Beginner
- Time: About 15 minutes
- Board: Arduino Uno R3
- Parts: 7
How it works
A tilt switch on pin 2 is a metal ball in a can. Upright, it reads LOW. Tipped, the ball rolls off the contacts and the pull-up makes pin 2 read HIGH. Since the ball rattles on landing, the sketch only believes a reading once it has held for 50 ms.
When a tip is accepted, the alarm latches on. The buzzer on pin 8 and the red LED on pin 9 beep together every 150 ms. Standing the box back up does not stop it. Only the arcade button on pin 3 resets it.
Parts list
7 parts, plus the jumper wires. They retail for about $32; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Half breadboard
- 1 × Tilt switch
- 1 × Arcade buttonIn Claw Machine Kit, Fight Stick Kit, Pinball Table Kit.
- 1 × BuzzerIn Starter Kit, Rocket Flight Computer Kit.
- 1 × Resistor, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
- 1 × LED, redIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Resistor, 220 Ω pin 1 | Arduino Uno R3 pin 9 |
| Buzzer pin 1 | Arduino Uno R3 pin 8 |
| Arcade button pin 2 | Arduino Uno R3 pin 3 |
| Tilt switch pin 1 | Arduino Uno R3 pin 2 |
| Tilt switch pin 2 | Arduino Uno R3 pin GND |
| Arcade button pin 1 | Arduino Uno R3 pin GND |
| Buzzer pin 2 | Arduino Uno R3 pin GND |
| LED, red pin C | Arduino Uno R3 pin GND |
| LED, red pin A | Resistor, 220 Ω pin 2 |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Tilt alarm: knock it over and it shouts until you press the big button.
//
// pin 2 the tilt switch, other leg to GND, internal pull-up
// pin 3 the arcade button, other leg to GND, internal pull-up
// pin 8 the buzzer, other leg to GND
// pin 9 the lamp, through 220 ohm to GND
//
// A tilt switch is a metal ball in a can. Upright, the ball rests on both
// contacts and the pin reads LOW; tipped past about fifteen degrees, the ball
// rolls off and the pull-up takes the pin HIGH. That is the whole sensor, and
// the ball rattles for a good few milliseconds as it lands, which is why the
// sketch waits for the reading to hold before it believes it.
//
// # Latching
//
// The alarm does not stop when the box is stood back up. It has seen a tip,
// and it keeps sounding until somebody presses the button, which is what an
// alarm is for: the point is that it happened, not that it is still
// happening. Click the switch on the canvas to tip it, then press the button
// to reset.
const int TILT = 2;
const int BUTTON = 3;
const int BUZZER = 8;
const int LAMP = 9;
const unsigned long SETTLE_MS = 50;
const unsigned long BEEP_MS = 150;
bool alarm = false;
int lastRaw = LOW;
unsigned long changedAt = 0;
int tilt = LOW;
void setup() {
pinMode(TILT, INPUT_PULLUP);
pinMode(BUTTON, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
pinMode(LAMP, OUTPUT);
digitalWrite(BUZZER, LOW);
digitalWrite(LAMP, LOW);
Serial.begin(115200);
Serial.println("Mokxi Uno: tilt alarm armed. Tip the switch.");
}
void loop() {
// Debounce: a reading counts once it has held for SETTLE_MS.
int raw = digitalRead(TILT);
if (raw != lastRaw) {
lastRaw = raw;
changedAt = millis();
} else if (raw != tilt && millis() - changedAt >= SETTLE_MS) {
tilt = raw;
if (tilt == HIGH && !alarm) {
alarm = true;
Serial.println("TILT! alarm on");
}
}
if (digitalRead(BUTTON) == LOW && alarm) {
alarm = false;
digitalWrite(BUZZER, LOW);
digitalWrite(LAMP, LOW);
Serial.println("reset");
while (digitalRead(BUTTON) == LOW) {
delay(10);
}
}
if (alarm) {
int on = (millis() / BEEP_MS) % 2 == 0 ? HIGH : LOW;
digitalWrite(BUZZER, on);
digitalWrite(LAMP, on);
}
delay(5);
}
Code walkthrough
The key functions of the sketch, and what each one does.
setup sketch.ino
Sets the tilt switch and the button as INPUT_PULLUP, the buzzer and lamp as outputs, and turns both off. It opens serial and says the alarm is armed.
void setup() {
pinMode(TILT, INPUT_PULLUP);
pinMode(BUTTON, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
pinMode(LAMP, OUTPUT);
digitalWrite(BUZZER, LOW);
digitalWrite(LAMP, LOW);
Serial.begin(115200);
Serial.println("Mokxi Uno: tilt alarm armed. Tip the switch.");
}loop sketch.ino
First it debounces the tilt pin. A change must last SETTLE_MS before it counts, and a HIGH then sets alarm. Then, if the button is pressed while the alarm is on, it clears the alarm and waits for release. While the alarm is on, it toggles the buzzer and lamp every BEEP_MS.
void loop() {
// Debounce: a reading counts once it has held for SETTLE_MS.
int raw = digitalRead(TILT);
if (raw != lastRaw) {
lastRaw = raw;
changedAt = millis();
} else if (raw != tilt && millis() - changedAt >= SETTLE_MS) {
tilt = raw;
if (tilt == HIGH && !alarm) {
alarm = true;
Serial.println("TILT! alarm on");
}
}
if (digitalRead(BUTTON) == LOW && alarm) {
alarm = false;
digitalWrite(BUZZER, LOW);
digitalWrite(LAMP, LOW);
Serial.println("reset");
while (digitalRead(BUTTON) == LOW) {
delay(10);
}
}
if (alarm) {
int on = (millis() / BEEP_MS) % 2 == 0 ? HIGH : LOW;
digitalWrite(BUZZER, on);
digitalWrite(LAMP, on);
// ... 3 more lines in the editorTroubleshooting
The usual mistakes with this circuit, and the fix for each.
- The alarm triggers when the box is upright This project
The switch must read LOW when upright. Check one leg goes to pin 2 and the other to GND. - The alarm will not stop This project
The button on pin 3 needs its other leg on GND. Press it while the alarm is sounding. - The buzzer is silent but the lamp blinks This project
Check the buzzer is on pin 8 with its other pin on GND. - The reading flickers when the switch is moved. Tilt switch
The ball bounces on the contacts, giving many fast changes. Debounce in software by waiting 20 to 50 ms before accepting a new state, or average a few readings. - The input floats and never gives a clean reading. Tilt switch
A tilt switch is just a switch, so the pin floats when it is open. Use INPUT_PULLUP with the switch between the pin and GND, or add a 10 k pull-down resistor. - The button reads pressed all the time, or never changes, when wired to a pin. Arcade button
Use the COM and NO terminals of the microswitch. Wire COM to ground, NO to the pin, and use INPUT_PULLUP. NC is the opposite and reads pressed when released. - One press counts as several presses in your code. Arcade button
Microswitch contacts bounce for a few milliseconds. Ignore changes for 10 to 20 ms after the first one, or react only to the edge and wait before checking again. - The buzzer makes a constant tone, or you cannot change its pitch. Buzzer
An active buzzer has its own oscillator, so it only beeps on and off. A passive buzzer needs tone() to set pitch. Check which type you have.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.