Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. General Discussion
  3. Combining BinarySwitch with PressureSensor

Combining BinarySwitch with PressureSensor

Scheduled Pinned Locked Moved General Discussion
14 Posts 3 Posters 2.9k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Øyvind LauritzenØ Offline
    Øyvind LauritzenØ Offline
    Øyvind Lauritzen
    wrote on last edited by
    #1

    I am having troubles combining these two sketches, for some reason whatever how I do it, pressure and temperature is always working, binary switch is not(actually window magnet)

    This is what I end up with... Anyone who can show me where it goes sour?

    TIA

    /**
     * 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.
     *
     *******************************
     *
     * DESCRIPTION
     *
     * Simple binary switch example 
     * Connect button or door/window reed switch between 
     * digitial I/O pin 3 (BUTTON_PIN below) and GND.
     * http://www.mysensors.org/build/binary
     */
    
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <Wire.h>
    #include <Adafruit_BMP085.h>
    
    #define CHILD_ID 3
    #define BUTTON_PIN  3  // Arduino Digital I/O pin for button/reed switch
    #define BARO_CHILD 0
    #define TEMP_CHILD 1
    
    const float ALTITUDE = 93; // <-- adapt this value to your own location's altitude.
    
    // Sleep time between reads (in seconds). Do not change this value as the forecast algorithm needs a sample every minute.
    const unsigned long SLEEP_TIME = 60000; 
    
    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)
    };
    
    Adafruit_BMP085 bmp = Adafruit_BMP085();      // Digital Pressure Sensor 
    
    MySensor gw;
    Bounce debouncer = Bounce(); 
    int oldValue=-1;
    
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(CHILD_ID,V_TRIPPED);
    
    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;
    boolean metric;
    MyMessage tempMsg(TEMP_CHILD, V_TEMP);
    MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
    MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
    
    void setup()  
    {  
      gw.begin();
    
     // Setup the button
      pinMode(BUTTON_PIN,INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN,HIGH);
      
      // After setting up the button, setup debouncer
      debouncer.attach(BUTTON_PIN);
      debouncer.interval(5);
      
      // Register binary input sensor to gw (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      gw.present(CHILD_ID, S_DOOR);  
      
      
    	// Send the sketch version information to the gateway and Controller
    	gw.sendSketchInfo("Pressure Sensor", "1.1");
    
    	if (!bmp.begin()) 
    	{
    		Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    		while (1) {}
    	}
    
    	// Register sensors to gw (they will be created as child devices)
    	gw.present(BARO_CHILD, S_BARO);
    	gw.present(TEMP_CHILD, S_TEMP);
    	metric = gw.getConfig().isMetric;
    }
    
    
    //  Check if digital input has changed and send in new value
    void loop() 
    {
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
     
      if (value != oldValue) {
         // Send in the new value
         gw.send(msg.set(value==HIGH ? 1 : 0));
         oldValue = value;
      }
    	float pressure = bmp.readSealevelPressure(ALTITUDE) / 100.0;
    	float temperature = bmp.readTemperature();
    
    	if (!metric) 
    	{
    		// Convert to fahrenheit
    		temperature = temperature * 9.0 / 5.0 + 32.0;
    	}
    
    	int forecast = sample(pressure);
    
    	Serial.print("Temperature = ");
    	Serial.print(temperature);
    	Serial.println(metric ? " *C" : " *F");
    	Serial.print("Pressure = ");
    	Serial.print(pressure);
    	Serial.println(" hPa");
    	Serial.print("Forecast = ");
    	Serial.println(weather[forecast]);
    
    
    	if (temperature != lastTemp) 
    	{
    		gw.send(tempMsg.set(temperature, 1));
    		lastTemp = temperature;
    	}
    
    	if (pressure != lastPressure) 
    	{
    		gw.send(pressureMsg.set(pressure, 0));
    		lastPressure = pressure;
    	}
    
    	if (forecast != lastForecast)
    	{
    		gw.send(forecastMsg.set(weather[forecast]));
    		lastForecast = forecast;
    	}
    
    	gw.sleep(SLEEP_TIME);
      } 
    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;
    }
    
    1 Reply Last reply
    0
    • mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by mfalkvidd
      #2

      The sketch looks pretty good, except two things:

      • it is not correctly formatted (use CMD/Ctrl+T in the Arduino IDE). This will make the code much more readable, both for yourself and anyone reading your code on the forum.
      • The sensor goes to sleep, which will prevent it from detecting a change in the window magnet. The binary switch example) doesn't sleep, while the pressure example always sleeps for SLEEP_TIME milliseconds. Change your current sleep to
      gw.sleep(digitalPinToInterrupt(BUTTON_PIN), CHANGE, SLEEP_TIME);
      

      to wake up if the switch is changed.

      I think that's it. If it isn't, please post the serial debug from the node.

      This simple change will cause the sensor to send temp and pressure every time the switch is changed but I don't think that will be a problem.

      1 Reply Last reply
      0
      • Øyvind LauritzenØ Offline
        Øyvind LauritzenØ Offline
        Øyvind Lauritzen
        wrote on last edited by Øyvind Lauritzen
        #3

        Does this mean the temp and pressure data will only be sent every time the switch is changed? If this is the case and since this is not gonna be run from battery, is there a easy way to let pressure and temp be updated every 60 seconds, and let it check for the state of the switch reasonable often?

        According to Henrik Ekblad the forecast algorithm needs this info at that rate.

        TIA

        1 Reply Last reply
        0
        • mfalkviddM Offline
          mfalkviddM Offline
          mfalkvidd
          Mod
          wrote on last edited by
          #4

          The node will wake up at SLEEP_TIME if the window switch doesn't change, so you'll get data at least as often as SLEEP_TIME.

          1 Reply Last reply
          0
          • Øyvind LauritzenØ Offline
            Øyvind LauritzenØ Offline
            Øyvind Lauritzen
            wrote on last edited by
            #5

            I've change the line

            gw.sleep(SLEEP_TIME);
            

            to

            gw.sleep(digitalPinToInterrupt(BUTTON_PIN), CHANGE, SLEEP_TIME);
            

            This was what you meant? It doesn't seem to do more than wake up as you said every 60 seconds to transfer the status of all sensors - pressure, switch and temp.

            Did I misunderstand what you meant maybe? :)

            TIA

            1 Reply Last reply
            0
            • mfalkviddM Offline
              mfalkviddM Offline
              mfalkvidd
              Mod
              wrote on last edited by
              #6

              Good thinking. Let's make sure we have the same goal :-)

              • The sensor should send temp/pressure data at least every 60 seconds
              • The sensor should also send switch information every time there is a change (window is opened or closed)

              correct?

              Øyvind LauritzenØ 1 Reply Last reply
              0
              • mfalkviddM mfalkvidd

                Good thinking. Let's make sure we have the same goal :-)

                • The sensor should send temp/pressure data at least every 60 seconds
                • The sensor should also send switch information every time there is a change (window is opened or closed)

                correct?

                Øyvind LauritzenØ Offline
                Øyvind LauritzenØ Offline
                Øyvind Lauritzen
                wrote on last edited by
                #7

                @mfalkvidd Yes as far as I understand that should be it, unless the forecast algorithm is not for some reason depending on it updating exactly every 60 seconds?

                I am actually gonna be using the switch info to know the state of my garage door, making sure it's not by mistake left open when it shouldn't.

                1 Reply Last reply
                0
                • mfalkviddM Offline
                  mfalkviddM Offline
                  mfalkvidd
                  Mod
                  wrote on last edited by
                  #8

                  Great. Then your code change should be enough. What does the serial debug log of the node say?

                  1 Reply Last reply
                  0
                  • Øyvind LauritzenØ Offline
                    Øyvind LauritzenØ Offline
                    Øyvind Lauritzen
                    wrote on last edited by Øyvind Lauritzen
                    #9

                    From what the serial monitor is telling me is that it is updating at least temp and pressure, I don't know where I see the actual switch? Domoticz only update temp and pressure every time the switch is triggered, it is not telling me the new state of the switch until at least 60sec from what it seems.

                    send: 2-2-0-0 s=0,c=1,t=4,pt=7,l=5,sg=0,st=ok:1019
                    Temperature = 25.40 *C
                    Pressure = 1019.35 hPa
                    Forecast = stable
                    send: 2-2-0-0 s=0,c=1,t=4,pt=7,l=5,sg=0,st=ok:1019
                    Temperature = 25.40 *C
                    Pressure = 1019.32 hPa
                    Forecast = stable
                    send: 2-2-0-0 s=0,c=1,t=4,pt=7,l=5,sg=0,st=ok:1019
                    Temperature = 25.40 *C
                    Pressure = 1019.37 hPa
                    Forecast = stable
                    send: 2-2-0-0 s=0,c=1,t=4,pt=7,l=5,sg=0,st=ok:1019
                    Temperature = 25.40 *C
                    Pressure = 1019.38 hPa
                    Forecast = stable
                    send: 2-2-0-0 s=0,c=1,t=4,pt=7,l=5,sg=0,st=ok:1019

                    1 Reply Last reply
                    0
                    • mfalkviddM Offline
                      mfalkviddM Offline
                      mfalkvidd
                      Mod
                      wrote on last edited by
                      #10

                      Could you include output from startup as well? You should get at least one switch message when the node is reset.

                      Next step is probably to add som Serial.println in various places to see what is happening.

                      You have double-checked the wiring? The switch is connected to GND on one side and pin 3 on the other sie?

                      1 Reply Last reply
                      0
                      • Øyvind LauritzenØ Offline
                        Øyvind LauritzenØ Offline
                        Øyvind Lauritzen
                        wrote on last edited by Øyvind Lauritzen
                        #11

                        Yes it is clear that it is working partly because it will eventually update the state of the switch, but it will not do this as often as temp/pressure. Temp/pressure is updated every time switch is triggered, but still the state of the switch is not reported every time , only when 60+ seconds have passed.

                        This is the startup.

                        send: 2-2-0-0 s=255,c=3,t=15,pt=2,l=2,sg=0,st=ok:0
                        send: 2-2-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.4
                        send: 2-2-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
                        read: 0-0-2 s=255,c=3,t=6,pt=0,l=1,sg=0:M
                        sensor started, id=2, parent=0, distance=1
                        send: 2-2-0-0 s=3,c=0,t=0,pt=0,l=0,sg=0,st=ok:
                        send: 2-2-0-0 s=255,c=3,t=11,pt=0,l=15,sg=0,st=ok:Pressure Sensor
                        send: 2-2-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.1
                        send: 2-2-0-0 s=0,c=0,t=8,pt=0,l=0,sg=0,st=ok:
                        send: 2-2-0-0 s=1,c=0,t=6,pt=0,l=0,sg=0,st=ok:
                        send: 2-2-0-0 s=3,c=1,t=16,pt=2,l=2,sg=0,st=ok:0
                        Temperature = 25.30 *C
                        Pressure = 1019.42 hPa
                        Forecast = unknown
                        send: 2-2-0-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:25.3
                        send: 2-2-0-0 s=0,c=1,t=4,pt=7,l=5,sg=0,st=ok:1019
                        send: 2-2-0-0 s=0,c=1,t=5,pt=0,l=7,sg=0,st=ok:unknown

                        1 Reply Last reply
                        0
                        • mfalkviddM Offline
                          mfalkviddM Offline
                          mfalkvidd
                          Mod
                          wrote on last edited by
                          #12

                          If you load the pure binary switch example, does the switch work then? My best guess is that the reed switch is broken or incorrectly wired.

                          1 Reply Last reply
                          0
                          • Øyvind LauritzenØ Offline
                            Øyvind LauritzenØ Offline
                            Øyvind Lauritzen
                            wrote on last edited by
                            #13

                            I've actually already tried that, worked with no problem. Maybe i've missed something or something similair, lets see what happens after a good nights sleep. Thank you for you help so far. :)

                            martinhjelmareM 1 Reply Last reply
                            1
                            • Øyvind LauritzenØ Øyvind Lauritzen

                              I've actually already tried that, worked with no problem. Maybe i've missed something or something similair, lets see what happens after a good nights sleep. Thank you for you help so far. :)

                              martinhjelmareM Offline
                              martinhjelmareM Offline
                              martinhjelmare
                              Plugin Developer
                              wrote on last edited by
                              #14

                              @Øyvind-Lauritzen

                              Debouncer Bounce won't work with sleep. Use a short sleep of 5 ms to debounce instead. Look at the binary switch sleep example.

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              24

                              Online

                              11.7k

                              Users

                              11.2k

                              Topics

                              113.1k

                              Posts


                              Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • MySensors
                              • OpenHardware.io
                              • Categories
                              • Recent
                              • Tags
                              • Popular