286 lines
9.6 KiB
C++
286 lines
9.6 KiB
C++
#include <ESP8266WiFi.h>
|
|
#include <time.h>
|
|
#include <Wire.h>
|
|
#include <Adafruit_Sensor.h>
|
|
#include <Adafruit_BME280.h>
|
|
#include "Config.h"
|
|
|
|
WiFiClient client;
|
|
|
|
/***************************************************************/
|
|
/* Eltako 20000082 WS */
|
|
/***************************************************************/
|
|
unsigned long next_timestamp = 0;
|
|
volatile unsigned long i = 0;
|
|
float wind = 0;
|
|
float last_wind = 0;
|
|
int count = 0;
|
|
volatile unsigned long last_micros;
|
|
long debouncing_time = 5; //in millis
|
|
int input_pin = 13;
|
|
char charBuffer[32];
|
|
|
|
//this part is needed by the anemometer sensor
|
|
void ICACHE_RAM_ATTR Interrupt()
|
|
{
|
|
if((long)(micros() - last_micros) >= debouncing_time * 1000) {
|
|
i++;
|
|
last_micros = micros();
|
|
}
|
|
}
|
|
|
|
// Current time
|
|
unsigned long currentTime = millis();
|
|
// Previous time
|
|
unsigned long previousTime = 0;
|
|
// Define timeout time in milliseconds (example: 2000ms = 2s)
|
|
const long timeoutTime = 2000;
|
|
|
|
/***************************************************************/
|
|
/* Batterylevel */
|
|
/***************************************************************/
|
|
unsigned int raw=0;
|
|
float calib_factor = 5.28; // change this value to calibrate the battery voltage
|
|
float volt=0.0;
|
|
|
|
/***************************************************************/
|
|
/* BME280 */
|
|
/***************************************************************/
|
|
//Define Sensor BME280 and variables
|
|
Adafruit_BME280 bme;
|
|
float sensorTemperature = 0;
|
|
float sensorHumidity = 0;
|
|
float sensorPressure = 0;
|
|
float sensorPressureSealevel = 0;
|
|
float sensorDewpoint = 0;
|
|
|
|
//Calculate dew Point
|
|
double dewPoint(double tempf, double humidity) {
|
|
double A0= 373.15/(273.15 + tempf);
|
|
double SUM = -7.90298 * (A0-1);
|
|
SUM += 5.02808 * log10(A0);
|
|
SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
|
|
SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
|
|
SUM += log10(1013.246);
|
|
double VP = pow(10, SUM-3) * humidity;
|
|
double T = log(VP/0.61078);
|
|
return (241.88 * T) / (17.558-T);
|
|
}
|
|
|
|
/***************************************************************/
|
|
/* openSenseMap */
|
|
/***************************************************************/
|
|
typedef struct measurement {
|
|
const char *sensorId;
|
|
float value;
|
|
} measurement;
|
|
|
|
measurement measurements[NUM_SENSORS];
|
|
uint8_t num_measurements = 0;
|
|
|
|
// buffer for sprintf
|
|
char buffer[500];
|
|
|
|
void addMeasurement(const char *sensorId, float value) {
|
|
measurements[num_measurements].sensorId = sensorId;
|
|
measurements[num_measurements].value = value;
|
|
num_measurements++;
|
|
}
|
|
|
|
void writeMeasurementsToClient() {
|
|
// iterate throug the measurements array
|
|
for (uint8_t i = 0; i < num_measurements; i++) {
|
|
sprintf_P(buffer, PSTR("%S,"), measurements[i].sensorId);
|
|
// arduino sprintf just returns "?" for floats, use dtostrf
|
|
dtostrf(measurements[i].value, 9, 2, &buffer[strlen(buffer)]);
|
|
|
|
// transmit buffer to client
|
|
client.println(buffer);
|
|
if (ENABLE_DEBUG) Serial.println(buffer);
|
|
}
|
|
|
|
// reset num_measurements
|
|
num_measurements = 0;
|
|
}
|
|
|
|
void submitValues() {
|
|
// close any connection before send a new request.
|
|
// This will free the socket on the WiFi shield
|
|
if (client.connected()) {
|
|
client.stop();
|
|
delay(1000);
|
|
}
|
|
bool connected = false;
|
|
char _server[strlen_P(SENSEBOX_SERVER)];
|
|
strcpy_P(_server, SENSEBOX_SERVER);
|
|
for (uint8_t timeout = 2; timeout != 0; timeout--) {
|
|
if (ENABLE_DEBUG) Serial.println("connecting...");
|
|
connected = client.connect(_server, 80);
|
|
if (connected == true) {
|
|
if (ENABLE_DEBUG) Serial.println("Connection successful, transferring...");
|
|
// construct the HTTP POST request:
|
|
sprintf_P(buffer,
|
|
/* PLEASE insert you Authorization key from the scetch insted of AUTHORIZATIONKEY !!!!!!!!!!1 */
|
|
PSTR("POST /boxes/%S/data HTTP/1.1\nAuthorization: AUTHORIZATIONKEY\nHost: %S\nContent-Type: "
|
|
"text/csv\nConnection: close\nContent-Length: %i\n"),
|
|
SENSEBOX_ID, SENSEBOX_SERVER, num_measurements * 36);
|
|
if (ENABLE_DEBUG) Serial.println(buffer);
|
|
|
|
// send the HTTP POST request:
|
|
client.println(buffer);
|
|
|
|
// send measurements
|
|
writeMeasurementsToClient();
|
|
|
|
// send empty line to end the request
|
|
client.println();
|
|
|
|
delay(100);
|
|
client.flush();
|
|
client.stop();
|
|
|
|
if (ENABLE_DEBUG) Serial.print("done!");
|
|
|
|
// reset number of measurements
|
|
num_measurements = 0;
|
|
break;
|
|
}
|
|
delay(1000);
|
|
}
|
|
}
|
|
|
|
void setup() {
|
|
/***************************************************************/
|
|
/* Enable Serial output */
|
|
/***************************************************************/
|
|
Serial.begin(115200);
|
|
if (ENABLE_DEBUG) Serial.println("");
|
|
|
|
/***************************************************************/
|
|
/* Enable Wifi */
|
|
/***************************************************************/
|
|
WiFi.mode(WIFI_STA);
|
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
|
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
|
if (ENABLE_DEBUG) Serial.print("WiFi Connect Failed! Rebooting...");
|
|
delay(1000);
|
|
ESP.restart();
|
|
} else {
|
|
if (ENABLE_DEBUG) Serial.println("WiFi Connected");
|
|
}
|
|
|
|
/***************************************************************/
|
|
/* Setup pin for voltage messurment */
|
|
/***************************************************************/
|
|
Wire.begin();
|
|
pinMode(A0, INPUT);
|
|
|
|
/***************************************************************/
|
|
/* Setup BME280 sensor */
|
|
/***************************************************************/
|
|
// Sensor initialization
|
|
if (ENABLE_DEBUG) Serial.println("Initializing sensors...");
|
|
if (!bme.begin(0x76)) {
|
|
if (ENABLE_DEBUG) Serial.print("Could not find a valid BME280 sensor, check wiring!");
|
|
while (1);
|
|
}
|
|
else {
|
|
if (ENABLE_DEBUG) Serial.print("BME280 sensor connected!");
|
|
}
|
|
|
|
/***************************************************************/
|
|
/* Setup Eltako 20000082 WS */
|
|
/***************************************************************/
|
|
pinMode(input_pin, INPUT_PULLUP);//D7
|
|
attachInterrupt(input_pin,Interrupt,RISING);
|
|
}
|
|
|
|
void loop() {
|
|
|
|
/***************************************************************/
|
|
/* Batterie calculation */
|
|
/***************************************************************/
|
|
unsigned long raw = analogRead(A0);
|
|
float volt= raw * calib_factor/1024;
|
|
|
|
/***************************************************************/
|
|
/* Anenmometer calculation */
|
|
/***************************************************************/
|
|
if (millis() > next_timestamp ) {
|
|
detachInterrupt(input_pin);
|
|
count++;
|
|
float rps = i/number_reed; //computing rounds per second
|
|
if(i == 0)
|
|
wind = 0.0;
|
|
else
|
|
wind = 1.761 / (1 + rps) + 3.013 * rps;// found here: https://www.amazon.de/gp/customer-reviews/R3C68WVOLJ7ZTO/ref=cm_cr_getr_d_rvw_ttl?ie=UTF8&ASIN=B0018LBFG8 (in German)
|
|
if(last_wind - wind > 0.8 || last_wind - wind < -0.8 || count >= 10){
|
|
String strBuffer;
|
|
strBuffer = String(wind);
|
|
strBuffer.toCharArray(charBuffer,10);
|
|
count = 0;
|
|
}
|
|
i = 0;
|
|
last_wind = wind;
|
|
if(WiFi.status() != WL_CONNECTED) {
|
|
ESP.restart();
|
|
delay(100);
|
|
}
|
|
next_timestamp = millis()+1000; //intervall is 1s
|
|
attachInterrupt(input_pin,Interrupt,RISING);
|
|
}
|
|
|
|
/***************************************************************/
|
|
/* Collect data from BME280 sensor */
|
|
/***************************************************************/
|
|
sensorTemperature = bme.readTemperature();
|
|
sensorDewpoint = (dewPoint(bme.readTemperature(), bme.readHumidity()));
|
|
sensorHumidity = bme.readHumidity();
|
|
sensorPressure = bme.readPressure() / 100.0F;
|
|
sensorPressureSealevel = ((bme.readPressure())/pow((1-((float)(ELEVATION))/44330), 5.255))/100.0;
|
|
|
|
if (ENABLE_DEBUG) {
|
|
Serial.print("Temperature: ");
|
|
Serial.print(sensorTemperature);
|
|
Serial.println(" °C");
|
|
Serial.print("DewPoint: ");
|
|
Serial.print(sensorDewpoint);
|
|
Serial.println(" °C");
|
|
Serial.print("abs. Humidity: ");
|
|
Serial.print(sensorHumidity);
|
|
Serial.println(" %");
|
|
Serial.print("rel. Humidity: ");
|
|
Serial.print(sensorHumidity);
|
|
Serial.println(" %");
|
|
Serial.print("abs. Pressure: ");
|
|
Serial.print(sensorPressure);
|
|
Serial.println(" hPa");
|
|
Serial.print("rel. Pressure: ");
|
|
Serial.print(sensorPressureSealevel);
|
|
Serial.println(" hPa");
|
|
Serial.print("Wind: ");
|
|
Serial.print(wind);
|
|
Serial.println(" km/h");
|
|
Serial.print("Batterie: ");
|
|
Serial.print(volt);
|
|
Serial.println(" V");
|
|
}
|
|
/***************************************************************/
|
|
/* Send data to OpenSenseMap */
|
|
/***************************************************************/
|
|
if (startSENSEBOX) {
|
|
addMeasurement(TEMPERATURE_ID, sensorTemperature);
|
|
addMeasurement(DEWPOINT_ID, sensorDewpoint);
|
|
addMeasurement(HUMIDITY_ID, sensorHumidity);
|
|
addMeasurement(PRESSURE_ID, sensorPressure);
|
|
addMeasurement(PRESSURE_NN_ID, sensorPressureSealevel);
|
|
addMeasurement(ANEMOMETER_ID, wind);
|
|
addMeasurement(VOLTMETER_ID, volt);
|
|
|
|
submitValues();
|
|
}
|
|
|
|
//delay(5000);
|
|
ESP.deepSleep(480e6); //8 minutes deepSleep
|
|
}
|