Commit ce87c556 authored by Eric Duminil's avatar Eric Duminil
Browse files

Merge. Ready for release

parents 1815167d b8a71725
......@@ -10,3 +10,8 @@ before_script:
job:
stage: build
script: "platformio run"
artifacts:
paths:
- .pio/build/esp32/firmware.bin
- .pio/build/esp8266/firmware.bin
expire_in: never
......@@ -16,6 +16,7 @@ The *CO<sub>2</sub> Ampel* can:
* Send data over [MQTT](https://en.wikipedia.org/wiki/MQTT).
* Send data over [LoRaWAN](https://en.wikipedia.org/wiki/LoRa#LoRaWAN).
* Display measurements and configuration on a small website.
* Allow configuration of every parameter via web-interface.
* Log data to a [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) file, directly on the ESP flash memory.
* Accept many interactive commands.
......@@ -36,7 +37,8 @@ or
## Installation
* If `config.h` does not exist, copy it from `config.public.h`
* Modify `config.h`, e.g. for measurement time-steps, WiFi access, MQTT, NTP and web-server.
* You can modify `config.h`, e.g. for measurement time-steps, WiFi access, MQTT, NTP and web-server.
* Every parameter can be modified later, via the web-interface.
### PlatformIO
......@@ -68,15 +70,44 @@ make upload board=esp32 && make monitor # For ESP32
* *Upload*
* *Tools > Serial Monitor*
## Usage and configuration
* Start the *Ampel*
* If you didn't define wifi SSID and Passwords in config.h
* The *Ampel* should blink turquoise, to indicate *Access Point* mode.
* Connect with a laptop/smartphone to ESPxxxxxx WiFi.
* Open a browser, it should bring you to the *Ampel* web-page.
* The *Ampel* web-page will be shown. You can click on "Configuration".
* You'll have to set an *Ampel* password with at least 8 characters.
* You can set WiFi SSID + Password if you want. It will then try to connect if you disconnect from the *Access Point*.
* If you don't specify SSID + Password, the *Ampel* will simply stay in *Access Point* mode.
* The *Ampel* password will be required if a connection fails, and the *Access Point* starts again.
* The *Ampel* password will be needed (with user 'admin') to connect to the config web-page once the *Ampel* is connected to WiFi.
* Once you defined Wifi SSID, Ampel password and WiFi password:
* the *Ampel* will try to connect, displaying a rainbow wheel.
* if the connection is successful, LEDs will be green.
* if the connection fails, LEDs will be red, and the *Ampel* will return back to *Access Point* mode.
* It might be necessary to reset the *Ampel* after changing important parameters.
* You can rename the *Ampel*. This name will be used instead of ESPxxxxxx for CSV files and the mDNS address. You'll get a new CSV file after renaming, which can be convenient, e.g. to indicate at which location the measurements were made.
* If you forgot the password, you can send `reset_config` as command, and `reset` the ampel.
* If you disabled WiFi, you can enable it again with `wifi 1`.
* It's also possible to specify WiFi SSID and password in the console, with `ssid wifi_ssid_here` and `pwd wifi_password_here` commands.
* You can enable CSV by clicking on "+CSV", or disable it by clicking on "Disable CSV".
* The same applies to MQTT and LoRaWAN.
* If you disable a set, the parameters are still saved, and will appear again once the service is enabled.
## Available commands
In Arduino IDE *Serial Monitor* or PlatformIO *Monitor*, type `help` + <kbd>Enter</kbd> in order to list the available commands:
* `ap 0/1` (Disables/enables access point).
* `auto_calibrate 0/1` (Disables/enables autocalibration).
* `calibrate` (Starts calibration process).
* `calibrate 600` (Starts calibration process, to given ppm).
* `calibrate` (Starts calibration process).
* `calibrate! 600` (Calibrates right now, to given ppm).
* `co2 1500` (Sets CO<sub>2</sub> level, for debugging purposes).
* `co2 1500` (Sets CO<sub>2</sub> level, for debugging).
* `color 0xFF0015` (Shows color, specified as RGB, for debugging).
* `csv 60` (Sets CSV writing interval, in s).
* `format_filesystem` (Deletes the whole filesystem).
......@@ -85,12 +116,17 @@ In Arduino IDE *Serial Monitor* or PlatformIO *Monitor*, type `help` + <kbd>Ente
* `local_ip` (Displays local IP and current SSID).
* `lora 300` (Sets LoRaWAN sending interval, in s).
* `mqtt 60` (Sets MQTT sending interval, in s).
* `pwd abc` (Sets WiFi password to 'abc').
* `reset` (Restarts the ESP).
* `reset_config` (Resets the complete IotWeb config).
* `reset_scd` (Resets SCD30).
* `save_config` (Saves the config to EEPROM).
* `send_local_ip` (Sends local IP and SSID via MQTT. Can be useful to find sensor).
* `set_time 1618829570` (Sets time to the given UNIX time).
* `show_csv` (Displays the complete CSV file on Serial).
* `ssid name` (Sets SSID to 'name').
* `timer 30` (Sets measurement interval, in s).
* `wifi 0/1` (Turns Wifi on/off).
* `wifi_scan` (Scans available WiFi networks).
The commands can be sent via the Serial interface, from the webpage or via MQTT.
......
......@@ -3,34 +3,17 @@
/*****************************************************************
* Libraries *
*****************************************************************/
#include "config.h"
#ifndef MEASUREMENT_TIMESTEP
# error Missing config.h file. Please copy config.public.h to config.h.
#endif
#ifdef AMPEL_CSV
# include "csv_writer.h"
#endif
//NOTE: Too many headers. Move them to include/ folder?
#include "web_config.h" // Needed for offline config too.
#ifdef AMPEL_WIFI
# include "wifi_util.h"
# ifdef AMPEL_MQTT
# include "mqtt.h"
# endif
# ifdef AMPEL_HTTP
# include "web_server.h"
# endif
# if defined(ESP8266)
//allows sensor to be seen as SENSOR_ID.local, from the local network. For example : espd03cc5.local
# include <ESP8266mDNS.h>
# elif defined(ESP32)
# include <ESPmDNS.h>
# endif
#endif
#include "csv_writer.h"
#ifdef AMPEL_LORAWAN
# include "lorawan.h"
#endif
#include "wifi_util.h"
#include "mqtt.h"
#include "web_server.h"
#include "lorawan.h"
#include "util.h"
#include "ntp.h"
......@@ -38,4 +21,12 @@
#include "co2_sensor.h"
#include "led_effects.h"
void wifiConnecting();
void wifiConnected();
void wifiFailed();
void apModeStarts();
void keepServicesAlive();
void checkFlashButton();
#endif
......@@ -63,13 +63,22 @@ void setup() {
led_effects::setupOnBoardLED();
led_effects::onBoardLEDOff();
Serial.begin(BAUDS);
Serial.begin(config::bauds);
web_config::initialize();
web_config::setWifiConnectingCallback(wifiConnecting);
web_config::setWifiConnectionCallback(wifiConnected);
web_config::setWifiFailCallback(wifiFailed);
web_config::setApModeCallback(apModeStarts);
pinMode(0, INPUT); // Flash button (used for forced calibration)
Serial.println();
Serial.print(F("Sensor ID: "));
Serial.println(ampel.sensorId);
Serial.print(F("Name : "));
Serial.println(config::ampel_name());
Serial.print(F("MAC : "));
Serial.println(ampel.macAddress);
Serial.print(F("Board : "));
......@@ -81,56 +90,36 @@ void setup() {
sensor::initialize();
#ifdef AMPEL_CSV
csv_writer::initialize(ampel.sensorId);
#endif
#ifdef AMPEL_WIFI
wifi::connect(ampel.sensorId);
if (wifi::connected()) {
# ifdef AMPEL_HTTP
web_server::initialize();
# endif
csv_writer::initialize(config::ampel_name());
ntp::initialize();
ntp::initialize();
if (MDNS.begin(ampel.sensorId)) { // Start the mDNS responder for SENSOR_ID.local
MDNS.addService("http", "tcp", 80);
Serial.println(F("mDNS responder started"));
} else {
Serial.println(F("Error setting up MDNS responder!"));
}
# ifdef AMPEL_MQTT
mqtt::initialize(ampel.sensorId);
# endif
if (config::is_wifi_on) {
wifi::defineCommands();
web_server::definePages();
wifi::tryConnection();
}
#endif
#if defined(AMPEL_LORAWAN) && defined(ESP32)
lorawan::initialize();
#if defined(ESP32)
if (config::is_lorawan_active()) {
lorawan::initialize();
}
#endif
}
/*****************************************************************
* Helper functions *
*****************************************************************/
void keepServicesAlive();
void checkFlashButton();
void checkSerialInput();
/*****************************************************************
* Main loop *
*****************************************************************/
void loop() {
#if defined(AMPEL_LORAWAN) && defined(ESP32)
//LMIC Library seems to be very sensitive to timing issues, so run it first.
lorawan::process();
if (lorawan::waiting_for_confirmation) {
// If node is waiting for join confirmation from Gateway, nothing else should run.
return;
#if defined(ESP32)
if (config::is_lorawan_active()) {
//LMIC Library seems to be very sensitive to timing issues, so run it first.
lorawan::process();
if (lorawan::waiting_for_confirmation) {
// If node is waiting for join confirmation from Gateway, nothing else should run.
return;
}
}
#endif
//NOTE: Loop should never take more than 1000ms. Split in smaller methods and logic if needed.
......@@ -142,19 +131,21 @@ void loop() {
// Short press for night mode, Long press for calibration.
checkFlashButton();
checkSerialInput();
sensor_console::checkSerialInput();
if (sensor::processData()) {
#ifdef AMPEL_CSV
csv_writer::logIfTimeHasCome(sensor::timestamp, sensor::co2, sensor::temperature, sensor::humidity);
#endif
if (config::is_csv_active()) {
csv_writer::logIfTimeHasCome(sensor::timestamp, sensor::co2, sensor::temperature, sensor::humidity);
}
#if defined(AMPEL_WIFI) && defined(AMPEL_MQTT)
mqtt::publishIfTimeHasCome(sensor::timestamp, sensor::co2, sensor::temperature, sensor::humidity);
#endif
if (config::is_wifi_on && config::is_mqtt_active()) {
mqtt::publishIfTimeHasCome(sensor::timestamp, sensor::co2, sensor::temperature, sensor::humidity);
}
#if defined(AMPEL_LORAWAN) && defined(ESP32)
lorawan::preparePayloadIfTimeHasCome(sensor::co2, sensor::temperature, sensor::humidity);
#if defined(ESP32)
if (config::is_lorawan_active()) {
lorawan::preparePayloadIfTimeHasCome(sensor::co2, sensor::temperature, sensor::humidity);
}
#endif
}
......@@ -167,12 +158,59 @@ void loop() {
}
}
void checkSerialInput() {
while (Serial.available() > 0) {
sensor_console::processSerialInput(Serial.read());
/*****************************************************************
* Callbacks *
*****************************************************************/
void wifiConnecting() {
Serial.print(F("WiFi - Trying to connect to "));
Serial.print(config::selected_ssid());
Serial.print(F(" (max "));
Serial.print(config::wifi_timeout);
Serial.println(F("s)."));
led_effects::showRainbowWheel();
}
void wifiConnected() {
Serial.println();
Serial.print(F("WiFi - Connected to "));
Serial.print(WiFi.SSID());
Serial.print(F(", IP address: "));
IPAddress address = WiFi.localIP();
snprintf(wifi::local_ip, sizeof(wifi::local_ip), "%d.%d.%d.%d", address[0], address[1], address[2], address[3]);
Serial.println(wifi::local_ip);
led_effects::showKITTWheel(color::green);
ntp::connect();
if (config::is_mqtt_active()) {
mqtt::initialize(ampel.sensorId);
}
Serial.print(F("You can access this sensor via http://"));
Serial.print(config::ampel_name());
Serial.print(F(".local (might be unstable) or http://"));
Serial.println(WiFi.localIP());
}
void wifiFailed() {
// Ampel will go back to Access Point mode for AP_TIMEOUT seconds, and try connection again after
Serial.println();
Serial.print(F("WiFi - Could not connect to "));
Serial.println(config::selected_ssid());
led_effects::showKITTWheel(color::red);
}
void apModeStarts() {
Serial.print(F("WiFi - Starting Access Point mode ("));
Serial.print(config::ampel_name());
Serial.println(F(")."));
led_effects::alert(color::turquoise);
}
/*****************************************************************
* Helper functions *
*****************************************************************/
/**
* Checks if flash button has been pressed:
* If not, do nothing.
......@@ -186,6 +224,7 @@ void checkFlashButton() {
if (digitalRead(0)) {
Serial.println(F("Flash has been pressed for a short time. Should toggle night mode."));
led_effects::toggleNightMode();
//NOTE: Start Access Point instead?
} else {
Serial.println(F("Flash has been pressed for a long time. Keep it pressed for calibration."));
if (led_effects::countdownToZero()) {
......@@ -199,20 +238,13 @@ void checkFlashButton() {
}
void keepServicesAlive() {
#ifdef AMPEL_WIFI
if (wifi::connected()) {
# if defined(ESP8266)
//NOTE: Sadly, there seems to be a bug in the current MDNS implementation.
// It stops working after 2 minutes. And forcing a restart leads to a memory leak.
MDNS.update();
# endif
ntp::update(); // NTP client has its own timer. It will connect to NTP server every 60s.
# ifdef AMPEL_HTTP
web_server::update();
# endif
# ifdef AMPEL_MQTT
mqtt::keepConnection(); // MQTT client has its own timer. It will keep alive every 15s.
# endif
if (config::is_wifi_on) {
web_config::update();
if (wifi::connected()) {
ntp::update(); // NTP client has its own timer. It will connect to NTP server every 60s.
if (config::is_mqtt_active()) {
mqtt::keepConnection(); // MQTT client has its own timer. It will keep alive every 15s.
}
}
}
#endif
}
#include "co2_sensor.h"
#include "config.h"
#include "web_config.h"
#include "ntp.h"
#include "led_effects.h"
#include "sensor_console.h"
......@@ -11,25 +11,12 @@
#include "src/lib/SparkFun_SCD30_Arduino_Library/src/SparkFun_SCD30_Arduino_Library.h" // From: http://librarymanager/All#SparkFun_SCD30
namespace config {
// UPPERCASE values should be defined in config.h
uint16_t measurement_timestep = MEASUREMENT_TIMESTEP; // [s] Value between 2 and 1800 (range for SCD30 sensor).
const uint16_t altitude_above_sea_level = ALTITUDE_ABOVE_SEA_LEVEL; // [m]
uint16_t co2_calibration_level = ATMOSPHERIC_CO2_CONCENTRATION; // [ppm]
const uint16_t measurement_timestep_bootup = 5; // [s] Measurement timestep during acclimatization.
const uint8_t max_deviation_during_bootup = 20; // [%]
const int8_t max_deviation_during_calibration = 30; // [ppm]
const int16_t timestep_during_calibration = 10; // [s] WARNING: Measurements can be unreliable for timesteps shorter than 10s.
const int8_t stable_measurements_before_calibration = 120 / timestep_during_calibration; // [-] Stable measurements during at least 2 minutes.
const uint16_t co2_alert_threshold = 2000; // [ppm] Display a flashing led ring, if concentration exceeds this value
#ifdef TEMPERATURE_OFFSET
// Residual heat from CO2 sensor seems to be high enough to change the temperature reading. How much should it be offset?
// NOTE: Sign isn't relevant. The returned temperature will always be shifted down.
const float temperature_offset = TEMPERATURE_OFFSET; // [K]
#else
const float temperature_offset = -3.0; // [K] Temperature measured by sensor is usually at least 3K too high.
#endif
bool auto_calibrate_sensor = AUTO_CALIBRATE_SENSOR; // [true / false]
const bool debug_sensor_states = false; // If true, log state transitions over serial console
}
......@@ -65,6 +52,10 @@ namespace sensor {
state current_state = BOOTUP;
void switchState(state);
void setCO2forDebugging(int32_t fakeCo2);
void calibrateSensorToSpecificPPM(int32_t calibrationLevel);
void calibrateSensorRightNow(int32_t calibrationLevel);
void setAutoCalibration(int32_t autoCalibration);
void initialize() {
#if defined(ESP8266)
......@@ -95,14 +86,17 @@ namespace sensor {
// for acclimatization. Resetting it after startup seems to fix this behaviour.
scd30.reset();
//NOTE: It seems that the sensor needs some time for getting/setting temperature offset.
delay(500);
Serial.print(F("Setting temperature offset to -"));
Serial.print(abs(config::temperature_offset));
Serial.println(F(" K."));
scd30.setTemperatureOffset(abs(config::temperature_offset)); // setTemperatureOffset only accepts positive numbers, but shifts the temperature down.
delay(100);
delay(500);
Serial.print(F("Temperature offset is : -"));
Serial.print(scd30.getTemperatureOffset());
//NOTE: Even once the temperature offset is saved, the sensor still needs some time (~10 minutes?) to apply it.
Serial.print(F("Temperature offset is : "));
Serial.print(getTemperatureOffset());
Serial.println(F(" K"));
Serial.print(F("Auto-calibration is "));
......@@ -116,7 +110,7 @@ namespace sensor {
Serial.println(F(" s during acclimatization."));
scd30.setMeasurementInterval(config::measurement_timestep_bootup); // [s]
sensor_console::defineIntCommand("co2", setCO2forDebugging, F("1500 (Sets co2 level, for debugging purposes)"));
sensor_console::defineIntCommand("co2", setCO2forDebugging, F("1500 (Sets co2 level, for debugging)"));
sensor_console::defineIntCommand("timer", setTimer, F("30 (Sets measurement interval, in s)"));
sensor_console::defineCommand("calibrate", startCalibrationProcess, F("(Starts calibration process)"));
sensor_console::defineIntCommand("calibrate", calibrateSensorToSpecificPPM,
......@@ -243,7 +237,7 @@ namespace sensor {
delay(100);
} else {
// Display a flashing led ring, if concentration exceeds a specific value
led_effects::redAlert();
led_effects::alert(color::red);
}
}
......@@ -294,6 +288,10 @@ namespace sensor {
return freshData && (current_state == READY || current_state == NEEDS_CALIBRATION);
}
float getTemperatureOffset() {
return -abs(scd30.getTemperatureOffset());
}
/*****************************************************************
* Callbacks for sensor commands *
*****************************************************************/
......
......@@ -3,13 +3,6 @@
#include <stdint.h> // For uint16_t
namespace config {
extern uint16_t measurement_timestep; // [s] Value between 2 and 1800 (range for SCD30 sensor)
extern bool auto_calibrate_sensor; // [true / false]
extern uint16_t co2_calibration_level; // [ppm]
extern const float temperature_offset; // [K] Sign isn't relevant.
}
namespace sensor {
extern uint16_t co2;
extern float temperature;
......@@ -19,12 +12,8 @@ namespace sensor {
void initialize();
bool processData();
void startCalibrationProcess();
void setCO2forDebugging(int32_t fakeCo2);
void setTimer(int32_t timestep);
void calibrateSensorToSpecificPPM(int32_t calibrationLevel);
void calibrateSensorRightNow(int32_t calibrationLevel);
void setAutoCalibration(int32_t autoCalibration);
void resetSCD();
float getTemperatureOffset();
}
#endif
<
#ifndef CONFIG_H_INCLUDED
# define CONFIG_H_INCLUDED
// This file is a config template, and can be copied to config.h. Please don't save any important password in this template.
/*** _ _
* / \ _ __ ___ _ __ ___| |
* / _ \ | '_ ` _ \| '_ \ / _ \ |
* / ___ \| | | | | | |_) | __/ |
* /_/ __\_\_| |_| |_| .__/_\___|_|
* / ___|___ _ __|_/ _(_) __ _
* | | / _ \| '_ \| |_| |/ _` |
* | |__| (_) | | | | _| | (_| |
* \____\___/|_| |_|_| |_|\__, |
* |___/
***/
// This file is a config template, and can be copied to config.h.
// Please don't save any important password in this template.
// IMPORTANT: Parameters defined in config.h are only default values, and are applied if:
// * the ampel is flashed for the first time
// * or 'reset_config' command is called
// * or AMPEL_CONFIG_VERSION has been changed.
// Once those default values have been applied, uploading the firmware with a modified config.h will not update the ampel configuration!
// Every parameter can be modified and saved later via the web-config.
// Some of those parameters can also be modified via commands in the Serial monitor :
// e.g. 'wifi 0' to turn WiFi off, or 'csv 60' to log data in csv every minute.
/***
* AMPEL
*/
// You can rename the Ampel if you want.
// This name will be used for CSV files and the mDNS address.
// You'll get a new CSV file after renaming, which can be convenient, e.g. after moving
// the ampel to another room.
// If left empty, the name will be ESPxxxxxx, where xxxxxx represent the last half of the MAC address.
# define AMPEL_NAME ""
// This password will be used for Access Point (without username), and for web-server available at http://local_ip with user 'admin', without quotes.
// If left empty, the password will have to be set during the first configuration, via access point.
// In order to be set successfully, it should have at least 8 characters.
# define AMPEL_PASSWORD ""
// AMPEL_CONFIG_VERSION should be defined, and have exactly 3 characters.
// If you modify this string, every parameter saved on the Ampel will be replaced by the ones in config.h.
// AMPEL_CONFIG_VERSION should also be updated if the configuration structure is modified.
// The structure of the Ampel configuration has been modified 11 times, so it's called "a11" for now.
# define AMPEL_CONFIG_VERSION "a11"
/**
* SERVICES
*/
// Comment or remove those lines if you want to disable the corresponding services
# define AMPEL_WIFI // Should ESP connect to WiFi? It allows the Ampel to get time from an NTP server.
# define AMPEL_HTTP // Should HTTP web server be started? (AMPEL_WIFI should be enabled too)
# define AMPEL_MQTT // Should data be sent over MQTT? (AMPEL_WIFI should be enabled too)
# define AMPEL_CSV // Should data be logged as CSV, on the ESP flash memory?
// # define AMPEL_LORAWAN // Should data be sent over LoRaWAN? (Requires ESP32 + LoRa modem, and "MCCI LoRaWAN LMIC library")
// Define the default for corresponding services. They can be enabled/disabled later in the web-config.
# define AMPEL_WIFI true // Should ESP connect to WiFi? Web configuration will not be available when set to false. Use "wifi 1" command to set to true.
# define AMPEL_MQTT true // Should data be sent over MQTT? (AMPEL_WIFI should be enabled too)
# define AMPEL_CSV true // Should data be logged as CSV, on the ESP flash memory?
# define AMPEL_LORAWAN false // Should data be sent over LoRaWAN? (Requires ESP32 + LoRa modem, and "MCCI LoRaWAN LMIC library")
/**
* WIFI
*/
# define WIFI_SSID "MY_SSID"
# define WIFI_PASSWORD "P4SSW0RD"
// SSID and PASSWORD need to be defined, but can be empty.
# define WIFI_SSID ""
# define WIFI_PASSWORD ""
// How long should the Ampel try to connect to WIFI_SSID?
# define WIFI_TIMEOUT 30 // [s]
// If the Ampel cannot connect to WIFI_SSID, it will start an Access Point for ACCESS_POINT_TIMEOUT seconds.
// If someone connects to this Access Point, the Ampel will stay in this mode until everybody logs out.
// If nobody connects to the Access Point before ACCESS_POINT_TIMEOUT seconds, the Ampel will try to connect WIFI_SSID again.
# define ACCESS_POINT_TIMEOUT 60 // [s]
/**
* Sensor
......@@ -61,22 +107,14 @@
// LED brightness, which can vary between min and max brightness ("LED breathing")
// MAX_BRIGHTNESS must be defined, and should be between 0 and 255.
# define MAX_BRIGHTNESS 255
// MIN_BRIGHTNESS, if defined, should be between 0 and MAX_BRIGHTNESS - 1
// If MIN_BRIGHTNESS is not set, or if it is set to MAX_BRIGHTNESS, breathing is disabled.
# define MIN_BRIGHTNESS 60
// How many LEDs in the ring? 12 and 16 are currently supported. If undefined, 12 is used as default.
// NOTE: LEDs require a decent amount of electricity, so the default is chosen to be relativitely low.
# define MAX_BRIGHTNESS 80
// MIN_BRIGHTNESS, must be defined, and should be between 0 and MAX_BRIGHTNESS
// If MIN_BRIGHTNESS is set to MAX_BRIGHTNESS, breathing is disabled.
# define MIN_BRIGHTNESS 40
// How many LEDs in the ring? 12 and 16 are currently supported.
# define LED_COUNT 12
/**
* WEB SERVER
* available at http://local_ip, with user HTTP_USER and password HTTP_PASSWORD
*/
// Define empty strings in order to disable authentication, or remove the constants altogether.
# define HTTP_USER "co2ampel"
# define HTTP_PASSWORD "my_password"
/**
* MQTT
*/
......@@ -107,48 +145,49 @@
// How often should measurements be sent to MQTT server?
// Set to 0 if you want to send values after each measurement
// # define MQTT_SENDING_INTERVAL MEASUREMENT_TIMESTEP * 5 // [s]
# define MQTT_SENDING_INTERVAL 60 // [s]
# define MQTT_SENDING_INTERVAL 300 // [s]
# define MQTT_SERVER "test.mosquitto.org" // MQTT server URL or IP address
# define MQTT_PORT 8883
# define MQTT_ENCRYPTED true // Set to false for unencrypted MQTT (e.g. with port 1883). If undefined, MQTT_ENCRYPTED will be set to true.
# define MQTT_ENCRYPTED true // Set to false for unencrypted MQTT (e.g. with port 1883).
# define MQTT_USER ""
# define MQTT_PASSWORD ""
# define MQTT_TOPIC_PREFIX "CO2sensors/" // ESPxxxxxx will be added to the prefix, so complete topic will be "CO2sensors/ESPxxxxxx". The prefix should probably end with '/'