Датчик состояния окна закрыто/открыто
Добавлено: 02 авг 2017, 05:59
Датчик положения окна устанавливается на двусторонний скотч в нужном месте окна. На противоположной части которую надо контролировать устанавливается магнит. Датчик положения реализован на паре: геркон-магнит. На вывод 4 ардуино подается высокий уровень при старте процессора для первоначальной калибровки уровня заряда батареи, который в дальнейшем передается в систему в процентах. Подключение радио к ардуино стандартное без использования стабилизаторов. Между 8 и 2 выводами ардуино устанавливается геркон. Питание 3В. Между выводами A2 и землей установлен резистор 110К и A2 и VCC 330k так реализован делитель для ацп-контроля уровня батареи.
Код: Выделить всё
#define MY_RADIO_NRF24
#define MY_NODE_ID 46
#include <MySensors.h>
#include <SPI.h>
#include <avr/wdt.h>
#define DIGITAL_INPUT_SENSOR 2 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
#define NODE_IDSM1 1
#define NODE_IDV 2
#define NODE_Time 4
#define NODE_Prog 5
unsigned long SLEEP_TIME = 60000;
int ADCin=2, prog = 4;
int BatteryPcnt, s;
byte flag = 0, mot=0, flagProg;
MyMessage msgSM(NODE_IDSM1, V_ARMED);
MyMessage msgbatt(NODE_IDV, V_VAR1);
MyMessage msgTime(NODE_Time, V_VAR2);
MyMessage msgProg(NODE_Prog, V_VAR5);
void presentation()
{
sendSketchInfo("Motion_sensor_window", "V1.0_01082017");
present(NODE_IDSM1, S_MOTION, "Open/Close");
present(NODE_IDV, S_CUSTOM, "Battery");
present(NODE_Time, S_CUSTOM, "Time sleep");
present(NODE_Prog, S_CUSTOM, "Set programm");
}
void setup(){
wdt_disable();
analogReference(INTERNAL);
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
digitalWrite(DIGITAL_INPUT_SENSOR, LOW);
pinMode(ADCin, INPUT);
pinMode(8, OUTPUT);
pinMode(prog, INPUT);
digitalWrite(prog, LOW);
if(digitalRead(prog)==1)
flag=1;
else
flag=0;
int L = loadState(3);
if((L) > 0 && (L)< 255)
SLEEP_TIME=L*60000;
send(msgProg.set(0));
flagProg=0;
digitalWrite(8, HIGH);
}
void loop()
{
if(flag == 1)
{
for(int i=0; i<3; i++)
{
s = analogRead(ADCin);
send(msgbatt.set(s)); //value переменная 2-указываеьт сколько знаков после запятой выводить.
delay(10000);
}
saveState(1, lowByte(s));
saveState(2, highByte(s));
flag = 0;
}
else{
bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
send(msgSM.set(tripped?"1":"0")); // Send tripped value to gw
int a = analogRead(ADCin);
int sl = loadState (1);
int sh = loadState (2);
int battconst = word(sh, sl);
int batt3V = (22*battconst)/30;
int b = battconst - batt3V;
if((a - batt3V)>0){
BatteryPcnt = ((a - batt3V)*100)/b; // 293=1023=100%=4.2V
}
else
BatteryPcnt = 0;
send(msgbatt.set(BatteryPcnt)); //value переменная 2-указываеьт сколько знаков после запятой выводить.
send(msgTime.set((SLEEP_TIME)/60000));
if(flagProg){
delay(10000);
send(msgProg.set(10));
}
else{
send(msgProg.set(0));
}
smartSleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
}
}
//********************************************************
void receive(const MyMessage &message) {
if (message.type==V_VAR2) {
if((message.getInt())<255){
saveState(3, message.getInt());
SLEEP_TIME = (loadState(3)*60000);
send(msgTime.set((SLEEP_TIME)/60000));
}
}
if (message.type==V_VAR5) {
if((message.getInt())<255){
SLEEP_TIME = message.getInt();
if (SLEEP_TIME == 52)
flagProg = 1;
}
}
}