Hello,
I am doing some project and in that, I wish to use ESP8266 and Magnetic Switch. The magnetic switch is attached to the door. I need to get output when I open the gate, not when I close the gate. But by using RISING mode it gives me output on both when I open and close gate. FALLING mode gives me output when I close the gate. I tried LOW and HIGH mode also, but they also didn’t worked as expected.
My code is in the link given.
CODE: https://pastebin.com/xN2Gd9RV
Thanks
Hi Ashish,
You’re faced with a twofold problem here:
1. The magnetic sensor is made up of a mechanical part which is not perfect. Each time the door is opened or closed there is necessarily a bouncing phenomenon. In other words, the sensor will oscillate between the two states HIGH and LOW many times before stabilizing. You must therefore introduce a debounce mechanism in your code to eliminate these imperfections and detect the event only once.
2. to guarantee a clean reading of the sensor when it is at rest, you must necessarily connect its reading pin either to the power supply or to ground, but in both cases through a high resistance (e.g. 10 kΩ) to avoid short circuits. This resistor is called a pull-up resistor when it is connected to the power supply, because when the magnetic sensor is idle, the read signal is at HIGH level. On the other hand, if you connect this resistor to ground, it is called a pull-down resistor, because when the magnetic sensor is at rest, the signal read is at LOW level.
For example, if you look at this circuit, you can see that the reading pin of the sensor is connected to ground through a pull-down resistor:
In other words, when the door is closed, the contactor within the magnetic sensor is closed (current is flowing) and the signal on the reading pin is therefore HIGH. On the other hand, if the door opens, the contactor also opens (the current no longer flows) and the signal on the reading pin is therefore LOW thanks to the pull-down resistor.
Here is a piece of code, which implements the debouncing mechanism, which will allow you to clearly distinguish what happens at each opening and closing of the door:
#include <Arduino.h> // the sensor is connected to ground // through a pull-down resistor of 10 kΩ constexpr gpio_num_t SENSOR_PIN = GPIO_NUM_5; constexpr uint8_t DEBOUNCE_DELAY = 50; // in milliseconds uint16_t lastCounter; volatile uint16_t counter; volatile bool signal; volatile uint32_t lastInterrupt; void IRAM_ATTR onEvent() { uint32_t now = millis(); if (now - lastInterrupt > DEBOUNCE_DELAY) { signal = digitalRead(SENSOR_PIN); counter++; lastInterrupt = now; } } void setup() { Serial.begin(115200); pinMode(SENSOR_PIN, INPUT); counter = 0; lastCounter = 0; lastInterrupt = 0; attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), onEvent, CHANGE); } void loop() { if (counter != lastCounter) { Serial.printf("counter: %u, signal: %s\n", counter, signal ? "HIGH" : "LOW"); lastCounter = counter; } }
The interrupt is associated with the CHANGE
event so that you can clearly distinguish between opening and closing the door. But if the only event you are interested in is the opening of the door, simply replace CHANGE
with FALLING
.
But beware: if your sensor is connected to the power supply by a pull-up resistor, you have to reverse the reasoning and thus detect the RISING
event!
I hope things are clearer for you now.
Regards,
Steph
Hello Sir, Thank You for this good explanation. I was trying to run your code, but it gives me this error :
error: ‘gpio_num_t’ does not name a type
I am using NodeMCU 1.0 (ESP-12E Module) module and connected magnetic switch to D1 (means GPIO 5).
Can you please tell me how to solve this issue? I searched on the internet about this error, but nothing worked.
Thanks
No big deal… Replace this line:
constexpr gpio_num_t SENSOR_PIN = GPIO_NUM_5;
By this one:
constexpr uint8_t SENSOR_PIN = 5;
Oh and, sorry I don’t have ESP8266 to test… only ESP32, but I think this line needs to be replaced as well:
void IRAM_ATTR onEvent() {
whith this one:
void ICACHE_RAM_ATTR onEvent() {
Hello Sir, thanks for your help. I tried your sketch, now it’s running. But now also the problem is same. In both pull-up and pull-down, while RISING it gives the output when I open the gate and close the gate. And in FALLING it give output when I close the gate. My circuits are as follows:
pull_up=https://imgur.com/gDaq5RX
pull_down=https://imgur.com/Crkmdxu
R=10 K ohm
Thanks
Dear Sir, Thank you so much. It worked. I tried Pull Down in FALLING mode and it worked as expected. In Pull up, it didn’t work. But worked in Pull Down. And the explanation you provided me helped me a lot to understand the concept. I really really appreciate your help.
Thanks Again, Sir.
Hi Ashish,
I’m glad you got the result you were looking for.
And it’s nice to keep me informed (not everyone does).
It must also work in pull-up!
Check your connections…
There’s no reason it shouldn’t work.
Try to detect the CHANGE
event to see what’s going on in pull-up and pull-down (with the code I suggested):
attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), onEvent, CHANGE);
Have fun 😉
Steph