Сенсорный выключатель с дополнительной флуоресцентной подсветкой

Ответить
Berkseo
Сообщения: 56
Зарегистрирован: Вт янв 24, 2017 12:30 am
Благодарил (а): 6 раз
Поблагодарили: 22 раза

Сенсорный выключатель с дополнительной флуоресцентной подсветкой

Сообщение Berkseo » Чт июн 27, 2019 5:52 pm

Делюсь новостями об очередном своём проектикике. Это сенсорный выключатель на 1 канал для сети Майсенсорс, работает от батареек типа cr2430-50. Девайс обещает работать на одной батарейки более 1 года.
IMG_20190624_170956.jpg
IMG_20190624_170956.jpg (3.08 МБ) 1915 просмотров
Характеристики:
  • чип nRF5283
  • питание: батарейное, тип CR2430, CR2450
  • дополнительная флуоресцентная подсветка
  • магниты в корпусе для быстрого крепления к металлическим поверхностям
  • передает состояние, с индикацией успешной отправки, уровень заряда, уровень радиосигнала
GitHub проекта: https://github.com/smartboxchannel/EFEK ... UCH_SWITCH

Видео: https://youtu.be/DVpDjXjeUKg

Место где всегда с радостью помогут всем кто хочется познакомиться с MYSENSORS (установка плат, работа с микроконтролерами nRF5 в среде Arduino IDE, советы по работе с протоколом mysensors — "mysensors_rus
Последний раз редактировалось Berkseo Чт июн 27, 2019 5:59 pm, всего редактировалось 1 раз.
Berkseo
Сообщения: 56
Зарегистрирован: Вт янв 24, 2017 12:30 am
Благодарил (а): 6 раз
Поблагодарили: 22 раза

Re: Сенсорный выключатель с дополнительной флуоресцентной подсветкой

Сообщение Berkseo » Чт июн 27, 2019 5:55 pm

Тестовый скетч:

sens_test001.ino

Код: Выделить всё

/**
  ТЕСТОВЫЙ СКЕТЧ СЕНСОРНОГО ВЫКЛЮЧАТЕЛЯ С ПРЕРЫВАНИЯМИ НА NRF_LPCOMP
*/
bool button_flag;
bool sens_flag;
bool send_flag;
bool detection;
bool nosleep;
byte timer;
unsigned long SLEEP_TIME = 21600000; //6 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 = 2400;
uint16_t battery_vcc_max = 3000;

#define MY_RADIO_NRF5_ESB
//#define MY_PASSIVE_NODE
#define MY_NODE_ID 30
#define MY_PARENT_NODE_ID 0
#define MY_PARENT_NODE_IS_STATIC
#define MY_TRANSPORT_UPLINK_CHECK_DISABLED
#define IRT_PIN 3 //(PORT0,  gpio 5)
#include <MySensors.h>
// see https://www.mysensors.org/download/serial_api_20
#define SENS_CHILD_ID 0
#define CHILD_ID_VOLT 254
MyMessage sensMsg(SENS_CHILD_ID, V_VAR1);
//MyMessage voltMsg(CHILD_ID_VOLT, V_VOLTAGE);


void preHwInit() {
  sleep(2000);
  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(MODE_PIN, INPUT);
  pinMode(SENS_PIN, INPUT);
}

void before()
{
  NRF_POWER->DCDCEN = 1;
  NRF_UART0->ENABLE = 0;
  sleep(1000);
  digitalWrite(BLUE_LED, LOW);
  sleep(150);
  digitalWrite(BLUE_LED, HIGH);
}

void presentation()  {
  sendSketchInfo("EFEKTA Sens 1CH Sensor", "1.1");
  present(SENS_CHILD_ID, S_CUSTOM, "SWITCH STATUS");
  //present(CHILD_ID_VOLT, S_MULTIMETER, "Battery");
}

void setup() {
  digitalWrite(BLUE_LED, LOW);
  sleep(100);
  digitalWrite(BLUE_LED, HIGH);
  sleep(200);
  digitalWrite(BLUE_LED, LOW);
  sleep(100);
  digitalWrite(BLUE_LED, HIGH);
  lpComp();
  detection = false;
  SLEEP_TIME_W = SLEEP_TIME;
  pinMode(31, OUTPUT);
  digitalWrite(31, HIGH);
  /*
    while (timer < 10) {
    timer++;
    digitalWrite(GREEN_LED, LOW);
    wait(5);
    digitalWrite(GREEN_LED, HIGH);
    wait(500);
    }
    timer = 0;
  */
  sleep(7000);
  while (timer < 3) {
    timer++;
    digitalWrite(GREEN_LED, LOW);
    sleep(15);
    digitalWrite(GREEN_LED, HIGH);
    sleep(85);
  }
  timer = 0;
  sleep(1000);
}

void loop() {

  if (detection) {
    if (digitalRead(MODE_PIN) == 1 && button_flag == 0 && digitalRead(SENS_PIN) == 0) {
      //back side button detection
      button_flag = 1;
      nosleep = 1;
    }
    if (digitalRead(MODE_PIN) == 1 && button_flag == 1 && digitalRead(SENS_PIN) == 0) {
      digitalWrite(RED_LED, LOW);
      wait(10);
      digitalWrite(RED_LED, HIGH);
      wait(50);
    }
    if (digitalRead(MODE_PIN) == 0 && button_flag == 1 && digitalRead(SENS_PIN) == 0) {
      nosleep = 0;
      button_flag = 0;
      digitalWrite(RED_LED, HIGH);
      lpComp_reset();
    }

    if (digitalRead(SENS_PIN) == 1 && sens_flag == 0 && digitalRead(MODE_PIN) == 0) {
      //sens detection
      sens_flag = 1;
      nosleep = 1;
      newmillis = millis();
      interrupt_time = newmillis - oldmillis;
      SLEEP_TIME_W = SLEEP_TIME_W - interrupt_time;
      if (send(sensMsg.set(detection))) {
        send_flag = 1;
      }
    }
    if (digitalRead(SENS_PIN) == 1 && sens_flag == 1 && digitalRead(MODE_PIN) == 0) {
      if (send_flag == 1) {
        while (timer < 10) {
          timer++;
          digitalWrite(GREEN_LED, LOW);
          wait(20);
          digitalWrite(GREEN_LED, HIGH);
          wait(30);
        }
        timer = 0;
      } else {
        while (timer < 10) {
          timer++;
          digitalWrite(RED_LED, LOW);
          wait(20);
          digitalWrite(RED_LED, HIGH);
          wait(30);
        }
        timer = 0;
      }
    }
    if (digitalRead(SENS_PIN) == 0 && sens_flag == 1 && digitalRead(MODE_PIN) == 0) {
      sens_flag = 0;
      nosleep = 0;
      send_flag = 0;
      digitalWrite(GREEN_LED, HIGH);
      sleep(500);
      lpComp_reset();
    }
    if (SLEEP_TIME_W < 60000) {
      SLEEP_TIME_W = SLEEP_TIME;
      sendBatteryStatus();
    }
  }
  else {
    //if (detection == -1) {
    SLEEP_TIME_W = SLEEP_TIME;
    sendBatteryStatus();
  }
  if (nosleep == 0) {
    oldmillis = millis();
    sleep(SLEEP_TIME_W);
  }
}

void sendBatteryStatus() {
  wait(20);
  batteryVoltage = hwCPUVoltage();
  wait(2);

  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(2000, C_INTERNAL, I_BATTERY_LEVEL);
  //send(powerMsg.set(batteryVoltage), 1);
  //wait(2000, 1, V_VAR1);
}

void lpComp() {
  NRF_LPCOMP->PSEL = IRT_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

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);
  }
}

void lpComp_reset () {
  s_lpComp();
  detection = false;
  NRF_LPCOMP->EVENTS_UP = 0;
  r_lpComp();
}
MyBoardNRF5.cpp

Код: Выделить всё

#ifdef MYBOARDNRF5
#include <variant.h>

/*
 * Pins descriptions. Attributes are ignored by arduino-nrf5 variant. 
 * Definition taken from Arduino Primo Core with ordered ports
 */
const PinDescription g_APinDescription[]=
{
  { NOT_A_PORT, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // LFCLK
  { NOT_A_PORT, 1, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // LFCLK
  { PORT0,  2, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A0, PWM4, NOT_ON_TIMER},
  { PORT0,  3, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A1, PWM5, NOT_ON_TIMER},
  { PORT0,  4, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A2, PWM6, NOT_ON_TIMER},
  { PORT0,  5, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A3, PWM7, NOT_ON_TIMER},
  { PORT0,  6, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT3
  { PORT0,  7, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT4
  { PORT0,  8, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM10, NOT_ON_TIMER},    //USER_LED
  { PORT0,  9, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // NFC1
  { PORT0, 10, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // NFC2
  { PORT0, 11, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // TX
  { PORT0, 12, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // RX
  { PORT0, 13, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // SDA
  { PORT0, 14, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // SCL
  { PORT0, 15, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // SDA1
  { PORT0, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // SCL1
  { PORT0, 17, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // TP4
  { PORT0, 18, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // TP5
  { PORT0, 19, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT2
  { PORT0, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT1
  { PORT0, 21, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT1
  { PORT0, 22, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM9, NOT_ON_TIMER},
  { PORT0, 23, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM8, NOT_ON_TIMER},
  { PORT0, 24, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT
  { PORT0, 25, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM11, NOT_ON_TIMER},   //RED_LED
  { PORT0, 26, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM11, NOT_ON_TIMER},  //GREEN_LED
  { PORT0, 27, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM11, NOT_ON_TIMER},  //BLUE_LED
  { PORT0, 28, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A4, PWM3, NOT_ON_TIMER},
  { PORT0, 29, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A5, PWM2, NOT_ON_TIMER},
  { PORT0, 30, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A6, PWM1, NOT_ON_TIMER},
  { PORT0, 31, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A7, PWM0, NOT_ON_TIMER}
};

// Don't remove this line
#include <compat_pin_mapping.h>

#endif
MyBoardNRF5.h

Код: Выделить всё

#ifndef _MYBOARDNRF5_H_
#define _MYBOARDNRF5_H_

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

// Number of pins defined in PinDescription array
#define PINS_COUNT           (32u)
#define NUM_DIGITAL_PINS     (32u)
#define NUM_ANALOG_INPUTS    (8u)
#define NUM_ANALOG_OUTPUTS   (8u)

/* 
 *  LEDs
 *  
 *  This is optional
 *  
 *  With My Sensors, you can use
 *  hwPinMode() instead of pinMode()
 *  hwPinMode() allows to use advanced modes like OUTPUT_H0H1 to drive LEDs.
 *  https://github.com/mysensors/MySensors/blob/development/drivers/NRF5/nrf5_wiring_constants.h
 *
 */
#define PIN_LED1                (16)
#define PIN_LED2                (15)
#define PIN_LED3                (17)
#define RED_LED                 (PIN_LED1)
#define GREEN_LED              (PIN_LED2)
#define BLUE_LED                 (PIN_LED3)
#define INTERRUPT_PIN                 (5)
#define MODE_PIN                 (25)
#define SENS_PIN                 (27)


/* 
 * Analog ports
 *  
 * If you change g_APinDescription, replace PIN_AIN0 with
 * port numbers mapped by the g_APinDescription Array.
 * You can add PIN_AIN0 to the g_APinDescription Array if
 * you want provide analog ports MCU independed, you can add
 * PIN_AIN0..PIN_AIN7 to your custom g_APinDescription Array
 * defined in MyBoardNRF5.cpp
 */
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;

/*
 * Serial interfaces
 * 
 * RX and TX are required.
 * If you have no serial port, use unused pins
 * CTS and RTS are optional.
 */
#define PIN_SERIAL_RX       (11)
#define PIN_SERIAL_TX       (12)


#ifdef __cplusplus
}
#endif

#endif
Berkseo
Сообщения: 56
Зарегистрирован: Вт янв 24, 2017 12:30 am
Благодарил (а): 6 раз
Поблагодарили: 22 раза

Re: Сенсорный выключатель с дополнительной флуоресцентной подсветкой

Сообщение Berkseo » Чт июн 27, 2019 5:56 pm

Настройка в Мажордомо:

Код: Выделить всё

if (getGlobal("MysensorsButton01.status")==1) {
if (getGlobal('MysensorsRelay04.status') == 0) {
setGlobal('MysensorsRelay04.status', '1');
} else if (getGlobal('MysensorsRelay04.status') == 1) {
setGlobal('MysensorsRelay04.status', '0');
} 
}
IMG_20190627_011809.jpg
IMG_20190627_011809.jpg (77.26 КБ) 1914 просмотров
Berkseo
Сообщения: 56
Зарегистрирован: Вт янв 24, 2017 12:30 am
Благодарил (а): 6 раз
Поблагодарили: 22 раза

Re: Сенсорный выключатель с дополнительной флуоресцентной подсветкой

Сообщение Berkseo » Чт июн 27, 2019 5:58 pm

Фотки:
СпойлерПоказать
IMG_20190620_111730.jpg
IMG_20190620_111730.jpg (83 КБ) 1914 просмотров
IMG_20190620_111739.jpg
IMG_20190620_111739.jpg (85.49 КБ) 1914 просмотров
IMG_20190622_140526.jpg
IMG_20190622_140526.jpg (75.6 КБ) 1914 просмотров
IMG_20190622_140641.jpg
IMG_20190622_140641.jpg (79.26 КБ) 1914 просмотров
IMG_20190624_170037_1.jpg
IMG_20190624_170037_1.jpg (118.39 КБ) 1914 просмотров
IMG_20190624_170636.jpg
IMG_20190624_170636.jpg (22.15 КБ) 1914 просмотров
IMG_20190627_012203.jpg
IMG_20190627_012203.jpg (67.83 КБ) 1914 просмотров
11.png
11.png (37.27 КБ) 1914 просмотров
22.png
22.png (62.78 КБ) 1914 просмотров
Ответить