Мульти нода для санузла с датчиками движения температуры и влажности.

Показывайте и делитесь своими замечательными проектами здесь! Мы любим картинки!
Ответить
Sergey2055
Сообщения: 50
Зарегистрирован: 04 июл 2017, 13:43

Мульти нода для санузла с датчиками движения температуры и влажности.

Сообщение Sergey2055 »

Нода работает в паре с исполнительным устройством. Нода отсылает данные в можор что она жива и работоспособна, остаток батареи. а в исполнительный узел данные с датчика движения, датчика температуры и влажности.

Скетч мульти ноды

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

#define MY_RADIO_NRF24
#define MY_NODE_ID 21
#include <MySensors.h>
#include <SPI.h>
#include <Wire.h>
#include <SHT2x.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_IDT 2
#define NODE_IDH 3
#define NODE_IDV 4
#define NODE_Time 5
#define NODE_BattCall 6

#define MaxSmallTry 5 //Количество попыток отправки пакета.

unsigned long SLEEP_TIME = 60000;
unsigned long SEND_FREQUENCY = 60000; //время нормального сна
unsigned long SEND_FREQUENCY_NOTSEND = 3000; //Время сна если пакет не был доставлен
//unsigned long SEND_FREQUENCY_MOTION = 60000;
int ADCin=3, a;
int BatteryPcnt, OldBatteryPcnt, s;
byte value, sendValue;
long sendtry=0;
float Temp, OldTemp, Humidity, OldHumidity;


MyMessage msgSM(NODE_IDSM1, V_ARMED);
MyMessage msgT(NODE_IDT, V_TEMP);
MyMessage msgH(NODE_IDH, V_HUM);
MyMessage msgbatt(NODE_IDV, V_VAR1);
MyMessage msgTime(NODE_Time, V_VAR2);
MyMessage msgCall(NODE_BattCall, V_VAR5);


void presentation()
{
sendSketchInfo("Motion_sensor + Temp_sensor", "V1.0_17082017"); 

present(NODE_IDSM1, S_MOTION, "Motion");
present(NODE_IDT, S_TEMP, "Temp");
present(NODE_IDH, S_HUM, "humidity");
present(NODE_IDV, S_CUSTOM, "Battery");
present(NODE_Time, S_CUSTOM, "Time sleep");
present(NODE_BattCall, S_CUSTOM, "BattCall");


}
void setup(){
  wdt_enable(WDTO_8S);
  Wire.begin();
  analogReference(INTERNAL);
  pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
  digitalWrite(DIGITAL_INPUT_SENSOR, LOW);
  pinMode(ADCin, INPUT);
  int L = loadState(3);
  if((L) > 0 && (L)< 255)
  SEND_FREQUENCY=L*60000;
  a = analogRead(ADCin);
  delay(1000);
  a = analogRead(ADCin);
}

void loop()
{
wdt_reset();
SendDevInfo();

  value = digitalRead(DIGITAL_INPUT_SENSOR);  
  if (value != sendValue) {
     // Value has changed from last transmission, send the updated value
     if (!send(msgSM.set(value == HIGH ? 1 : 0))){
       
       // Not send last state
       if (sendtry < MaxSmallTry){
         sendtry++;
       }
     } else {
       sendValue = value;
       sendtry = 0;
     }
  }

  if (((sendtry >= 1) && (sendtry < MaxSmallTry)))
  {
    SLEEP_TIME = SEND_FREQUENCY_NOTSEND;
  } else {
   // value = digitalRead(DIGITAL_INPUT_SENSOR);
   // if(value == HIGH)
    //{
   // SLEEP_TIME = SEND_FREQUENCY_MOTION; 
    //}
   // else
    SLEEP_TIME = SEND_FREQUENCY;
  }
 
  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());
    SEND_FREQUENCY = (loadState(3)*60000);
    send(msgTime.set((SEND_FREQUENCY)/60000));
      }
   }  
  
    if (message.type==V_VAR5) { 
      if((message.getInt()) == 255){
      send(msgCall.set(255));
      BattCall();
      send(msgCall.set(0));
      }
   } 
}
//000000000000000000000000000000000000000000000000000000

void BattCall()
{
  for(int i=0; i<3; i++)
    {  
      wdt_reset();
      s = analogRead(ADCin);
      send(msgbatt.set(s));  //value переменная 2-указываеьт сколько знаков после запятой выводить.
      delay(5000);
    }
    s = s + 2;
    saveState(1, lowByte(s));
    saveState(2, highByte(s));
}    

void BattInfo()
{
      a = analogRead(ADCin);
  int sl = loadState (1);
  int sh = loadState (2);
  int max_batt = word(sh, sl);
  float con = (4.20/3.00);
  int min_batt = a/con;
  BatteryPcnt = min(map(a, min_batt, max_batt, 0, 100), 100);

}

void SendDevInfo()
{
   Temp = (SHT2x.readT());
   Humidity = (SHT2x.readRH());
  //========= Temp =============
  //send(msgT.setDestination(22).setSensor(2).set(Temp, 1));
  //send(msgT.set(Temp, 1));
  if (OldTemp != Temp){
    
   // //if (!send(msgT.set(Temp, 1)))
    if(!send(msgT.setDestination(22).setSensor(2).set(Temp, 1)))
      { 
        OldTemp = 0;
      } 
      else 
      {
        OldTemp = Temp;
      }
  }
  //========= Humidity =============
  //send(msgH.setDestination(22).setSensor(3).set(Humidity, 0));
  //send(msgH.set(Humidity, 0));
    if (OldHumidity != Humidity){
    
    ////if (!send(msgH.set(Humidity, 0)))
    if(!send(msgH.setDestination(22).setSensor(3).set(Humidity, 0)))
      { 
        OldHumidity = 0;
      } 
      else 
      {
        OldHumidity = Humidity;
      }
  }
  //========= Battery =============
  BattInfo();
//send(msgbatt.set(BatteryPcnt));
  if (OldBatteryPcnt != BatteryPcnt){
    
    if (!send(msgbatt.set(BatteryPcnt)))
      { 
        OldBatteryPcnt = 0;
      } 
      else 
      {
        OldBatteryPcnt = BatteryPcnt;
      }
  }
}


Наброски скетча исполнительного устройства для совместной работы с мульти нодой.

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

#define MY_DEBUG 
#define MY_RADIO_NRF24
#define MY_NODE_ID 22
#include <SPI.h>
#include <MySensors.h>
#include <avr/wdt.h>

#define IDLight1 1
#define IDLight2 2
#define IDMotion 3
#define IDTemp 4 //приточка воздуха 13
#define IDHum 5 //вытяжка 14
#define IDTime 6
#define IDHumTrig 7
#define IDHeartBeat 8


#define LED1 14 
#define LED2 15
#define LED3 16 
#define LED4 17 
#define BUTTON1 7
#define BUTTON2 8
#define OUT1 5
#define OUT2 6

#define ON 1  // GPIO value to write to turn on attached relay
#define OFF 0 // GPIO value to write to turn off attached relay

#define MaxSmallTry 5 //Количество попыток отправки пакета.


MyMessage msgTemp(IDTemp, V_TEMP);
MyMessage msgHum(IDHum, V_HUM);
MyMessage msgMot(IDMotion, V_ARMED);
MyMessage msgLight1(IDLight1, V_STATUS);
MyMessage msgLight2(IDLight2, V_STATUS);
MyMessage msgTime(IDTime, V_VAR1);
MyMessage msgHumTrig(IDHumTrig, V_VAR2);
MyMessage msgHeartBeat(IDHeartBeat, V_VAR3);

void presentation()
{
sendSketchInfo("Light_sensor", "V1.0_18082017"); 

present(IDMotion, S_MOTION, "Motion");
present(IDTemp, S_TEMP, "Temp");
present(IDHum, S_HUM, "humidity");
present(IDLight1, S_LIGHT, "Light1");
present(IDLight2, S_LIGHT, "Light2");
present(IDTime, S_CUSTOM, "Time sleep prog");
present(IDHumTrig, S_CUSTOM, "Hum Trigger");
present(IDHeartBeat, S_CUSTOM, "HeartBeat");

}

unsigned long SEND_FREQUENCY = 60000; //время нормального сна
unsigned long SEND_FREQUENCY_NOTSEND = 30000; //Время сна если пакет не был доставлен
unsigned long previousMillis = 0; // время, когда состояние обновлялось
unsigned long previousMillis1 = 0; // время, когда состояние обновлялось

float Temp, OldTemp, Humidity, OldHumidity; 
byte Relay[2], sendMotion, oldButton1, oldButton2;
byte sendRelay0, sendRelay1, Flag = 1, Flag2, Flag3;
long sendtry=0, sendtry2=0, sendtryM=0;
int HumidityTrig = 70, a, Motion;

void setup() {
 wdt_enable(WDTO_8S);
 pinMode(BUTTON1, INPUT);
 digitalWrite(BUTTON1, HIGH);
 pinMode(BUTTON2, INPUT);
 digitalWrite(BUTTON2, HIGH);
 pinMode(OUT1, OUTPUT);
 pinMode(OUT2, OUTPUT); 
 pinMode(LED1, OUTPUT);
 pinMode(LED2, OUTPUT); 
 pinMode(LED3, OUTPUT);
 pinMode(LED4, OUTPUT); 
 
 int L = loadState(3);
  if((L) > 0 && (L)< 255)
  SEND_FREQUENCY=L*60000;
  
  L = loadState(4);
  if((L) > 0 && (L)< 255)
  HumidityTrig=L;
  
}

void loop() 
{
 wdt_reset();
 if(Flag)
 start();
 
 info();

// ОБРАБОТКА КНОПОК

 if (digitalRead(BUTTON1) != oldButton1){
  oldButton1 = digitalRead(BUTTON1);
  Relay[0] = !oldButton1;
}

 if (digitalRead(OUT1) != Relay[0])
 { 
  digitalWrite(OUT1,  Relay[0]);
  digitalWrite(LED3, Relay[0]);
  }
 
  if (digitalRead(BUTTON2) != oldButton2){
  oldButton2 = digitalRead(BUTTON2);
  Relay[1] = !oldButton2;
}

 if (digitalRead(OUT2) != Relay[1])
 {
  digitalWrite(OUT2,  Relay[1]);
  digitalWrite(LED4, Relay[1]);
  }
  
// Обработка датчика движения 
 
 if(Motion == 1)
 digitalWrite(LED2, HIGH);
 else
 digitalWrite(LED2, LOW);

 
 if((HumidityTrig + 3) < Humidity && Flag3 == 0)
 { 
  Relay[1] = 1;
  Flag3 = 1;
 }

 if((HumidityTrig - 3) > Humidity && Flag3 == 1)
 { 
  Relay[1] = 0;
  Flag3 = 0;
 }

// ОТПРАВКА ДАННЫХ.
  if (Motion != sendMotion) {
     // Value has changed from last transmission, send the updated value
    if (sendtryM < MaxSmallTry){
      if (!send(msgMot.set(Motion))){
       // Not send last state
         sendtryM++;
       }
      else {
       sendMotion = Motion;
       sendtryM = 0;
     }
    }
  }

  if (Relay[0] != sendRelay0) {
     // Value has changed from last transmission, send the updated value
    if (sendtry < MaxSmallTry){
      if (!send(msgLight1.set(Relay[0]))){
       // Not send last state
         sendtry++;
       }
      else {
       sendRelay0 = Relay[0];
       sendtry = 0;
     }
    }
  }
  
  if (Relay[1] != sendRelay1) {
     // Value has changed from last transmission, send the updated value
    if (sendtry2 < MaxSmallTry){
      if (!send(msgLight2.set(Relay[1]))){
       // Not send last state
         sendtry2++;
       }
      else {
       sendRelay1 = Relay[1];
       sendtry2 = 0;
     }
    }
   }

  
// ТАЙМЕРЫ  

 if(millis() - previousMillis > SEND_FREQUENCY)
{
  previousMillis = millis();
  send(msgHeartBeat.set(previousMillis));
}

 if(millis() - previousMillis1 > SEND_FREQUENCY_NOTSEND)
{
  previousMillis1 = millis();
  sendtry = 0;
  sendtry2 = 0;
  sendtryM = 0;
}
 
}  //END

void receive(const MyMessage &message) {
  // We only expect one type of message from controller. But we better check anyway.
  
        if (message.type==V_LIGHT) {
      Relay[message.sensor-1] = (message.getBool()?ON:OFF);
      Serial.print("Relay - ");
      Serial.print(Relay[0]);
      Serial.println(Relay[1]);
      } 
   
        if (message.type==V_ARMED) { 
      Motion = (message.getInt());
      Relay[0] = Motion;
      Serial.print("Motion - rx:");
      Serial.println(Motion);
      Serial.println(Relay[0]);
      }
        if (message.type==V_TEMP) { 
     Temp = (message.getFloat());
     Serial.print("Temp - rx");
     Serial.println(Temp);
      }
        if (message.type==V_HUM) { 
     Humidity = (message.getFloat());
     Serial.print("Hum - rx");
     Serial.println(Humidity);
      }
        if (message.type==V_VAR2) { 
        if((message.getInt())<255){
    saveState(4, message.getInt());
    HumidityTrig = (loadState(4));
    send(msgHumTrig.set(HumidityTrig));
     Serial.println("HumProg - rx");
      }
    }  
   
     if (message.type==V_VAR1) { 
     if((message.getInt())<255){
    saveState(3, message.getInt());
    SEND_FREQUENCY = (loadState(3)*60000);
    send(msgTime.set((SEND_FREQUENCY)/60000));
      }
   }
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void info()
{
   if(Temp != OldTemp)
 {
  OldTemp = Temp; 
  send(msgTemp.set(Temp,1));
  Serial.print("T: ");
  Serial.println(Temp);
  digitalWrite(LED1, !digitalRead(LED1));
 }
 delay(100);
 if(Humidity != OldHumidity)
 {
  OldHumidity = Humidity;
  send(msgHum.set(Humidity,0));
  Flag2 = 1;
  Serial.print("H: ");
  Serial.println(Humidity);
  digitalWrite(LED1, !digitalRead(LED1));
 }
}
void start()
{
  send(msgTime.set((SEND_FREQUENCY)/60000));
  delay(100);
  send(msgHumTrig.set(HumidityTrig));
  delay(100);
  send(msgMot.set(Motion));
  delay(100);
  send(msgLight1.set(Relay[0]));
  delay(100);
  send(msgLight2.set(Relay[1])); 
  Flag = 0;
}
Вложения
IMG_20170828_194205.jpg
IMG_20170828_194205.jpg (126.02 КБ) 18108 просмотров
IMG_20170828_194148.jpg
IMG_20170828_194148.jpg (153.71 КБ) 18108 просмотров
IMG_20170828_194037.jpg
IMG_20170828_194037.jpg (124.19 КБ) 18108 просмотров
Аватара пользователя
Ivan
Администратор
Сообщения: 21
Зарегистрирован: 07 июн 2017, 08:03
Откуда: Taganrog
Контактная информация:

Re: Мульти нода для санузла с датчиками движения температуры и влажности.

Сообщение Ivan »

Какой элемент питания вы используете?

Конденсатор лучше ставить прямо на NRF


Sergey2055
Сообщения: 50
Зарегистрирован: 04 июл 2017, 13:43

Re: Мульти нода для санузла с датчиками движения температуры и влажности.

Сообщение Sergey2055 »

Конденсатор в принципе на радио не нужен там свои блокировочные стоят. Если только при питании от сети от помех но тогда лучше применить фильтр по питанию. Элемент питания вот такой, просто замотал изолентой для удобства термоусадки не было под рукой. Тесты показали реальную емкость что на нем заявлено плюс минус немного, хз удача это или правда.
Вложения
2017-08-29_08-23-17.png
2017-08-29_08-23-17.png (152.04 КБ) 18095 просмотров
Аватара пользователя
Ivan
Администратор
Сообщения: 21
Зарегистрирован: 07 июн 2017, 08:03
Откуда: Taganrog
Контактная информация:

Re: Мульти нода для санузла с датчиками движения температуры и влажности.

Сообщение Ivan »

Явно удача. У меня такие - дели на 10

Отправлено с моего SM-G7102 через Tapatalk

Ответить