Датчик движения (инфракрасный) | MySensors | DIY
Добавлено: Пн авг 27, 2018 12:32 pm
Приветствую всех адептов секты Майсенсорс на форуме Мажордомо. Решил поделится своим проектом это Датчик движения для сети Майсенсорс, работает от батареек типа 14250(половинка AA). Девайс обещает работать на одном комплекте батареек более 3 лет.
Возможности:
Работа на всех бутлоадерах.
Прошивка по воздуху.
Отправка состояния датчика движения на контролер
Три режима работы датчика движения (Ночь|День|Круглосуточно)
Регулируемая задержка (без задержки|1минута - 4 часа)
Отправка остатка заряда батарейки в процентах
Отправка уровня освещенности в Люксах
Настройка через модуль Майсенсорс в Мажордомо(да впринципе и через любой другой контролер):
Интервал отправки остатка заряда батарейки
Интервал отправки уровня освещенности
Настройка режима работы сигнального светодиода (RGB) - Скрытый режим|Красный|Зеленый|Синий
Настройка уровня границы освещенности при которой датчик движения будет работать
Настройка времени удержания тригера датчика движения в активном состоянии. Так же программно применен рестарт указанного интервала при повторном движении во время уже сработавшего детекта движения.
На борту есть плата криптографии atsha204a-stucz-t
Так же присутствует внешняя SPI Flash AT25F512B-SSH-T
Применен очень интересный понижающий преобразователь 3.3-10в в 3.3 в очень классным собственным потреблением 360 наноампер - Dual-cell Ultra Low IQ Step Down Converter for Low Power Wireless Applications|
выведены как FTDI так и ICSP, так что полная свобода в манипуляциях над девайсом. Можете использовать мое ПО, можете улучшить его, можете написать крутое свое. Я только ЗА!!! Главное выкладывайте.
Скрин страницы датчика движения в модуле Майсенсорс в Мажордомо Небольшой скетч для датчика движения написанный мною:
Доп. библиотека:
Список компонентов которые присутствуют у датчика:
Плата PCB - 50 руб.
Держатель батареи 4 шт - 146 руб.
http://ali.ski/0j22k8
Кварц 8 мГц - 26.5 руб.
http://ali.ski/3wpZcC
Кнопки тактовые смд 2 шт - 14 руб.
http://ali.ski/TIXuLK
Линза Френеля - 18 руб.
http://ali.ski/PyfAb
Разьем 2x3 P6 1.27мм 2 шт - 17.7 руб.
http://ali.ski/2GRtq
NRF24L01 - 68.2 руб.
http://ali.ski/Jx3z00
Конденсатор 100nf 8 шт - 10.25 руб.
http://ali.ski/ctayFM
BH1750FVI-TR - 92.4 руб.
http://ali.ski/d9RYX5
TPS62745DSSR - 97 руб.
http://ali.ski/wD_r6G
AM312 - 110 руб.
http://ali.ski/ZqJSAW
Atmega328p-au - 155 руб.
http://ali.ski/B2JbY
Atsha204a-stucz-t - 66.2 руб.
http://ali.ski/88sem_
RGB SMD 0805 (2012) - 5 руб.
http://ali.ski/GxnHju
Конденсатор 10uf 25в 1206 XTR7 - 6 руб.
http://ali.ski/RiAZ8F
Конденсатор 10uf 16в 1206 XTR5 - 1.2 руб.
http://ali.ski/1OQW2
Индуктивность 4.7uh 1210 - 5 руб.
http://ali.ski/JC2n1
AT25F512B-SSH-T - 48 руб.
http://ali.ski/vfpdL
Конденсатор тантал 1uf 16в 0805 - 6.2 руб.
http://ali.ski/CHz126
Переключатель dsc0011 smd - 24.5 руб.
http://ali.ski/acHKDe
Резисторы 10К 1% 0805 6 шт - 1.2 руб.
http://ali.ski/i1tnsM
Резисторы 1M 1% 0805 1 шт - 0.24 руб.
http://ali.ski/i1tnsM
Резисторы 160К 1% 0805 1 шт - 0.18 руб.
http://ali.ski/i1tnsM
Резисторы 11К 1% 0805 1 шт - 0.18 руб.
http://ali.ski/i1tnsM
Резисторы 27К 1% 0805 1 шт - 0.18 руб.
http://ali.ski/i1tnsM
Резисторы 20К 1% 0805 1 шт - 0.18 руб.
http://ali.ski/i1tnsM
Себестоимость девайса - 969 рублей 31копейка (это в полной комплектации)
Батарейка 3.6в 14250 2шт. - 240 руб.
http://ali.ski/Bf7ny
Архив с платой в формате программы Диптрейс - вариант под !!! ЛУТ !!!
Фотки датчика движения:
По вопросам приобретения готового девайса или пром.плат для самостоятельной сборки - вэлкам в тему - https://majordomo.smartliving.ru/forum/ ... =15&t=5662
Возможности:
Работа на всех бутлоадерах.
Прошивка по воздуху.
Отправка состояния датчика движения на контролер
Три режима работы датчика движения (Ночь|День|Круглосуточно)
Регулируемая задержка (без задержки|1минута - 4 часа)
Отправка остатка заряда батарейки в процентах
Отправка уровня освещенности в Люксах
Настройка через модуль Майсенсорс в Мажордомо(да впринципе и через любой другой контролер):
Интервал отправки остатка заряда батарейки
Интервал отправки уровня освещенности
Настройка режима работы сигнального светодиода (RGB) - Скрытый режим|Красный|Зеленый|Синий
Настройка уровня границы освещенности при которой датчик движения будет работать
Настройка времени удержания тригера датчика движения в активном состоянии. Так же программно применен рестарт указанного интервала при повторном движении во время уже сработавшего детекта движения.
На борту есть плата криптографии atsha204a-stucz-t
Так же присутствует внешняя SPI Flash AT25F512B-SSH-T
Применен очень интересный понижающий преобразователь 3.3-10в в 3.3 в очень классным собственным потреблением 360 наноампер - Dual-cell Ultra Low IQ Step Down Converter for Low Power Wireless Applications|
выведены как FTDI так и ICSP, так что полная свобода в манипуляциях над девайсом. Можете использовать мое ПО, можете улучшить его, можете написать крутое свое. Я только ЗА!!! Главное выкладывайте.
Скрин страницы датчика движения в модуле Майсенсорс в Мажордомо Небольшой скетч для датчика движения написанный мною:
Код: Выделить всё
#include <Wire.h>
#include <BH1750.h>
BH1750 lightMeter;
#define MY_DEBUG
//#define MY_DISABLED_SERIAL
#define MY_RADIO_RF24
#define MY_OTA_FIRMWARE_FEATURE
//#define MY_SIGNING_ATSHA204
//#define MY_SIGNING_ATSHA204_PIN A3
//#define MY_SIGNING_REQUEST_SIGNATURES
#define MOTION_SENS_ID 1
#define LUX_SENS_ID 2
#define SETTING_LED_SENS_ID 100
#define DELAY_TIME_SENS_ID 101
#define MOTION_MODE_ID 102
#define SETTING_LUX_SENS_ID 103
#define BATTARY_SEND_SENS_ID 104
#define MYLED_ON 1
#define MYLED_OFF 0
#define BAT_COOF 7.4
#define BAT_MIN 350
#define BAT_MAX 720
#define SLEEP_TIME 300000
static uint8_t motion_pin = 3;
static uint8_t bled_pin = 14;
static uint8_t rled_pin = 15;
static uint8_t gled_pin = 16;
uint8_t selected_led;
uint8_t selected_motion_mode;
uint16_t count_batteryTime = 0;
uint16_t lux;
uint16_t boundary_DNlux;
uint32_t send_batteryTime;
uint32_t delayTime;
int8_t battery;
int8_t old_battery;
int8_t woke_up_from;
boolean flag = 0;
boolean flag2 = 0;
boolean flag3 = 0;
boolean sleep_mode = 1;
boolean tripped;
boolean first_send_battery = 1;
boolean flag_motion_mode;
#include <MySensors.h>
MyMessage msg_motion(MOTION_SENS_ID, V_TRIPPED);
MyMessage msg_lux(LUX_SENS_ID, V_LEVEL);
MyMessage msg_setting_led(SETTING_LED_SENS_ID, V_VAR1);
MyMessage msg_delay_time(DELAY_TIME_SENS_ID, V_VAR1);
MyMessage msg_motion_mode(MOTION_MODE_ID, V_VAR1);
MyMessage msg_setting_lux(SETTING_LUX_SENS_ID, V_LEVEL);
MyMessage msg_battary_send(BATTARY_SEND_SENS_ID, V_VAR1);
void preHwInit()
{
pinMode(motion_pin, INPUT);
pinMode(gled_pin, OUTPUT);
pinMode(rled_pin, OUTPUT);
pinMode(bled_pin, OUTPUT);
digitalWrite(bled_pin, HIGH);
digitalWrite(rled_pin, HIGH);
digitalWrite(gled_pin, HIGH);
}
void before()
{
selected_led = loadState(100);
if (selected_led == 255) {
selected_led = 0;
saveState(100, selected_led);
}
delayTime = loadState(101);
if (delayTime > 240) {
delayTime = 1;
saveState(101, delayTime);
}
send_batteryTime = loadState(102);
if (send_batteryTime > 250) {
send_batteryTime = 1;
saveState(102, send_batteryTime);
}
send_batteryTime = send_batteryTime * 10;
boundary_DNlux = loadState(103);
if (boundary_DNlux > 250) {
boundary_DNlux = 0;
saveState(103, boundary_DNlux);
}
selected_motion_mode = loadState(104);
if (selected_motion_mode > 2) {
selected_motion_mode = 0;
saveState(104, selected_motion_mode);
}
}
void presentation()
{
sendSketchInfo("Motion Sensor", "1.2");
wait(100);
present(MOTION_SENS_ID, S_MOTION, "MOTION STATUS");
wait(100);
present(LUX_SENS_ID, S_LIGHT_LEVEL, "LUX LEVEL");
wait(100);
present(SETTING_LED_SENS_ID, S_CUSTOM, "LED MODE (R,G,B)");
wait(100);
present(DELAY_TIME_SENS_ID, S_CUSTOM, "DELAY TIME/MIN");
wait(100);
present(MOTION_MODE_ID, S_CUSTOM, "MOTION MODE (D|N|ALL");
wait(100);
present(SETTING_LUX_SENS_ID, S_LIGHT_LEVEL, "LUX MODE");
wait(100);
present(BATTARY_SEND_SENS_ID, S_CUSTOM, "BATTERY SEND TIME X10");
}
void setup()
{
lightMeter.begin();
readBatLev();
wait(100);
lux = lightMeter.readLightLevel();
send(msg_lux.set(lux));
wait(100);
tripped = digitalRead(motion_pin);
send(msg_motion.set(tripped));
wait(100);
send(msg_setting_led.set(selected_led));
wait(100);
send(msg_motion_mode.set(selected_motion_mode));
wait(100);
send(msg_setting_lux.set(boundary_DNlux));
wait(100);
send(msg_battary_send.set(send_batteryTime));
}
void loop()
{
if (delayTime != 0) {
if (sleep_mode == 0) {
woke_up_from = sleep(digitalPinToInterrupt(motion_pin), RISING, delayTime * 60 * 1000, false);
}
if (sleep_mode == 1) {
woke_up_from = sleep(digitalPinToInterrupt(motion_pin), RISING, delayTime * 60 * 1000, true);
sleep_mode = 0;
}
} else {
if (sleep_mode == 0) {
woke_up_from = sleep(digitalPinToInterrupt(motion_pin), CHANGE, 0, false);
}
if (sleep_mode == 1) {
woke_up_from = sleep(digitalPinToInterrupt(motion_pin), CHANGE, 0, true);
sleep_mode = 0;
}
}
if (flag != 1) {
if (selected_motion_mode != 2) {
lux = lightMeter.readLightLevel();
if (selected_motion_mode == 0) {
if (lux <= boundary_DNlux) {
flag_motion_mode = 1;
}
} else {
if (lux > boundary_DNlux) {
flag_motion_mode = 1;
}
}
} else {
flag_motion_mode = 1;
}
}else{
flag_motion_mode = 1;
}
if (woke_up_from == 1) {
if (flag_motion_mode == 1) {
tripped = digitalRead(motion_pin);
if (delayTime != 0) {
if (flag == 0) {
flag = 1;
led_show_detect(selected_led, MYLED_ON);
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION: DETECTED\n"));
send(msg_motion.set(1));
TRANSPORT_DEBUG(PSTR("MyS: SEND STATUS TO GW\n"));
if (count_batteryTime < send_batteryTime) {
TRANSPORT_DEBUG(PSTR("MyS: COUNTER BATTERY SEND: %d, < %d\n"), count_batteryTime, send_batteryTime);
count_batteryTime++;
}
else {
readBatLev();
count_batteryTime = 0;
TRANSPORT_DEBUG(PSTR("MyS: COUNTER BATTERY SEND: 0\n"));
if (selected_motion_mode == 2) {
lux = lightMeter.readLightLevel();
send(msg_lux.set(lux));
TRANSPORT_DEBUG(PSTR("MyS: LUX LEVEL SEND\n"));
} else {
send(msg_lux.set(lux));
TRANSPORT_DEBUG(PSTR("MyS: LUX LEVEL SEND\n"));
}
sleep_mode = 1;
}
}
else {
TRANSPORT_DEBUG(PSTR("MyS: UPDATE DELAY STATUS MOTION: DETECTED\n"));
}
} else {
if (tripped == 0) {
flag = 1;
led_show_detect(selected_led, MYLED_OFF);
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION: NOT DETECTED\n"));
send(msg_motion.set(0));
TRANSPORT_DEBUG(PSTR("MyS: SEND STATUS TO GW\n"));
} else {
flag = 0;
led_show_detect(selected_led, MYLED_ON);
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION: DETECTED\n"));
send(msg_motion.set(1));
TRANSPORT_DEBUG(PSTR("MyS: SEND STATUS TO GW\n"));
if (count_batteryTime < send_batteryTime * 10) {
TRANSPORT_DEBUG(PSTR("MyS: COUNTER BATTERY SEND: %d, < %d\n"), count_batteryTime, send_batteryTime);
count_batteryTime++;
}
else {
readBatLev();
count_batteryTime = 0;
TRANSPORT_DEBUG(PSTR("MyS: COUNTER BATTERY SEND: 0\n"));
if (selected_motion_mode == 2) {
lux = lightMeter.readLightLevel();
send(msg_lux.set(lux));
TRANSPORT_DEBUG(PSTR("MyS: LUX LEVEL SEND\n"));
} else {
send(msg_lux.set(lux));
TRANSPORT_DEBUG(PSTR("MyS: LUX LEVEL SEND\n"));
}
sleep_mode = 1;
}
}
}
flag_motion_mode = 0;
}
}
if (woke_up_from == -1) {
if (flag == 0) {
if (count_batteryTime < send_batteryTime) {
count_batteryTime++;
TRANSPORT_DEBUG(PSTR("MyS: COUNTER BATTERY SEND: %d, < %d\n"), count_batteryTime, send_batteryTime);
}
else {
readBatLev();
count_batteryTime = 0;
TRANSPORT_DEBUG(PSTR("MyS: COUNTER BATTERY SEND: 0\n"));
if (selected_motion_mode == 2) {
lux = lightMeter.readLightLevel();
send(msg_lux.set(lux));
TRANSPORT_DEBUG(PSTR("MyS: LUX LEVEL SEND\n"));
} else {
send(msg_lux.set(lux));
TRANSPORT_DEBUG(PSTR("MyS: LUX LEVEL SEND\n"));
}
sleep_mode = 1;
}
} else {
flag = 0;
led_show_detect(selected_led, MYLED_OFF);
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION: NOT DETECTED\n"));
send(msg_motion.set(0));
TRANSPORT_DEBUG(PSTR("MyS: SEND STATUS TO GW\n"));
}
flag_motion_mode = 0;
}
}
void receive(const MyMessage & message)
{
if (message.sensor == SETTING_LED_SENS_ID) {
if (message.type == V_VAR1) {
if (message.getByte() <= 3) {
selected_led = message.getByte();
saveState(100, selected_led);
send(msg_setting_led.set(selected_led));
if (selected_led == 0) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION LED: OFF\n"));
}
if (selected_led == 1) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION LED: GREEN\n"));
}
if (selected_led == 2) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION LED: RED\n"));
}
if (selected_led == 3) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION LED: BLUE\n"));
}
}
}
}
if (message.sensor == DELAY_TIME_SENS_ID) {
if (message.type == V_VAR1) {
if (message.getULong() <= 240) {
delayTime = message.getULong();
saveState(101, delayTime);
send(msg_delay_time.set(delayTime));
TRANSPORT_DEBUG(PSTR("MyS: THE NEW DELAY VALUE IS SET: %d MIN.\n"), delayTime);
}
}
}
if (message.sensor == BATTARY_SEND_SENS_ID) {
if (message.type == V_VAR1) {
if (message.getULong() <= 250) {
send_batteryTime = message.getULong();
saveState(102, send_batteryTime);
send(msg_battary_send.set(send_batteryTime));
send_batteryTime = send_batteryTime * 10;
TRANSPORT_DEBUG(PSTR("MyS: THE NEW BATTERY TIME SEND IS SET: %d MOTION SENSOR OPERATIONS\n"), send_batteryTime);
}
}
}
if (message.sensor == MOTION_MODE_ID) {
if (message.type == V_VAR1) {
if (message.getByte() <= 2) {
selected_motion_mode = message.getByte();
saveState(104, selected_motion_mode);
send(msg_motion_mode.set(selected_motion_mode));
if (selected_motion_mode == 0) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION MODE: WORK IN THE DARK\n"));
}
if (selected_motion_mode == 1) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION MODE: WORK IN THE LIGHT\n"));
}
if (selected_motion_mode == 2) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS MOTION MODE: ALWAYS WORK\n"));
}
}
}
}
if (message.sensor == SETTING_LUX_SENS_ID) {
if (message.type == V_LEVEL) {
if (message.getUInt() <= 250) {
boundary_DNlux = message.getUInt();
saveState(103, boundary_DNlux);
send(msg_setting_lux.set(boundary_DNlux));
TRANSPORT_DEBUG(PSTR("MyS: THE NEW BORDER LIGHT LUX IS SET: %d\n"), boundary_DNlux);
}
}
}
}
void readBatLev() {
wait(100);
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX2) | _BV(MUX1);
wait(100);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA, ADSC));
uint8_t low = ADCL;
uint8_t high = ADCH;
long temp = (high << 8) | low;
float vcc = temp * 1.1 / 1023 * BAT_COOF * 100;
battery = map((int)vcc, BAT_MIN, BAT_MAX, 0, 100);
if (battery < 0) {
battery = 0;
}
if (battery > 100) {
battery = 100;
}
TRANSPORT_DEBUG(PSTR("MyS: BATTERY LEVEL: %d, PREVIUS BATTERY LEVEL: %d\n"), battery, old_battery);
if (first_send_battery == 1) {
first_send_battery = 0;
sendBatteryLevel(battery);
TRANSPORT_DEBUG(PSTR("MyS: SEND BATTERY LEVEL\n"));
old_battery = battery;
} else {
if (old_battery != battery) {
if (battery < old_battery) {
old_battery = battery;
sendBatteryLevel(battery);
TRANSPORT_DEBUG(PSTR("MyS: SEND BATTERY LEVEL\n"));
} else {
battery = old_battery;
}
}
}
}
void led_show_detect(uint8_t led, uint8_t mode) {
if (led == 1) {
if (mode == 1) {
digitalWrite(gled_pin, LOW);
TRANSPORT_DEBUG(PSTR("MyS: STATUS LED GREEN: ON\n"));
} else {
digitalWrite(gled_pin, HIGH);
TRANSPORT_DEBUG(PSTR("MyS: STATUS LED GREEN: OFF\n"));
}
}
if (led == 2) {
if (mode == 1) {
digitalWrite(rled_pin, LOW);
TRANSPORT_DEBUG(PSTR("MyS: STATUS LED RED: ON\n"));
} else {
digitalWrite(rled_pin, HIGH);
TRANSPORT_DEBUG(PSTR("MyS: STATUS LED RED: OFF\n"));
}
}
if (led == 3) {
if (mode == 1) {
digitalWrite(bled_pin, LOW);
TRANSPORT_DEBUG(PSTR("MyS: STATUS LED BLUE: ON\n"));
} else {
digitalWrite(bled_pin, HIGH);
TRANSPORT_DEBUG(PSTR("MyS: STATUS LED BLUE: OFF\n"));
}
}
}
Доп. библиотека:
Список компонентов которые присутствуют у датчика:
Плата PCB - 50 руб.
Держатель батареи 4 шт - 146 руб.
http://ali.ski/0j22k8
Кварц 8 мГц - 26.5 руб.
http://ali.ski/3wpZcC
Кнопки тактовые смд 2 шт - 14 руб.
http://ali.ski/TIXuLK
Линза Френеля - 18 руб.
http://ali.ski/PyfAb
Разьем 2x3 P6 1.27мм 2 шт - 17.7 руб.
http://ali.ski/2GRtq
NRF24L01 - 68.2 руб.
http://ali.ski/Jx3z00
Конденсатор 100nf 8 шт - 10.25 руб.
http://ali.ski/ctayFM
BH1750FVI-TR - 92.4 руб.
http://ali.ski/d9RYX5
TPS62745DSSR - 97 руб.
http://ali.ski/wD_r6G
AM312 - 110 руб.
http://ali.ski/ZqJSAW
Atmega328p-au - 155 руб.
http://ali.ski/B2JbY
Atsha204a-stucz-t - 66.2 руб.
http://ali.ski/88sem_
RGB SMD 0805 (2012) - 5 руб.
http://ali.ski/GxnHju
Конденсатор 10uf 25в 1206 XTR7 - 6 руб.
http://ali.ski/RiAZ8F
Конденсатор 10uf 16в 1206 XTR5 - 1.2 руб.
http://ali.ski/1OQW2
Индуктивность 4.7uh 1210 - 5 руб.
http://ali.ski/JC2n1
AT25F512B-SSH-T - 48 руб.
http://ali.ski/vfpdL
Конденсатор тантал 1uf 16в 0805 - 6.2 руб.
http://ali.ski/CHz126
Переключатель dsc0011 smd - 24.5 руб.
http://ali.ski/acHKDe
Резисторы 10К 1% 0805 6 шт - 1.2 руб.
http://ali.ski/i1tnsM
Резисторы 1M 1% 0805 1 шт - 0.24 руб.
http://ali.ski/i1tnsM
Резисторы 160К 1% 0805 1 шт - 0.18 руб.
http://ali.ski/i1tnsM
Резисторы 11К 1% 0805 1 шт - 0.18 руб.
http://ali.ski/i1tnsM
Резисторы 27К 1% 0805 1 шт - 0.18 руб.
http://ali.ski/i1tnsM
Резисторы 20К 1% 0805 1 шт - 0.18 руб.
http://ali.ski/i1tnsM
Себестоимость девайса - 969 рублей 31копейка (это в полной комплектации)
Батарейка 3.6в 14250 2шт. - 240 руб.
http://ali.ski/Bf7ny
Архив с платой в формате программы Диптрейс - вариант под !!! ЛУТ !!!
Фотки датчика движения:
По вопросам приобретения готового девайса или пром.плат для самостоятельной сборки - вэлкам в тему - https://majordomo.smartliving.ru/forum/ ... =15&t=5662