Skip to content
Snippets Groups Projects
Verified Commit fea5ac8f authored by Zoe Michaela Dietmar Pfister's avatar Zoe Michaela Dietmar Pfister :gay_pride_flag:
Browse files

initial version of DS18B20 (cheap) temperature sensor

parent 3593da7b
No related branches found
No related tags found
2 merge requests!39Merge Develop into Main,!31Resolve "Cheap DS18B20 Sensor"
Pipeline #103351 passed
//
// Created by zoe on 3/23/23.
//
#include "DS18B20.h"
std::list<Measurement> DS18B20::readData() {
sensors.requestTemperatures();
float temperature = sensors.getTempC(sensorAddress);
if (temperature == DEVICE_DISCONNECTED_C) {
Serial.println("Error: Could not read temperature data");
// error measurement
auto errorMessage = Measurement(ERROR_VALUE, NO_CHANNEL, NO_I2C_ADDRESS, MeasurementType::TEMPERATURE,
ErrorType::SENSOR_NOT_CONNECTED);
return std::list<Measurement>{errorMessage};
}
auto measurement =
Measurement(temperature, NO_CHANNEL, NO_I2C_ADDRESS, MeasurementType::TEMPERATURE, ErrorType::DATA_OK);
return std::list<Measurement>{measurement};
}
std::list<Message> DS18B20::buildMessages() {
std::list<Message> messages;
auto measurements = readData();
for (auto measurement : measurements) {
messages.emplace_back(measurement, getSensorInformation(), Time::getInstance().getEpochSeconds());
}
return messages;
}
SensorInformation DS18B20::getSensorInformation() const {
return {HardwareName::DS18B20, SensorProtocol::OneWire};
}
void DS18B20::setup() {
ESP_LOGD("DS18B20", "Setting up DS18B20\n");
oneWire = OneWireSingleton::getInstance().getOneWire(33);
sensors = DallasTemperature(oneWire.get());
sensors.begin();
ESP_LOGD("DS18B20", "Found %d devices\n", sensors.getDeviceCount());
ESP_LOGD("DS18B20", "Parasite power is: %s\n", sensors.isParasitePowerMode() ? "ON" : "OFF");
// TODO: This is hardcoded to only use the first device
if (!sensors.getAddress(sensorAddress, 0)) {
ESP_LOGD("DS18B20", "Unable to find address for Device 0\n");
}
ESP_LOGD("DS18B20", "Device 0 Address: %s\n", getAddressString(sensorAddress).c_str());
// set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
sensors.setResolution(sensorAddress, 9);
ESP_LOGD("DS18B20", "Device 0 Resolution: %d\n", sensors.getResolution(sensorAddress));
ESP_LOGD("DS18B20", "Setup complete\n");
}
//
// Created by zoe on 3/23/23.
//
#ifndef CLIENT_SATELLITE_DS18B20_H
#define CLIENT_SATELLITE_DS18B20_H
#include <ForteSensor.hpp>
#include "DallasTemperature.h"
#include <OneWire.h>
#include <OneWireSingleton.h>
class DS18B20 : ForteSensor<std::list<Measurement>> {
public:
void setup() override;
std::list<Measurement> readData() override;
std::list<Message> buildMessages() override;
[[nodiscard]] SensorInformation getSensorInformation() const override;
private:
std::shared_ptr<OneWire> oneWire;
DallasTemperature sensors;
DeviceAddress sensorAddress;
// function to print a device address
String getAddressString(DeviceAddress deviceAddress) {
String addressString = "";
for (uint8_t i = 0; i < 8; i++) {
if (deviceAddress[i] < 16) {
addressString += "0";
}
char hexBuffer[3];
snprintf(hexBuffer, sizeof(hexBuffer), "%02X", deviceAddress[i]);
addressString += hexBuffer;
}
return addressString;
}
};
#endif // CLIENT_SATELLITE_DS18B20_H
//
// Created by zoe on 3/23/23.
//
#include "OneWireSingleton.h"
std::shared_ptr<OneWire> OneWireSingleton::getOneWire(int pin) {
if (oneWireMap.find(pin) == oneWireMap.end()) {
oneWireMap[pin] = std::make_shared<OneWire>(OneWire(pin));
}
return oneWireMap[pin];
}
\ No newline at end of file
//
// Created by zoe on 3/23/23.
//
#ifndef CLIENT_SATELLITE_ONEWIRESINGLETON_H
#define CLIENT_SATELLITE_ONEWIRESINGLETON_H
#include <OneWire.h>
#include <memory>
class OneWireSingleton {
public:
static OneWireSingleton &getInstance() {
static OneWireSingleton instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
// This returns a shared pointer to the OneWire object. I made this shared so that the OneWire object is only
// cleared when not only the singleton is destroyed, but when the last reference to the OneWire object is
// destroyed.
std::shared_ptr<OneWire> getOneWire(int pin);
private:
OneWireSingleton() {} // Constructor? (the {} brackets) are needed here.
std::unordered_map<int, std::shared_ptr<OneWire>> oneWireMap;
// C++ 11
// =======
// We can use the better technique of deleting the methods
// we don't want.
public:
OneWireSingleton(OneWireSingleton const &) = delete;
void operator=(OneWireSingleton const &) = delete;
// Note: Scott Meyers mentions in his Effective Modern
// C++ book, that deleted functions should generally
// be public as it results in better error messages
// due to the compilers behavior to check accessibility
// before deleted status
};
#endif // CLIENT_SATELLITE_ONEWIRESINGLETON_H
......@@ -126,7 +126,7 @@ esp_err_t espnow_setup() {
if (result != ESP_OK) {
// initialization failed
ESP_LOGE(TAG, "ESPNow setup failed");
return result; // not sure about this
return result;
}
get_host_mac(hostInfo.peer_addr); // check if there is a host saved in flash mem, broadcast otherwise
......
......@@ -4,42 +4,44 @@
#include "HardwareNames.h"
namespace HardwareNames {
std::string hardwareNameToString(HardwareName hardwareName) {
// switch
switch (hardwareName) {
case HardwareName::RS485:
return "RS485";
case HardwareName::INA219:
return "INA219";
case HardwareName::SCD30:
return "SCD30";
case HardwareName::RAIN_GAUGE:
return "RAIN_GAUGE";
case HardwareName::SOIL_MOISTURE_SENSOR:
return "SOIL_MOISTURE_SENSOR";
case HardwareName::SOIL_TEMPERATURE_SENSOR:
return "SOIL_TEMPERATURE_SENSOR";
case HardwareName::SOLAR_RADIATION_SENSOR:
return "SOLAR_RADIATION_SENSOR";
case HardwareName::SHT85:
return "SHT85";
case HardwareName::DRS26:
return "DRS26";
case HardwareName::DR26:
return "DR26";
case HardwareName::MOCK:
return "MOCK";
case HardwareName::NONE:
return "NONE";
case HardwareName::LC709203:
return "LC709203";
case HardwareName::SEM228A:
return "SEM228A";
case HardwareName::SEM225:
return "SEM225";
case HardwareName::SEM404:
return "SEM404";
}
return "UNKNOWN_HARDWARE_NAME";
}
std::string hardwareNameToString(HardwareName hardwareName) {
// switch
switch (hardwareName) {
case HardwareName::RS485:
return "RS485";
case HardwareName::INA219:
return "INA219";
case HardwareName::SCD30:
return "SCD30";
case HardwareName::RAIN_GAUGE:
return "RAIN_GAUGE";
case HardwareName::SOIL_MOISTURE_SENSOR:
return "SOIL_MOISTURE_SENSOR";
case HardwareName::SOIL_TEMPERATURE_SENSOR:
return "SOIL_TEMPERATURE_SENSOR";
case HardwareName::SOLAR_RADIATION_SENSOR:
return "SOLAR_RADIATION_SENSOR";
case HardwareName::SHT85:
return "SHT85";
case HardwareName::DRS26:
return "DRS26";
case HardwareName::DR26:
return "DR26";
case HardwareName::MOCK:
return "MOCK";
case HardwareName::NONE:
return "NONE";
case HardwareName::LC709203:
return "LC709203";
case HardwareName::SEM228A:
return "SEM228A";
case HardwareName::SEM225:
return "SEM225";
case HardwareName::SEM404:
return "SEM404";
case HardwareName::DS18B20:
return "DS18B20";
}
return "UNKNOWN_HARDWARE_NAME";
}
} // namespace HardwareNames
\ No newline at end of file
......@@ -9,29 +9,29 @@
// 32,767 possible values
enum class HardwareName : short {
RS485, // TODO: THIS IS THE PROTOCOL NAME NOT THE HARDWARE NAME
INA219,
SCD30,
RAIN_GAUGE,
SOIL_MOISTURE_SENSOR,
SOIL_TEMPERATURE_SENSOR,
SOLAR_RADIATION_SENSOR,
SEM404,
SEM228A,
SEM225,
SHT85,
DRS26,
DR26,
MOCK,
NONE,
LC709203,
RS485, // TODO: THIS IS THE PROTOCOL NAME NOT THE HARDWARE NAME
INA219,
SCD30,
RAIN_GAUGE,
SOIL_MOISTURE_SENSOR,
SOIL_TEMPERATURE_SENSOR,
SOLAR_RADIATION_SENSOR,
SEM404,
SEM228A,
SEM225,
DS18B20,
SHT85,
DRS26,
DR26,
MOCK,
NONE,
LC709203,
};
// hardware name to string function
namespace HardwareNames {
std::string hardwareNameToString(HardwareName hardwareName);
std::string hardwareNameToString(HardwareName hardwareName);
}
#endif //CLIENT_MOCK_HARDWARENAMES_H
#endif // CLIENT_MOCK_HARDWARENAMES_H
......@@ -4,19 +4,21 @@
#include "SensorProtocol.hpp"
namespace SensorProtocols {
std::string sensorProtocolToString(SensorProtocol sensorProtocol) {
switch (sensorProtocol) {
case SensorProtocol::I2C:
return "I2C";
case SensorProtocol::RS485:
return "RS485";
case SensorProtocol::Analog:
return "Analog";
case SensorProtocol::Mock:
return "Mock";
case SensorProtocol::NULL_PROTOCOL:
return "NULL_PROTOCOL";
}
return "UNKNOWN";
}
}
\ No newline at end of file
std::string sensorProtocolToString(SensorProtocol sensorProtocol) {
switch (sensorProtocol) {
case SensorProtocol::I2C:
return "I2C";
case SensorProtocol::RS485:
return "RS485";
case SensorProtocol::Analog:
return "Analog";
case SensorProtocol::Mock:
return "Mock";
case SensorProtocol::OneWire:
return "OneWire";
case SensorProtocol::NULL_PROTOCOL:
return "NULL_PROTOCOL";
}
return "UNKNOWN";
}
} // namespace SensorProtocols
\ No newline at end of file
......@@ -6,7 +6,7 @@
#define CLIENT_PROTOCOL_HPP
#include <map>
enum class SensorProtocol : short { I2C, RS485, Analog, Mock, NULL_PROTOCOL };
enum class SensorProtocol : short { I2C, RS485, Analog, Mock, OneWire, NULL_PROTOCOL };
namespace SensorProtocols {
std::string sensorProtocolToString(SensorProtocol sensorProtocol);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment