Home IoT Hub Series · 04
[Part 4] Did I close the door? Checking front-door state through the IoT hub
In [Part 3] Stop guessing room comfort. This time it is the front door. When the door opens, the hub OLED inverts the warning label and the buzzer starts beeping. This is the first part where the warning system feels real.
The sensor structure is actually simpler than Part 3. A reed switch has one magnet and one sensor body. Connect just one data pin and that is it. No complicated library is needed.
![[Part 4] Did I close the door? Checking front-door state through the IoT hub hero image](/iot-lab/assets/front-door-reed-switch-hero.png)
This article is part of the Home IoT Hub system connected to the central NodeMCU server built in Part 2: Building the Brain. The MC-38 reed switch reports the door-open state used by the hub's intrusion warning logic. The collected data is sent over the local
IoT_Hub_Net network and updates slot 9 for front-door open state on the central server (/set?no9=value), becoming part of the decision pipeline for the 20-channel smart-home controller.Parts and cost
| Part | Qty | Unit price | Note |
|---|---|---|---|
| Wemos D1 Mini (ESP8266) | 1 pc | $1.50 | Sensor node body |
| MC-38 reed switch | 1 pc | $0.60 | Magnetic door sensor, wiring screws included |
| Jumper wires (female-to-female) | 2 pcs | — | Use from the jumper wire pack |
| Micro USB cable + charger | 1 set | — | Reuse an old charger |
| Total | $2.10 | Excluding charger and cable |
How the MC-38 reed switch works
It looks like two small plastic pieces, but the idea is simple.
- The sensor body contains a small glass tube called a reed switch. When the magnet comes close, the two metal contacts touch and the circuit closes. When the magnet moves away, the contacts separate and the circuit opens.
- Attach the magnet piece to the door and the sensor body to the door frame. When the door is closed, the magnet is close to the sensor, so the signal becomes LOW. When the door opens, the magnet moves away, so the signal becomes HIGH.
The sensor has two wires. There is no polarity, so either wire can go to GND and the other can go to GPIO. The important part is using INPUT_PULLUP in the code.
Door closed → magnet close → circuit closed → GND connected → GPIO = LOW → "0" Door open → magnet away → circuit open → pull-up only → GPIO = HIGH → "1"
Pin wiring
| MC-38 | Wemos D1 Mini |
|---|---|
| Wire 1 | GND |
| Wire 2 | D1 (GPIO5) |
pinMode(5, INPUT_PULLUP) turns on the internal pull-up resistor so HIGH is clearly detected when the magnet moves away.Attach it to the door like this:
┌─ door frame ─┐ ┌────── door ──────┐ │ │ │ │ │ [sensor] │ ◄─── │ [magnet] │ │ body │ close │ small piece │ │ │ │ │ └──────────────┘ └──────────────────┘
Keep the gap between the sensor body and the magnet within about 1 cm. At around 1.5 cm it may stop detecting reliably. Double-sided tape is usually clean enough for installation.
Prerequisite
No additional library is required in this part. It uses only the basic GPIO read, Wi-Fi, and HTTP features of the ESP8266. In Arduino IDE, set the board to LOLIN(WEMOS) D1 R2 & mini.
Before uploading the code
This is the same as Part 3. The Wi-Fi information is already set to IoT_Hub_Net / iothub1234. The hub brain must be powered on first. If the sensor node starts first, it cannot find Wi-Fi and will stay at Connecting....
In this part, data goes into slot 9 (Front Door). When the door opens it sends 1, and when it closes it sends 0. Slot 9 is a warning slot, so the buzzer starts as soon as 1 arrives. Do not be surprised during the first test. That is normal.
Full code
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> // ============================================= // 1. Wi-Fi settings (connect to the hub brain AP) // ============================================= const char* ssid = "IoT_Hub_Net"; const char* password = "iothub1234"; const char* hubURL = "http://192.168.1.1"; // ============================================= // 2. Sensor settings // ============================================= #define DOOR_PIN 5 // D1 (GPIO5) #define SLOT_NO 9 // Hub slot 9 = Front Door // ============================================= // 3. Send interval and debounce // ============================================= #define INTERVAL 1000 // Check every 1 second #define DEBOUNCE 300 // Prevent repeated sends within 300 ms int lastState = -1; // Previous door state (-1 = initial) unsigned long lastSend = 0; // ============================================= // setup // ============================================= void setup() { Serial.begin(115200); pinMode(DOOR_PIN, INPUT_PULLUP); // Use the internal pull-up resistor WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("Connecting to IoT_Hub_Net"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.print("Connected! IP: "); Serial.println(WiFi.localIP()); Serial.println("Waiting for door state change..."); Serial.println("---"); } // ============================================= // loop // ============================================= void loop() { // Read the current door state // LOW = door closed (magnet attached) // HIGH = door open (magnet away) int currentState = digitalRead(DOOR_PIN); // Send only when the state changes to avoid unnecessary traffic if (currentState != lastState) { // Debounce: ignore changes too soon after the previous send unsigned long now = millis(); if (now - lastSend > DEBOUNCE) { lastState = currentState; lastSend = now; // Send 1 when the door is open, 0 when it is closed String val = (currentState == HIGH) ? "1" : "0"; Serial.print("Door "); Serial.print(currentState == HIGH ? "OPEN " : "CLOSED"); Serial.print(" -> sending "); Serial.print(val); Serial.print(" to slot "); Serial.println(SLOT_NO); // Send the value to the hub brain WiFiClient client; HTTPClient http; String url = String(hubURL) + "/set?no" + String(SLOT_NO) + "=" + val; http.begin(client, url); int code = http.GET(); http.end(); Serial.print("HTTP "); Serial.print(code); Serial.print(" -> "); Serial.println(url); Serial.println(); } } delay(INTERVAL); }
Upload
- Connect the Wemos D1 Mini to the PC with USB.
- Select
Tools → Board → LOLIN(WEMOS) D1 R2 & mini. - Select the port and upload.
- Open the serial monitor and confirm the baud rate is 115200.
What to check
Serial monitor
When the sensor node boots, it enters waiting mode:
Connecting to IoT_Hub_Net.... Connected! IP: 192.168.1.3 Waiting for door state change... ---
Now open the door:
Door OPEN -> sending 1 to slot 9 HTTP 200 -> http://192.168.1.1/set?no9=1
When the door closes:
Door CLOSED -> sending 0 to slot 9 HTTP 200 -> http://192.168.1.1/set?no9=0
Check the warning on the hub brain
When the door opens:
- The hub OLED highlights the 9th
Front Doorlabel. - The buzzer starts beeping at about 0.5 second intervals.
- The 9th card on the HTML dashboard turns red.
When the door closes:
- The OLED highlight clears and the buzzer stops.
- The card returns to its normal color.
This is the moment where the i == 8 condition placed in the checkWarning() function in Part 2 actually works.
Troubleshooting
No reaction when the door opens
| Symptom | Cause | Fix |
|---|---|---|
| Nothing appears in the serial monitor | Wi-Fi connection failed | Check whether IoT_Hub_Net is alive and place the sensor node in the same room as the hub brain. |
Door OPEN appears, but HTTP is -1 | Wrong hub address | Check that the hub brain opened its AP at 192.168.1.1. Also check whether WiFi.softAP() is called correctly in the Part 2 code. |
| The serial monitor works, but the hub OLED does not change | Slot number mismatch | Check that SLOT_NO 9 is correct and that label[8] in the hub code is "Front Door". |
It says CLOSED even when the door is open
| Symptom | Cause | Fix |
|---|---|---|
Only Door CLOSED keeps appearing | Pull-up setting missing | Check that pinMode(DOOR_PIN, INPUT_PULLUP) exists in the code. Without it, the pin can float and read LOW. |
| It stays OPEN even with the magnet attached | The magnet is too far away | Reduce the gap between the magnet and sensor to within about 1 cm. If it is over 1.5 cm, detection can fail. |
| The door is fully closed but still reads OPEN | Sensor and magnet are misaligned | Adjust the position so the magnet faces the sensor body when the door is closed. Test by hand before fixing it with double-sided tape. |
It sends several times whenever the door opens
| Symptom | Cause | Fix |
|---|---|---|
Door OPEN appears several times in a row | Contact bouncing | This is normal. The code uses DEBOUNCE 300 to block repeated sends within 300 ms. If it still repeats too much, increase DEBOUNCE to 500. |
Additional field checkpoints
The node code can look short, but real home installation is affected by placement, power, Wi-Fi quality, and sensor noise. Check these points before letting the node become a decision input for the brain server.
| Symptom | Likely cause | Field fix |
|---|---|---|
| The door still shows closed after opening | The metal door or poor magnet alignment keeps the reed switch engaged | Keep a 5-10 mm gap and use foam PVC or a wood spacer on steel doors to reduce magnetic interference. |
| The state toggles several times when the door closes | Contact chatter occurs from door impact | Add a 200-500 ms debounce window and transmit only after the state remains stable. |
| Intrusion alerts sometimes appear late | Weak Wi-Fi near the entrance or reconnect delay on the node | Check signal strength near the door and retry failed HTTP updates up to three times before the next cycle. |
| The adhesive tape comes loose | Dust, moisture, or temperature changes weaken the mounting tape | Clean the surface with alcohol and use a separate cable clip so cable tension does not pull the sensor body. |
Installation tips
- Double-sided tape is enough, so you do not have to drill holes in the door.
- Attach the sensor body to the door frame and the magnet to the door. The reverse also works electrically.
- Power it from a USB charger near the entrance. If the Micro USB cable is short, use a 2 m extension cable.
- The D1 Mini is small enough to hide in an upper corner of the door frame. White cable ties make it less noticeable.
What we have done so far
- Built the second sensor node with an MC-38 reed switch and Wemos D1 Mini.
- Sent
1to the hub when the door opens, and0when it closes. - Confirmed the hub warning system for the first time: OLED inversion plus buzzer alert.
- Now the hub tells you with a beep whenever the front door opens.
Serial Monitor
After uploading, open Tools → Serial Monitor in the Arduino IDE and set the baud rate to 115200. The following is an example Serial Monitor flow for checking normal operation. This is not a real screenshot. It is an example Serial Monitor log for checking MC-38 wiring and door open/closed detection.
[BOOT] Home IoT Node #04 - Front door reed switch [WIFI] connected to IoT_Hub_Net, ip=192.168.1.49 [GPIO] reed raw=LOW, debounce=stable [SENSOR] door_state=CLOSED [HTTP] GET /set?no9=0 [HUB] 200 OK - slot no9=CLOSED [EVENT] door opened -> no9=1
- If
Connectedorconnectedappears, the Wi-Fi step passed. - If
HTTP 200or200 OKappears, the value reached the brain server. - If the value does not update, check both the slot number in the URL and the sensor wiring.
This article is part of the 20-channel Home IoT system built from the Part 2 central brain server and the distributed edge nodes in Parts 3-19. Use this map to check the slot and sensor flow across the series.
[Part 1] Home IoT Hub overview[Part 2] Central brain server · slots 1-20[Part 3] Stop guessing room comfort · slots 1/2[Part 4] Did I close the door? · slots 9[Part 5] Is the fridge really cooling? · slots 12[Part 6] Should I open the window? · slots 3[Part 7] Stop bathroom mold before it starts · slots 19[Part 8] Is the boiler actually running? · slots 5/17[Part 9] Did I leave the gas stove on? · slots 6[Part 10] Get warned before gas smell becomes obvious · slots 7[Part 11] Catch flame signs while away from home · slots 8[Part 12] Is bad air making you foggy? · slots 13/14[Part 13] Why is the power bill so high? · slots 15[Part 14] Is water leaking, and how much are we using? · slots 16[Part 15] Do not leave windows open in the rain · slots 18[Part 16] Are the lights off and the door locked? · slots 11/10[Part 17] Control the air conditioner from the IoT hub · slots 4[Part 18] Is the dog bowl empty? · slots 20[Part 19] Cool the room only when someone is there · slots 1/4[Part 20] The house finally fits on one screen · slots all