Compare commits

...

7 commits

Author SHA1 Message Date
Kai Lauterbach 5fcfd89652 Waiting for wind sensor result code changed to be processed by FSM states. Added new battery mode main function. Renamed FSM state names. 2022-09-14 11:58:13 +02:00
Kai Lauterbach 7225866dd4 Newline added 2022-09-14 11:56:53 +02:00
Kai Lauterbach 8c907ce1e1 Added start, wait, read functions and changed main sensor read function. 2022-09-14 11:56:41 +02:00
Kai Lauterbach 4bd4944d6b Code optically cleared 2022-09-14 11:55:43 +02:00
Kai Lauterbach 67d3a7053a Renamed FSM state defines and added some new 2022-09-14 11:55:18 +02:00
Kai Lauterbach d323eedfae Added serial baudrate define 2022-09-14 11:54:59 +02:00
Kai Lauterbach f6333c2801 Cleaned order of defines in user config header. 2022-09-14 11:54:27 +02:00
9 changed files with 267 additions and 132 deletions

View file

@ -41,6 +41,8 @@
#define BME_CS 10
#define BME_ADDRESS 0x76
#define SERIAL_BAUD_RATE 115200
#define WEB_UPDATER_HTTP_PORT 8080
#endif

View file

@ -12,28 +12,43 @@
// maybe have a TOO LONG SSID!
String DEVICE_NAME = "weatherstation";
// Enable/Disable features
/********************************************************************************/
// Enable/Disable general features
#define BATTERY_POWERED
// retries to connect after 5 seconds or starts the wifimanager
//#define SLEEP_IF_NO_WLAN_CONNECTION
#define INFLUXDB_FEATURE
#define INFLUXDB_VERSION 1 // 1 or 2
#define SERIAL_FEATURE
//#define BATTERY_POWERED
//#define SENSOR_WIND
//#define LOG_MILLIS_TO_INFLUXDB
//#define SERIAL_FEATURE
#define SENSOR_WIND
#define SENSOR_APDS9960
//#define SENSOR_APDS9930
#define SENSOR_BME280
#define SENSOR_BATTERY
//#define BAT_PINS_D34
// Homebridge Webstat is only possible if webupdater is also enabled
//#define HOMEBRIDGE_WEBSTAT
// retries to connect after 5 seconds or starts the wifimanager
#define SLEEP_IF_NO_WLAN_CONNECTION
/********************************************************************************/
// not available or recommended for battery mode
/********************************************************************************/
// Restarts the firmware every n seconds
//#define RESET_ESP_TIMEINTERVAL // BETA STATUS
//#define HTTP_CALL_ON_WINDSPEED_EXCEED // BETA STATUS
//#define DEBUG_WINDSPEED_MEASUREMENT // for debugging windspeed measurement only
//#define LOG_MILLIS_TO_INFLUXDB
//#define RESET_ESP_TIME_INTERVAL
//#define ENABLE_WATCHDOG
//#define WATCHDOG_TIMEOUT_MS 30000
//#define WEBUPDATER_FEATURE
// only available in case that webupdater is enabled
//#define USE_LOGGER
// only possible if webupdater is also enabled
//#define HOMEBRIDGE_WEBSTAT
// for debugging windspeed measurement only, trigger and results are handled by webupdater
//#define DEBUG_WINDSPEED_MEASUREMENT
//#define HTTP_CALL_ON_WINDSPEED_EXCEED
const float HUMIDITY_FACTOR = 1.0;
const float LIGHT_FACTOR = 1.0;

View file

@ -18,14 +18,17 @@
#define ENERGY_SAVE_MODE_ENABLED 1.0
#define ENERGY_SAVE_MODE_DISABLED 0.0
#define FSM_STATE_WU 0
#define FSM_STATE_WSE 1
#define FSM_STATE_RS 2
#define FSM_STATE_WC 3
#define FSM_STATE_WS 4
#define FSM_STATE_US 5
#define FSM_STATE_SC 6
#define FSM_STATE_ID 7
#define FSM_STATE_SD 8
#define FSM_STATE_1 0
#define FSM_STATE_2 1
#define FSM_STATE_3 2
#define FSM_STATE_4 3
#define FSM_STATE_5 4
#define FSM_STATE_6 5
#define FSM_STATE_7 6
#define FSM_STATE_8 7
#define FSM_STATE_9 8
#define FSM_STATE_10 9
#define FSM_STATE_11 10
#define FSM_STATE_12 11
#endif

View file

@ -40,7 +40,7 @@ const String wifiName = "oko-weather-" + DEVICE_NAME;
WiFiManager wifiManager;
uint8_t fsm_state = FSM_STATE_WU;
uint8_t fsm_state = FSM_STATE_1;
uint8_t sensor_cnt = 0;
@ -67,7 +67,7 @@ void setup()
{
#if defined(DEBUG) || defined(SERIAL_FEATURE)
Serial.begin(115200);
Serial.begin(SERIAL_BARD_RATE);
#endif
// Pin settings
@ -109,7 +109,11 @@ void setup()
#ifdef BATTERY_POWERED
debug("battery powered");
_loop();
do {
_battery_mode_main();
} while (fsm_state != FSM_STATE_1);
digitalWrite(STATUS_LED_PIN, LOW);
@ -126,10 +130,12 @@ void setup()
delay(100);
#endif
#ifndef BATTERY_POWERED
#ifdef ENABLE_WATCHDOG
// Enable the internal watchdog
ESP.wdtEnable(WATCHDOG_TIMEOUT_MS);
#endif
#endif
}
@ -238,7 +244,7 @@ void wifiConnectionCheck()
return;
}
debug("no connection or time to check " + String(WiFi.status() == WL_CONNECTED));
debug("no wifi connection, try to reconnect");
wifiConnect();
@ -303,19 +309,23 @@ void loop()
#ifdef BATTERY_POWERED
delay(50);
return;
#endif
// call sub loop function
_loop();
#else
// call fsm loop function
_fsm_loop();
// Needed to give WIFI time to function properly
delay(DELAY_LOOP_MS);
#endif
}
//*************************************************************************//
void _loop()
#ifndef BATTERY_POWERED
void _fsm_loop()
{
#ifdef WEBUPDATER_FEATURE
@ -330,37 +340,27 @@ void _loop()
switch (fsm_state)
{
case FSM_STATE_WU:
/*
//debug("web updater call if required");
#ifdef WEBUPDATER_FEATURE
if ((update_webserver_cnt + (UPDATE_WEBSERVER_INTVERVAL_S * 1000)) <= millis())
{
//debug("web updater call");
update_webserver_cnt = millis();
doWebUpdater();
}
#endif
*/
fsm_state = FSM_STATE_WSE;
break;
case FSM_STATE_WSE:
/* -------------------------------------------------------------------------------- */
case FSM_STATE_1:
//debug("wind speed exceeded check if required");
#ifdef HTTP_CALL_ON_WINDSPEED_EXCEED
if ((update_windspeed_exceed_cnt + (HTTP_CALL_ON_WINDSPEED_INTERVAL_S * 1000)) <= millis())
{
debug("reading wind sensor exceed");
// reset the wait timer to get a value every HTTP_CALL_ON_WINDSPEED_INTERVAL_S independently to the runtime of the measurement
update_windspeed_exceed_cnt = millis();
readWindSpeedExceed();
start_measure_wind(); // start measurement of wind speed
fsm_state = FSM_STATE_11; // wait untile the wind meas time exceeded
break; // abort case here to prevent read of next sensor in list
}
#endif
fsm_state = FSM_STATE_RS;
fsm_state = FSM_STATE_2;
break;
case FSM_STATE_RS:
/* -------------------------------------------------------------------------------- */
case FSM_STATE_2:
//debug("reset time check if required");
#ifdef RESET_ESP_TIME_INTERVAL
// if millis() reached interval restart ESP
@ -371,18 +371,21 @@ void _loop()
ESP.restart();
}
#endif
fsm_state = FSM_STATE_WC;
fsm_state = FSM_STATE_3;
break;
case FSM_STATE_WC:
/* -------------------------------------------------------------------------------- */
case FSM_STATE_3:
wifiConnectionCheck();
fsm_state = FSM_STATE_WS;
fsm_state = FSM_STATE_4;
break;
case FSM_STATE_WS:
/* -------------------------------------------------------------------------------- */
case FSM_STATE_4:
//debug("disable measure of wind speed if required");
#ifdef defined(BATTERY_POWERED) && defined(SENSOR_WIND)
if (energySavingMode() == 1) {
if (energySavingMode() == 1)
{
// Disable expensive tasks
//sensors[SENSOR_WINDSPEED] = 0;
//debug("read of wind sensor because of low battery disabled");
@ -395,45 +398,57 @@ void _loop()
}
#endif
sensor_cnt = 0;
fsm_state = FSM_STATE_US;
fsm_state = FSM_STATE_5;
break;
case FSM_STATE_US:
/* -------------------------------------------------------------------------------- */
case FSM_STATE_5:
//debug("read sensor data check");
if ((update_sensor_cnt + (UPDATE_SENSOR_INTERVAL_S * 1000)) <= millis())
{
debug("read sensor data " + String(sensor_cnt));
currentSensorData[sensor_cnt] = readSensors(sensor_cnt);
if (sensor_cnt != SENSOR_WINDSPEED)
{
// read data from sensor
currentSensorData[sensor_cnt] = readSensors(sensor_cnt);
} else {
start_measure_wind(); // start measurement of wind speed
fsm_state = FSM_STATE_9; // wait untile the wind meas time exceeded
break; // abort case here to prevent read of next sensor in list
}
if (sensor_cnt < VALUES)
{
sensor_cnt++;
fsm_state = FSM_STATE_US; // jump to same state again, more sensors to read
fsm_state = FSM_STATE_5; // jump to same state again, more sensors to read
} else {
update_sensor_cnt = millis();
update_sensor_cnt = millis(); // reset the update interval counter
sensor_cnt = 0;
fsm_state = FSM_STATE_SC; // next state
fsm_state = FSM_STATE_6; // next state
}
} else {
//debug("skip read sensor data");
fsm_state = FSM_STATE_WU; // no new data, reset FSM
fsm_state = FSM_STATE_1; // no new data, reset FSM
}
break;
case FSM_STATE_SC:
/* -------------------------------------------------------------------------------- */
case FSM_STATE_6:
//debug("log to serial if required");
#ifdef SERIAL_FEATURE
logToSerial(currentSensorData);
#endif
fsm_state = FSM_STATE_ID;
fsm_state = FSM_STATE_7;
break;
case FSM_STATE_ID:
/* -------------------------------------------------------------------------------- */
case FSM_STATE_7:
//debug("send data to influxdb if required");
#ifdef INFLUXDB_FEATURE
for (uint8_t i = 0; i < 5 and validData == false; i++)
@ -450,73 +465,157 @@ void _loop()
pushToInfluxDB(DEVICE_NAME, currentSensorData);
}
#endif
fsm_state = FSM_STATE_SD;
fsm_state = FSM_STATE_8;
break;
case FSM_STATE_SD:
/* -------------------------------------------------------------------------------- */
case FSM_STATE_8:
//debug("set sensor data in webupdater if required");
#ifdef WEBUPDATER_FEATURE
setSensorData(currentSensorData);
#endif
fsm_state = FSM_STATE_WU;
fsm_state = FSM_STATE_1;
break;
/* -------------------------------------------------------------------------------- */
case FSM_STATE_9:
#ifdef SENSOR_WIND
if (check_measure_wind_done() == false)
{
//debug("wait for wind sensor finish");
fsm_state = FSM_STATE_9; // stay here until the wind measurement is done
} else {
debug("wind sensor read finish");
fsm_state = FSM_STATE_10;
}
#else
// in case that the wind sensor is not used skip this step
sensor_cnt++;
fsm_state = FSM_STATE_5;
#endif
break;
/* -------------------------------------------------------------------------------- */
case FSM_STATE_10:
#ifdef SENSOR_WIND
currentSensorData[sensor_cnt] = measure_wind_result();
debug("wind sensor " + String(currentSensorData[sensor_cnt]));
#endif
// step into read of next sensor read
sensor_cnt++;
fsm_state = FSM_STATE_5;
break;
/* -------------------------------------------------------------------------------- */
case FSM_STATE_11:
#ifdef SENSOR_WIND
if (check_measure_wind_done() == false)
{
//debug("wait for wind sensor finish");
fsm_state = FSM_STATE_11; // stay here until the wind measurement is done
} else {
debug("wind sensor read finish");
fsm_state = FSM_STATE_12;
}
#else
// in case that the wind sensor is not used skip this step
sensor_cnt++;
fsm_state = FSM_STATE_5;
#endif
break;
/* -------------------------------------------------------------------------------- */
case FSM_STATE_12:
#ifdef HTTP_CALL_ON_WINDSPEED_EXCEED
currentSensorData[sensor_cnt] = measure_wind_result();
debug("wind sensor value " + String(currentSensorData[sensor_cnt]));
if (currentSensorData[SENSOR_WINDSPEED] >= HTTP_CALL_ON_WINDSPEED_EXCEED_MPS)
{
// windspeed exceeded send http call
digitalWrite(STATUS_LED_PIN, HIGH);
// call the url HTTP_CALL_ON_WINDSPEED_URL
WiFiClient client;
HTTPClient http;
http.begin(client, String(HTTP_CALL_ON_WINDSPEED_URL).c_str());
// Send HTTP GET request
int httpResponseCode = http.GET();
if (httpResponseCode > 0)
{
String response = http.getString();
debug("http response code: " + String(httpResponseCode) + " = " + response);
// TODO handle response
}
http.end();
debug("Called windspeed exceed callout");
digitalWrite(STATUS_LED_PIN, LOW);
}
#ifdef WEBUPDATER_FEATURE
setSensorData(currentSensorData);
#endif
#endif
// step into read of next fsm state
fsm_state = FSM_STATE_2;
break;
/* -------------------------------------------------------------------------------- */
default:
fsm_state = FSM_STATE_WU;
fsm_state = FSM_STATE_1;
break;
} // close of switch
//delay(100); // TODO warum hier ein delay?
//debug("FSM state = " + String(fsm_state));
/*if (fsm_state == FSM_STATE_WU)
/*if (fsm_state == FSM_STATE_1)
{
debug("----------");
}*/
}
#endif
//*************************************************************************//
void readWindSpeedExceed()
void _battery_mode_main()
{
// read from windspeed sensorSTATUS_LED_PIN
digitalWrite(STATUS_LED_PIN, HIGH);
currentSensorData[SENSOR_WINDSPEED] = readSensors(SENSOR_WINDSPEED);
digitalWrite(STATUS_LED_PIN, LOW);
if (currentSensorData[SENSOR_WINDSPEED] >= HTTP_CALL_ON_WINDSPEED_EXCEED_MPS)
if (energySavingMode() == 1)
{
digitalWrite(STATUS_LED_PIN, HIGH);
// Disable expensive tasks
//debug("read of wind sensor because of low battery disabled");
do_not_read_windsensor = true;
// call the url HTTP_CALL_ON_WINDSPEED_URL
WiFiClient client;
HTTPClient http;
http.begin(client, String(HTTP_CALL_ON_WINDSPEED_URL).c_str());
// Send HTTP GET request
int httpResponseCode = http.GET();
if (httpResponseCode > 0) {
String response = http.getString();
debug("http response code: " + String(httpResponseCode) + " = " + response);
// TODO handle response
}
http.end();
debug("Called windspeed exceed callout");
digitalWrite(STATUS_LED_PIN, LOW);
} else {
//debug("read of wind sensor because of high battery enabled");
do_not_read_windsensor = false;
}
for (uint8_t i = 0; i < VALUES; i++)
{
currentSensorData[i] = readSensors(i);
}
#ifdef SERIAL_FEATURE
logToSerial(currentSensorData);
#endif
#ifdef INFLUXDB_FEATURE
pushToInfluxDB(DEVICE_NAME, currentSensorData);
#endif
#ifdef WEBUPDATER_FEATURE
setSensorData(currentSensorData);
#endif
}
//*************************************************************************//
#ifdef SERIAL_FEATURE
void logToSerial(float sensorValues[])
{
Serial.println("");
@ -530,5 +629,6 @@ void logToSerial(float sensorValues[])
Serial.println("Bat charge state: " + String(sensorValues[SENSOR_BATCHARGESTATE]));
Serial.println("Energy saving: " + String(sensorValues[SENSOR_ESAVEMODE]));
}
#endif
//*************************************************************************//

View file

@ -2,21 +2,30 @@
APDS9930 _sensor_apds9930 = APDS9930();
bool sensor_apds9930_begin() {
bool sensor_apds9930_begin()
{
bool status = _sensor_apds9930.init();
if (status) {
if (status)
{
_sensor_apds9930.enableLightSensor(false);
debug("APDS9930 Connected");
} else {
debug("Could not find a valid APDS9930 sensor, check wiring!");
}
return status;
}
float apds9930_light() {
float apds9930_light()
{
float ambient_light = 0;
if (_sensor_apds9930.readAmbientLightLux(ambient_light)) {
if (_sensor_apds9930.readAmbientLightLux(ambient_light))
{
return ambient_light;
} else {
return 0;
}

View file

@ -2,26 +2,34 @@
Adafruit_APDS9960 _sensor_apds9960;
bool sensor_apds9960_begin() {
bool sensor_apds9960_begin()
{
bool status = _sensor_apds9960.begin();
if (status) {
if (status)
{
_sensor_apds9960.enableColor(true);
debug("APDS9960 Connected");
} else {
debug("Could not find a valid APDS9960 sensor, check wiring!");
}
return status;
}
float apds9960_light() {
float apds9960_light()
{
uint16_t red, green, blue, white, lux;
while(!_sensor_apds9960.colorDataReady()) {
while(!_sensor_apds9960.colorDataReady())
{
delay(5);
}
_sensor_apds9960.getColorData(&red, &green, &blue, &white);
//calculate lux
lux = _sensor_apds9960.calculateLux(red, green, blue);
return lux * LIGHT_FACTOR;
}

View file

@ -3,22 +3,32 @@
Adafruit_BME280 _sensor_bme280;
bool sensor_bme280_begin(uint8_t addr) {
bool sensor_bme280_begin(uint8_t addr)
{
bool status = _sensor_bme280.begin(addr);
if (status) {
if (status)
{
debug("BME280 Connected");
} else {
debug("Could not find a valid BME280 sensor, check wiring!");
}
return status;
}
float bme280_temperature() {
float bme280_temperature()
{
return _sensor_bme280.readTemperature() * TEMP_FACTOR;
}
float bme280_pressure() {
float bme280_pressure()
{
return _sensor_bme280.readPressure() / 100.0F;
}
float bme280_humidity() {
float bme280_humidity()
{
return _sensor_bme280.readHumidity() * HUMIDITY_FACTOR;
}

View file

@ -4,6 +4,7 @@
unsigned int anemometerRotations = 0;
uint32_t start_meas_wind_time = 0;
int interruptNumber;
ICACHE_RAM_ATTR void _anemometerInterrupt()
{
@ -13,28 +14,14 @@ ICACHE_RAM_ATTR void _anemometerInterrupt()
#endif
}
/*
float wind_speed()
{
anemometerRotations = 0;
int interruptNumber = digitalPinToInterrupt(ANEMOMETER_PIN);
attachInterrupt(interruptNumber, _anemometerInterrupt, RISING);
delay(1000 * WIND_SENSOR_MEAS_TIME_S); // time to measure
detachInterrupt(interruptNumber);
// calculate the speed as km/h
float tmp_speed = (float)anemometerRotations * WINDSPEED_FACTOR;
#ifdef DEBUG
Serial.print("Windspeed: " + String(tmp_speed));
#endif
return tmp_speed;
start_measure_wind();
do {
delay(1000); // minimum delay of measurement time is 1 second
} while (check_measure_wind_done() == false);
return measure_wind_result();
}
*/
void start_measure_wind()
{
@ -45,7 +32,7 @@ void start_measure_wind()
boolean check_measure_wind_done()
{
if (start_meas_wind + WIND_SENSOR_MEAS_TIME_S <= millis())
if ((start_meas_wind_time + (WIND_SENSOR_MEAS_TIME_S * 1000)) <= millis())
{
detachInterrupt(interruptNumber);
return true;
@ -53,7 +40,7 @@ boolean check_measure_wind_done()
return false;
}
float stop_measure_wind()
float measure_wind_result()
{
return (float)anemometerRotations * WINDSPEED_FACTOR;
}

View file

@ -86,7 +86,8 @@ void setSensorData(float sensorValues[])
}
}
for (uint8_t i = 0; i < VALUES; i++) {
for (uint8_t i = 0; i < VALUES; i++)
{
_webUpdater_sensValues[i] = sensorValues[i];
}
}