Датчик детектор протечки воды с батарейным питанием, на чипе nRF52832.
Тип питания: Батарейка, тип CR2477, возможны варианты для CR2430 или CR2450
Размеры: Д 4.7мм Х Ш 3.4мм Х В 2.2мм (CR2477)<br/>
Характеристики:
Разработан для экосистемы MySensors
Питание от батареек CR2430, CR2450, CR2477 (> 5 работы на батарейке любого качества)
Температура эксплуатации: комнатный, 0 до +40
Передает состояние сенсоров детектирования протечки с индикацией успешной отправки, уровень заряда, уровень радиосигнала.
Модифицированный режим работы с сетью майсенсорс(опционально)
Режим привязки по воздуху(опционально)
Не требует внесений изменений в код ПО через Ардуино IDE(опционально)
GitHub: https://github.com/smartboxchannel/EFEK ... EAK_SENSOR
Разработчики: Андрей Ламченко
Видео: https://youtu.be/5jZt3NWf9GA
Место где всегда с радостью помогут всем кто хочется познакомиться с MYSENSORS (установка плат, работа с микроконтролерами nRF5 в среде Arduino IDE, советы по работе с протоколом mysensors — телеграм чат @mysensors_rus</t>
Список используемых компонентов:
YJ-17103 - http://ali.ski/1Hm3u
SN74LVC1G00 - http://ali.ski/iLK_F
1PS76SB10.115(SOD-323) SMD Schottky Barrier Diode(2шт) - http://ali.ski/5dTu7U
100UF 107C D-type SMD Tantalum Capacitor - http://ali.ski/-NkuK
100nF | 50v | +80-20% | SMD 0805 | SMD ceramic capacitor 100nF | Y5V - http://ali.ski/nnISH
2UF | 50v | +80-20% | SMD 0805 | SMD ceramic capacitor 2UF | Y5V - http://ali.ski/nnISH
CR2450 Battery Socket Holder Case (TBH-CR2450-03) - http://ali.ski/49emH8
Micro Button Tact Switch SMD 4Pin 3X4X2.5MM White(2шт) - http://ali.ski/8wHa4-
2x3P | 6pin | 1.27mm | SMT | J1 Pin Header Female - http://ali.ski/tKqX1J
10K | 5% | SMD 0603 | SMD resistor 10K Ohm(3шт) - http://ali.ski/1xMf-
100K | 5% | SMD 0603 | SMD resistor 100K Ohm(3шт - http://ali.ski/1xMf-
2K7 | 5% | SMD 0603 | SMD resistor 2K7 Ohm(1шт) - http://ali.ski/1xMf-
6K8 | 5% | SMD 0603 | SMD resistor 6K8 Ohm(1шт) - http://ali.ski/1xMf-
9K1 | 5% | SMD 0603 | SMD resistor 9K1 Ohm(1шт) - http://ali.ski/1xMf-
1M | 5% | SMD 0603 | SMD resistor 1M Ohm(1шт) - http://ali.ski/1xMf-
100 | 5% | SMD 0603 | SMD resistor 100 Ohm(1шт - http://ali.ski/1xMf-
RGB LED | SMD 0805 | RGBL | RGB LED - http://ali.ski/BPc4y
M1.4 4mm Round Head Micro Screws(4шт) - http://ali.ski/sV_W2
M3 11mm Nickel plated Brass Standoff Spacer Female(2шт - http://ali.ski/gxLz3d
M3 6mm Hexagon Socket Thin low Short Head Cap Screw(2шт) - http://ali.ski/y_jhn
M3 4mm Hexagon Socket Button Head Screws(2шт) - http://ali.ski/Fsm9k
тестовый код:
wl_standart_test.ino
Код: Выделить всё
bool button_flag;
bool send_flag;
bool detection;
bool nosleep;
byte timer;
bool AckG;
bool AckB;
bool AckL;
bool PRESENT_ACK;
bool flag_lq;
unsigned long SLEEP_TIME = 43200000; //12 hours
//unsigned long SLEEP_TIME = 3600000; //1 hours
unsigned long oldmillis;
unsigned long newmillis;
unsigned long interrupt_time;
unsigned long SLEEP_TIME_W;
uint16_t currentBatteryPercent;
uint16_t batteryVoltage = 0;
uint16_t battery_vcc_min = 2200;
uint16_t battery_vcc_max = 3000;
int16_t linkQuality;
#define MY_DISABLED_SERIAL
#define MY_RADIO_NRF5_ESB
#define MY_RF24_PA_LEVEL (NRF5_PA_MAX)
//#define MY_PASSIVE_NODE
#define MY_NODE_ID 86
#define MY_PARENT_NODE_ID 0
#define MY_PARENT_NODE_IS_STATIC
#define MY_TRANSPORT_UPLINK_CHECK_DISABLED
#define INTR_PIN 3 //(PORT0, gpio 5)
#include <MySensors.h>
// see https://www.mysensors.org/download/serial_api_20
#define W_L_SENS_CHILD_ID 0
#define LINK_QUALITY_CHILD_ID 253
MyMessage sensMsg(W_L_SENS_CHILD_ID, V_VAR1);
//MyMessage voltMsg(CHILD_ID_VOLT, V_VOLTAGE);
void preHwInit() {
pinMode(POWER_PIN, OUTPUT);
digitalWrite(POWER_PIN, HIGH);
wait(3000);
pinMode(RED_LED, OUTPUT);
digitalWrite(RED_LED, HIGH);
pinMode(GREEN_LED, OUTPUT);
digitalWrite(GREEN_LED, HIGH);
pinMode(BLUE_LED, OUTPUT);
digitalWrite(BLUE_LED, HIGH);
pinMode(PIN_BUTTON, INPUT);
pinMode(W_L_SENS, INPUT);
//pinMode(24, OUTPUT);
//pinMode(20, OUTPUT);
}
void before()
{
NRF_POWER->DCDCEN = 1;
NRF_UART0->ENABLE = 0;
digitalWrite(BLUE_LED, LOW);
sleep(50);
digitalWrite(BLUE_LED, HIGH);
}
void presentation() {
sendSketchInfo("EFEKTA ST WL Sensor", "1.1");
present(W_L_SENS_CHILD_ID, S_CUSTOM, "SWITCH STATUS");
present(LINK_QUALITY_CHILD_ID, S_CUSTOM, "LINK_QUALITY");
}
void setup() {
digitalWrite(BLUE_LED, LOW);
wait(100);
digitalWrite(BLUE_LED, HIGH);
wait(200);
digitalWrite(BLUE_LED, LOW);
wait(100);
digitalWrite(BLUE_LED, HIGH);
lpComp();
detection = false;
SLEEP_TIME_W = SLEEP_TIME;
wait(100);
sendBatteryStatus();
wait(100);
send(sensMsg.set(detection), 1);
wait(2000, 1, V_VAR1);
}
void loop() {
if (nosleep == 0) {
oldmillis = millis();
sleep(SLEEP_TIME_W);
}
if (detection) {
if (digitalRead(PIN_BUTTON) == 1 && button_flag == 0 && digitalRead(W_L_SENS) == 0) {
//back side button detection
button_flag = 1;
nosleep = 1;
}
if (digitalRead(PIN_BUTTON) == 1 && button_flag == 1 && digitalRead(W_L_SENS) == 0) {
digitalWrite(GREEN_LED, LOW);
wait(10);
digitalWrite(GREEN_LED, HIGH);
wait(50);
}
if (digitalRead(PIN_BUTTON) == 0 && button_flag == 1 && digitalRead(W_L_SENS) == 0) {
nosleep = 0;
button_flag = 0;
digitalWrite(GREEN_LED, HIGH);
lpComp_reset();
}
if (digitalRead(W_L_SENS) == 1 && digitalRead(PIN_BUTTON) == 0) {
//sens detection
newmillis = millis();
interrupt_time = newmillis - oldmillis;
SLEEP_TIME_W = SLEEP_TIME_W - interrupt_time;
send(sensMsg.set(detection), 1);
wait(3000, 1, V_VAR1);
if (AckG == 1) {
while (timer < 10) {
timer++;
digitalWrite(BLUE_LED, LOW);
wait(20);
digitalWrite(BLUE_LED, HIGH);
wait(30);
}
timer = 0;
AckG = 0;
wait(200);
} else {
while (timer < 10) {
timer++;
digitalWrite(RED_LED, LOW);
wait(20);
digitalWrite(RED_LED, HIGH);
wait(30);
}
timer = 0;
send(sensMsg.set(detection), 1);
wait(3000, 1, V_VAR1);
if (AckG == 1) {
while (timer < 10) {
timer++;
digitalWrite(BLUE_LED, LOW);
wait(20);
digitalWrite(BLUE_LED, HIGH);
wait(30);
}
timer = 0;
AckG = 0;
} else {
while (timer < 10) {
timer++;
digitalWrite(RED_LED, LOW);
wait(20);
digitalWrite(RED_LED, HIGH);
wait(30);
}
timer = 0;
}
lpComp_reset();
}
}
if (SLEEP_TIME_W < 60000) {
SLEEP_TIME_W = SLEEP_TIME;
sendBatteryStatus();
}
}
else {
//if (detection == -1) {
SLEEP_TIME_W = SLEEP_TIME;
sendBatteryStatus();
}
}
void receive(const MyMessage & message) {
if (message.type == V_VAR1) {
if (message.sensor == W_L_SENS_CHILD_ID) {
if (mGetCommand(message) == 1) {
if (message.isAck()) {
AckG = 1;
} else {
}
}
}
}
if (message.type == I_BATTERY_LEVEL) {
if (message.sensor == 255) {
if (mGetCommand(message) == 3) {
if (message.isAck()) {
AckB = 1;
} else {
}
}
}
}
if (message.type == V_VAR1) {
if (message.sensor == 255) {
if (mGetCommand(message) == 1) {
if (message.isAck()) {
AckL = 1;
} else {
}
}
}
}
}
void sendBatteryStatus() {
wait(100);
batteryVoltage = hwCPUVoltage();
wait(20);
if (batteryVoltage > battery_vcc_max) {
currentBatteryPercent = 100;
}
else if (batteryVoltage < battery_vcc_min) {
currentBatteryPercent = 0;
} else {
currentBatteryPercent = (100 * (batteryVoltage - battery_vcc_min)) / (battery_vcc_max - battery_vcc_min);
}
sendBatteryLevel(currentBatteryPercent, 1);
wait(3000, C_INTERNAL, I_BATTERY_LEVEL);
if (AckB == 1) {
AckB = 0;
flag_lq = 1;
} else {
sendBatteryLevel(currentBatteryPercent, 1);
wait(3000, C_INTERNAL, I_BATTERY_LEVEL);
if (AckB == 1) {
AckB = 0;
flag_lq = 1;
}
}
//send(powerMsg.set(batteryVoltage), 1);
//wait(2000, 1, V_VAR1);
//sleep(10000); //
if (flag_lq == 1) {
linkQuality = calculationRxQuality();
wait(50);
sendSignalStrength(linkQuality, 1);
wait(2000, 1, V_VAR1);
if (AckL == 1) {
AckL = 0;
} else {
sendSignalStrength(linkQuality, 1);
wait(2000, 1, V_VAR1);
if (AckL == 1) {
AckG = 0;
}
}
flag_lq = 0;
}
}
void lpComp() {
NRF_LPCOMP->PSEL = INTR_PIN;
NRF_LPCOMP->ANADETECT = 1;
NRF_LPCOMP->INTENSET = B0100;
NRF_LPCOMP->ENABLE = 1;
NRF_LPCOMP->TASKS_START = 1;
NVIC_SetPriority(LPCOMP_IRQn, 15);
NVIC_ClearPendingIRQ(LPCOMP_IRQn);
NVIC_EnableIRQ(LPCOMP_IRQn);
}
void s_lpComp() {
if ((NRF_LPCOMP->ENABLE) && (NRF_LPCOMP->EVENTS_READY)) {
NRF_LPCOMP->INTENCLR = B0100;
}
}
void r_lpComp() {
NRF_LPCOMP->INTENSET = B0100;
}
#if __CORTEX_M == 0x04
#define NRF5_RESET_EVENT(event) \
event = 0; \
(void)event
#else
#define NRF5_RESET_EVENT(event) event = 0
#endif
void lpComp_reset () {
s_lpComp();
detection = false;
NRF_LPCOMP->EVENTS_UP = 0;
r_lpComp();
}
//****************************** very experimental *******************************
bool sendSignalStrength(const int16_t level, const bool ack)
{
return _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_SET, V_VAR1,
ack).set(level));
}
int16_t calculationRxQuality() {
int16_t nRFRSSI_temp = transportGetReceivingRSSI();
int16_t nRFRSSI = map(nRFRSSI_temp, -85, -40, 0, 100);
if (nRFRSSI < 0) {
nRFRSSI = 0;
}
if (nRFRSSI > 100) {
nRFRSSI = 100;
}
return nRFRSSI;
}
//****************************** very experimental *******************************
extern "C" {
void LPCOMP_IRQHandler(void) {
detection = true;
NRF5_RESET_EVENT(NRF_LPCOMP->EVENTS_UP);
NRF_LPCOMP->EVENTS_UP = 0;
MY_HW_RTC->CC[0] = (MY_HW_RTC->COUNTER + 2);
}
}
Код: Выделить всё
#ifndef _MYBOARDNRF5_H_
#define _MYBOARDNRF5_H_
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
#define PINS_COUNT (32u)
#define NUM_DIGITAL_PINS (32u)
#define NUM_ANALOG_INPUTS (8u)
#define NUM_ANALOG_OUTPUTS (8u)
#define PIN_LED1 (27)
#define PIN_LED2 (25)
#define PIN_LED3 (26)
#define RED_LED (PIN_LED1)
#define GREEN_LED (PIN_LED2)
#define BLUE_LED (PIN_LED3)
#define LED_BUILTIN (PIN_LED1)
#define PIN_BUTTON (14)
#define W_L_SENS (8)
#define POWER_PIN (7)
static const uint8_t A0 = ADC_A0;
static const uint8_t A1 = ADC_A1;
static const uint8_t A2 = ADC_A2;
static const uint8_t A3 = ADC_A3;
static const uint8_t A4 = ADC_A4;
static const uint8_t A5 = ADC_A5;
static const uint8_t A6 = ADC_A6;
static const uint8_t A7 = ADC_A7;
#define PIN_SERIAL_RX (12)
#define PIN_SERIAL_TX (11)
#ifdef __cplusplus
}
#endif
#endif
Spoiler
Show