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
System architecture and data pipeline note
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

PartQtyUnit priceNote
Wemos D1 Mini (ESP8266)1 pc$1.50Sensor node body
MC-38 reed switch1 pc$0.60Magnetic door sensor, wiring screws included
Jumper wires (female-to-female)2 pcsUse from the jumper wire pack
Micro USB cable + charger1 setReuse an old charger
Total$2.10Excluding 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

[Part 4] MC-38 and Wemos D1 Mini wiring diagram
MC-38Wemos D1 Mini
Wire 1GND
Wire 2D1 (GPIO5)
There is no polarity. Put either wire into GND and the other into D1. In the code, 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

[Part 4] Did I close the door? Checking front-door state through the IoT hub - 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

  1. Connect the Wemos D1 Mini to the PC with USB.
  2. Select Tools → Board → LOLIN(WEMOS) D1 R2 & mini.
  3. Select the port and upload.
  4. 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 Door label.
  • 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

SymptomCauseFix
Nothing appears in the serial monitorWi-Fi connection failedCheck 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 -1Wrong hub addressCheck 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 changeSlot number mismatchCheck 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

SymptomCauseFix
Only Door CLOSED keeps appearingPull-up setting missingCheck 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 attachedThe magnet is too far awayReduce 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 OPENSensor and magnet are misalignedAdjust 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

SymptomCauseFix
Door OPEN appears several times in a rowContact bouncingThis 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.

SymptomLikely causeField fix
The door still shows closed after openingThe metal door or poor magnet alignment keeps the reed switch engagedKeep 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 closesContact chatter occurs from door impactAdd a 200-500 ms debounce window and transmit only after the state remains stable.
Intrusion alerts sometimes appear lateWeak Wi-Fi near the entrance or reconnect delay on the nodeCheck signal strength near the door and retry failed HTTP updates up to three times before the next cycle.
The adhesive tape comes looseDust, moisture, or temperature changes weaken the mounting tapeClean 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 1 to the hub when the door opens, and 0 when 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 Connected or connected appears, the Wi-Fi step passed.
  • If HTTP 200 or 200 OK appears, the value reached the brain server.
  • If the value does not update, check both the slot number in the URL and the sensor wiring.