ESP8266 Mercury Open Optical Module Project
This project demonstrates how to interface an ESP8266 microcontroller with a mercury open optical module to detect the presence of objects. The optical module provides a digital output signal based on whether an object is detected within its sensing range.
How It Works
A mercury tilt switch is a sealed glass capsule containing a bead of mercury and two electrodes. Tilt the capsule one way and the mercury flows across both electrodes, closing the circuit; tilt it back and the connection opens. The KY-017 module packages this with a resistor and indicator LED.
Mercury makes a genuinely excellent contact — it is liquid, so there is no wear, no pitting and no oxidation, and the switching action is clean. That is why these switches were used for decades in thermostats and tilt alarms.
They are also hazardous. Mercury is toxic and the capsule is glass; a broken switch is a contamination problem, and these parts are restricted or banned in many jurisdictions under RoHS and similar regulations. Modern designs use a ball tilt switch instead, where a conductive ball rolls between contacts. It behaves almost identically and the KY-020 is a drop-in replacement.
Both types bounce as the mercury or ball settles, so the same debouncing a mechanical switch needs applies here — and the settling time is typically longer.
Components Needed
- ESP8266 (NodeMCU)
- Mercury Tilt Switch Module module
- ESP8266 (NodeMCU)
- USB cable for programming and power
- ESP8266 (NodeMCU)
Wiring to the ESP8266 (NodeMCU)
Connect S to D5, the middle pin to the 3.3 V rail and − to GND. Declaring the pin as INPUT_PULLUP gives a defined idle level whichever way the carrier is wired.
Orientation is the whole point of this sensor, so mount it deliberately. Note the angle at which it switches — typically 15–30° from its reference position — and fix it so that angle corresponds to the tilt you care about.
Handle the glass capsule gently and never force the leads close to the body. If a mercury capsule breaks, treat it as hazardous waste rather than sweeping it up.
| Module pin | ESP8266 (NodeMCU) pin | Function |
|---|---|---|
| S (signal) | D5 | Switch state — HIGH or LOW depending on tilt |
| Middle / + | 3V3 | Supply |
| − (GND) | GND | Common ground |
Build and Upload
After uploading the code, open the Serial Monitor(baud rate: 9600).
The Serial Monitor will display whether an object is detected ("Object Detected") or not ("No Object Detected").
Place an object within the sensing range of the optical module to observe changes in detection status.
Example Code
Debounced tilt detection, reporting only settled changes. Upload it with the board set to ESP8266 (NodeMCU) and open the Serial Monitor at 115200 baud.
const int TILT_PIN = 5;
const unsigned long SETTLE_MS = 80; // longer than a dry contact — the bead rolls
int stable = HIGH;
int lastRead = HIGH;
unsigned long lastChange = 0;
void setup() {
Serial.begin(115200);
pinMode(TILT_PIN, INPUT_PULLUP);
}
void loop() {
int reading = digitalRead(TILT_PIN);
if (reading != lastRead) {
lastChange = millis();
lastRead = reading;
}
if (millis() - lastChange > SETTLE_MS && reading != stable) {
stable = reading;
Serial.println(stable == LOW ? "TILTED" : "upright");
}
}
Applications
A mercury tilt switch module turns up in a wide range of projects. These are the uses where it is the right choice rather than a compromise:
- Tilt and tip-over alarms on equipment, heaters and machinery
- Orientation detection in handheld and wearable projects
- Anti-theft triggers that fire when an object is lifted or moved
- Simple game controllers responding to board tilt
- Automatic shutoff for appliances that must not run on their side
Working with the ESP8266 (NodeMCU)
The ESP8266 (NodeMCU) is built around the ESP8266 and runs on 3.3 V logic with roughly 80 KB usable of SRAM and 4 MB on most NodeMCU boards of program flash. These details change how this circuit is wired and what the sketch can do, so they are worth stating plainly before you build.
The ESP8266 is a 3.3 V part and is not 5 V tolerant — feeding a 5 V sensor output straight into a GPIO can damage the chip. Use a divider or level shifter.
There is only one ADC channel, so reading several analog sensors needs an external multiplexer such as a CD4051 or an ADS1115.
D3 (GPIO0), D4 (GPIO2) and D8 (GPIO15) are strapping pins sampled at boot; holding them at the wrong level stops the board starting.
Built-in WiFi means the same sketch can publish readings to a dashboard without extra hardware.
| ESP8266 (NodeMCU) characteristic | Value | Why it matters here |
|---|---|---|
| Logic voltage | 3.3 V | Sensor outputs above this level need a divider or level shifter |
| ADC resolution | 10-bit (0–1023) | Sets how finely an analog reading can be resolved |
| Analog inputs | a single analog channel, A0 | Determines how many analog sensors can share the board |
| PWM outputs | any GPIO via software PWM | Needed for brightness, speed and tone control |
| I²C pins | D2 (SDA, GPIO4) and D1 (SCL, GPIO5) by default | Fixed by hardware — wiring copied from another board may not match |
| Interrupt pins | any GPIO except D0 (GPIO16) | Required for counting fast or asynchronous events |
| Serial | one hardware UART plus a transmit-only second port | Monitor runs at 115200 baud by default |
Troubleshooting
Most problems with this module fall into a handful of categories. Work through these before suspecting the part itself:
- The state flickers around the switching angle — that is the bead settling. Lengthen the debounce window.
- It never changes — the switch is mounted at the wrong angle; rotate it and retest through its full travel.
- The output is inverted compared with expectations — carrier wiring varies, so simply swap the comparison.
- Readings are unstable with vibration present — tilt switches cannot distinguish vibration from tilt. Use an accelerometer such as the MPU6050 for anything that moves.
- The sketch compiles but the board resets or behaves erratically — a 5 V module output is being driven into a 3.3 V pin. Measure the signal before connecting it.
- Readings differ from an Arduino tutorial for the same part — the 10-bit ADC returns 0–1023, not 0–1023, so any constant copied from an Uno example needs rescaling.
Taking It Further on the ESP8266 (NodeMCU)
Once the basic reading works, where you go next depends very much on which board you are using. These are the directions that suit the ESP8266 (NodeMCU) specifically:
The obvious extension on an ESP8266 is to stop printing to Serial and publish instead. A few lines using ESP8266WiFi and an HTTP client will push each reading to a dashboard such as ThingSpeak, or to an MQTT broker for home automation.
Running an onboard web server turns the board into its own display: serve a small HTML page that fetches the latest reading over AJAX, and any phone on the network becomes the instrument panel.
For battery operation, deep sleep is essential — the ESP8266 draws around 70 mA with WiFi active but under 20 µA asleep. Wire D0 (GPIO16) to RST so the board can wake itself, take a reading, publish and sleep again.
Notes and Practical Limits
Prefer the ball-type KY-020 over a mercury KY-017 for any new build. The electrical behaviour is the same, the code is identical, and it avoids both the toxicity and the regulatory problem entirely.
A tilt switch reports one axis crossing one threshold. For actual angle measurement in three dimensions, an accelerometer is the right part — it reports continuous orientation rather than a single binary transition.