@skywatch said in Which magnetic door/window switch for battery powered projects?:
@maddhin You attach the 'large resistor' on the ATmega board from ground to input pin used for interrupt. Then connect the same input pin to 3V via the reed relay switch contacts that are OPEN when the door/window/letterbox is in the untripped (closed) position. If you use the sketch on here you need to reverse the tripped/untripped (open/closed) as the basic sketch is negative triggered and this way it is positive triggered -
sorry, it took me a while to get back to this project as finally all parts for my slim nodes arrived and I first had to tinker with the temp sensor:)
The NC door switch is working now - although I did connect the large resistor with VCC and pin and connected the switch with pin and GND. The other way around didn't seem to work for me.
Here is my sketch for other people having similar issue or for comments (improvements always welcome!).
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* DESCRIPTION
*
* Simple binary switch example
* Connect button or door/window reed switch between
* digitial I/O pin 3 (BUTTON_PIN below) and GND.
* http://www.mysensors.org/build/binary
*
* Connect normally closed (NC) door sensor:
* VCC <--> 3.3M ohm resistor <--> pin D3
* GND <--> NC door sensor <--> pin D3
* REVISION HISTORY
* v1.0: Example at https://www.mysensors.org/build/binary
* v1.01: Maddhin
* v1.03: first working version
*
*/
#define SKETCH_NAME "DoorSen_NC"
#define SKETCH_VERSION "1.03" //<--------- UPDATE version nummer!!!
// Enable debug prints
#define MY_DEBUG //<--------- switch DEBUG mode on/off
// Enable REPORT_BATTERY_LEVEL to measure battery level and send changes to gateway
#define REPORT_BATTERY_LEVEL
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RS485
#define MY_NODE_ID 101
//#define MY_PARENT_NODE_ID 0
//#define MY_PARENT_NODE_IS_STATIC
//#define MY_RF24_PA_LEVEL RF24_PA_MAX
#include <MySensors.h>
//#include <Bounce2.h>
//#define CHILD_ID_HUM 0
//#define CHILD_ID_TEMP 1
#define CHILD_ID_VOLT 2
//Door sensor
#define CHILD_ID_DOOR 3
#define BUTTON_PIN 3 // Arduino Digital I/O pin for button/reed switch
#define ONE_DAY_SLEEP_TIME 86400000 // report battery status each day at least once
//Bounce debouncer = Bounce();
int oldValue=-1;
// Change to V_LIGHT if you use S_LIGHT in presentation below
MyMessage msg(CHILD_ID_DOOR,V_TRIPPED);
// Sleep time between sensor updates (in milliseconds)
static const uint64_t UPDATE_INTERVAL = 5*60000; // x * 1 min
//for debugging:
//static const uint64_t UPDATE_INTERVAL = 5000;
/*#include "Adafruit_HTU21DF.h"
Adafruit_HTU21DF sensor = Adafruit_HTU21DF();
// Set this offset if the sensor has a permanent small offset to the real temperatures
#define SENSOR_TEMP_OFFSET 0
*/
#ifdef REPORT_BATTERY_LEVEL
#include <Vcc.h>
static uint8_t oldBatteryPcnt = 200; // Initialize to 200 to assure first time value will be sent.
const float VccMin = 1.8; // Minimum expected Vcc level, in Volts: Brownout at 1.8V -> 0%
const float VccMax = 2.0*1.6; // Maximum expected Vcc level, in Volts: 2xAA fresh Alkaline -> 100%
const float VccCorrection = 1.0; // Measured Vcc by multimeter divided by reported Vcc
static Vcc vcc(VccCorrection);
#endif
#ifdef MY_DEBUG
#define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTDEC(x) Serial.print (x, DEC)
#define DEBUG_PRINTLN(x) Serial.println (x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTDEC(x)
#define DEBUG_PRINTLN(x)
#endif
void setup()
{
/*// Temp Hum Sensor
while (!sensor.begin())
{
DEBUG_PRINTLN(F("Sensor not detected!"));
while(1);
delay(5000);
}*/
//Door Sensor
// Setup the button
pinMode(BUTTON_PIN,INPUT);
// Activate internal pull-up
digitalWrite(BUTTON_PIN,HIGH);
/*// After setting up the button, setup debouncer
debouncer.attach(BUTTON_PIN);
debouncer.interval(5);
*/
}
void presentation()
{
// Send the sketch version information to the gateway and Controller
DEBUG_PRINT("SKETCH NAME: ");
DEBUG_PRINT(SKETCH_NAME);
DEBUG_PRINT(", VERSION: ");
DEBUG_PRINTLN(SKETCH_VERSION);
sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
// Present sensors as children to gateway
//present(CHILD_ID_HUM, S_HUM, "Humidity");
//present(CHILD_ID_TEMP, S_TEMP, "Temperature");
present(CHILD_ID_VOLT, S_MULTIMETER, "Voltage");
// Register binary input sensor to gw (they will be created as child devices)
// You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
// If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
present(CHILD_ID_DOOR, S_DOOR);
}
void loop()
{
/*// Read temperature & humidity from sensor.
const float temperature = float( sensor.readTemperature() );
const float humidity = float( sensor.readHumidity() );
DEBUG_PRINT(F("Temp "));
DEBUG_PRINT(temperature);
DEBUG_PRINT(F("\tHum "));
DEBUG_PRINTLN(humidity);
static MyMessage msgHum( CHILD_ID_HUM, V_HUM );
static MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
send(msgTemp.set(temperature, 1));
send(msgHum.set(humidity, 1));
*/
//Door sensor
/* debouncer.update();
// Get the update value
int value = debouncer.read();
*/
int value = digitalRead(BUTTON_PIN);
//DEBUG_PRINT("digitalRead PIN: ");
//DEBUG_PRINTLN(value);
wait(50); // "debouncing"
//if (value != oldValue) {
if (value != oldValue) {
// Send in the new value
DEBUG_PRINT(F("DOOR SENSOR: "));
DEBUG_PRINTLN(value==HIGH ? 1 : 0);
send(msg.set(value==HIGH ? 1 : 0));
oldValue = value;
}
#ifdef REPORT_BATTERY_LEVEL
const uint8_t batteryPcnt = static_cast<uint8_t>(0.5 + vcc.Read_Perc(VccMin, VccMax));
static MyMessage MsgVolt(CHILD_ID_VOLT, V_VOLTAGE); // Node voltage
DEBUG_PRINT(F("Vbat "));
DEBUG_PRINT(vcc.Read_Volts());
DEBUG_PRINT(F("\tPerc "));
DEBUG_PRINTLN(batteryPcnt);
// Battery readout should only go down. So report only when new value is smaller than previous one.
if ( batteryPcnt < oldBatteryPcnt )
{
send(MsgVolt.set(vcc.Read_Volts(),2));
sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;
}
#endif
// Sleep until next update to save energy
//sleep(UPDATE_INTERVAL);
sleep(BUTTON_PIN-2, CHANGE, ONE_DAY_SLEEP_TIME);
}
Now, I'll look into adding a second door switch onto the same 328P and hope I have a neat letterbox sensor up and running soon...
Power consumption I will have to monitor though. But I don't really know how to measure the sleep / send current. I guess I should build some INA219 based monitor or similar. I guess, for the moment, I just "hope" the setup is good and I'll see how long the batteries will last. After running for ~24h and having triggered a bunch of times, the voltage didn't seem to have changed, so I guess that is good news...
Thanks for your help, guys!