...
 
Commits (16)
image: python:2.7
image: python:3
stages:
- test
......
## v1.0.3 - 2018-06-04
- Added fix for unplausible values read from the DHT sensor
- Added possibility to change host and port of the control app via env vars
- Only include dht.h if a DHT sensor is used
## v1.0.2 - 2018-05-30
- First public release
## v2.3.0 - 2020-05-16
- Added config option to disable battery readings
## v2.2.0 - 2020-05-13
- Added temperature-dependent switch to control a fan or heating
## v2.1.1 - 2020-04-23
- Fixed bug with *delay after send*
## v2.1.0 - 2020-04-22
- Polled data will always be send to the address of the polling node
- Made *server address*, *own address* and *delay after send* configurable at runtime
## v2.0.0 - 2020-04-13
- Added support for DS18B20, DS18S20, DS1820, DS1822 temperature sensors
- Added polling mode
- Changed some RadioHead messages
- Updated control app to support old and new version of the automatic watering system
## v1.0.3 - 2018-06-04
- Added fix for unplausible values read from the DHT sensor
- Added possibility to change host and port of the control app via env vars
- Only include dht.h if a DHT sensor is used
## v1.0.2 - 2018-05-30
- First public release
File mode changed from 100755 to 100644
......@@ -7,7 +7,7 @@ It also measures the air temperature and humidity and sends them via 433 MHz rad
Using the 433 MHz radio messages you are able to control and configure the watering system. For this the [RadioHead](http://www.airspayce.com/mikem/arduino/RadioHead/) library is used.
A full description of the *Automatic Watering System* is available at https://crycode.de/diy-automatisches-bewaesserungssystem (in german only).
A full description of the *Automatic Watering System* is available at https://crycode.de/diy-automatisches-bewaesserungssystem (in German only).
## Software
......@@ -18,6 +18,7 @@ PlatformIO takes care of all dependencies automatically and you don't need to in
Alternatively you may use ArduinoIDE for flashing the microcontroller.
Then you have to install the following librarys by hand:
* [RadioHead v1.82](https://platformio.org/lib/show/124/RadioHead/installation)
* [DallasTemperature v3.8.1](https://platformio.org/lib/show/54/DallasTemperature/installation)
* [DHTStable v0.2.4](https://platformio.org/lib/show/1337/DHTStable/installation)
* [PinChangeInterrupt v1.2.6](https://platformio.org/lib/show/725/PinChangeInterrupt/installation)
......@@ -32,4 +33,4 @@ All needed information are there in the [readme](control/README.md).
Licensed under GPL Version 2
Copyright (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de/)
Copyright (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de/)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Automatic Watering System Control App
* Automatic Watering System - Control-App
*
* Frontend styles
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*/
* {
font-family: Arial;
}
#fetchError {
background-color: #FDD;
border: 1px dotted #f00;
background: #fcc;
color: #A00;
font-weight: bold;
padding: 20px;
......@@ -43,6 +48,10 @@
width: 80px;
}
.cell button.wide {
width: auto;
}
#port {
width: 150px;
}
......@@ -66,3 +75,51 @@ input:focus, select:focus, button:focus {
color: #0A0;
font-weight: bold;
}
#versionOutdatedInfo {
display: none;
border: 1px dotted #f00;
background: #fcc;
}
h1 {
font-size: 1.2em;
font-weight: bold;
}
[data-info] {
color: #009;
cursor: pointer;
font-weight: bold;
user-select: none;
float: right;
display: inline-block;
width: 20px;
margin: 0 3px;
text-align: center;
border-radius: 8px;
background: #ddd;
}
[data-info]:hover {
background: #eee;
color: #00a;
}
.description {
padding: 10px;
left: 50px;
min-width: 50%;
display: none;
position: absolute;
background: #eeeeeef0;
box-shadow: 5px 5px #aaaaaa55;
border: 1px dotted #aaa;
}
code {
font-family: monospace;
font-size: 1.2em;
font-weight: bold;
}
This diff is collapsed.
This diff is collapsed.
{
"name": "auto-watering-control",
"version": "1.0.3",
"version": "2.3.0",
"description": "Control tool for the automatic watering system",
"main": "index.js",
"scripts": {
......@@ -21,7 +21,8 @@
"body-parser": "^1.19.0",
"express": "^4.17.1",
"radiohead-serial": "^4.1.1",
"serialport": "^7.1.5"
"semver": "^7.2.2",
"serialport": "^8.0.7"
},
"private": true
}
......@@ -13,17 +13,8 @@ platform = atmelavr
board = pro16MHzatmega328
framework = arduino
lib_deps =
DallasTemperature@3.8.1
DHTStable@0.2.4
PinChangeInterrupt@1.2.6
RadioHead@1.82
RadioHead@1.89
SPI
#[env:nanoatmega328]
#platform = atmelavr
#board = nanoatmega328
#framework = arduino
#lib_deps =
# DHTStable@0.2.4
# PinChangeInterrupt@1.2.6
# RadioHead@1.82
# SPI
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*
* Functions to do some actions.
*/
......@@ -54,8 +54,7 @@ bool turnValveOn (uint8_t chan) {
channelOn[chan] = true;
// send RadioHead message
rhBufTx[1] = chan;
rhSend(RH_MSG_CHANNEL_ON, 2);
rhSendData(RH_MSG_CHANNEL_STATE);
return true;
}
......@@ -71,6 +70,5 @@ void turnValveOff (uint8_t chan) {
channelOn[chan] = false;
// send RadioHead message
rhBufTx[1] = chan;
rhSend(RH_MSG_CHANNEL_OFF, 2);
rhSendData(RH_MSG_CHANNEL_STATE);
}
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*/
#ifndef __MAIN_H__
#define __MAIN_H__
......@@ -12,11 +12,11 @@
#define BLINK_SHORT 100
#define BLINK_VERRY_SHORT 50
#define BLINK_CODE_RH_INIT_ERROR BLINK_LONG, BLINK_SHORT, BLINK_SHORT
#define BLINK_CODE_RH_SEND_ERROR BLINK_LONG, BLINK_SHORT, BLINK_LONG
#define BLINK_CODE_DHT_ERROR BLINK_LONG, BLINK_LONG, BLINK_SHORT
#define BLINK_CODE_RH_INIT_ERROR BLINK_LONG, BLINK_SHORT, BLINK_SHORT
#define BLINK_CODE_RH_SEND_ERROR BLINK_LONG, BLINK_SHORT, BLINK_LONG
#define BLINK_CODE_TEMP_SENSOR_ERROR BLINK_LONG, BLINK_LONG, BLINK_SHORT
#define BLINK_CODE_RH_RECV BLINK_VERRY_SHORT, BLINK_VERRY_SHORT
#define BLINK_CODE_RH_RECV BLINK_VERRY_SHORT, BLINK_VERRY_SHORT
void blinkCode (uint16_t t1, uint16_t t2 = 0, uint16_t t3 = 0);
bool turnValveOn (uint8_t chan);
......
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*
* Config containing all options which can be changed before compile.
*/
......@@ -23,12 +23,14 @@
#define VALVE_2_BUTTON_PIN 8
#define VALVE_3_BUTTON_PIN 9
#define SENSORS_ACTIVE_PIN 10
#define RH_TX_PIN 11
#define RH_RX_PIN 12
#define RH_PTT_PIN 17 // unused but needed
#define LED_PIN 13
#define DHT_PIN 14
#define TEMP_SENSOR_PIN 14
#define EEPROM_RESET_PIN 15
#define TEMP_SWITCH_PIN 17
#define RH_TX_PIN 11
#define RH_RX_PIN 12
#define RH_PTT_PIN EEPROM_RESET_PIN // unused but needed ... set to EEPROM_RESET_PIN because this is only used at early startup -> no conflicts :-)
/*
* Analog pins
......@@ -40,20 +42,31 @@
#define BATTERY_ADC A2
/*
* DHT temperature and humidity sensor
* Temperature (and humidity) sensor
*/
// Type of the used Sensor, 11 for DHT11, 12 for DHT12, 22 for DHT22, 0 for no Sensor
#define DHT_TYPE 22
// Type of the used Sensor
// 11 for DHT11
// 12 for DHT12
// 22 for DHT22
// 1820 for DS18B20, DS18S20, DS1820, DS1822
// 0 for no Sensor
#define TEMP_SENSOR_TYPE 1820
// resolution for the DS18x20 temperature sendor, if used
// higher resolutions leads to longer conversion time
// 9 to 12
#define DS1820_RESOLUTION 11
/*
* RadioHead
*/
// the own RadioHead address
// The default own RadioHead address. Can be overwritten by settings.
#define RH_OWN_ADDR 0xDC // 220
// the server RadioHead address
// The default server RadioHead address. Can be overwritten by settings.
#define RH_SERVER_ADDR 0x01
// RadioHead bitrate in bit/s
#define RH_SPEED 2000
......@@ -64,9 +77,13 @@
#define RH_SEND_TIMEOUT 200
/*
* Battery adc values
* Battery
*/
#define BAT_ADC_LOW 511 // 2,5V
#define BAT_ADC_FULL 859 // 4,2V
// Enable battery readings (1 enabled, 0 disabled)
#define BAT_ENABLED 1
// Battery adc values
#define BAT_ADC_LOW 593 // 2.9V # 1023 * 2.9V / 5V
#define BAT_ADC_FULL 859 // 4.2V # 1023 * 4.2V / 5V
#endif
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*
* Global definition of some variables/constants.
*/
......@@ -11,15 +11,30 @@
// global variables
Settings settings;
volatile bool channelTurnOn[4]; // volatile to use this inside a ISR
volatile unsigned long channelTurnOffTime[4];
unsigned long adcNextReadTime;
unsigned long dhtNextReadTime;
unsigned long tempSensorNextReadTime;
volatile bool channelOn[4];
uint16_t adcValues[4] = {0, 0, 0, 0};
float temperature = -99;
float humidity = -99;
#if BAT_ENABLED == 1
uint16_t batteryRaw;
#endif
bool tempSwitchOn = false;
float tempSwitchTriggerValueHigh = 32;
float tempSwitchTriggerValueLow = 28;
bool pauseAutomatic;
#if DHT_TYPE != 0
#if TEMP_SENSOR_TYPE == 11 || TEMP_SENSOR_TYPE == 12 || TEMP_SENSOR_TYPE == 22
dht dhtSensor;
#elif TEMP_SENSOR_TYPE == 1820
OneWire oneWire(TEMP_SENSOR_PIN);
DallasTemperature ds1820(&oneWire);
#endif
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*/
#ifndef __GLOBALS_H__
#define __GLOBALS_H__
......@@ -10,18 +10,21 @@
#include <Arduino.h>
#include <SPI.h>
#if DHT_TYPE != 0
#if TEMP_SENSOR_TYPE == 11 || TEMP_SENSOR_TYPE == 12 || TEMP_SENSOR_TYPE == 22
#include <dht.h>
#elif TEMP_SENSOR_TYPE == 1820
#include <OneWire.h>
#include <DallasTemperature.h>
#endif
#include <PinChangeInterrupt.h>
// version number of the software
#define SOFTWARE_VERSION_MAJOR 1
#define SOFTWARE_VERSION_MINOR 0
#define SOFTWARE_VERSION_PATCH 3
#define SOFTWARE_VERSION_MAJOR 2
#define SOFTWARE_VERSION_MINOR 3
#define SOFTWARE_VERSION_PATCH 0
// version of the eeporm data model; must be increased if the data model changes
#define EEPROM_VERSION 1
#define EEPROM_VERSION 5
// eeprom addresses
#define EEPROM_ADDR_VERSION 0 // 1 byte
......@@ -39,8 +42,15 @@ struct Settings {
uint16_t adcTriggerValue[4]; // minimum adc value which will trigger the watering
uint16_t wateringTime[4]; // watering time in seconds
uint16_t checkInterval; // adc check interval in seconds
uint16_t dhtInterval; // dht sensor read interval in seconds
uint16_t tempSensorInterval; // temperature sensor read interval in seconds
bool sendAdcValuesThroughRH; // send all adc values through RadioHead or not
bool pushDataEnabled; // if data will be actively pushed by the system over RadioHead
uint8_t serverAddress; // the address of the server in the RadioHead network
uint8_t ownAddress; // the address of this node in the RadioHead network
uint16_t delayAfterSend; // time in milliseconds to delay after each data send
int8_t tempSwitchTriggerValue; // value where to trigger the temperature switch
uint8_t tempSwitchHystTenth; // hysteresis of the temperature switch in tenth of the value (10 = 0,1)
bool tempSwitchInverted; // if the switch will be inverted (default temp>value = on)
};
/**
......@@ -53,17 +63,31 @@ struct Settings {
// global variables
extern Settings settings;
extern volatile bool channelTurnOn[4]; // volatile to use this inside a ISR
extern volatile unsigned long channelTurnOffTime[4];
extern unsigned long adcNextReadTime;
extern unsigned long dhtNextReadTime;
extern unsigned long tempSensorNextReadTime;
extern volatile bool channelOn[4];
extern uint16_t adcValues[4];
extern float temperature;
extern float humidity;
#if BAT_ENABLED == 1
extern uint16_t batteryRaw;
#endif
extern bool tempSwitchOn;
extern float tempSwitchTriggerValueHigh;
extern float tempSwitchTriggerValueLow;
extern bool pauseAutomatic;
#if DHT_TYPE != 0
#if TEMP_SENSOR_TYPE == 11 || TEMP_SENSOR_TYPE == 12 || TEMP_SENSOR_TYPE == 22
extern dht dhtSensor;
#elif TEMP_SENSOR_TYPE == 1820
extern DallasTemperature ds1820;
#endif
#endif
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*
* The Arduino loop function which is called in a infinite loop.
*/
......@@ -17,38 +17,81 @@ bool adcOn = false;
void loop () {
unsigned long now = millis();
// DHT code only if DHT_TYPE is not zero
#if DHT_TYPE != 0
// check if we need to read from the dht sensor
if (checkTime(now, dhtNextReadTime)) {
// temperature sensor code only if TEMP_SENSOR_TYPE is not 0
#if TEMP_SENSOR_TYPE != 0
// check if we need to read from the temperature sensor
if (checkTime(now, tempSensorNextReadTime)) {
// read from the sensor using the correct method for the sensor type
#if DHT_TYPE == 11
int dhtResult = dhtSensor.read11(DHT_PIN);
#elif DHT_TYPE == 12
int dhtResult = dhtSensor.read12(DHT_PIN);
#elif DHT_TYPE == 22
int dhtResult = dhtSensor.read22(DHT_PIN);
bool sensorReadOk = false;
#if TEMP_SENSOR_TYPE == 11 || TEMP_SENSOR_TYPE == 12 || TEMP_SENSOR_TYPE == 22
// DHT sensor
#if TEMP_SENSOR_TYPE == 11
int dhtResult = dhtSensor.read11(TEMP_SENSOR_PIN);
#elif TEMP_SENSOR_TYPE == 12
int dhtResult = dhtSensor.read12(TEMP_SENSOR_PIN);
#elif TEMP_SENSOR_TYPE == 22
int dhtResult = dhtSensor.read22(TEMP_SENSOR_PIN);
#endif
// check the result and also if the values are plausible
if (dhtResult == DHTLIB_OK
&& dhtSensor.humidity >= 0 && dhtSensor.humidity <= 100
&& dhtSensor.temperature >= -50 && dhtSensor.temperature <= 100) {
// sensor read ok
temperature = dhtSensor.temperature;
humidity = dhtSensor.humidity;
sensorReadOk = true;
} else {
temperature = -99;
humidity = -99;
}
#elif TEMP_SENSOR_TYPE == 1820
// DS18x20 sensor
ds1820.requestTemperatures();
temperature = ds1820.getTempCByIndex(0);
if (temperature != DEVICE_DISCONNECTED_C) {
sensorReadOk = true;
} else {
temperature = -99;
}
#else
#error DHT_TYPE must be 11, 12, 22 or 0!
#error TEMP_SENSOR_TYPE must be 11, 12, 22, 1820 or 0!
#endif
// check the result and also if the values are plausible
if (dhtResult == DHTLIB_OK
&& dhtSensor.humidity >= 0 && dhtSensor.humidity <= 100
&& dhtSensor.temperature >= -50 && dhtSensor.temperature <= 100) {
// sensor read ok
// send RadioHead message
memcpy(&rhBufTx[1], &dhtSensor.temperature, 4);
memcpy(&rhBufTx[5], &dhtSensor.humidity, 4);
rhSend(RH_MSG_DHTDATA, 9);
if (sensorReadOk) {
// check temperature switch
if (tempSwitchTriggerValueLow != 0.0 && tempSwitchTriggerValueHigh != 0.0) {
// automatic switching enabled
if (!tempSwitchOn && (
(temperature >= tempSwitchTriggerValueHigh && !settings.tempSwitchInverted)
|| (temperature <= tempSwitchTriggerValueLow && settings.tempSwitchInverted)
)) {
// turn on the temperature switch
digitalWrite(TEMP_SWITCH_PIN, HIGH);
tempSwitchOn = true;
} else if (tempSwitchOn && (
(temperature <= tempSwitchTriggerValueLow && !settings.tempSwitchInverted)
|| (temperature >= tempSwitchTriggerValueHigh && settings.tempSwitchInverted)
)) {
// turn off the temperature switch
digitalWrite(TEMP_SWITCH_PIN, LOW);
tempSwitchOn = false;
}
}
// send data
rhSendData(RH_MSG_TEMP_SENSOR_DATA);
} else {
// sensor read error
blinkCode(BLINK_CODE_DHT_ERROR);
blinkCode(BLINK_CODE_TEMP_SENSOR_ERROR);
}
// calc next dht read time
dhtNextReadTime = now + ((uint32_t)settings.dhtInterval * 1000);
tempSensorNextReadTime = now + ((uint32_t)settings.tempSensorInterval * 1000);
}
#endif
......@@ -73,47 +116,26 @@ void loop () {
for (uint8_t chan = 0; chan < 4; chan++) {
if (settings.channelEnabled[chan]) {
// read the adc value of the channel
uint16_t adcVal = analogRead(sensorAdcPins[chan]);
adcValues[chan] = analogRead(sensorAdcPins[chan]);
// check trigger value
if (adcVal >= settings.adcTriggerValue[chan]) {
if (adcValues[chan] >= settings.adcTriggerValue[chan]) {
// set marker to turn the channel on
channelTurnOn[chan] = true;
}
// save for RadioHead
if (settings.sendAdcValuesThroughRH) {
memcpy(&rhBufTx[1+chan*2], &adcVal, 2);
}
} else if (settings.sendAdcValuesThroughRH) {
// if channel is disabled but sending adc values is enabled set the value in buffer to 0x0000
rhBufTx[1+chan*2] = 0x00;
rhBufTx[2+chan*2] = 0x00;
}
}
// send adc sensor values through RadioHead
if (settings.sendAdcValuesThroughRH) {
// send RadioHead message
rhSend(RH_MSG_SENSOR_VALUES, 9);
}
// send RadioHead message (send adc check is done later...)
rhSendData(RH_MSG_SENSOR_VALUES);
}
// disable the sensors
digitalWrite(SENSORS_ACTIVE_PIN, LOW);
// read battery voltage
uint16_t batRaw = analogRead(BATTERY_ADC);
uint8_t batPercent;
if (batRaw <= BAT_ADC_LOW) {
batPercent = 0;
} else if (batRaw >= BAT_ADC_FULL) {
batPercent = 100;
} else {
batPercent = 100 * (batRaw - BAT_ADC_LOW) / (BAT_ADC_FULL - BAT_ADC_LOW);
}
// send RadioHead message
rhBufTx[1] = batPercent;
memcpy(&rhBufTx[2], &batRaw, 2);
rhSend(RH_MSG_BATTERY, 4);
#if BAT_ENABLED == 1
batteryRaw = analogRead(BATTERY_ADC);
rhSendData(RH_MSG_BATTERY);
#endif
// disable the adc
ADCSRA &= ~(1<<ADEN);
......
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*/
#ifndef __LOOP_H__
#define __LOOP_H__
......
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*
* Handler functions for PCINTs triggered by pressed buttons.
*/
......
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*/
#ifndef __PCINT_H__
#define __PCINT_H__
......
This diff is collapsed.
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*/
#ifndef __RH_H__
#define __RH_H__
#include "globals.h"
#define RH_MSG_START 0x00
#define RH_MSG_BATTERY 0x02
#define RH_MSG_SENSOR_VALUES 0x10
#define RH_MSG_DHTDATA 0x20
#define RH_MSG_CHANNEL_ON 0x21
#define RH_MSG_CHANNEL_OFF 0x22
#define RH_MSG_START 0x00
#define RH_MSG_BATTERY 0x02
#define RH_MSG_SENSOR_VALUES 0x10
#define RH_MSG_TEMP_SENSOR_DATA 0x20
//#define RH_MSG_CHANNEL_ON 0x21 // < v2.0.0
//#define RH_MSG_CHANNEL_OFF 0x22 // < v2.0.0
#define RH_MSG_CHANNEL_STATE 0x25
#define RH_MSG_SETTINGS 0x50
#define RH_MSG_GET_SETTINGS 0x51
#define RH_MSG_SET_SETTINGS 0x52
#define RH_MSG_SAVE_SETTINGS 0x53
#define RH_MSG_SETTINGS 0x50
#define RH_MSG_GET_SETTINGS 0x51
#define RH_MSG_SET_SETTINGS 0x52
#define RH_MSG_SAVE_SETTINGS 0x53
#define RH_MSG_CHECK_NOW 0x60
#define RH_MSG_TURN_CHANNEL_ON 0x61
#define RH_MSG_TURN_CHANNEL_OFF 0x62
//#define RH_MSG_TURN_CHANNEL_ON 0x61 // < v2.0.0
//#define RH_MSG_TURN_CHANNEL_OFF 0x62 // < v2.0.0
#define RH_MSG_PAUSE 0x63
#define RH_MSG_RESUME 0x64
#define RH_MSG_TURN_CHANNEL_ON_OFF 0x65
#define RH_MSG_POLL_DATA 0x66
#define RH_MSG_PAUSE_ON_OFF 0x67
#define RH_MSG_TURN_TEMP_SWITCH_ON_OFF 0x68
#define RH_MSG_GET_VERSION 0xF0
#define RH_MSG_VERSION 0xF1
......@@ -33,16 +38,20 @@
// buffer for RadioHead messages
// rhBuf?x[0] - message type
#define RH_BUF_TX_LEN 22
#define RH_BUF_RX_LEN 22
#define RH_BUF_TX_LEN 28
#define RH_BUF_RX_LEN 28
extern uint8_t rhBufTx[RH_BUF_TX_LEN];
extern uint8_t rhBufRx[RH_BUF_RX_LEN];
// reduce the RadioHead max message length to save memory
#define RH_ASK_MAX_MESSAGE_LEN RH_BUF_LEN
#define RH_FORCE_SEND true
#define RH_SEND_ONLY_WHEN_PUSH_ENABLED false
void rhInit ();
void rhRecv ();
bool rhSend(uint8_t msgType, uint8_t len, uint8_t delayAfterSend = 10);
bool rhSend(uint8_t msgType, uint8_t len, uint8_t sendTo = settings.serverAddress, uint16_t delayAfterSend = settings.delayAfterSend);
bool rhSendData(uint8_t msgType, bool forceSend = RH_SEND_ONLY_WHEN_PUSH_ENABLED, uint8_t sendTo = settings.serverAddress, uint16_t delayAfterSend = settings.delayAfterSend);
#endif
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*
* Settings and setting-handlers for the options which can be changed at runtime.
*/
......@@ -21,8 +21,17 @@ void loadDefaultSettings () {
settings.wateringTime[chan] = 5; // opening time in seconds
}
settings.checkInterval = 300; // check interval - 5 minutes
settings.dhtInterval = 60; // dht sensor read interval - 1 minute
settings.tempSensorInterval = 60; // temperature sensor read interval - 1 minute
settings.sendAdcValuesThroughRH = true; // send all read adc values using through RadioHead
settings.pushDataEnabled = true; // push data actively via RadioHead
settings.serverAddress = RH_SERVER_ADDR; // RadioHead remote node address
settings.ownAddress = RH_OWN_ADDR; // RadioHead address of this node
settings.delayAfterSend = 10; // milliseconds to delay after each send
settings.tempSwitchTriggerValue = 30; // turn on temperature switch if > 30°C
settings.tempSwitchHystTenth = 20; // 2°C hysteresis -> 32°C on, 28°C off
settings.tempSwitchInverted = false; // don't invert - turn on if greater
calcTempSwitchTriggerValues();
}
/**
......@@ -30,6 +39,8 @@ void loadDefaultSettings () {
*/
void loadSettings () {
EEPROM.get(EEPROM_ADDR_SETTINGS, settings);
calcTempSwitchTriggerValues();
}
/**
......@@ -39,3 +50,11 @@ void saveSettings () {
// write to eeprom
EEPROM.put(EEPROM_ADDR_SETTINGS, settings);
}
/**
* Calculate temperature switch high/low trigger values.
*/
void calcTempSwitchTriggerValues () {
tempSwitchTriggerValueHigh = settings.tempSwitchTriggerValue + (float)settings.tempSwitchHystTenth/10;
tempSwitchTriggerValueLow = settings.tempSwitchTriggerValue - (float)settings.tempSwitchHystTenth/10;
}
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*/
#ifndef __SETTINGS_H__
#define __SETTINGS_H__
......@@ -11,5 +11,6 @@
void loadDefaultSettings ();
void loadSettings ();
void saveSettings ();
void calcTempSwitchTriggerValues();
#endif
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*
* The Arduino setup function which is called once on startup.
*/
......@@ -28,6 +28,7 @@ void setup () {
pinMode(SENSORS_ACTIVE_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(EEPROM_RESET_PIN, INPUT_PULLUP);
pinMode(TEMP_SWITCH_PIN, OUTPUT);
// blink the LED to indecate starting
blinkCode(BLINK_LONG);
......@@ -40,6 +41,7 @@ void setup () {
digitalWrite(valvePins[chan], LOW);
}
digitalWrite(SENSORS_ACTIVE_PIN, LOW);
digitalWrite(TEMP_SWITCH_PIN, LOW);
pauseAutomatic = false;
// enable PCINT for the buttons
......@@ -93,12 +95,21 @@ void setup () {
// init RadioHead
rhInit();
// init temperature sensor if necessary
#if TEMP_SENSOR_TYPE == 1820
#if DS1820_RESOLUTION != 9 && DS1820_RESOLUTION != 10 && DS1820_RESOLUTION != 11 && DS1820_RESOLUTION != 12
#error DS1820_RESOLUTION must be 9, 10, 11 or 12!
#endif
// calc adc and dht next read time, 5/10 seconds from now
// dht read is 5 seconds before adc read to avoid both readings at the same time
dhtNextReadTime = millis() + 5000;
ds1820.begin();
ds1820.setResolution(DS1820_RESOLUTION);
#endif
// calc adc and temperature sensor next read time, 5/10 seconds from now
// temperature sensor read is 5 seconds before adc read to avoid both readings at the same time
tempSensorNextReadTime = millis() + 5000;
adcNextReadTime = millis() + 10000;
// send RadioHead start message
rhSend(RH_MSG_START, 1);
rhSendData(RH_MSG_START);
}
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*/
#ifndef __SETUP_H__
#define __SETUP_H__
......
/*
* Automatic Watering System
*
* (c) 2018 Peter Müller <peter@crycode.de> (https://crycode.de)
* (c) 2018-2020 Peter Müller <peter@crycode.de> (https://crycode.de)
*
****************************************************************
* This file is for compatibility reasons with ArduinoIDE only. *
......@@ -11,7 +11,8 @@
*
* To use this code with the ArduinoIDE make sure you have installed the
* following libraries in your ArduinoIDE:
* - DallasTemperature@3.8.1 (https://platformio.org/lib/show/54/DallasTemperature/installation)
* - DHTStable@0.2.4 (https://platformio.org/lib/show/1337/DHTStable/installation)
* - PinChangeInterrupt@1.2.6 (https://platformio.org/lib/show/725/PinChangeInterrupt/installation)
* - RadioHead@1.82 (https://platformio.org/lib/show/124/RadioHead/installation)
* - RadioHead@1.89 (https://platformio.org/lib/show/124/RadioHead/installation)
*/