solarweatherstion-with-open.../solarweatherstation-with-opensensemap.ino
2024-03-10 13:43:21 +01:00

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
}