Commit 1600799a authored by Eric Duminil's avatar Eric Duminil
Browse files

Merge branch 'develop'

parents 6412c4ea cb136628
Pipeline #4025 passed with stage
in 1 minute and 47 seconds
......@@ -17,12 +17,13 @@ The *CO<sub>2</sub> Ampel* can:
* Send data over [LoRaWAN](https://en.wikipedia.org/wiki/LoRa#LoRaWAN).
* Display measurements and configuration on a small website.
* Log data to a [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) file, directly on the ESP flash memory.
* Accept many interactive commands.
## Hardware Requirements
* [ESP8266](https://en.wikipedia.org/wiki/ESP8266) or [ESP32](https://en.wikipedia.org/wiki/ESP32) microcontroller (this project has been tested with *ESP8266 ESP-12 WIFI* and *TTGO ESP32 SX1276 LoRa*)
* [Sensirion SCD30](https://www.sensirion.com/en/environmental-sensors/carbon-dioxide-sensors/carbon-dioxide-sensors-co2/) "Sensor Module for HVAC and Indoor Air Quality Applications"
* [NeoPixel Ring - 12](https://www.adafruit.com/product/1643)
* [NeoPixel Ring - 12](https://www.adafruit.com/product/1643), or [NeoPixel Ring - 16](https://www.adafruit.com/product/1463) (experimental)
See the [documentation](https://transfer.hft-stuttgart.de/gitlab/co2ampel/ampel-documentation) for more info.
......@@ -67,6 +68,33 @@ make upload board=esp32 && make monitor # For ESP32
* *Upload*
* *Tools > Serial Monitor*
## Available commands
In Arduino IDE *Serial Monitor* or PlatformIO *Monitor*, type `help` + <kbd>Enter</kbd> in order to list the available commands:
* `auto_calibrate 0/1` (Disables/enables autocalibration).
* `calibrate` (Starts calibration process).
* `calibrate 600` (Starts calibration process, to given ppm).
* `calibrate! 600` (Calibrates right now, to given ppm).
* `co2 1500` (Sets co2 level, for debugging purposes).
* `color 0xFF0015` (Shows color, specified as RGB, for debugging).
* `csv 60` (Sets CSV writing interval, in s).
* `format_filesystem` (Deletes the whole filesystem).
* `free` (Displays available heap space).
* `local_ip` (Displays local IP and current SSID).
* `lora 300` (Sets LoRaWAN sending interval, in s).
* `mqtt 60` (Sets MQTT sending interval, in s).
* `night_mode` (Toggles night mode on/off).
* `reset` (Restarts the sensor).
* `reset_scd` (Resets SCD30).
* `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).
* `timer 30` (Sets measurement interval, in s).
* `wifi_scan` (Scans available WiFi networks).
The commands can be sent via the Serial interface, from the webpage or via MQTT.
## Authors
* Eric Duminil (HfT Stuttgart)
......
......@@ -113,6 +113,7 @@ namespace sensor {
sensor_console::defineIntCommand("calibrate!", calibrateSensorRightNow,
F("600 (Calibrates right now, to given ppm)"));
sensor_console::defineIntCommand("auto_calibrate", setAutoCalibration, F("0/1 (Disables/enables autocalibration)"));
sensor_console::defineCommand("reset_scd", resetSCD, F("(Resets SCD30)"));
}
bool hasSensorSettled() {
......@@ -157,13 +158,14 @@ namespace sensor {
switchState(PREPARE_CALIBRATION_UNSTABLE);
}
void calibrateAndRestart() {
void calibrate() {
Serial.print(F("Calibrating SCD30 now..."));
scd30.setAltitudeCompensation(config::altitude_above_sea_level);
scd30.setForcedRecalibrationFactor(config::co2_calibration_level);
Serial.println(F(" Done!"));
Serial.println(F("Sensor calibrated."));
ESP.restart(); // softer than ESP.reset
//WARNING: Do not reset the ampel or the SCD30!
//At least one measurement needs to happen in order for the calibration to be correctly applied.
}
void logToSerial() {
......@@ -209,7 +211,7 @@ namespace sensor {
// leave them before calibration is done.
bool ready_for_calibration = countStableMeasurements();
if (ready_for_calibration) {
calibrateAndRestart();
calibrate();
}
} else if (co2 < 250) {
// Sensor should be calibrated.
......@@ -325,7 +327,13 @@ namespace sensor {
config::co2_calibration_level = calibrationLevel;
Serial.print(config::co2_calibration_level);
Serial.println(F(" ppm."));
calibrateAndRestart();
calibrate();
}
}
void resetSCD() {
Serial.print(F("Resetting SCD30..."));
scd30.reset();
Serial.println(F("done."));
}
}
......@@ -33,5 +33,6 @@ namespace sensor {
void calibrateSensorToSpecificPPM(int32_t calibrationLevel);
void calibrateSensorRightNow(int32_t calibrationLevel);
void setAutoCalibration(int32_t autoCalibration);
void resetSCD();
}
#endif
......@@ -30,10 +30,9 @@ namespace mqtt {
void initialize(const char *sensorId) {
json_sensor_format = PSTR("{\"time\":\"%s\", \"co2\":%d, \"temp\":%.1f, \"rh\":%.1f}");
snprintf(publish_topic, sizeof(publish_topic), "CO2sensors/%s", sensorId);
#if defined(ESP8266)
espClient.setInsecure(); // Sorry, we don't want to flash the sensors every 3 months.
#endif
// mqttClient.setSocketTimeout(config::mqtt_timeout); //NOTE: somehow doesn't seem to have any effect on connect()
// The sensor doesn't check the fingerprint of the MQTT broker, because otherwise this fingerprint should be updated
// on the sensor every 3 months. The connection can still be encrypted, though:
espClient.setInsecure(); // If not available for ESP32, please update Arduino IDE / PlatformIO
mqttClient.setServer(config::mqtt_server, config::mqtt_port);
sensor_console::defineIntCommand("mqtt", setMQTTinterval, F("60 (Sets MQTT sending interval, in s)"));
......
......@@ -34,7 +34,7 @@ Code
The MIT License (MIT)
Copyright (c) 2016 SparkFun Electronics
Copyright (c) 2020 SparkFun Electronics
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
......
......@@ -24,6 +24,7 @@ Thanks to!
* [awatterott](https://github.com/awatterott) for adding [getAltitudeCompensation()](https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library/pull/18)
* [jogi-k](https://github.com/jogi-k) for adding [teensy i2clib](https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library/pull/19) support
* [paulvha](https://github.com/paulvha) for the suggestions and corrections in [his version of the library](https://github.com/paulvha/scd30)
* [yamamaya](https://github.com/yamamaya) for the [3ms delay](https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library/pull/24)
Repository Contents
-------------------
......@@ -43,8 +44,6 @@ License Information
This product is _**open source**_!
Various bits of the code have different licenses applied. Anything SparkFun wrote is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round!
Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license.
Distributed as-is; no warranty is given.
......
name=SparkFun SCD30 Arduino Library
version=1.0.11
version=1.0.13
author=SparkFun Electronics
maintainer=SparkFun Electronics <sparkfun.com>
sentence=Library for the Sensirion SCD30 CO2 Sensor
......
......@@ -266,6 +266,8 @@ bool SCD30::readMeasurement()
if (_i2cPort->endTransmission() != 0)
return (0); //Sensor did not ACK
delay(3);
const uint8_t receivedBytes = _i2cPort->requestFrom((uint8_t)SCD30_ADDRESS, (uint8_t)18);
bool error = false;
if (_i2cPort->available())
......@@ -358,6 +360,8 @@ bool SCD30::getSettingValue(uint16_t registerAddress, uint16_t *val)
if (_i2cPort->endTransmission() != 0)
return (false); //Sensor did not ACK
delay(3);
_i2cPort->requestFrom((uint8_t)SCD30_ADDRESS, (uint8_t)3); // Request data and CRC
if (_i2cPort->available())
{
......@@ -389,6 +393,8 @@ uint16_t SCD30::readRegister(uint16_t registerAddress)
if (_i2cPort->endTransmission() != 0)
return (0); //Sensor did not ACK
delay(3);
_i2cPort->requestFrom((uint8_t)SCD30_ADDRESS, (uint8_t)2);
if (_i2cPort->available())
{
......
......@@ -57,9 +57,10 @@
#define COMMAND_STOP_MEAS 0x0104
#define COMMAND_READ_FW_VER 0xD100
typedef union {
byte array[4];
float value;
typedef union
{
byte array[4];
float value;
} ByteToFl; // paulvha
class SCD30
......@@ -69,9 +70,9 @@ public:
bool begin(bool autoCalibrate) { return begin(Wire, autoCalibrate); }
#ifdef USE_TEENSY3_I2C_LIB
bool begin(i2c_t3 &wirePort = Wire, bool autoCalibrate=true, bool measBegin=true); //By default use Wire port
bool begin(i2c_t3 &wirePort = Wire, bool autoCalibrate = false, bool measBegin = true); //By default use Wire port
#else
bool begin(TwoWire &wirePort = Wire, bool autoCalibrate=true, bool measBegin=true); //By default use Wire port
bool begin(TwoWire &wirePort = Wire, bool autoCalibrate = false, bool measBegin = true); //By default use Wire port
#endif
void enableDebugging(Stream &debugPort = Serial); //Turn on debug printing. If user doesn't specify then Serial will be used.
......@@ -82,11 +83,11 @@ public:
// based on paulvha
bool getSettingValue(uint16_t registerAddress, uint16_t *val);
bool getForcedRecalibration(uint16_t *val) {return(getSettingValue(COMMAND_SET_FORCED_RECALIBRATION_FACTOR, val));}
bool getMeasurementInterval(uint16_t *val) {return(getSettingValue(COMMAND_SET_MEASUREMENT_INTERVAL, val));}
bool getTemperatureOffset(uint16_t *val) {return(getSettingValue(COMMAND_SET_TEMPERATURE_OFFSET, val));}
bool getAltitudeCompensation(uint16_t *val) {return(getSettingValue(COMMAND_SET_ALTITUDE_COMPENSATION, val));}
bool getFirmwareVersion(uint16_t *val) {return(getSettingValue(COMMAND_READ_FW_VER, val));}
bool getForcedRecalibration(uint16_t *val) { return (getSettingValue(COMMAND_SET_FORCED_RECALIBRATION_FACTOR, val)); }
bool getMeasurementInterval(uint16_t *val) { return (getSettingValue(COMMAND_SET_MEASUREMENT_INTERVAL, val)); }
bool getTemperatureOffset(uint16_t *val) { return (getSettingValue(COMMAND_SET_TEMPERATURE_OFFSET, val)); }
bool getAltitudeCompensation(uint16_t *val) { return (getSettingValue(COMMAND_SET_ALTITUDE_COMPENSATION, val)); }
bool getFirmwareVersion(uint16_t *val) { return (getSettingValue(COMMAND_READ_FW_VER, val)); }
uint16_t getCO2(void);
float getHumidity(void);
......@@ -115,12 +116,11 @@ public:
uint8_t computeCRC8(uint8_t data[], uint8_t len);
private:
//Variables
#ifdef USE_TEENSY3_I2C_LIB
i2c_t3 *_i2cPort; //The generic connection to user's chosen I2C hardware
#else
TwoWire *_i2cPort; //The generic connection to user's chosen I2C hardware
TwoWire *_i2cPort; //The generic connection to user's chosen I2C hardware
#endif
//Global main datums
float co2 = 0;
......@@ -136,6 +136,5 @@ private:
//Debug
Stream *_debugPort; //The stream to send debug messages to if enabled. Usually Serial.
boolean _printDebug = false; //Flag to print debugging variables
};
#endif
......@@ -38,7 +38,7 @@ class Ampel {
private:
static void showFreeSpace();
public:
const char *version = "v0.1.1"; // Update manually after significant changes.
const char *version = "v0.2.0"; // Update manually after significant changes.
const char *board;
const char *sensorId;
uint32_t max_loop_duration;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment