Navigation

    • Register
    • Login
    • OpenHardware.io
    • Categories
    • Recent
    • Tags
    • Popular
    1. Home
    2. marekd
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    marekd

    @marekd

    25
    Reputation
    29
    Posts
    930
    Profile views
    1
    Followers
    0
    Following
    Joined Last Online
    Location Poland

    marekd Follow

    Best posts made by marekd

    • My New IrrigationController

      Last summer during vacation, was quite hot at my place. My green grass in the garden became ... brown and yellow - there was nobody to irrigate and was no rain, of course!
      So I made a decision to buy irrigation controller and all that stuff. I wanted to have 7-8 zones, BT or wireless control, temperature and rain based control, RTC, Keypad, etc. The problem was that nobody had it or was to expencive.
      So long story short I came up with idea to build one with all those features i need. Without having experience with uC I start to learn (google and youtube) a bit and build some "prototypes". Than IrrigatonController ver 1.0 was ready (December 2015):0_1462825721811_1.jpg
      0_1462825767664_2.jpg
      Than I found @petewill IrrigationControler at youtube - but it was to hard for me from software (all this MySensors) and hardware side - I thought!
      So I built new one - well it is almost done.
      It is tested and working, few things are still missing like running without HA controller and rain sensor. Anyway I post some pictures and script what I've done. At my place it is working under Domoticz and manual (keypad). Tomorrow final wiring!
      0_1462826910120_4.jpg
      0_1462826941290_IMG_20160509_203348.jpg .

      Any comments are more than welcome, know that script need some more work - but it is just a beginning.

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * based on Version 1.0 - Henrik Ekblad
       * Version 2.0 - Marek Dajnowicz
       *
       * DESCRIPTION
       * Example sketch showing how to control physical relays.
       * 
       * http://www.mysensors.org/build/relay
       */
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      #define MY_RF24_CE_PIN A8 // żółty 51
      #define MY_RF24_CS_PIN A9 // pomarańczowy 53
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      #define MY_NODE_ID 66
      // Enable repeater functionality for this node
      #define MY_REPEATER_FEATURE
      
      #include <Wire.h>
      #include <Time.h>
      #include <SPI.h>
      #include <MySensor.h>
      #include <LiquidCrystal.h>
      #include <LiquidCrystal_I2C.h>
      #include <DallasTemperature.h>
      #include <OneWire.h>
      #include <DS3232RTC.h>  // A  DS3231/DS3232 library
      #include <Keypad_I2C.h> // Klawiatura na I2c
      #include <Keypad.h> // klawiatura
      
      #define RELAY_1  2  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
      #define NUMBER_OF_RELAYS 8 // Total number of attached relays
      #define RELAY_ON 1  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
      
      #define ONE_WIRE_BUS 22 // Pin where dallase sensor is connected MEGA256
      #define MAX_ATTACHED_DS18B20 16
      #define TEMPERATURE_PRECISION 12
      
      #define CHILD_ID_SPRINKLER1 1
      #define CHILD_ID_SPRINKLER2 2
      #define CHILD_ID_SPRINKLER3 3
      #define CHILD_ID_SPRINKLER4 4
      #define CHILD_ID_SPRINKLER5 5
      #define CHILD_ID_SPRINKLER6 6
      #define CHILD_ID_SPRINKLER7 7
      #define CHILD_ID_PUMP 10
      #define CHILD_ID_TEMP 11
      #define CHILD_ID_TEMP2 12
      
      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
      
      boolean timeReceived = false;
      
      byte clock[8] = {0x0, 0xe, 0x15, 0x17, 0x11, 0xe, 0x0}; // fetching time indicator
      byte raindrop[8] = {0x4, 0x4, 0xA, 0xA, 0x11, 0xE, 0x0,}; // fetching Valve Data indicator
      
      LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address to 0x27
      DeviceAddress addrT1 = { 0x28, 0xFF, 0x9F, 0x80, 0x93, 0x15, 0x04, 0xF7 }; //DS18 Dallas temp.
      float T1;
      float lastTemperature[MAX_ATTACHED_DS18B20];
      int numSensors = 0;
      
      
      MyMessage msgValve1(CHILD_ID_SPRINKLER1, V_LIGHT);
      MyMessage msgValve2(CHILD_ID_SPRINKLER2, V_LIGHT);
      MyMessage msgValve3(CHILD_ID_SPRINKLER3, V_LIGHT);
      MyMessage msgValve4(CHILD_ID_SPRINKLER4, V_LIGHT);
      MyMessage msgValve5(CHILD_ID_SPRINKLER5, V_LIGHT);
      MyMessage msgValve6(CHILD_ID_SPRINKLER6, V_LIGHT);
      MyMessage msgValve7(CHILD_ID_SPRINKLER7, V_LIGHT);
      MyMessage msgPump(CHILD_ID_PUMP, V_LIGHT);
      MyMessage msgT1(CHILD_ID_TEMP, V_TEMP);
      MyMessage msgT2(CHILD_ID_TEMP2, V_TEMP);
      
      
      /**** Kepad settings */
      const byte ROWS = 4;
      const byte COLS = 4;
      char keys[ROWS][COLS] = {
        {'1', '2', '3', 'A'},
        {'4', '5', '6', 'B'},
        {'7', '8', '9', 'C'},
        {'*', '0', '#', 'D'}
      };
      
      byte rowPins[ROWS] = {47, 45, 43, 41};
      byte colPins[COLS] = {39, 37, 35, 33};
      int i2caddress = 0x20;
      Keypad_I2C kpd = Keypad_I2C( makeKeymap(keys), rowPins, colPins, ROWS, COLS, i2caddress );
      bool state;
      
      // system messages
      const char *string_table[] =
      {
        "     WELCOME! =)", 			// 0
        "DOMOTICZ TIME", 				// 1
        "WATERING",  					// 2
        "    SYSTEM CHECK  ",			// 3
        "  STARTING UP THE",			// 4
        "  WATERING SYSTEM", 			// 5
        "    Popmp is ON ", 		    // 6
        "      MySensors",		   	// 7
        "   Watering System",	      	// 8
        "   Please wait !!"	        // 9
      };
      
      const char *string_table2[] = {
        "Strefa 1", "Strefa 2", "Strefa 3", "Strefa 4", "Strefa 5", "Strefa 6", "Strefa 7", "Pompa zasilająca" // ZONE 1...2...
      };
      
      
      const unsigned long tUpdate = 60000; // update interval for temp sensors
      unsigned long t0;
      
      void setup()
      {
        for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++)
        {
          pinMode(pin, OUTPUT); // Then set relay pins in output mode
          digitalWrite(pin, RELAY_OFF); // set all relays OFF
          saveState(sensor, state); // save data at startup.
        }
        requestTime();
        kpd.begin();  //keypad
        sensors.begin(); //dallas temp
        sensors.setResolution(addrT1, TEMPERATURE_PRECISION);
        lcd.begin(20, 4); //(20 characters and 4 line display)
        lcd.clear();
        lcd.backlight();
        lcd.createChar(0, clock);
        lcd.createChar(1, raindrop);
        lcd.home();
        lcd.print(string_table[4]);
        lcd.setCursor(0, 1);
        lcd.print(string_table[5]);
        lcd.setCursor(0, 3);
        lcd.print(string_table[7]);
        delay(3000);
        for (int i = 0; i < 20; i++) {
          delay(100);
          lcd.scrollDisplayLeft();
        }
        lcd.clear();
        lcd.home();
        lcd.print(string_table[0]);
        lcd.setCursor(0, 1);
        lcd.print(string_table[3]);
        (lcd.setCursor(0, 3));
        for (int M = 1; M >= 0; M--) // countdown
        {
          lcd.setCursor(10, 3);
          lcd.print(M);
          delay(1000);
        }
        lcd.clear();
        lcd.home ();
        requestTime();
        ServerUpdate();
      }
      
      void presentation()
      {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Watering", "2.0");
        for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
          // Register all sensors to gw (they will be created as child devices)
          present(sensor, S_LIGHT, string_table2[sensor - 1]); // use CHILD ID names from table
        }
        present(CHILD_ID_TEMP, S_TEMP,"Dallas");
        present(CHILD_ID_TEMP2, S_TEMP,"RTC Temp");
      }
      
      
      void loop()
      {
        domoticztime(); // to PRINT the time from conroller
        keypad(); // READING KEYPAD
        if ((millis() - t0) > tUpdate) ServerUpdate();
      }
      
      void ServerUpdate() 
      {
        sensors.requestTemperatures();	
        T1 = sensors.getTempC(addrT1);
        send(msgT1.set(T1 , 1));
        int t= RTC.temperature()/4;
        send(msgT2.set(t,2));
        lcd.setCursor(11, 2);
        lcd.print("T:");
        lcd.print(T1);
        lcd.print(char(223));
        lcd.print("C");
        lcd.setCursor(11, 3);
        lcd.print("T:");
        lcd.print(t);
        lcd.print(char(223));
        lcd.print("C");
        t0 = millis();
      }
      void domoticztime()
      { 
        lcd.home();
        lcd.setCursor(0, 2);
       // lcd.print(string_table[1]);
        //lcd.setCursor(2, 2);
        lcd.write(byte(0));
        lcd.setCursor(1, 2);
        lcd.print(hour());
        lcd.print(":");
        int min = minute();
        if (min < 10) lcd.print("0");
        lcd.print(minute());
        lcd.print(":");
        lcd.print(second());
        lcd.setCursor(0, 3);
        lcd.print(day());
        lcd.print("/");
        lcd.print(month());
        lcd.print("/");
        lcd.print(year());
        
        
        }
      
      
      void keypad()
      {
        char key = kpd.getKey(); delay(50);
        if (key == '*') ALL_OFF();
        if (key == '#') WRONG();
        if (key == '1') ZONE_1();
        if (key == '2') ZONE_2();
        if (key == '3') ZONE_3();
        if (key == '4') ZONE_4();
        if (key == '5') ZONE_5();
        if (key == '6') ZONE_6();
        if (key == '7') ZONE_7();
        if (key == '8') WRONG();
        if (key == '9') WRONG();
        if (key == '0') WRONG();
        if (key == 'D') DEBUG();
      }
      void DEBUG()
      {for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++)
        {
          state = loadState(sensor);
          Serial.print("sensor: ");
          Serial.print(sensor);
          Serial.print("  /  stan:  ");
          Serial.println(state);
        }}
      
      void ALL_OFF()// TURNING ALL ZONES OFF @ ONE KEY PRESSED
      {
        for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++)
        {
          digitalWrite(pin, RELAY_OFF);
          saveState(sensor, state);
        }
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print(" TURN ALL ZONES OFF");
        Serial.println(" turn ALL OFF");
       /* 
        send(msgValve1.set(0) );delay(100);
        send(msgValve2.set(0) );delay(100);
        send(msgValve3.set(0) );delay(100);
        send(msgValve4.set(0) );delay(100);
        send(msgValve5.set(0) );delay(100);
        send(msgValve6.set(0) );delay(100);
        send(msgValve7.set(0) ); 
        */
        send(msgValve1.set(0), true); delay(100);
        send(msgValve2.set(0), true);delay(100);
        send(msgValve3.set(0), true);delay(100);
        send(msgValve4.set(0), true);delay(100);
        send(msgValve5.set(0), true);delay(100);
        send(msgValve6.set(0), true);delay(100);
        send(msgValve7.set(0), true); 
        DEBUG();
        delay(1500);
        lcd.clear();
      }
      
      void ZONE_1()
      { // zone 1, pin 2
        byte pin=RELAY_1;
        state = loadState(CHILD_ID_SPRINKLER1);
        digitalWrite(pin, state ? RELAY_ON : RELAY_OFF);
        saveState(CHILD_ID_SPRINKLER1, state);
        lcd.setCursor(0, 1);
        if (state == 1)
        {
          lcd.setCursor(0, 1);
          lcd.print(" ");
        }
        send(msgValve1.set(state ? false : true), true);
      
      }
      void ZONE_2()
      {
        byte pin=RELAY_1+1;
        state = loadState(CHILD_ID_SPRINKLER2);
        digitalWrite(pin, state ? RELAY_ON : RELAY_OFF);
        saveState(CHILD_ID_SPRINKLER2, state);
       if (state == 1)
        {
          lcd.setCursor(1, 1);
          lcd.print(" ");
        }
        send(msgValve2.set(state ? false : true), true);
      }
      void ZONE_3()
      {
      byte pin=RELAY_1+2;
        state = loadState(CHILD_ID_SPRINKLER3);
        digitalWrite(pin, state ? RELAY_ON : RELAY_OFF);
        saveState(CHILD_ID_SPRINKLER3, state);
        if (state == 1)
        {
          lcd.setCursor(2, 1);
          lcd.print(" ");
        }
        send(msgValve3.set(state ? false : true), true);
      }
      void ZONE_4() 
      {
      
      byte pin=RELAY_1+3;
        state = loadState(CHILD_ID_SPRINKLER4);
        digitalWrite(pin, state ? RELAY_ON : RELAY_OFF);
        saveState(CHILD_ID_SPRINKLER4, state);
        if (state == 1)
        {
          lcd.setCursor(3, 1);
          lcd.print(" ");
        }
        send(msgValve4.set(state ? false : true), true);
      
      }
      void ZONE_5()
      {
      byte pin=RELAY_1+4;
        state = loadState(CHILD_ID_SPRINKLER5);
        digitalWrite(pin, state ? RELAY_ON : RELAY_OFF);
        saveState(CHILD_ID_SPRINKLER5, state);
        if (state == 1)
        {
          lcd.setCursor(4, 1);
          lcd.print(" ");
        }
        send(msgValve5.set(state ? false : true), true);
      }
      void ZONE_6()
      {
      
      byte pin=RELAY_1+5;
        state = loadState(CHILD_ID_SPRINKLER6);
        digitalWrite(pin, state ? RELAY_ON : RELAY_OFF);
        saveState(CHILD_ID_SPRINKLER6, state);
        if (state == 1)
        {
          lcd.setCursor(5, 1);
          lcd.print(" ");
        }
        send(msgValve6.set(state ? false : true), true);
      }
      void ZONE_7()
      {
      
      byte pin=RELAY_1+6;
        state = loadState(CHILD_ID_SPRINKLER7);
        digitalWrite(pin, state ? RELAY_ON : RELAY_OFF);
        saveState(CHILD_ID_SPRINKLER7, state);
        if (state == 1)
        {
          lcd.setCursor(6, 1);
          lcd.print(" ");
        }
        send(msgValve7.set(state ? false : true), true);
      }
      
      void WRONG() {}
      
      
      void receive(const MyMessage &message) {
        byte zone;
        if (message.isAck()) {
          Serial.println("This is an ack from gateway");
        }
      
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type == V_LIGHT) {
          // Change relay state
          digitalWrite(message.sensor - 1 + RELAY_1, message.getBool() ? RELAY_ON : RELAY_OFF);
          zone = message.sensor; // less typing :)
          // Store state in eeprom
          saveState(message.sensor, message.getBool());
          
          // representing active zones at LCD
          if (message.getBool() == RELAY_ON) // checking new state of relay
          {
            Serial.print("Watering ZONE: "); Serial.println(zone);
            lcd.setCursor(0, 0);
            lcd.print("Watering ZONE: ");
            lcd.setCursor(zone - 1, 1);
            lcd.print(zone);
          }
          if (message.getBool() == RELAY_OFF) // checking new state of relay
          { 
            lcd.setCursor(zone - 1, 1);
            lcd.print(" ");
          }
             // Write some debug info
          Serial.print("Incoming change for ZONE:");
          Serial.print(message.sensor);
          Serial.print(", New status: ");
          Serial.println(message.getBool());
        }
      }
      
      

      Regards

      posted in My Project
      marekd
      marekd
    • BMP280 + I2C

      Hello,
      This is my first post here, so please "be nice" to me.
      So far I built several nodes for temperature measurement, LED control, RF433 to control my outside sockets, in future my heating system will be based on reading from temperature nodes. Finishing at the moment irrigation controller for 8 zones ( think to post it when finish).

      Few days ago I received my BMP280 sensor
      for my outdoor weather station but couldn't find any projects here so I made it by myself (partly).
      So if anyone of you is going to use this sensor you may use this.
      Tested on Uno and works. I use Domoticz and it works just fine.

      //                  BMP280 I2C
      // this program is for BMP280 library :
      
       /*       
      	Bosch BMP280 pressure sensor library for the Arduino microcontroller.
      	This library uses I2C connection.
      
      	Uses floating-point equations from BMP280 datasheet.
      
      	modified by mhafuzul islam
      
      	version 1.01		 16/9/2014 initial version
      	https://github.com/mahfuz195/BMP280-Arduino-Library/tree/master/BMP280
      
      	Our example code uses the "pizza-eating" license. You can do anything
      	you like with this code. No really, anything. If you find it useful,
      	buy me italian pizza someday.
      
      I also used some parts from oryginal MySensors PressureSensor for BMP085 module  
      
      To use with MySensors 2.0.0 dev.branch
      
      * REVISION HISTORY
       * Version 1.0 - Henrik Ekblad
       * Version 1.1 - Marek Dajnowicz
      
      
      */
      
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      //#define MY_REPEATER_FEATURE
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      //#define MY_NODE_ID 33 
      
      //#define MY_PARENT_NODE_ID
      
      #include <SPI.h>
      #include <MySensor.h>
      #include "BMP280.h"
      #include "Wire.h"
      
      #define P0 1010.6 // sea level pressure for my place
      #define CHILD_ID_TEMP 1
      #define CHILD_ID_PRESS 2
      
      const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
      enum FORECAST
      {
        STABLE = 0,			// "Stable Weather Pattern"
        SUNNY = 1,			// "Slowly rising Good Weather", "Clear/Sunny "
        CLOUDY = 2,			// "Slowly falling L-Pressure ", "Cloudy/Rain "
        UNSTABLE = 3,		// "Quickly rising H-Press",     "Not Stable"
        THUNDERSTORM = 4,	// "Quickly falling L-Press",    "Thunderstorm"
        UNKNOWN = 5			// "Unknown (More Time needed)
      };
      
      BMP280 bmp; // call for sensor
      // for forecast
        float lastPressure = -1;
        float lastTemp = -1;
        int lastForecast = -1;
        const int LAST_SAMPLES_COUNT = 5;
        float lastPressureSamples[LAST_SAMPLES_COUNT];
        // this CONVERSION_FACTOR is used to convert from Pa to kPa in forecast algorithm
        // get kPa/h be dividing hPa by 10
        #define CONVERSION_FACTOR (1.0/10.0)
        int minuteCount = 0;
        bool firstRound = true;
        // average value is used in forecast algorithm.
        float pressureAvg;
        // average after 2 hours is used as reference value for the next iteration.
        float pressureAvg2;
        float dP_dt;
      
      // MyMessage to controler
      MyMessage msgT1(CHILD_ID_TEMP, V_TEMP);
      MyMessage msgP1(CHILD_ID_PRESS, V_PRESSURE);
      MyMessage msgF1(CHILD_ID_PRESS, V_FORECAST);
      
      // values for ServerUpdate, unmark when not using smartSleep
      //const unsigned long tUpdate = 60000; // update interval
      //unsigned long t0;
      
      void presentation()
      {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("OUTSIDE P&T", "1.1");
        present(CHILD_ID_TEMP, S_TEMP);
        present(CHILD_ID_PRESS, S_BARO);
      }
      
      void setup()
      {
        delay(500);// just in case
        if (!bmp.begin())
        {
          Serial.println("BMP init failed!");
          while (1);
        }
        else Serial.println("BMP init success!");
        bmp.setOversampling(4);
        ServerUpdate(); // for first data reading and sending to controler
      }
      
      void loop()
      { smartSleep(60000); // adjust sleeping time here 1 minute in this case 
        ServerUpdate();
        //  if ((millis() - t0) > tUpdate) ServerUpdate();
      }
      
      void ServerUpdate() // used to read sensor data and send it to controler
      {
        double T, P;
        char result = bmp.startMeasurment();
      
        if (result != 0) {
          delay(result);
          result = bmp.getTemperatureAndPressure(T, P);
      
          int forecast = sample(P);
          if (result != 0)
          {
            // double A = bmp.altitude(P, P0); // this is to get barometric Altitude, not used in this program 
            send(msgT1.set(T, 1));
            send(msgP1.set(P, 1));
            send(msgF1.set(weather[forecast]));
            
         // unmark for debuging
         //   Serial.print("T = \t"); Serial.print(T, 1); Serial.print(" degC\t");
         //   Serial.print("P = \t"); Serial.print(P, 1); Serial.print(" mBar\t");
         //   Serial.print("A = \t"); Serial.print(A, 1); Serial.println(" m");
         //   Serial.print("F = \t"); Serial.print(weather[forecast]); Serial.println(" ?");
          }
          else {
            Serial.println("Error.");
          }
        }
        else {
          Serial.println("Error.");
        }
      
       // t0 = millis(); used without smartSleep
      }
      
      float getLastPressureSamplesAverage()
      {
        float lastPressureSamplesAverage = 0;
        for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
        {
          lastPressureSamplesAverage += lastPressureSamples[i];
        }
        lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
      
        return lastPressureSamplesAverage;
      }
      
      // Algorithm found here
      // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
      // Pressure in hPa -->  forecast done by calculating kPa/h
      int sample(float pressure)
      {
        // Calculate the average of the last n minutes.
        int index = minuteCount % LAST_SAMPLES_COUNT;
        lastPressureSamples[index] = pressure;
      
        minuteCount++;
        if (minuteCount > 185)
        {
          minuteCount = 6;
        }
      
        if (minuteCount == 5)
        {
          pressureAvg = getLastPressureSamplesAverage();
        }
        else if (minuteCount == 35)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change * 2; // note this is for t = 0.5hour
          }
          else
          {
            dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
          }
        }
        else if (minuteCount == 65)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) //first time initial 3 hour
          {
            dP_dt = change; //note this is for t = 1 hour
          }
          else
          {
            dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 95)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 1.5; // note this is for t = 1.5 hour
          }
          else
          {
            dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 125)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          pressureAvg2 = lastPressureAvg; // store for later use.
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 2; // note this is for t = 2 hour
          }
          else
          {
            dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 155)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 2.5; // note this is for t = 2.5 hour
          }
          else
          {
            dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 185)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 3; // note this is for t = 3 hour
          }
          else
          {
            dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
          }
          pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
          firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
        }
      
        int forecast = UNKNOWN;
        if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
        {
          forecast = UNKNOWN;
        }
        else if (dP_dt < (-0.25))
        {
          forecast = THUNDERSTORM;
        }
        else if (dP_dt > 0.25)
        {
          forecast = UNSTABLE;
        }
        else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
        {
          forecast = CLOUDY;
        }
        else if ((dP_dt > 0.05) && (dP_dt < 0.25))
        {
          forecast = SUNNY;
        }
        else if ((dP_dt > (-0.05)) && (dP_dt < 0.05))
        {
          forecast = STABLE;
        }
        else
        {
          forecast = UNKNOWN;
        }
      
        // uncomment when debugging
        //Serial.print(F("Forecast at minute "));
        //Serial.print(minuteCount);
        //Serial.print(F(" dP/dt = "));
        //Serial.print(dP_dt);
        //Serial.print(F("kPa/h --> "));
        //Serial.println(weather[forecast]);
      
        return forecast;
      }
      
      posted in My Project
      marekd
      marekd
    • RE: BMP280 + I2C

      @TheoL, I have some pictures of my Ver 1.0 (before I found MySensors), but anyway it was based on standard Promini + RTC, Bluetooth, LCD 16x2, Keyboard and some other sensors.
      And it was a bit messy with all the wires.

      Now is going to be based on Mega256, NRF24 ... still under development.
      0_1461441907000_IMG_20151229_193719.jpg 0_1461442038865_IMG_20160106_1828271.jpg 0_1461442190195_IMG_20151230_231357.jpg 0_1461442213334_IMG_20151230_231426.jpg

      posted in My Project
      marekd
      marekd
    • Multi sensor node - Rc433MHz, 2xRelay, DHT11

      Hi!

      This is my last fast project.
      With this I can control 3x Rc433 MHz wall plugs, 2 relays and to measure room temperature and humidity with a single node.
      This is very simple to make for almost everyone, with some small, like me, soldering skills!
      This is how it looks like:
      0_1489863953729_2017-03-18 11.52.33.bmp
      0_1489864033560_22.bmp
      The box was drilled to use motion sensor as well - but i change my mind 😉
      0_1489864142333_33.bmp

      Below you can find sketch:

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0 - Henrik Ekblad
       * Version 2.0 - Marek Dajnowicz (Rc433, DHT11 upgrade)
       *
       * DESCRIPTION
       * Example sketch showing how to control physical relays.
       * How to control Rc433 MHz wall plugs and usage of DHT11
       
       */
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      //#define MY_NODE_ID 16
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      
      #define CHILD_ID_HUM 1 // DHT11
      #define CHILD_ID_TEMP 2 // DHT11
      #define HUMIDITY_SENSOR_DIGITAL_PIN 3 // where DHT is coneccted
      #define RELAY_1 4
      #define RELAY_2 5
      #define CHILD_ID_L1 6 // for Rc433 PLUG 1
      #define CHILD_ID_L2 7 // for Rc433 PLUG 2
      #define CHILD_ID_L3 8 // for Rc433 PLUG 3
      
      #define RELAY_ON 0  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 1 // GPIO value to write to turn off attached relay
      #define NUMBER_OF_RELAYS 2 // Total number of attached relays
      
      
      #include <SPI.h>
      #include <MySensors.h>
      #include <DHT.h>
      #include <NewRemoteTransmitter.h>
      
      DHT dht;
      float Temp;
      float Hum;
      boolean metric = true;
      
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      MyMessage msgL1(CHILD_ID_L1, V_STATUS);
      MyMessage msgL2(CHILD_ID_L2, V_STATUS);
      MyMessage msgL3(CHILD_ID_L3, V_STATUS);
      MyMessage msgR1(RELAY_1, V_STATUS);
      MyMessage msgR2(RELAY_2, V_STATUS);
      
      // Create a transmitter on address xxxxxxxx, using digital pin 6 to transmit, 
      // with a period duration of 260ms (default), repeating the transmitted
      // code 2^3=8 times.
      NewRemoteTransmitter transmitter(60548078, 6, 260, 3); // address got by ShowReceivedCode.ino from Arduino IDE  
      
      boolean receivedConfig = false;
      const unsigned long tUpdate = 60000; // update interval 60sec
      unsigned long t0;
      
      void setup() {
      
        dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
        t0 = millis();
        ServerUpdate();
      }
      
      void ServerUpdate() {
        dht.readSensor(true);
        Hum = dht.getHumidity(); 
        delay(20);
        Temp = dht.getTemperature(); 
        delay(20);
        send(msgTemp.set(Temp, 1));
        delay(20);
        send(msgHum.set(Hum, 1)); 
        delay(20);
        t0 = millis();
      }
      
      void presentation() {
        // Present locally attached sensors
        sendSketchInfo("Multi Node", "2.0.0");
        present(CHILD_ID_HUM, S_HUM, "HUM");
        present(CHILD_ID_TEMP, S_TEMP, "TEMP");
        present(CHILD_ID_L1, S_LIGHT, "PLUG_1");
        present(CHILD_ID_L2, S_LIGHT, "PLUG_2");
        present(CHILD_ID_L3, S_LIGHT, "PLUG_3");
        present(RELAY_1, S_BINARY, "Relay 1");
        present(RELAY_2, S_BINARY, "Relay 2");
      
      }
      
      void before()
      {
        for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
          // Then set relay pins in output mode
          pinMode(pin, OUTPUT);
          digitalWrite(pin, RELAY_OFF);
        }
      
      }
      
      void loop()
        {
        if ((millis() - t0) > tUpdate) ServerUpdate();
        }
      
      
      void receive(const MyMessage &message) {
      
        if (message.type == V_STATUS) {
          int incomingLightState =  message.getBool();
          int incomingOutlet = message.sensor;
      
          Serial.print("Outlet #: ");
          Serial.println(message.sensor);
          Serial.print("Command: ");
          Serial.println(message.getBool());
      
      // Rc433 Plugs
          if ((incomingOutlet == 6) && (incomingLightState == 1))
          {
            transmitter.sendUnit(15, true);
          }
          if ((incomingOutlet == 6) && (incomingLightState == 0))
          {
            transmitter.sendUnit(15, false);
          }
      
          if ((incomingOutlet == 7) && (incomingLightState == 1))
          {
            transmitter.sendUnit(14, true);
          }
          if ((incomingOutlet == 7) && (incomingLightState == 0 ))
          {
            transmitter.sendUnit(14, false);
          }
      
          if ((incomingOutlet == 8) && (incomingLightState == 1))
          {
            transmitter.sendUnit(13, true);
          }
          if ((incomingOutlet == 8) && (incomingLightState == 0))
          {
            transmitter.sendUnit(13, false);
          }
      // RELAYS
      if (incomingOutlet == 4) {
            if (incomingLightState == 1) {
              // Turn on  Relay 1
              digitalWrite(incomingOutlet, RELAY_ON);}
              
            if (incomingLightState == 0)  {
              // Turn off Relay 1
              Serial.println("Turn off Relay 1");
              digitalWrite(incomingOutlet, RELAY_OFF);}}
              
          if (incomingOutlet == 5) {
            if (incomingLightState == 1) {
              // Turn on  Relay 2
              digitalWrite(incomingOutlet, RELAY_ON);}
              
            if (incomingLightState == 0)  {
              // Turn off Relay 2
              Serial.println("Turn off Relay 2");
              digitalWrite(incomingOutlet, RELAY_OFF);}}
             
         
      
        }
      }
      
      
      
      posted in My Project
      marekd
      marekd
    • RE: My New IrrigationController

      Finally I launched my Irrigation System, there are some small bugs in the code, but can live with it - for now. Have plans how to rebuild this in winter time to be more robust and to look better.
      Runs under Domoticz and manually with keypad.
      For now it looks like this:
      0_1466414001281_IMG_20160620_080309.jpg

      posted in My Project
      marekd
      marekd
    • Home made "Arduino with power supply" + relay board + DHT11

      Hi,
      This is for those who can solder but making own board with SMD is to advanced 🙂 like me...maybe someday...

      Few pictures of whole set with some code for MySensors node.
      This device is to run bathroom ventilator, simply turn on and off my heating system and to measure temp & hum in the bathroom.
      System is based on Atmega 328p chip

      0_1490359079880_211.png,

      power supply made according to this:
      https://forum.mysensors.org/topic/1607/safe-in-wall-ac-to-dc-transformers
      with adjustment for 230V mains.
      0_1490359390131_hlk.jpg
      Used also voltage regulation board for radio and double relay board from ebay:

      0_1490360138803_1.jpg

      0_1490360152088_2.jpg

      now it is running over one month, box is hidden in the dry wall.
      The code:

      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      #define MY_NODE_ID 11 // Bathroom
      //#define MY_PARENT_NODE_ID 13
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      // Enable repeater functionality for this node
      //#define MY_REPEATER_FEATURE
      
      
      //  Include related libraries
      #include <MySensors.h>
      #include <SPI.h>
      #include <Wire.h>
      #include <DHT.h>
      
      DHT dht;
      float Temp;
      float Hum;
      boolean metric = true; 
      #define DHT_PIN 2
      #define DHT_H 1
      #define DHT_T 2
      #define RELAY_1 3
      #define RELAY_2 4
      
      #define RELAY_ON 1  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
      #define NUMBER_OF_RELAYS 2 // Total number of attached relays
      
      
      MyMessage msgT1(DHT_H, V_HUM);
      MyMessage msgH1(DHT_T, V_TEMP);
      MyMessage msgR1(RELAY_1, V_STATUS);
      MyMessage msgR2(RELAY_2, V_STATUS);
      
      
      float T1;
      byte b_state=0;
      byte last_b_state=0;
      int numSensors = 0;
      boolean receivedConfig = false;
      
      
      const unsigned long tUpdate = 60000; // update interval
      unsigned long t0;
      
      void presentation()
      {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Bathroom MyS 2.1.1", "032417");
        // Fetch the number of attached temperature sensors
        present(DHT_H, S_HUM,"Hum Bath");
        present(DHT_T, S_TEMP,"Temp Bath");
        present(RELAY_1, S_BINARY, "VENT");
        present(RELAY_2, S_BINARY, "Central heating");
      
      }
      
      void before()
      {
        for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
          // Then set relay pins in output mode
          pinMode(pin, OUTPUT);
          // Set relay to last known state (using eeprom storage)
          digitalWrite(pin, RELAY_OFF);
        }
      
      }
      
      
      void setup()
      {  delay(1000);
        // Startup up the OneWire library
        dht.setup(DHT_PIN); 
      
        t0=millis();
        ServerUpdate();
        
      }
      
      
      
      void loop()
      { 
        if ((millis() - t0) > tUpdate) ServerUpdate(); // I believe that we can use now the Wait() command
       
      }
      
      void ServerUpdate() {
        Hum = dht.getHumidity(); delay(50);
        Temp = dht.getTemperature();delay(50);
        send(msgT1.set(Hum, 1));
        send(msgH1.set(Temp, 1));
        t0 = millis();
      }
      
      void receive(const MyMessage &message) {
      
        if (message.type == V_STATUS) {
          int incomingLightState =  message.getBool();
          int incomingOutlet = message.sensor;
      
          Serial.print("Outlet #: ");
          Serial.println(message.sensor);
          Serial.print("Command: ");
          Serial.println(message.getBool());
      
          if (incomingOutlet == 3) {
            if (incomingLightState == 1) {
              // Turn on  Relay1
              Serial.println("Turn off Relay 1");
              digitalWrite(incomingOutlet, incomingLightState);}
              
            if (incomingLightState == 0)  {
              // Turn off Ralay1
              Serial.println("Turn off Relay 1");
              digitalWrite(incomingOutlet, incomingLightState);}
              }
              
          if (incomingOutlet == 4) {
            if (incomingLightState == 1) {
              // Turn on  Relay2
              Serial.println("Turn on Relay 2");
              digitalWrite(incomingOutlet, incomingLightState);}
              
            if (incomingLightState == 0)  {
              // Turn off Relay2
              Serial.println("Turn off Relay 2");
              digitalWrite(incomingOutlet, incomingLightState);}}
      
      }
      }
      
      
      
      
      
      
      posted in My Project
      marekd
      marekd
    • RE: NRF24L01+PA+LNA wiring question

      Hi, did you try to use standard NRF24 with the same wiring? That is the shortest way to check are they faulty or your wiring is not so good.

      posted in Hardware
      marekd
      marekd
    • RE: BMP280 + I2C

      @emc2, Thank you for your comment, my sensor is BME280 so now I can use hum as well.
      I made quick upgrade of my sketch. Had to modify I2C address (good that you wrote that in your post), I change in the library for 0x76 instead.
      Here is my sketch for BME280:

      /*                  BME280 I2C for MySensors
      
      // this program is for BMEP280 library :Adafriut BME280 
      
      I use some parts from oryginal MySensors PressureSensor for BMP085 module  
      
      To use with MySensors 2.0.0 dev.branch
      
      * REVISION HISTORY
       * Version 1.0 - Henrik Ekblad
       * Version 1.2 - Marek Dajnowicz
      
      
      */
      
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      //#define MY_REPEATER_FEATURE
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      //#define MY_NODE_ID 33 
      
      //#define MY_PARENT_NODE_ID
      
      #include <SPI.h>
      #include <MySensor.h>
      #include <Adafruit_Sensor.h>
      #include <Adafruit_BME280.h> // I had to change I2C address in library for 0x76 (line 32)
      #include "Wire.h"
      
      Adafruit_BME280 bme; // I2C
      
      #define CHILD_ID_HUM 0
      #define CHILD_ID_TEMP 1
      #define CHILD_ID_PRESS 2
      
      const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
      enum FORECAST
      {
        STABLE = 0,			// "Stable Weather Pattern"
        SUNNY = 1,			// "Slowly rising Good Weather", "Clear/Sunny "
        CLOUDY = 2,			// "Slowly falling L-Pressure ", "Cloudy/Rain "
        UNSTABLE = 3,		// "Quickly rising H-Press",     "Not Stable"
        THUNDERSTORM = 4,	// "Quickly falling L-Press",    "Thunderstorm"
        UNKNOWN = 5			// "Unknown (More Time needed)
      };
      
      
      // for forecast - untouched by me :)
      
        float lastPressure = -1;
        float lastTemp = -1;
        int lastForecast = -1;
        const int LAST_SAMPLES_COUNT = 5;
        float lastPressureSamples[LAST_SAMPLES_COUNT];
        // this CONVERSION_FACTOR is used to convert from Pa to kPa in forecast algorithm
        // get kPa/h be dividing hPa by 10
        #define CONVERSION_FACTOR (1.0/10.0)
        int minuteCount = 0;
        bool firstRound = true;
        // average value is used in forecast algorithm.
        float pressureAvg;
        // average after 2 hours is used as reference value for the next iteration.
        float pressureAvg2;
        float dP_dt;
      
      // MyMessage to controler
      MyMessage msgT1(CHILD_ID_TEMP, V_TEMP);
      MyMessage msgP1(CHILD_ID_PRESS, V_PRESSURE);
      MyMessage msgF1(CHILD_ID_PRESS, V_FORECAST);
      MyMessage msgH1(CHILD_ID_HUM, V_HUM);
      
      void presentation()
      {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("OUTSIDE P&T&H", "1.2");
        present(CHILD_ID_TEMP, S_TEMP);
        present(CHILD_ID_PRESS, S_BARO);
        present(CHILD_ID_HUM, S_HUM);  
      }
      
      void setup()
      {
        delay(500);// just in case
        if (!bme.begin())
         {
          Serial.println("BME init failed!");
          while (1);
         }
        else Serial.println("BME init success!");
        
        ServerUpdate(); // for first data reading and sending to controler
      }
      
      void loop()
      { 
         smartSleep(60000); // adjust sleeping time here 1 minute in this case 
         ServerUpdate();
      }
      
      void ServerUpdate() // used to read sensor data and send it to controller
      {
        double T, P, H;
        T=bme.readTemperature();
        P=bme.readPressure()/100.0;
        H=bme.readHumidity();
        
          int forecast = sample(P);
            send(msgT1.set(T, 1));
            send(msgP1.set(P, 1));
            send(msgH1.set(H,1));
            send(msgF1.set(weather[forecast]));
            
         // unmark for debuging
            Serial.print("T = \t"); Serial.print(T, 1); Serial.print(" degC\t");
            Serial.print("P = \t"); Serial.print(P, 1); Serial.print(" mBar\t");
            Serial.print("F = \t"); Serial.print(weather[forecast]); Serial.println(" ?");
      }
      
      float getLastPressureSamplesAverage()
      {
        float lastPressureSamplesAverage = 0;
        for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
        {
          lastPressureSamplesAverage += lastPressureSamples[i];
        }
        lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
      
        return lastPressureSamplesAverage;
      }
      
      // Algorithm found here
      // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
      // Pressure in hPa -->  forecast done by calculating kPa/h
      int sample(float pressure)
      {
        // Calculate the average of the last n minutes.
        int index = minuteCount % LAST_SAMPLES_COUNT;
        lastPressureSamples[index] = pressure;
      
        minuteCount++;
        if (minuteCount > 185)
        {
          minuteCount = 6;
        }
      
        if (minuteCount == 5)
        {
          pressureAvg = getLastPressureSamplesAverage();
        }
        else if (minuteCount == 35)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change * 2; // note this is for t = 0.5hour
          }
          else
          {
            dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
          }
        }
        else if (minuteCount == 65)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) //first time initial 3 hour
          {
            dP_dt = change; //note this is for t = 1 hour
          }
          else
          {
            dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 95)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 1.5; // note this is for t = 1.5 hour
          }
          else
          {
            dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 125)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          pressureAvg2 = lastPressureAvg; // store for later use.
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 2; // note this is for t = 2 hour
          }
          else
          {
            dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 155)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 2.5; // note this is for t = 2.5 hour
          }
          else
          {
            dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 185)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 3; // note this is for t = 3 hour
          }
          else
          {
            dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
          }
          pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
          firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
        }
      
        int forecast = UNKNOWN;
        if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
        {
          forecast = UNKNOWN;
        }
        else if (dP_dt < (-0.25))
        {
          forecast = THUNDERSTORM;
        }
        else if (dP_dt > 0.25)
        {
          forecast = UNSTABLE;
        }
        else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
        {
          forecast = CLOUDY;
        }
        else if ((dP_dt > 0.05) && (dP_dt < 0.25))
        {
          forecast = SUNNY;
        }
        else if ((dP_dt > (-0.05)) && (dP_dt < 0.05))
        {
          forecast = STABLE;
        }
        else
        {
          forecast = UNKNOWN;
        }
      
        // uncomment when debugging
        //Serial.print(F("Forecast at minute "));
        //Serial.print(minuteCount);
        //Serial.print(F(" dP/dt = "));
        //Serial.print(dP_dt);
        //Serial.print(F("kPa/h --> "));
        //Serial.println(weather[forecast]);
      
        return forecast;
      }
      
      posted in My Project
      marekd
      marekd
    • RE: BMP280 + I2C

      @TRS-80 Thanks. The box is MINI PRAGMA MIP12112 SCHNEIDER ELECTRIC got it from LeroyMerlin

      posted in My Project
      marekd
      marekd
    • RE: Multisensor Multiactuator Sketch / Testboard - tested with FHEM Controller

      @oscarc
      hope this will answer your question:
      0_1463496828500_ds18b20-normal-power.jpg
      or this:

      0_1463496847603_ds18b20-parasite-power.jpg

      posted in My Project
      marekd
      marekd

    Latest posts made by marekd

    • Home made "Arduino with power supply" + relay board + DHT11

      Hi,
      This is for those who can solder but making own board with SMD is to advanced 🙂 like me...maybe someday...

      Few pictures of whole set with some code for MySensors node.
      This device is to run bathroom ventilator, simply turn on and off my heating system and to measure temp & hum in the bathroom.
      System is based on Atmega 328p chip

      0_1490359079880_211.png,

      power supply made according to this:
      https://forum.mysensors.org/topic/1607/safe-in-wall-ac-to-dc-transformers
      with adjustment for 230V mains.
      0_1490359390131_hlk.jpg
      Used also voltage regulation board for radio and double relay board from ebay:

      0_1490360138803_1.jpg

      0_1490360152088_2.jpg

      now it is running over one month, box is hidden in the dry wall.
      The code:

      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      #define MY_NODE_ID 11 // Bathroom
      //#define MY_PARENT_NODE_ID 13
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      // Enable repeater functionality for this node
      //#define MY_REPEATER_FEATURE
      
      
      //  Include related libraries
      #include <MySensors.h>
      #include <SPI.h>
      #include <Wire.h>
      #include <DHT.h>
      
      DHT dht;
      float Temp;
      float Hum;
      boolean metric = true; 
      #define DHT_PIN 2
      #define DHT_H 1
      #define DHT_T 2
      #define RELAY_1 3
      #define RELAY_2 4
      
      #define RELAY_ON 1  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
      #define NUMBER_OF_RELAYS 2 // Total number of attached relays
      
      
      MyMessage msgT1(DHT_H, V_HUM);
      MyMessage msgH1(DHT_T, V_TEMP);
      MyMessage msgR1(RELAY_1, V_STATUS);
      MyMessage msgR2(RELAY_2, V_STATUS);
      
      
      float T1;
      byte b_state=0;
      byte last_b_state=0;
      int numSensors = 0;
      boolean receivedConfig = false;
      
      
      const unsigned long tUpdate = 60000; // update interval
      unsigned long t0;
      
      void presentation()
      {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Bathroom MyS 2.1.1", "032417");
        // Fetch the number of attached temperature sensors
        present(DHT_H, S_HUM,"Hum Bath");
        present(DHT_T, S_TEMP,"Temp Bath");
        present(RELAY_1, S_BINARY, "VENT");
        present(RELAY_2, S_BINARY, "Central heating");
      
      }
      
      void before()
      {
        for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
          // Then set relay pins in output mode
          pinMode(pin, OUTPUT);
          // Set relay to last known state (using eeprom storage)
          digitalWrite(pin, RELAY_OFF);
        }
      
      }
      
      
      void setup()
      {  delay(1000);
        // Startup up the OneWire library
        dht.setup(DHT_PIN); 
      
        t0=millis();
        ServerUpdate();
        
      }
      
      
      
      void loop()
      { 
        if ((millis() - t0) > tUpdate) ServerUpdate(); // I believe that we can use now the Wait() command
       
      }
      
      void ServerUpdate() {
        Hum = dht.getHumidity(); delay(50);
        Temp = dht.getTemperature();delay(50);
        send(msgT1.set(Hum, 1));
        send(msgH1.set(Temp, 1));
        t0 = millis();
      }
      
      void receive(const MyMessage &message) {
      
        if (message.type == V_STATUS) {
          int incomingLightState =  message.getBool();
          int incomingOutlet = message.sensor;
      
          Serial.print("Outlet #: ");
          Serial.println(message.sensor);
          Serial.print("Command: ");
          Serial.println(message.getBool());
      
          if (incomingOutlet == 3) {
            if (incomingLightState == 1) {
              // Turn on  Relay1
              Serial.println("Turn off Relay 1");
              digitalWrite(incomingOutlet, incomingLightState);}
              
            if (incomingLightState == 0)  {
              // Turn off Ralay1
              Serial.println("Turn off Relay 1");
              digitalWrite(incomingOutlet, incomingLightState);}
              }
              
          if (incomingOutlet == 4) {
            if (incomingLightState == 1) {
              // Turn on  Relay2
              Serial.println("Turn on Relay 2");
              digitalWrite(incomingOutlet, incomingLightState);}
              
            if (incomingLightState == 0)  {
              // Turn off Relay2
              Serial.println("Turn off Relay 2");
              digitalWrite(incomingOutlet, incomingLightState);}}
      
      }
      }
      
      
      
      
      
      
      posted in My Project
      marekd
      marekd
    • Multi sensor node - Rc433MHz, 2xRelay, DHT11

      Hi!

      This is my last fast project.
      With this I can control 3x Rc433 MHz wall plugs, 2 relays and to measure room temperature and humidity with a single node.
      This is very simple to make for almost everyone, with some small, like me, soldering skills!
      This is how it looks like:
      0_1489863953729_2017-03-18 11.52.33.bmp
      0_1489864033560_22.bmp
      The box was drilled to use motion sensor as well - but i change my mind 😉
      0_1489864142333_33.bmp

      Below you can find sketch:

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0 - Henrik Ekblad
       * Version 2.0 - Marek Dajnowicz (Rc433, DHT11 upgrade)
       *
       * DESCRIPTION
       * Example sketch showing how to control physical relays.
       * How to control Rc433 MHz wall plugs and usage of DHT11
       
       */
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      //#define MY_NODE_ID 16
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      
      #define CHILD_ID_HUM 1 // DHT11
      #define CHILD_ID_TEMP 2 // DHT11
      #define HUMIDITY_SENSOR_DIGITAL_PIN 3 // where DHT is coneccted
      #define RELAY_1 4
      #define RELAY_2 5
      #define CHILD_ID_L1 6 // for Rc433 PLUG 1
      #define CHILD_ID_L2 7 // for Rc433 PLUG 2
      #define CHILD_ID_L3 8 // for Rc433 PLUG 3
      
      #define RELAY_ON 0  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 1 // GPIO value to write to turn off attached relay
      #define NUMBER_OF_RELAYS 2 // Total number of attached relays
      
      
      #include <SPI.h>
      #include <MySensors.h>
      #include <DHT.h>
      #include <NewRemoteTransmitter.h>
      
      DHT dht;
      float Temp;
      float Hum;
      boolean metric = true;
      
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      MyMessage msgL1(CHILD_ID_L1, V_STATUS);
      MyMessage msgL2(CHILD_ID_L2, V_STATUS);
      MyMessage msgL3(CHILD_ID_L3, V_STATUS);
      MyMessage msgR1(RELAY_1, V_STATUS);
      MyMessage msgR2(RELAY_2, V_STATUS);
      
      // Create a transmitter on address xxxxxxxx, using digital pin 6 to transmit, 
      // with a period duration of 260ms (default), repeating the transmitted
      // code 2^3=8 times.
      NewRemoteTransmitter transmitter(60548078, 6, 260, 3); // address got by ShowReceivedCode.ino from Arduino IDE  
      
      boolean receivedConfig = false;
      const unsigned long tUpdate = 60000; // update interval 60sec
      unsigned long t0;
      
      void setup() {
      
        dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
        t0 = millis();
        ServerUpdate();
      }
      
      void ServerUpdate() {
        dht.readSensor(true);
        Hum = dht.getHumidity(); 
        delay(20);
        Temp = dht.getTemperature(); 
        delay(20);
        send(msgTemp.set(Temp, 1));
        delay(20);
        send(msgHum.set(Hum, 1)); 
        delay(20);
        t0 = millis();
      }
      
      void presentation() {
        // Present locally attached sensors
        sendSketchInfo("Multi Node", "2.0.0");
        present(CHILD_ID_HUM, S_HUM, "HUM");
        present(CHILD_ID_TEMP, S_TEMP, "TEMP");
        present(CHILD_ID_L1, S_LIGHT, "PLUG_1");
        present(CHILD_ID_L2, S_LIGHT, "PLUG_2");
        present(CHILD_ID_L3, S_LIGHT, "PLUG_3");
        present(RELAY_1, S_BINARY, "Relay 1");
        present(RELAY_2, S_BINARY, "Relay 2");
      
      }
      
      void before()
      {
        for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
          // Then set relay pins in output mode
          pinMode(pin, OUTPUT);
          digitalWrite(pin, RELAY_OFF);
        }
      
      }
      
      void loop()
        {
        if ((millis() - t0) > tUpdate) ServerUpdate();
        }
      
      
      void receive(const MyMessage &message) {
      
        if (message.type == V_STATUS) {
          int incomingLightState =  message.getBool();
          int incomingOutlet = message.sensor;
      
          Serial.print("Outlet #: ");
          Serial.println(message.sensor);
          Serial.print("Command: ");
          Serial.println(message.getBool());
      
      // Rc433 Plugs
          if ((incomingOutlet == 6) && (incomingLightState == 1))
          {
            transmitter.sendUnit(15, true);
          }
          if ((incomingOutlet == 6) && (incomingLightState == 0))
          {
            transmitter.sendUnit(15, false);
          }
      
          if ((incomingOutlet == 7) && (incomingLightState == 1))
          {
            transmitter.sendUnit(14, true);
          }
          if ((incomingOutlet == 7) && (incomingLightState == 0 ))
          {
            transmitter.sendUnit(14, false);
          }
      
          if ((incomingOutlet == 8) && (incomingLightState == 1))
          {
            transmitter.sendUnit(13, true);
          }
          if ((incomingOutlet == 8) && (incomingLightState == 0))
          {
            transmitter.sendUnit(13, false);
          }
      // RELAYS
      if (incomingOutlet == 4) {
            if (incomingLightState == 1) {
              // Turn on  Relay 1
              digitalWrite(incomingOutlet, RELAY_ON);}
              
            if (incomingLightState == 0)  {
              // Turn off Relay 1
              Serial.println("Turn off Relay 1");
              digitalWrite(incomingOutlet, RELAY_OFF);}}
              
          if (incomingOutlet == 5) {
            if (incomingLightState == 1) {
              // Turn on  Relay 2
              digitalWrite(incomingOutlet, RELAY_ON);}
              
            if (incomingLightState == 0)  {
              // Turn off Relay 2
              Serial.println("Turn off Relay 2");
              digitalWrite(incomingOutlet, RELAY_OFF);}}
             
         
      
        }
      }
      
      
      
      posted in My Project
      marekd
      marekd
    • RE: My New IrrigationController

      @karl261
      Capacitor is not so big 😉 generally helps.
      I my wiring there is no pull-up resistors at I2C lines. Rest is the same.

      posted in My Project
      marekd
      marekd
    • RE: My New IrrigationController

      @karl261
      Thanks,
      in case I2C yes, and no.
      with 1st generation [with 1 ProMini] I used I2C port expander PCF8574.
      with 2nd generation [with MEGA2560] just pins, 8 pins, declared like this:

      /**** Kepad settings /
      const byte ROWS = 4;
      const byte COLS = 4;
      char keys[ROWS][COLS] = {
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'
      ', '0', '#', 'D'}
      };

      byte rowPins[ROWS] = {47, 45, 43, 41};
      byte colPins[COLS] = {39, 37, 35, 33};
      int i2caddress = 0x20;
      Keypad_I2C kpd = Keypad_I2C( makeKeymap(keys), rowPins, colPins, ROWS, COLS, i2caddress );

      with 3rd generation - plan to have 2nd ProMini with PCF expander.

      attached library I use.

      0_1474294070076_Keypad_I2C.zip

      and some pictures of generation 3, which is under construct 🙂

      Power supply:
      0_1474294426219_IMG_20160914_183822.jpg

      and control box with 2 ProMinis:
      0_1474294458646_IMG_20160914_183837.jpg

      posted in My Project
      marekd
      marekd
    • RE: My New IrrigationController

      @fets
      Manufacturer is RAIN S.p.a Italy, www.rain.it.
      Model I use is RN150.
      Got them from Leroy Merlin, price was around 11 EUR.

      posted in My Project
      marekd
      marekd
    • RE: My New IrrigationController

      @gbgent_nc
      Yes I could and did already because have to use ProMini [my MEGA2560 was killed 😉 ].
      Anyway plan is now to use 2xProMini., one for LCD, Keyboard, relays and second for temperature x2, water meter, rain sensor and relay for pump.

      posted in My Project
      marekd
      marekd
    • RE: My New IrrigationController

      @epierre
      Started to play with LM2596, I've got sth. like this:
      http://www.ebay.com/itm/1pcs-1-23V-30V-DC-DC-Buck-Converter-Step-Down-Module-LM2596-Power-Supply-Output-/400985220074?hash=item5d5c94e3ea:g:o10AAOxy0x1TVSpD

      Added diode bridge between transformer and this converter. But my concern is that I've some big voltage peaks the the output of it. It happens when I'm opening/closing valves (AC solenoids) connected to this transformer.
      Set this converter to 12V DC but my readings are sometimes around 20V DC and I am affraid that I could destroy by Arduino.
      Do you (anyone) have any suggestion ?

      posted in My Project
      marekd
      marekd
    • RE: Water high volume flow meter

      @ericvdb said:

      The pump of my swimming pool can do 240L/min, the pipe diameter is 35mm.

      this is over 14m3/h of water, this is a lot. Are you sure about that?
      you can find a flow meter up to 120L/min for 1.5" pipe, but 240 is like industrial size for me.

      posted in Hardware
      marekd
      marekd
    • RE: MySensors 2.0.0 Released

      Hi there.
      Good work.
      I was using dev ver. - should I recompile all nodes and GW to 2.0.0, to use it?

      posted in Announcements
      marekd
      marekd
    • RE: My New IrrigationController

      Finally I launched my Irrigation System, there are some small bugs in the code, but can live with it - for now. Have plans how to rebuild this in winter time to be more robust and to look better.
      Runs under Domoticz and manually with keypad.
      For now it looks like this:
      0_1466414001281_IMG_20160620_080309.jpg

      posted in My Project
      marekd
      marekd