@peka VCC and GND on arduino is 5,337V and from Pin 3-6 to IN1-4 i messurt 4,3V
Update i can trigger the relay when i remove the jumper
A picture of my setup:
@peka VCC and GND on arduino is 5,337V and from Pin 3-6 to IN1-4 i messurt 4,3V
Update i can trigger the relay when i remove the jumper
A picture of my setup:
@Heinz Thank you.
I have made this sketch without errors.
// DHT-Sensor
// BMP085 Sensor
#include <SPI.h>
#include <MySensor.h>
#include <Wire.h>
#include <Adafruit_BMP085_U.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
const bool sendAlways = true;
const float SEALEVEL = 688; // Westendorf
const float SEALEVEL_PRESSURE = 1013.25;
// ----------------------------------------------------------------------------
#define CHILD_ID_HUM 2
#define CHILD_ID_TEMP 3
#define HUMIDITY_SENSOR_DIGITAL_PIN 3
#define CHILD_ID_LIGHT 1
#define LIGHT_SENSOR_ANALOG_PIN 1
DHT dht;
float lastTemp;
float lastHum;
boolean metric = true;
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
// ----------------------------------------------------------------------------
#define BARO_CHILD 0
#define TEMP_CHILD 1
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
unsigned long SLEEP_TIME1 = 30000; // 1 minute required for forecast algorithm
unsigned long SLEEP_TIME2 = 30000; // 1 minute required for forecast algorithm
unsigned long SLEEP_TIME3 = 900000; // sleep time between reads (seconds * 1000 milliseconds)
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(1); // Digital Pressure Sensor
MySensor gw;
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
int lastLightLevel;
int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
int oldBatteryPcnt = 0;
/*
DP/Dt explanation
0 = "Stable Weather Pattern"
1 = "Slowly rising Good Weather", "Clear/Sunny "
2 = "Slowly falling L-Pressure ", "Cloudy/Rain "
3 = "Quickly rising H-Press", "Not Stable"
4 = "Quickly falling L-Press", "Thunderstorm"
5 = "Unknown (More Time needed)
*/
const char *weatherStrings[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
enum FORECAST
{
STABLE = 0, // Stable weather
SUNNY = 1, // Slowly rising HP stable good weather
CLOUDY = 2, // Slowly falling Low Pressure System, stable rainy weather
UNSTABLE = 3, // Quickly rising HP, not stable weather
THUNDERSTORM = 4, // Quickly falling LP, Thunderstorm, not stable
UNKNOWN = 5 // Unknown, more time needed
};
const char *situationStrings[] = { "very low", "low", "normal", "high", "very high" };
enum WEATHER_SITUATION
{
VERY_LOW_PRESSURE = 0, // Tiefdruck p>-7.5hPa
LOW_PRESSURE = 1, // Tiefdruck p>-2.5hPa
NORMAL_PRESSURE = 2, // Normal p <+/-02.5hPa
HIGH_PRESSURE = 3, // Hochdruck p>2.5hPa
VERY_HIGH_PRESSURE = 4, // Hochdruck p>7.5hPa
};
float lastPressure = -1;
float lastPressureTemp = -1;
int lastForecast = -1;
int lastSituation = NORMAL_PRESSURE;
const int LAST_SAMPLES_COUNT = 5;
float lastPressureSamples[LAST_SAMPLES_COUNT];
// 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 tempMsg(TEMP_CHILD, V_TEMP);
MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
MyMessage situationMsg(BARO_CHILD, V_VAR1);
MyMessage forecastMsg2(BARO_CHILD, V_VAR2);
void displaySensorDetails(void)
{
sensor_t sensor;
bmp.getSensor(&sensor);
Serial.println(F("------------------------------------"));
Serial.print(F("Sensor: ")); Serial.println(sensor.name);
Serial.print(F("Driver Ver: ")); Serial.println(sensor.version);
Serial.print(F("Unique ID: ")); Serial.println(sensor.sensor_id);
Serial.print(F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F(" hPa"));
Serial.print(F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F(" hPa"));
Serial.print(F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F(" hPa"));
Serial.println(F("------------------------------------"));
Serial.println(F(""));
delay(500);
}
void initPressureSensor()
{
if (!bmp.begin())
{
Serial.println(F("Could not find a valid BMP085 sensor, check wiring!"));
while (1) {}
}
displaySensorDetails();
}
void initHumiditySensor()
{
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
}
void setup()
{
// use the 1.1 V internal reference
#if defined(__AVR_ATmega2560__)
analogReference(INTERNAL1V1);
#else
analogReference(INTERNAL);
#endif
gw.begin();
gw.sendSketchInfo("Weather Station Sensor", "2.1");
initPressureSensor();
initHumiditySensor();
gw.present(BARO_CHILD, S_BARO);
gw.present(TEMP_CHILD, S_TEMP);
gw.present(CHILD_ID_HUM, S_HUM);
gw.present(CHILD_ID_TEMP, S_TEMP);
gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
metric = gw.getConfig().isMetric;
int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
Serial.println(lightLevel);
if (lightLevel != lastLightLevel) {
gw.send(msg.set(lightLevel));
lastLightLevel = lightLevel;
}
gw.sleep(SLEEP_TIME);
}
int getWeatherSituation(float pressure)
{
int situation = NORMAL_PRESSURE;
float delta = pressure - SEALEVEL_PRESSURE;
if (delta > 7.5)
{
situation = VERY_HIGH_PRESSURE;
}
else if (delta > 2.5)
{
situation = HIGH_PRESSURE;
}
else if (delta < -7.5)
{
situation = VERY_LOW_PRESSURE;
}
else if (delta < -2.5)
{
situation = LOW_PRESSURE;
}
else
{
situation = NORMAL_PRESSURE;
}
return situation;
}
bool updatePressureSensor()
{
bool changed = false;
sensors_event_t event;
bmp.getEvent(&event);
if (event.pressure)
{
float absolutePressure = event.pressure;
Serial.print(F("abs Pressure = "));
Serial.print(absolutePressure);
Serial.println(F(" hPa"));
//float altitude = bmp.pressureToAltitude(SEALEVEL_PRESSURE, pressure);
//Serial.print(F("Altitude = "));
//Serial.print(altitude);
//Serial.println(F(" m"));
//sealevel pressure p0 from absolute pressure.
float pressure = bmp.seaLevelForAltitude(SEALEVEL, absolutePressure);
float pressureTemperature;
bmp.getTemperature(&pressureTemperature);
if (!metric)
{
// Convert to fahrenheit
pressureTemperature = pressureTemperature * 9.0 / 5.0 + 32.0;
}
int forecast = sample(pressure);
int situation = getWeatherSituation(pressure);
if (sendAlways || (pressureTemperature != lastPressureTemp))
{
changed = true;
lastPressureTemp = pressureTemperature;
Serial.print(F("Temperature = "));
Serial.print(pressureTemperature);
Serial.println(metric ? F(" *C") : F(" *F"));
if (!gw.send(tempMsg.set(lastPressureTemp, 1)))
{
lastPressureTemp = -1.0;
}
}
if (sendAlways || (pressure != lastPressure))
{
changed = true;
lastPressure = pressure;
Serial.print(F("sealevel Pressure = "));
Serial.print(pressure);
Serial.println(F(" hPa"));
if (!gw.send(pressureMsg.set(lastPressure, 1)))
{
lastPressure = -1.0;
}
}
if (sendAlways || (forecast != lastForecast))
{
changed = true;
lastForecast = forecast;
Serial.print(F("Forecast = "));
Serial.println(weatherStrings[forecast]);
if (gw.send(forecastMsg.set(weatherStrings[lastForecast])))
{
if (!gw.send(forecastMsg2.set(lastForecast)))
{
}
}
else
{
lastForecast = -1.0;
}
}
if (sendAlways || (situation != lastSituation))
{
changed = true;
lastSituation = situation;
Serial.print(F("Situation = "));
Serial.println(situationStrings[situation]);
if (!gw.send(situationMsg.set(lastSituation, 0)))
{
lastSituation = -1.0;
}
}
}
return changed;
}
bool updateHumiditySensor()
{
bool changed = false;
float temperature = dht.getTemperature();
float humidity = dht.getHumidity();
if (!isnan(temperature))
{
#ifdef SEND_WHEN_CHANGED
if (temperature != lastTemp)
#endif
{
lastTemp = temperature;
if (!metric)
{
temperature = dht.toFahrenheit(temperature);
}
changed = true;
Serial.print(F("T: "));
Serial.println(temperature);
if (!gw.send(msgTemp.set(temperature, 1)))
{
lastTemp = -1.0;
}
}
}
else
{
Serial.println(F("Failed reading temperature from DHT"));
}
if (!isnan(humidity))
{
#ifdef SEND_WHEN_CHANGED
if (humidity != lastHum)
#endif
{
lastHum = humidity;
changed = true;
Serial.print(F("H: "));
Serial.println(humidity);
if (!gw.send(msgHum.set(lastHum, 1)))
{
lastHum = -1.0;
}
}
}
else
{
Serial.println(F("Failed reading humidity from DHT"));
}
return changed;
}
void loop()
{
// get the battery Voltage
int sensorValue = analogRead(BATTERY_SENSE_PIN);
#ifdef DEBUG
Serial.println(sensorValue);
#endif
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075
float batteryV = sensorValue * 0.003363075;
int batteryPcnt = sensorValue / 10;
#ifdef DEBUG
Serial.print("Battery Voltage: ");
Serial.print(batteryV);
Serial.println(" V");
Serial.print("Battery percent: ");
Serial.print(batteryPcnt);
Serial.println(" %");
#endif
if (oldBatteryPcnt != batteryPcnt) {
// Power up radio after sleep
gw.sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;
}
updatePressureSensor();
gw.sleep(SLEEP_TIME1);
updateHumiditySensor();
gw.sleep(SLEEP_TIME2);
gw.sleep(SLEEP_TIME3);
}
float getLastPressureSamplesAverage()
{
float lastPressureSamplesAverage = 0;
for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
{
lastPressureSamplesAverage += lastPressureSamples[i];
}
lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
//Serial.print(F("### 5min-Average:"));
//Serial.print(lastPressureSamplesAverage);
//Serial.println(F(" hPa"));
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;
}
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(weatherStrings[forecast]);
return forecast;
}```
Which size resitor did you use? And which pin did you connect with the bottum? Gnd and a3.
Great job do on the project.
@Heinz Thank you.
I have made this sketch without errors.
// DHT-Sensor
// BMP085 Sensor
#include <SPI.h>
#include <MySensor.h>
#include <Wire.h>
#include <Adafruit_BMP085_U.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
const bool sendAlways = true;
const float SEALEVEL = 688; // Westendorf
const float SEALEVEL_PRESSURE = 1013.25;
// ----------------------------------------------------------------------------
#define CHILD_ID_HUM 2
#define CHILD_ID_TEMP 3
#define HUMIDITY_SENSOR_DIGITAL_PIN 3
#define CHILD_ID_LIGHT 1
#define LIGHT_SENSOR_ANALOG_PIN 1
DHT dht;
float lastTemp;
float lastHum;
boolean metric = true;
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
// ----------------------------------------------------------------------------
#define BARO_CHILD 0
#define TEMP_CHILD 1
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
unsigned long SLEEP_TIME1 = 30000; // 1 minute required for forecast algorithm
unsigned long SLEEP_TIME2 = 30000; // 1 minute required for forecast algorithm
unsigned long SLEEP_TIME3 = 900000; // sleep time between reads (seconds * 1000 milliseconds)
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(1); // Digital Pressure Sensor
MySensor gw;
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
int lastLightLevel;
int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
int oldBatteryPcnt = 0;
/*
DP/Dt explanation
0 = "Stable Weather Pattern"
1 = "Slowly rising Good Weather", "Clear/Sunny "
2 = "Slowly falling L-Pressure ", "Cloudy/Rain "
3 = "Quickly rising H-Press", "Not Stable"
4 = "Quickly falling L-Press", "Thunderstorm"
5 = "Unknown (More Time needed)
*/
const char *weatherStrings[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
enum FORECAST
{
STABLE = 0, // Stable weather
SUNNY = 1, // Slowly rising HP stable good weather
CLOUDY = 2, // Slowly falling Low Pressure System, stable rainy weather
UNSTABLE = 3, // Quickly rising HP, not stable weather
THUNDERSTORM = 4, // Quickly falling LP, Thunderstorm, not stable
UNKNOWN = 5 // Unknown, more time needed
};
const char *situationStrings[] = { "very low", "low", "normal", "high", "very high" };
enum WEATHER_SITUATION
{
VERY_LOW_PRESSURE = 0, // Tiefdruck p>-7.5hPa
LOW_PRESSURE = 1, // Tiefdruck p>-2.5hPa
NORMAL_PRESSURE = 2, // Normal p <+/-02.5hPa
HIGH_PRESSURE = 3, // Hochdruck p>2.5hPa
VERY_HIGH_PRESSURE = 4, // Hochdruck p>7.5hPa
};
float lastPressure = -1;
float lastPressureTemp = -1;
int lastForecast = -1;
int lastSituation = NORMAL_PRESSURE;
const int LAST_SAMPLES_COUNT = 5;
float lastPressureSamples[LAST_SAMPLES_COUNT];
// 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 tempMsg(TEMP_CHILD, V_TEMP);
MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
MyMessage situationMsg(BARO_CHILD, V_VAR1);
MyMessage forecastMsg2(BARO_CHILD, V_VAR2);
void displaySensorDetails(void)
{
sensor_t sensor;
bmp.getSensor(&sensor);
Serial.println(F("------------------------------------"));
Serial.print(F("Sensor: ")); Serial.println(sensor.name);
Serial.print(F("Driver Ver: ")); Serial.println(sensor.version);
Serial.print(F("Unique ID: ")); Serial.println(sensor.sensor_id);
Serial.print(F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F(" hPa"));
Serial.print(F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F(" hPa"));
Serial.print(F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F(" hPa"));
Serial.println(F("------------------------------------"));
Serial.println(F(""));
delay(500);
}
void initPressureSensor()
{
if (!bmp.begin())
{
Serial.println(F("Could not find a valid BMP085 sensor, check wiring!"));
while (1) {}
}
displaySensorDetails();
}
void initHumiditySensor()
{
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
}
void setup()
{
// use the 1.1 V internal reference
#if defined(__AVR_ATmega2560__)
analogReference(INTERNAL1V1);
#else
analogReference(INTERNAL);
#endif
gw.begin();
gw.sendSketchInfo("Weather Station Sensor", "2.1");
initPressureSensor();
initHumiditySensor();
gw.present(BARO_CHILD, S_BARO);
gw.present(TEMP_CHILD, S_TEMP);
gw.present(CHILD_ID_HUM, S_HUM);
gw.present(CHILD_ID_TEMP, S_TEMP);
gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
metric = gw.getConfig().isMetric;
int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
Serial.println(lightLevel);
if (lightLevel != lastLightLevel) {
gw.send(msg.set(lightLevel));
lastLightLevel = lightLevel;
}
gw.sleep(SLEEP_TIME);
}
int getWeatherSituation(float pressure)
{
int situation = NORMAL_PRESSURE;
float delta = pressure - SEALEVEL_PRESSURE;
if (delta > 7.5)
{
situation = VERY_HIGH_PRESSURE;
}
else if (delta > 2.5)
{
situation = HIGH_PRESSURE;
}
else if (delta < -7.5)
{
situation = VERY_LOW_PRESSURE;
}
else if (delta < -2.5)
{
situation = LOW_PRESSURE;
}
else
{
situation = NORMAL_PRESSURE;
}
return situation;
}
bool updatePressureSensor()
{
bool changed = false;
sensors_event_t event;
bmp.getEvent(&event);
if (event.pressure)
{
float absolutePressure = event.pressure;
Serial.print(F("abs Pressure = "));
Serial.print(absolutePressure);
Serial.println(F(" hPa"));
//float altitude = bmp.pressureToAltitude(SEALEVEL_PRESSURE, pressure);
//Serial.print(F("Altitude = "));
//Serial.print(altitude);
//Serial.println(F(" m"));
//sealevel pressure p0 from absolute pressure.
float pressure = bmp.seaLevelForAltitude(SEALEVEL, absolutePressure);
float pressureTemperature;
bmp.getTemperature(&pressureTemperature);
if (!metric)
{
// Convert to fahrenheit
pressureTemperature = pressureTemperature * 9.0 / 5.0 + 32.0;
}
int forecast = sample(pressure);
int situation = getWeatherSituation(pressure);
if (sendAlways || (pressureTemperature != lastPressureTemp))
{
changed = true;
lastPressureTemp = pressureTemperature;
Serial.print(F("Temperature = "));
Serial.print(pressureTemperature);
Serial.println(metric ? F(" *C") : F(" *F"));
if (!gw.send(tempMsg.set(lastPressureTemp, 1)))
{
lastPressureTemp = -1.0;
}
}
if (sendAlways || (pressure != lastPressure))
{
changed = true;
lastPressure = pressure;
Serial.print(F("sealevel Pressure = "));
Serial.print(pressure);
Serial.println(F(" hPa"));
if (!gw.send(pressureMsg.set(lastPressure, 1)))
{
lastPressure = -1.0;
}
}
if (sendAlways || (forecast != lastForecast))
{
changed = true;
lastForecast = forecast;
Serial.print(F("Forecast = "));
Serial.println(weatherStrings[forecast]);
if (gw.send(forecastMsg.set(weatherStrings[lastForecast])))
{
if (!gw.send(forecastMsg2.set(lastForecast)))
{
}
}
else
{
lastForecast = -1.0;
}
}
if (sendAlways || (situation != lastSituation))
{
changed = true;
lastSituation = situation;
Serial.print(F("Situation = "));
Serial.println(situationStrings[situation]);
if (!gw.send(situationMsg.set(lastSituation, 0)))
{
lastSituation = -1.0;
}
}
}
return changed;
}
bool updateHumiditySensor()
{
bool changed = false;
float temperature = dht.getTemperature();
float humidity = dht.getHumidity();
if (!isnan(temperature))
{
#ifdef SEND_WHEN_CHANGED
if (temperature != lastTemp)
#endif
{
lastTemp = temperature;
if (!metric)
{
temperature = dht.toFahrenheit(temperature);
}
changed = true;
Serial.print(F("T: "));
Serial.println(temperature);
if (!gw.send(msgTemp.set(temperature, 1)))
{
lastTemp = -1.0;
}
}
}
else
{
Serial.println(F("Failed reading temperature from DHT"));
}
if (!isnan(humidity))
{
#ifdef SEND_WHEN_CHANGED
if (humidity != lastHum)
#endif
{
lastHum = humidity;
changed = true;
Serial.print(F("H: "));
Serial.println(humidity);
if (!gw.send(msgHum.set(lastHum, 1)))
{
lastHum = -1.0;
}
}
}
else
{
Serial.println(F("Failed reading humidity from DHT"));
}
return changed;
}
void loop()
{
// get the battery Voltage
int sensorValue = analogRead(BATTERY_SENSE_PIN);
#ifdef DEBUG
Serial.println(sensorValue);
#endif
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075
float batteryV = sensorValue * 0.003363075;
int batteryPcnt = sensorValue / 10;
#ifdef DEBUG
Serial.print("Battery Voltage: ");
Serial.print(batteryV);
Serial.println(" V");
Serial.print("Battery percent: ");
Serial.print(batteryPcnt);
Serial.println(" %");
#endif
if (oldBatteryPcnt != batteryPcnt) {
// Power up radio after sleep
gw.sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;
}
updatePressureSensor();
gw.sleep(SLEEP_TIME1);
updateHumiditySensor();
gw.sleep(SLEEP_TIME2);
gw.sleep(SLEEP_TIME3);
}
float getLastPressureSamplesAverage()
{
float lastPressureSamplesAverage = 0;
for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
{
lastPressureSamplesAverage += lastPressureSamples[i];
}
lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
//Serial.print(F("### 5min-Average:"));
//Serial.print(lastPressureSamplesAverage);
//Serial.println(F(" hPa"));
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;
}
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(weatherStrings[forecast]);
return forecast;
}```
Hi
Im trying to make an node with BMP085, DHT22 and LM393. Barometer, Temp/hum and light.
Can anyone help me to make the sketch work?
Do the barometer have to be connected to A4 and A5?
//Vejrstation - Temp, Fugt, Lux, Baro - V 1.0
#include <SPI.h>
#include <MySensor.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#define CHILD_ID_HUM 0
#define CHILD_ID_TEMP 1
#define HUMIDITY_SENSOR_DIGITAL_PIN 3
#define CHILD_ID_LIGHT 2
#define LIGHT_SENSOR_ANALOG_PIN 1
#define BARO_CHILD 2
#define TEMP_CHILD 3
//Temp
MySensor gw;
DHT dht;
float lastTemp;
float lastHum;
boolean metric = true;
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
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);
unsigned long SLEEP_TIME = 900000; // sleep time between reads (seconds * 1000 milliseconds)
int oldBatteryPcnt = 0;
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
int lastLightLevel;
//Batteri
int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
//Baro
const float ALTITUDE = 34.691; // <-- adapt this value to your own location's altitude.
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
void setup()
{
// use the 1.1 V internal reference
#if defined(__AVR_ATmega2560__)
analogReference(INTERNAL1V1);
#else
analogReference(INTERNAL);
#endif
gw.begin(incomingMessage, 9, true));
// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("Weather Station", "1.0");
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
// Register all sensors to gw (they will be created as child devices)
gw.present(CHILD_ID_HUM, S_HUM);
gw.present(CHILD_ID_TEMP, S_TEMP);
gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
gw.present(BARO_CHILD, S_BARO);
gw.present(TEMP_CHILD, S_TEMP);
metric = gw.getConfig().isMetric;
}
void loop()
{
// get the battery Voltage
int sensorValue = analogRead(BATTERY_SENSE_PIN);
#ifdef DEBUG
Serial.println(sensorValue);
#endif
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075
float batteryV = sensorValue * 0.003363075;
int batteryPcnt = sensorValue / 10;
#ifdef DEBUG
Serial.print("Battery Voltage: ");
Serial.print(batteryV);
Serial.println(" V");
Serial.print("Battery percent: ");
Serial.print(batteryPcnt);
Serial.println(" %");
#endif
if (oldBatteryPcnt != batteryPcnt) {
// Power up radio after sleep
gw.sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;
}
gw.sleep(SLEEP_TIME);
delay(dht.getMinimumSamplingPeriod());
float temperature = dht.getTemperature();
if (isnan(temperature)) {
Serial.println("Failed reading temperature from DHT");
} else if (temperature != lastTemp) {
lastTemp = temperature;
if (!metric) {
temperature = dht.toFahrenheit(temperature);
}
gw.send(msgTemp.set(temperature, 1));
Serial.print("T: ");
Serial.println(temperature);
}
float humidity = dht.getHumidity();
if (isnan(humidity)) {
Serial.println("Failed reading humidity from DHT");
} else if (humidity != lastHum) {
lastHum = humidity;
gw.send(msgHum.set(humidity, 1));
Serial.print("H: ");
Serial.println(humidity);
}
gw.sleep(SLEEP_TIME); //sleep a bit
int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
Serial.println(lightLevel);
if (lightLevel != lastLightLevel) {
gw.send(msg.set(lightLevel));
lastLightLevel = lightLevel;
}
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;
}
I get this error:
Arduino: 1.6.5 (Mac OS X), Board: "Arduino Pro or Pro Mini, ATmega328 (3.3V, 8 MHz)"
Vejrstation_v1.2:31: error: redefinition of 'float lastTemp'
Vejrstation_v1.2:24: error: 'float lastTemp' previously declared here
Vejrstation_v1.2:49: error: redefinition of 'boolean metric'
Vejrstation_v1.2:26: error: 'boolean metric' previously defined here
Vejrstation_v1.2.ino: In function 'void setup()':
Vejrstation_v1.2:89: error: 'incomingMessage' was not declared in this scope
Vejrstation_v1.2:89: error: expected ';' before ')' token
Vejrstation_v1.2.ino: In function 'void loop()':
Vejrstation_v1.2:175: error: redeclaration of 'float temperature'
Vejrstation_v1.2:142: error: 'float temperature' previously declared here
redefinition of 'float lastTemp'
This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
@sundberg84 When you desolder are you then removing the komponent? Both led?
Hi
Where to cut in this model pro mine to optimize battery power?
im trying to compare from this link http://www.mysensors.org/build/battery
But they are not the same.
/Nikolaj
I have solved the problem. I changes power supply and now it works.
Can someone recommend some power supply?
How do i change the node number?
It select node 2 all the time with new nodes?
In the sketch they are set to AUTO.
Im using standard sketch from the libery.
The sketch to the relay
/**
* 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
*
* DESCRIPTION
* Example sketch for a "light switch" where you can control light or something
* else from both HA controller and a local physical button
* (connected between digital pin 3 and GND).
* This node also works as a repeader for other nodes
* http://www.mysensors.org/build/relay
*/
#include <MySensor.h>
#include <SPI.h>
#include <Bounce2.h>
#define RELAY_PIN 4 // Arduino Digital I/O pin number for relay
#define BUTTON_PIN 3 // Arduino Digital I/O pin number for button
#define CHILD_ID 1 // Id of the sensor child
#define RELAY_ON 0
#define RELAY_OFF 1
Bounce debouncer = Bounce();
int oldValue=0;
bool state;
MySensor gw;
MyMessage msg(CHILD_ID,V_LIGHT);
void setup()
{
gw.begin(incomingMessage, AUTO, true);
// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("RELAY_BUTTON_JUL", "1.0");
// 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 all sensors to gw (they will be created as child devices)
gw.present(CHILD_ID, S_LIGHT);
// Make sure relays are off when starting up
digitalWrite(RELAY_PIN, RELAY_OFF);
// Then set relay pins in output mode
pinMode(RELAY_PIN, OUTPUT);
// Set relay to last known state (using eeprom storage)
state = gw.loadState(CHILD_ID);
digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
}
/*
* Example on how to asynchronously check for new messages from gw
*/
void loop()
{
gw.process();
debouncer.update();
// Get the update value
int value = debouncer.read();
if (value != oldValue && value==0) {
gw.send(msg.set(state?false:true), true); // Send new state and request ack back
}
oldValue = value;
}
void incomingMessage(const MyMessage &message) {
// We only expect one type of message from controller. But we better check anyway.
if (message.isAck()) {
Serial.println("This is an ack from gateway");
}
if (message.type == V_LIGHT) {
// Change relay state
state = message.getBool();
digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
// Store state in eeprom
gw.saveState(CHILD_ID, state);
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.sensor);
Serial.print(", New status: ");
Serial.println(message.getBool());
}
}
Log from gateway:
1;255;3;0;11;RELAY_BUTTON_JUL
0;0;3;0;9;read: 1-1-0 s=255,c=3,t=12,pt=0,l=3,sg=0:1.0
1;255;3;0;12;1.0
0;0;3;0;9;read: 1-1-0 s=1,c=0,t=3,pt=0,l=0,sg=0:
1;1;0;0;3;
0;0;3;0;9;send: 0-0-1-1 s=1,c=1,t=2,pt=0,l=1,sg=0,st=fail:1
0;0;3;0;9;read: 4-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0:17.9
4;1;1;0;0;17.9
0;0;3;0;9;read: 4-4-0 s=0,c=1,t=1,pt=7,l=5,sg=0:44.4
4;0;1;0;1;44.4
Without relay:
0;0;3;0;9;send: 0-0-1-1 s=1,c=1,t=2,pt=0,l=1,sg=0,st=ok:1
0;0;3;0;9;read: 1-1-0 s=1,c=1,t=2,pt=0,l=1,sg=0:1
1;1;1;1;2;1
But in domoticz it still gives me hardware error.
Gateway version 1.5.