diff --git a/client/libs/DS18B20/DS18B20.cpp b/client/libs/DS18B20/DS18B20.cpp new file mode 100644 index 0000000000000000000000000000000000000000..850951f6d559def960e5338667fcba9022eece2c --- /dev/null +++ b/client/libs/DS18B20/DS18B20.cpp @@ -0,0 +1,57 @@ +// +// 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"); +} diff --git a/client/libs/DS18B20/DS18B20.h b/client/libs/DS18B20/DS18B20.h new file mode 100644 index 0000000000000000000000000000000000000000..45dc6e70c2d90226040622827a8bd70725aea376 --- /dev/null +++ b/client/libs/DS18B20/DS18B20.h @@ -0,0 +1,41 @@ +// +// 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 diff --git a/client/libs/OneWireSingelton/OneWireSingleton.cpp b/client/libs/OneWireSingelton/OneWireSingleton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4591b8012e0418a6571bca2151ab4d76053f9fd8 --- /dev/null +++ b/client/libs/OneWireSingelton/OneWireSingleton.cpp @@ -0,0 +1,12 @@ +// +// 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 diff --git a/client/libs/OneWireSingelton/OneWireSingleton.h b/client/libs/OneWireSingelton/OneWireSingleton.h new file mode 100644 index 0000000000000000000000000000000000000000..bc63fc3cda5469dd104ff49e0cd563aaf019407f --- /dev/null +++ b/client/libs/OneWireSingelton/OneWireSingleton.h @@ -0,0 +1,44 @@ +// +// 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 diff --git a/client/libs/espnow/src/ESPNow.cpp b/client/libs/espnow/src/ESPNow.cpp index 6ef9054a64321ec0318602b66b738fd7ccc4f3f9..8d046c875b97624549374878a9e1f44e5d2b7f0d 100644 --- a/client/libs/espnow/src/ESPNow.cpp +++ b/client/libs/espnow/src/ESPNow.cpp @@ -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 diff --git a/shared-libs/DataTransfer/HardwareNames.cpp b/shared-libs/DataTransfer/HardwareNames.cpp index 94fbb405a8e7faf9fe22995f3720d12c9876b849..aebd8eedb7805b96b3dea185f575715c2f43cbbb 100644 --- a/shared-libs/DataTransfer/HardwareNames.cpp +++ b/shared-libs/DataTransfer/HardwareNames.cpp @@ -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 diff --git a/shared-libs/DataTransfer/HardwareNames.h b/shared-libs/DataTransfer/HardwareNames.h index ee689f81c5fc58f810fc99d83a2cfa6340fa3b34..c58cea35fbac4ffeb4dc030a58808c23c04746d0 100644 --- a/shared-libs/DataTransfer/HardwareNames.h +++ b/shared-libs/DataTransfer/HardwareNames.h @@ -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 diff --git a/shared-libs/DataTransfer/SensorProtocol.cpp b/shared-libs/DataTransfer/SensorProtocol.cpp index f2aa02da070bf93f3cdee9ca2682b792a6ee62cf..7e6fbbbab78d1da8071294135d0c4fa63ad17983 100644 --- a/shared-libs/DataTransfer/SensorProtocol.cpp +++ b/shared-libs/DataTransfer/SensorProtocol.cpp @@ -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 diff --git a/shared-libs/DataTransfer/SensorProtocol.hpp b/shared-libs/DataTransfer/SensorProtocol.hpp index fb4d0b0f114cb2e10decb6a263044bc05ade7c3d..d8eade29927ee4946f05060bef9e08f6941818cb 100644 --- a/shared-libs/DataTransfer/SensorProtocol.hpp +++ b/shared-libs/DataTransfer/SensorProtocol.hpp @@ -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);