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

WIP: Move MeasurementType, SensorProtocol, and HardwareName strings to enums

parent 3b43bb90
No related branches found
No related tags found
2 merge requests!39Merge Develop into Main,!27Move from json-string based transfer between client and host to C struct / class based transfer
Showing
with 513 additions and 514 deletions
...@@ -4,6 +4,7 @@ board = esp32dev ...@@ -4,6 +4,7 @@ board = esp32dev
framework = arduino framework = arduino
monitor_speed = 115200 monitor_speed = 115200
lib_ldf_mode = deep lib_ldf_mode = deep
upload_port = /dev/ttyUSB0
lib_extra_dirs = lib_extra_dirs =
../libs ../libs
../../shared-libs ../../shared-libs
......
...@@ -85,6 +85,8 @@ void setup() { ...@@ -85,6 +85,8 @@ void setup() {
ESP_LOGD(TAG, "Size of optional int: %d", sizeof(std::optional<int>)); ESP_LOGD(TAG, "Size of optional int: %d", sizeof(std::optional<int>));
// sizeof int // sizeof int
ESP_LOGD(TAG, "Size of int: %d", sizeof(int)); ESP_LOGD(TAG, "Size of int: %d", sizeof(int));
// sizeof short
ESP_LOGD(TAG, "Size of short: %d", sizeof(short));
// sizeof double // sizeof double
ESP_LOGD(TAG, "Size of double: %d", sizeof(double)); ESP_LOGD(TAG, "Size of double: %d", sizeof(double));
// sizeof float // sizeof float
......
...@@ -39,13 +39,13 @@ uint8_t i2c_address = LC709203F_I2C_ADDR; ...@@ -39,13 +39,13 @@ uint8_t i2c_address = LC709203F_I2C_ADDR;
* @return True if initialization was successful, otherwise false. * @return True if initialization was successful, otherwise false.
*/ */
bool LC709203F::begin(void) { bool LC709203F::begin(void) {
Wire.begin(); Wire.begin();
setPowerMode(LC709203F_POWER_OPERATE); setPowerMode(LC709203F_POWER_OPERATE);
setCellCapacity(LC709203F_APA_1000MAH); setCellCapacity(LC709203F_APA_1000MAH);
setTemperatureMode(LC709203F_TEMPERATURE_I2C); setTemperatureMode(LC709203F_TEMPERATURE_I2C);
setCellProfile(LC709203_NOM3p7_Charge4p2); setCellProfile(LC709203_NOM3p7_Charge4p2);
return true; return true;
} }
...@@ -54,9 +54,9 @@ bool LC709203F::begin(void) { ...@@ -54,9 +54,9 @@ bool LC709203F::begin(void) {
* @return 16-bit value read from LC709203F_RO_ICVERSION registers * @return 16-bit value read from LC709203F_RO_ICVERSION registers
*/ */
uint16_t LC709203F::getICversion(void) { uint16_t LC709203F::getICversion(void) {
uint16_t vers = 0; uint16_t vers = 0;
vers = read16(LC709203F_RO_ICVERSION); vers = read16(LC709203F_RO_ICVERSION);
return vers; return vers;
} }
...@@ -65,7 +65,7 @@ uint16_t LC709203F::getICversion(void) { ...@@ -65,7 +65,7 @@ uint16_t LC709203F::getICversion(void) {
* @return * @return
*/ */
void LC709203F::initRSOC(void) { void LC709203F::initRSOC(void) {
write16(LC709203F_WO_INITRSOC, 0xAA55); write16(LC709203F_WO_INITRSOC, 0xAA55);
} }
...@@ -74,9 +74,9 @@ void LC709203F::initRSOC(void) { ...@@ -74,9 +74,9 @@ void LC709203F::initRSOC(void) {
* @return Cell voltage in milliVolt * @return Cell voltage in milliVolt
*/ */
uint16_t LC709203F::cellVoltage_mV(void) { uint16_t LC709203F::cellVoltage_mV(void) {
uint16_t mV = 0; uint16_t mV = 0;
mV = read16(LC709203F_RO_CELLVOLTAGE); mV = read16(LC709203F_RO_CELLVOLTAGE);
return 1000 * (mV / 1000.0); return 1000 * (mV / 1000.0);
} }
...@@ -85,9 +85,9 @@ uint16_t LC709203F::cellVoltage_mV(void) { ...@@ -85,9 +85,9 @@ uint16_t LC709203F::cellVoltage_mV(void) {
* @return point value from 0 to 1000 * @return point value from 0 to 1000
*/ */
uint16_t LC709203F::cellRemainingPercent10(void) { uint16_t LC709203F::cellRemainingPercent10(void) {
uint16_t percent = 0; uint16_t percent = 0;
percent = read16(LC709203F_RO_ITE); percent = read16(LC709203F_RO_ITE);
return percent; return percent;
} }
/*! /*!
...@@ -95,9 +95,9 @@ uint16_t LC709203F::cellRemainingPercent10(void) { ...@@ -95,9 +95,9 @@ uint16_t LC709203F::cellRemainingPercent10(void) {
* @return point value from 0 to 100 * @return point value from 0 to 100
*/ */
uint16_t LC709203F::cellStateOfCharge(void) { uint16_t LC709203F::cellStateOfCharge(void) {
uint16_t percent = 0; uint16_t percent = 0;
percent = read16(LC709203F_RW_RSOC); percent = read16(LC709203F_RW_RSOC);
return percent; return percent;
} }
...@@ -106,9 +106,9 @@ uint16_t LC709203F::cellStateOfCharge(void) { ...@@ -106,9 +106,9 @@ uint16_t LC709203F::cellStateOfCharge(void) {
* @return value from -20 to 60 *C // CdB Needs testing, no thermistor on ESP32_Bat_R2 board * @return value from -20 to 60 *C // CdB Needs testing, no thermistor on ESP32_Bat_R2 board
*/ */
uint16_t LC709203F::getCellTemperature(void) { uint16_t LC709203F::getCellTemperature(void) {
uint16_t temp = 0; uint16_t temp = 0;
temp = read16(LC709203F_RW_CELLTEMPERATURE); temp = read16(LC709203F_RW_CELLTEMPERATURE);
return temp; return temp;
} }
...@@ -118,7 +118,7 @@ uint16_t LC709203F::getCellTemperature(void) { ...@@ -118,7 +118,7 @@ uint16_t LC709203F::getCellTemperature(void) {
* LC709203F_TEMPERATURE_THERMISTOR * LC709203F_TEMPERATURE_THERMISTOR
*/ */
void LC709203F::setTemperatureMode(lc709203_tempmode_t t) { void LC709203F::setTemperatureMode(lc709203_tempmode_t t) {
return write16(LC709203F_RW_STATUSBIT, (uint16_t) t); return write16(LC709203F_RW_STATUSBIT, (uint16_t) t);
} }
...@@ -127,7 +127,7 @@ void LC709203F::setTemperatureMode(lc709203_tempmode_t t) { ...@@ -127,7 +127,7 @@ void LC709203F::setTemperatureMode(lc709203_tempmode_t t) {
* @param apa The lc709203_adjustment_t enumerated approximate cell capacity * @param apa The lc709203_adjustment_t enumerated approximate cell capacity
*/ */
void LC709203F::setCellCapacity(lc709203_adjustment_t apa) { void LC709203F::setCellCapacity(lc709203_adjustment_t apa) {
write16(LC709203F_RW_APA, (uint16_t) apa); write16(LC709203F_RW_APA, (uint16_t) apa);
} }
...@@ -136,7 +136,7 @@ void LC709203F::setCellCapacity(lc709203_adjustment_t apa) { ...@@ -136,7 +136,7 @@ void LC709203F::setCellCapacity(lc709203_adjustment_t apa) {
* @param percent The threshold value, set to 0 to disable alarm * @param percent The threshold value, set to 0 to disable alarm
*/ */
void LC709203F::setAlarmRSOC(uint8_t percent) { void LC709203F::setAlarmRSOC(uint8_t percent) {
write16(LC709203F_RW_ALARMRSOC, percent); write16(LC709203F_RW_ALARMRSOC, percent);
} }
...@@ -145,7 +145,7 @@ void LC709203F::setAlarmRSOC(uint8_t percent) { ...@@ -145,7 +145,7 @@ void LC709203F::setAlarmRSOC(uint8_t percent) {
* @param voltage The threshold value, set to 0 to disable alarm * @param voltage The threshold value, set to 0 to disable alarm
*/ */
void LC709203F::setAlarmVoltage(float voltage) { void LC709203F::setAlarmVoltage(float voltage) {
write16(LC709203F_RW_ALARMVOLT, voltage * 1000); write16(LC709203F_RW_ALARMVOLT, voltage * 1000);
} }
...@@ -156,7 +156,7 @@ void LC709203F::setAlarmVoltage(float voltage) { ...@@ -156,7 +156,7 @@ void LC709203F::setAlarmVoltage(float voltage) {
* @return * @return
*/ */
void LC709203F::setPowerMode(lc709203_powermode_t t) { void LC709203F::setPowerMode(lc709203_powermode_t t) {
write16(LC709203F_RW_POWERMODE, (uint16_t) t); write16(LC709203F_RW_POWERMODE, (uint16_t) t);
} }
/*! /*!
...@@ -165,7 +165,7 @@ void LC709203F::setPowerMode(lc709203_powermode_t t) { ...@@ -165,7 +165,7 @@ void LC709203F::setPowerMode(lc709203_powermode_t t) {
* @return * @return
*/ */
void LC709203F::setCellProfile(lc709203_cell_profile_t t) { void LC709203F::setCellProfile(lc709203_cell_profile_t t) {
write16(LC709203F_RW_PROFILE, (uint16_t) t); write16(LC709203F_RW_PROFILE, (uint16_t) t);
} }
/*! /*!
...@@ -173,9 +173,9 @@ void LC709203F::setCellProfile(lc709203_cell_profile_t t) { ...@@ -173,9 +173,9 @@ void LC709203F::setCellProfile(lc709203_cell_profile_t t) {
* @return The uint16_t Beta value * @return The uint16_t Beta value
*/ */
uint16_t LC709203F::getThermistorBeta(void) { uint16_t LC709203F::getThermistorBeta(void) {
uint16_t val = 0; uint16_t val = 0;
val = read16(LC709203F_RW_THERMISTORB); val = read16(LC709203F_RW_THERMISTORB);
return val; return val;
} }
...@@ -185,17 +185,19 @@ uint16_t LC709203F::getThermistorBeta(void) { ...@@ -185,17 +185,19 @@ uint16_t LC709203F::getThermistorBeta(void) {
* @return * @return
*/ */
void LC709203F::setThermistorB(uint16_t beta) { void LC709203F::setThermistorB(uint16_t beta) {
write16(LC709203F_RW_THERMISTORB, beta); write16(LC709203F_RW_THERMISTORB, beta);
} }
std::list<Message> LC709203F::buildMessages() { std::list<Message> LC709203F::buildMessages() {
std::list<Message> messages; std::list<Message> messages;
float data = cellVoltage_mV() / 1000.0; float data = cellVoltage_mV() / 1000.0;
MeasurementData IncrementData{data, 0, {}, MeasurementData IncrementData{data, 0, {},
measurementTypeToString.at(MeasurementType::BATTERY_VOLTAGE)}; MeasurementType::BATTERY_VOLTAGE};
messages.emplace_back(IncrementData, sensorInformation, Time::getInstance().getEpochSeconds()); messages.emplace_back(IncrementData,
return messages; sensorInformation,
Time::getInstance().getEpochSeconds());
return messages;
} }
...@@ -216,52 +218,52 @@ std::list<Message> LC709203F::buildMessages() { ...@@ -216,52 +218,52 @@ std::list<Message> LC709203F::buildMessages() {
* @return The computed CRC8 value. * @return The computed CRC8 value.
*/ */
static uint8_t crc8(uint8_t *data, int len) { static uint8_t crc8(uint8_t *data, int len) {
const uint8_t POLYNOMIAL(0x07); const uint8_t POLYNOMIAL(0x07);
uint8_t crc(0x00); uint8_t crc(0x00);
for (int j = len; j; --j) { for (int j = len; j; --j) {
crc ^= *data++; crc ^= *data++;
for (int i = 8; i; --i) { for (int i = 8; i; --i) {
crc = (crc & 0x80) ? (crc << 1) ^ POLYNOMIAL : (crc << 1); crc = (crc & 0x80) ? (crc << 1) ^ POLYNOMIAL : (crc << 1);
}
} }
return crc; }
return crc;
} }
// writes a 16-bit word (d) to register pointer regAddress // writes a 16-bit word (d) to register pointer regAddress
// when selecting a register pointer to read from, data = 0 // when selecting a register pointer to read from, data = 0
void LC709203F::write16(uint8_t regAddress, uint16_t data) { void LC709203F::write16(uint8_t regAddress, uint16_t data) {
// Setup array to hold bytes to send including CRC-8 // Setup array to hold bytes to send including CRC-8
uint8_t crcArray[5]; uint8_t crcArray[5];
crcArray[0] = 0x16; crcArray[0] = 0x16;
crcArray[1] = regAddress; crcArray[1] = regAddress;
crcArray[2] = lowByte(data); crcArray[2] = lowByte(data);
crcArray[3] = highByte(data); crcArray[3] = highByte(data);
// Calculate crc of preceding four bytes and place in crcArray[4] // Calculate crc of preceding four bytes and place in crcArray[4]
crcArray[4] = crc8(crcArray, 4); crcArray[4] = crc8(crcArray, 4);
// Device address // Device address
Wire.beginTransmission(i2c_address); Wire.beginTransmission(i2c_address);
// Register address // Register address
Wire.write(regAddress); Wire.write(regAddress);
// low byte // low byte
Wire.write(crcArray[2]); Wire.write(crcArray[2]);
// high byte // high byte
Wire.write(crcArray[3]); Wire.write(crcArray[3]);
// Send crc8 // Send crc8
Wire.write(crcArray[4]); Wire.write(crcArray[4]);
Wire.endTransmission(); Wire.endTransmission();
} }
int16_t LC709203F::read16(uint8_t regAddress) { int16_t LC709203F::read16(uint8_t regAddress) {
int16_t data = 0; int16_t data = 0;
Wire.beginTransmission(i2c_address); Wire.beginTransmission(i2c_address);
Wire.write(regAddress); Wire.write(regAddress);
Wire.endTransmission(false); Wire.endTransmission(false);
Wire.requestFrom(i2c_address, static_cast<uint8_t>(2)); Wire.requestFrom(i2c_address, static_cast<uint8_t>(2));
uint8_t lowByteData = Wire.read(); uint8_t lowByteData = Wire.read();
uint8_t highByteData = Wire.read(); uint8_t highByteData = Wire.read();
data = word(highByteData, lowByteData); data = word(highByteData, lowByteData);
return (data); return (data);
} }
...@@ -40,33 +40,33 @@ static uint8_t crc8(uint8_t *data, int len); ...@@ -40,33 +40,33 @@ static uint8_t crc8(uint8_t *data, int len);
/*! Approx cell capacity Table 7 */ /*! Approx cell capacity Table 7 */
typedef enum { typedef enum {
LC709203F_APA_100MAH = 0x08, LC709203F_APA_100MAH = 0x08,
LC709203F_APA_200MAH = 0x0B, LC709203F_APA_200MAH = 0x0B,
LC709203F_APA_500MAH = 0x10, LC709203F_APA_500MAH = 0x10,
LC709203F_APA_1000MAH = 0x19, LC709203F_APA_1000MAH = 0x19,
LC709203F_APA_2000MAH = 0x2D, LC709203F_APA_2000MAH = 0x2D,
LC709203F_APA_3000MAH = 0x36, LC709203F_APA_3000MAH = 0x36,
} lc709203_adjustment_t; } lc709203_adjustment_t;
/*! Cell profile */ /*! Cell profile */
typedef enum { typedef enum {
LC709203_NOM3p7_Charge4p2 = 1, LC709203_NOM3p7_Charge4p2 = 1,
LC709203_NOM3p8_Charge4p35 = 3, LC709203_NOM3p8_Charge4p35 = 3,
LC709203_NOM3p8_Charge4p35_Less500mAh = 6, LC709203_NOM3p8_Charge4p35_Less500mAh = 6,
LC709203_ICR18650_SAMSUNG = 5, LC709203_ICR18650_SAMSUNG = 5,
LC709203_ICR18650_PANASONIC = 4 LC709203_ICR18650_PANASONIC = 4
} lc709203_cell_profile_t; } lc709203_cell_profile_t;
/*! Cell temperature source */ /*! Cell temperature source */
typedef enum { typedef enum {
LC709203F_TEMPERATURE_I2C = 0x0000, LC709203F_TEMPERATURE_I2C = 0x0000,
LC709203F_TEMPERATURE_THERMISTOR = 0x0001, LC709203F_TEMPERATURE_THERMISTOR = 0x0001,
} lc709203_tempmode_t; } lc709203_tempmode_t;
/*! Chip power state */ /*! Chip power state */
typedef enum { typedef enum {
LC709203F_POWER_OPERATE = 0x0001, LC709203F_POWER_OPERATE = 0x0001,
LC709203F_POWER_SLEEP = 0x0002, LC709203F_POWER_SLEEP = 0x0002,
} lc709203_powermode_t; } lc709203_powermode_t;
/*! /*!
...@@ -74,57 +74,53 @@ typedef enum { ...@@ -74,57 +74,53 @@ typedef enum {
* the LC709203F I2C LiPo monitor * the LC709203F I2C LiPo monitor
*/ */
class LC709203F { class LC709203F {
public: public:
LC709203F(); LC709203F();
~LC709203F(); ~LC709203F();
bool begin(void); bool begin(void);
void initRSOC(void); void initRSOC(void);
void setPowerMode(lc709203_powermode_t t); void setPowerMode(lc709203_powermode_t t);
void setCellCapacity(lc709203_adjustment_t apa); void setCellCapacity(lc709203_adjustment_t apa);
void setCellProfile(lc709203_cell_profile_t t); void setCellProfile(lc709203_cell_profile_t t);
uint16_t getICversion(void); uint16_t getICversion(void);
uint16_t cellVoltage_mV(void); uint16_t cellVoltage_mV(void);
uint16_t cellRemainingPercent10(void); // Remaining capacity in increments of 0.1% as integer uint16_t
uint16_t cellStateOfCharge(void); // In increments of 1% as integer cellRemainingPercent10(void); // Remaining capacity in increments of 0.1% as integer
uint16_t
cellStateOfCharge(void); // In increments of 1% as integer
uint16_t getThermistorBeta(void); uint16_t getThermistorBeta(void);
void setThermistorB(uint16_t beta); void setThermistorB(uint16_t beta);
void setTemperatureMode(lc709203_tempmode_t t); void setTemperatureMode(lc709203_tempmode_t t);
uint16_t getCellTemperature(void); uint16_t getCellTemperature(void);
void setAlarmRSOC(uint8_t percent); void setAlarmRSOC(uint8_t percent);
void setAlarmVoltage(float voltage); void setAlarmVoltage(float voltage);
std::list<Message> buildMessages(); std::list<Message> buildMessages();
protected: protected:
void write16(uint8_t regAddress, uint16_t data); void write16(uint8_t regAddress, uint16_t data);
int16_t read16(uint8_t regAddress); int16_t read16(uint8_t regAddress);
private: private:
const SensorInformation sensorInformation{"LC709203", SensorProtocol::I2C}; const SensorInformation
sensorInformation{HardwareName::LC709203, SensorProtocol::I2C};
enum class MeasurementType {
BATTERY_VOLTAGE,
};
std::map<MeasurementType, const char *> measurementTypeToString = {
{MeasurementType::BATTERY_VOLTAGE, "BATTERY_VOLTAGE"}};
}; };
#endif #endif
...@@ -2,45 +2,46 @@ ...@@ -2,45 +2,46 @@
static const char *TAG = "DR26"; static const char *TAG = "DR26";
void ForteDR26::setup() { void ForteDR26::setup() {
Wire.begin(); Wire.begin();
ads1.setGain(GAIN_ONE); ads1.setGain(GAIN_ONE);
ads1.setDataRate(RATE_ADS1115_8SPS); ads1.setDataRate(RATE_ADS1115_8SPS);
ads1.begin() ? ESP_LOGD(TAG, "ADS initialized") : ESP_LOGE(TAG, "failed to initialize ADS"); ads1.begin() ? ESP_LOGD(TAG, "ADS initialized") : ESP_LOGE(TAG,
delay(100); "failed to initialize ADS");
channel = 0; delay(100);
channel = 0;
} }
float ForteDR26::readData() { float ForteDR26::readData() {
float volts = 0; float volts = 0;
// adjust data rate instead of yourself. ADC averages on its on with low data rate // adjust data rate instead of yourself. ADC averages on its on with low data rate
// FIXME: Test which datarate gets most stable result. If it still is not good enough consider adding a small capacitor or averaging again // FIXME: Test which datarate gets most stable result. If it still is not good enough consider adding a small capacitor or averaging again
// for (int i = 0; i < 10; i++) { // for (int i = 0; i < 10; i++) {
// int16_t adc = 0; // int16_t adc = 0;
// float volt = 0; // float volt = 0;
// try { // try {
// adc = ads1.readADC_SingleEnded(channel); // adc = ads1.readADC_SingleEnded(channel);
// volt = ads1.computeVolts(adc); // volt = ads1.computeVolts(adc);
// } // }
// catch (NoDataAvailableException &e) { // catch (NoDataAvailableException &e) {
// throw NoDataAvailableException(); //propagate exception // throw NoDataAvailableException(); //propagate exception
// } // }
// volts += volt; // volts += volt;
// } // }
// volts /= 10; // volts /= 10;
int16_t adc = 0; int16_t adc = 0;
try { try {
adc = ads1.readADC_SingleEnded(channel); adc = ads1.readADC_SingleEnded(channel);
volts = ads1.computeVolts(adc); volts = ads1.computeVolts(adc);
} }
catch (NoDataAvailableException &e) { catch (NoDataAvailableException &e) {
throw NoDataAvailableException(); //propagate exception throw NoDataAvailableException(); //propagate exception
} }
return volts; return volts;
} }
// The following functions change the ADC input range: be careful // The following functions change the ADC input range: be careful
...@@ -59,33 +60,40 @@ float ForteDR26::readData() { ...@@ -59,33 +60,40 @@ float ForteDR26::readData() {
// GAIN_EIGHT // 8x gain +/- 0.512V 1 bit = 0.015625mV // GAIN_EIGHT // 8x gain +/- 0.512V 1 bit = 0.015625mV
// GAIN_SIXTEEN // 16x gain +/- 0.256V 1 bit = 0.0078125mV // GAIN_SIXTEEN // 16x gain +/- 0.256V 1 bit = 0.0078125mV
void ForteDR26::changeGain(adsGain_t gain) { void ForteDR26::changeGain(adsGain_t gain) {
ads1.setGain(gain); ads1.setGain(gain);
} }
void ForteDR26::setChannel(int c) { void ForteDR26::setChannel(int c) {
channel = c; channel = c;
} }
std::list<Message> ForteDR26::buildMessages() { std::list<Message> ForteDR26::buildMessages() {
std::list<Message> messages; std::list<Message> messages;
float data = readData(); float data = readData();
MeasurementData IncrementData{data, channel, {}, "CIRCUMFERENCE_INCREMENT"}; MeasurementData IncrementData
messages.emplace_back(IncrementData, sensorInformation, Time::getInstance().getEpochSeconds()); {data, channel, {}, MeasurementType::CIRCUMFERENCE_INCREMENT};
return messages; messages.emplace_back(IncrementData,
sensorInformation,
Time::getInstance().getEpochSeconds());
return messages;
} }
// FIXME: passing the measurementType as a string is not a good idea, we should use an enum like we do for other sensors // FIXME: passing the measurementType as a string is not a good idea, we should use an enum like we do for other sensors
std::list<Message> ForteDR26::buildMessages(std::string measurementType) { std::list<Message> ForteDR26::buildMessages(MeasurementType measurementType) {
std::list<Message> messages; std::list<Message> messages;
float data = readData(); float data = readData();
MeasurementData IncrementData{data, channel, {}, measurementType}; MeasurementData IncrementData{data, channel, {}, measurementType};
messages.emplace_back(IncrementData, sensorInformation, Time::getInstance().getEpochSeconds()); messages.emplace_back(IncrementData,
return messages; sensorInformation,
Time::getInstance().getEpochSeconds());
return messages;
} }
SensorInformation ForteDR26::getSensorInformation() const { SensorInformation ForteDR26::getSensorInformation() const {
return sensorInformation; return sensorInformation;
} }
Adafruit_ADS1115 ForteDR26::ads1 = ads1; // TODO: What is this? Adafruit_ADS1115 ForteDR26::ads1 = ads1;
\ No newline at end of file
// TODO: What is this?
\ No newline at end of file
...@@ -9,21 +9,22 @@ ...@@ -9,21 +9,22 @@
#include <Wire.h> #include <Wire.h>
#include "NoDataAvailableException.hpp" #include "NoDataAvailableException.hpp"
class ForteDR26 : public ForteSensor<float> { class ForteDR26: public ForteSensor<float> {
public: public:
void setup() override; void setup() override;
float readData() override; float readData() override;
void changeGain(adsGain_t gain); void changeGain(adsGain_t gain);
void setChannel(int channel); void setChannel(int channel);
std::list<Message> buildMessages() override; std::list<Message> buildMessages() override;
std::list<Message> buildMessages(std::string mesurment_type); std::list<Message> buildMessages(MeasurementType measurementType);
[[nodiscard]] SensorInformation getSensorInformation() const override; [[nodiscard]] SensorInformation getSensorInformation() const override;
static Adafruit_ADS1115 ads1; static Adafruit_ADS1115 ads1;
private: private:
Adafruit_ADS1115 ads; Adafruit_ADS1115 ads;
const SensorInformation sensorInformation{"DR26", SensorProtocol::Analog}; const SensorInformation
int channel; sensorInformation{HardwareName::DRS26, SensorProtocol::Analog};
int channel;
}; };
#endif #endif
\ No newline at end of file
...@@ -6,56 +6,55 @@ Because the sensor use sdi12 protocoll we have to wait aproxemettly 1 secound be ...@@ -6,56 +6,55 @@ Because the sensor use sdi12 protocoll we have to wait aproxemettly 1 secound be
It is not known how lond the response takes so we use a while loop which can be a risk wehre the programm can get stuck It is not known how lond the response takes so we use a while loop which can be a risk wehre the programm can get stuck
*/ */
void ForteDRS26 ::setup() void ForteDRS26::setup() {
{ drs26.begin(4);
drs26.begin(4);
} }
out_data_drs26 ForteDRS26 ::readData() out_data_drs26 ForteDRS26::readData() {
{ String sdiResponse = "";
String sdiResponse = ""; String measurement_command =
String measurement_command = "1M!"; // The drs26 sensor uses the sdi12 protocoll , in the sdi12 protocoll is the measurement command is
"1M!"; // The drs26 sensor uses the sdi12 protocoll , in the sdi12 protocoll is the measurement command is // specified as 1M!=Sebsir measurement request at adress 1
// specified as 1M!=Sebsir measurement request at adress 1 String data_command =
String data_command = "1D0!"; // and the followed data command 1D0! = Sensor data request at adress 1 "1D0!"; // and the followed data command 1D0! = Sensor data request at adress 1
drs26.sendCommand(measurement_command); drs26.sendCommand(measurement_command);
delay(1000); delay(1000);
drs26.sendCommand(data_command); drs26.sendCommand(data_command);
data = {-1, -1, -1}; data = {-1, -1, -1};
while (drs26.available()) { while (drs26.available()) {
char next_character = drs26.read(); char next_character = drs26.read();
if ((next_character != '\n') && (next_character != '\r')) { if ((next_character != '\n') && (next_character != '\r')) {
sdiResponse += next_character; sdiResponse += next_character;
delay(10); // 1 character ~ 7.5ms delay(10); // 1 character ~ 7.5ms
} }
} }
if (sdiResponse.length() > 1) { if (sdiResponse.length() > 1) {
data.id = sdiResponse.substring(0, 8).toInt(); data.id = sdiResponse.substring(0, 8).toInt();
data.circumferenceIncrement = sdiResponse.substring(9, 15).toFloat(); data.circumferenceIncrement = sdiResponse.substring(9, 15).toFloat();
data.temperature = sdiResponse.substring(16, 22).toFloat(); data.temperature = sdiResponse.substring(16, 22).toFloat();
} }
return data; return data;
} }
std::list<Message> ForteDRS26 ::buildMessages() std::list<Message> ForteDRS26::buildMessages() {
{ std::list<Message> messages;
std::list<Message> messages; MeasurementData circumferenceIncrementMeasurementData{
MeasurementData circumferenceIncrementMeasurementData{ data.circumferenceIncrement, 0, {},
data.circumferenceIncrement, 0, {}, measurementTypeToString.at(MeasurementType::CIRCUMFERENCE_INCREMENT)}; MeasurementType::CIRCUMFERENCE_INCREMENT};
MeasurementData temperatureMeasurementData{ MeasurementData temperatureMeasurementData{
data.temperature, 0, {}, measurementTypeToString.at(MeasurementType::TEMPERATURE)}; data.temperature, 0, {}, MeasurementType::TEMPERATURE};
messages.emplace_back(Message{circumferenceIncrementMeasurementData, sensorInformation, 0}); messages.emplace_back(circumferenceIncrementMeasurementData,
messages.emplace_back(Message{temperatureMeasurementData, sensorInformation, 0}); sensorInformation,
0);
messages.emplace_back(temperatureMeasurementData, sensorInformation, 0);
ESP_LOGE(sensorInformation.getHardwareName().c_str(), "test"); return messages;
return messages;
} }
SensorInformation ForteDRS26::getSensorInformation() const SensorInformation ForteDRS26::getSensorInformation() const {
{ return sensorInformation;
return sensorInformation;
} }
...@@ -10,28 +10,24 @@ ...@@ -10,28 +10,24 @@
#include <map> #include <map>
struct out_data_drs26 { struct out_data_drs26 {
int id; int id;
float circumferenceIncrement; float circumferenceIncrement;
float temperature; float temperature;
}; };
class ForteDRS26 : public ForteSensor<out_data_drs26> { class ForteDRS26: public ForteSensor<out_data_drs26> {
public: public:
void setup() override; void setup() override;
out_data_drs26 readData() override; out_data_drs26 readData() override;
std::list<Message> buildMessages() override; std::list<Message> buildMessages() override;
[[nodiscard]] SensorInformation getSensorInformation() const override; [[nodiscard]] SensorInformation getSensorInformation() const override;
private: private:
SDI12 drs26; SDI12 drs26;
out_data_drs26 data; out_data_drs26 data;
const SensorInformation sensorInformation{"DRS26", SensorProtocol::I2C}; const SensorInformation
enum class MeasurementType { TEMPERATURE, CIRCUMFERENCE_INCREMENT }; sensorInformation{HardwareName::DRS26, SensorProtocol::I2C};
// enum to string
std::map<MeasurementType, const char *> measurementTypeToString = {
{MeasurementType::TEMPERATURE, "TEMPERATURE"},
{MeasurementType::CIRCUMFERENCE_INCREMENT, "CIRCUMFERENCE_INCREMENT"}};
}; };
#endif #endif
\ No newline at end of file
...@@ -13,62 +13,64 @@ ...@@ -13,62 +13,64 @@
// having the data be a struct of basic types makes sending easier, // having the data be a struct of basic types makes sending easier,
// otherwise we would have to serialize the data before sending // otherwise we would have to serialize the data before sending
class ClientDataPackage { class ClientDataPackage {
private: private:
MeasurementData measurementData; MeasurementData measurementData;
SensorInformation sensorInformation; SensorInformation sensorInformation;
unsigned long timestamp; // maybe make this array unsigned long timestamp; // maybe make this array
public: public:
ClientDataPackage(MeasurementData value, SensorInformation sensorInformation, ClientDataPackage(MeasurementData value, SensorInformation sensorInformation,
unsigned long timestamp) unsigned long timestamp)
: measurementData(std::move(value)), sensorInformation(std::move(sensorInformation)), : measurementData(value),
timestamp(timestamp) { sensorInformation(sensorInformation),
} timestamp(timestamp) {
}
[[nodiscard]] const MeasurementData &getMeasurementData() const { return measurementData; } [[nodiscard]] const MeasurementData &
getMeasurementData() const { return measurementData; }
[[nodiscard]] const SensorInformation & [[nodiscard]] const SensorInformation &
getSensorInformation() const { return sensorInformation; } getSensorInformation() const { return sensorInformation; }
[[nodiscard]] unsigned long getTimestamp() const { return timestamp; } [[nodiscard]] unsigned long getTimestamp() const { return timestamp; }
[[nodiscard]] std::string getDataPackageAsMinifiedJsonString() const { [[nodiscard]] std::string getDataPackageAsMinifiedJsonString() const {
StaticJsonDocument<250> document; // 250 byte is the max send size of espnow StaticJsonDocument<250> document; // 250 byte is the max send size of espnow
document["hardwareName"] = sensorInformation.getHardwareName(); document["hardwareName"] = sensorInformation.getHardwareNameString();
document["timestamp"] = timestamp; document["timestamp"] = timestamp;
document["sensorProtocol"] = protocolToString.at(sensorInformation.getProtocol()); document["sensorProtocol"] = sensorInformation.getProtocolString();
document["value"] = measurementData.getValue(); document["value"] = measurementData.getValue();
if (measurementData.getChannel().has_value()) { if (measurementData.getChannel().has_value()) {
document["channel"] = measurementData.getChannel().value(); document["channel"] = measurementData.getChannel().value();
} }
if (measurementData.getI2CAddress().has_value()) { if (measurementData.getI2CAddress().has_value()) {
document["i2cAddress"] = measurementData.getI2CAddress().value(); document["i2cAddress"] = measurementData.getI2CAddress().value();
} }
document["measurementType"] = measurementData.getMeasurementType(); document["measurementType"] = measurementData.getMeasurementTypeString();
std::string jsonString; std::string jsonString;
serializeJson(document, jsonString); serializeJson(document, jsonString);
return jsonString; return jsonString;
} }
[[nodiscard]] CompressedDataPackage getCompressedDataPackage() const { [[nodiscard]] CompressedDataPackage getCompressedDataPackage() const {
CompressedDataPackage compressedDataPackage{}; CompressedDataPackage compressedDataPackage{};
compressedDataPackage.channel = measurementData.getChannel().value_or(-1); compressedDataPackage.channel = measurementData.getChannel().value_or(-1);
compressedDataPackage.i2cAddress = measurementData.getI2CAddress().value_or(-1); compressedDataPackage.i2cAddress =
compressedDataPackage.value = measurementData.getValue(); measurementData.getI2CAddress().value_or(-1);
compressedDataPackage.timestamp = timestamp; compressedDataPackage.value = measurementData.getValue();
compressedDataPackage.errorType = ErrorTypes::DATA_OK; compressedDataPackage.timestamp = timestamp;
strcpy(compressedDataPackage.hardwareName, sensorInformation.getHardwareName().c_str()); compressedDataPackage.errorType = ErrorTypes::DATA_OK;
strcpy(compressedDataPackage.sensorProtocol, compressedDataPackage.hardwareName = sensorInformation.getHardwareName();
protocolToString.at(sensorInformation.getProtocol())); compressedDataPackage.sensorProtocol = sensorInformation.getProtocol();
strcpy(compressedDataPackage.measurementType, compressedDataPackage.measurementType =
measurementData.getMeasurementType().c_str()); measurementData.getMeasurementType();
return compressedDataPackage; return compressedDataPackage;
}
}
}; };
...@@ -32,6 +32,7 @@ esp_err_t Message::sendMessages(const std::array<Message, 4> &messages) { ...@@ -32,6 +32,7 @@ esp_err_t Message::sendMessages(const std::array<Message, 4> &messages) {
esp_err_t success; esp_err_t success;
// list of compressed data. Sending 4 at a time // list of compressed data. Sending 4 at a time
std::array<CompressedDataPackage, 4> compressedDataPackages{}; std::array<CompressedDataPackage, 4> compressedDataPackages{};
// std::array<std::optional<CompressedDataPackage>, 4> cpd{};
// max 4 messages // max 4 messages
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
compressedDataPackages[i] = messages[i].getCompressedDataPackage(); compressedDataPackages[i] = messages[i].getCompressedDataPackage();
......
...@@ -27,8 +27,8 @@ class Message { ...@@ -27,8 +27,8 @@ class Message {
return Message{MeasurementData(ERROR_VALUE, return Message{MeasurementData(ERROR_VALUE,
std::nullopt, std::nullopt,
std::nullopt, std::nullopt,
"null"), MeasurementType::NULL_MEASUREMENT),
SensorInformation("null", SensorProtocol::NULL_PROTOCOL), SensorInformation(HardwareName::NONE, SensorProtocol::NULL_PROTOCOL),
NULL_TIMESTAMP}; NULL_TIMESTAMP};
} }
......
#include "ina219.hpp" #include "ina219.hpp"
void ForteINA219 ::setup() void ForteINA219::setup() {
{ Wire.begin(I2C_SDA, I2C_SCL);
Wire.begin(I2C_SDA, I2C_SCL); if (!ina219.init()) {
if (!ina219.init()) { // Sensor init went wrong
// Sensor init went wrong ESP_LOGW(sensorInformation.getHardwareNameString().c_str(),
ESP_LOGW(sensorInformation.getHardwareName().c_str(), "Initialization failed"); "Initialization failed");
return; return;
} }
} }
out_data_ina219 ForteINA219 ::readData() out_data_ina219 ForteINA219::readData() {
{ if (!ina219.getOverflow()) {
if (!ina219.getOverflow()) { data.shuntVoltage_mV = ina219.getShuntVoltage_mV();
data.shuntVoltage_mV = ina219.getShuntVoltage_mV(); data.busVoltage_V = ina219.getBusVoltage_V();
data.busVoltage_V = ina219.getBusVoltage_V(); data.current_mA = ina219.getCurrent_mA();
data.current_mA = ina219.getCurrent_mA(); data.power_mW = ina219.getBusPower();
data.power_mW = ina219.getBusPower(); data.loadVoltage_V = data.busVoltage_V + (data.shuntVoltage_mV / 1000);
data.loadVoltage_V = data.busVoltage_V + (data.shuntVoltage_mV / 1000); data.ina219_overflow = ina219.getOverflow();
data.ina219_overflow = ina219.getOverflow();
return data; return data;
} else } else
return data; return data;
} }
std::list<Message> ForteINA219::buildMessages() std::list<Message> ForteINA219::buildMessages() {
{ std::list<Message> messages;
std::list<Message> messages; out_data_ina219 data = readData();
out_data_ina219 data = readData(); MeasurementData shuntVoltageData{
MeasurementData shuntVoltageData{ data.shuntVoltage_mV, 0, {}, MeasurementType::SHUNT_VOLTAGE
data.shuntVoltage_mV, 0, {}, measurementTypeToString.at(MeasurementType::SHUNT_VOLTAGE) };
}; MeasurementData busVoltageData{
MeasurementData busVoltageData{ data.busVoltage_V, 0, {}, MeasurementType::BUS_VOLTAGE
data.busVoltage_V, 0, {}, measurementTypeToString.at(MeasurementType::BUS_VOLTAGE) };
}; MeasurementData currentMilliAmpData{
MeasurementData currentMilliAmpData{ data.current_mA, 0, {}, MeasurementType::CURRENT_mA
data.current_mA, 0, {}, measurementTypeToString.at(MeasurementType::CURRENT_mA) };
}; MeasurementData powerMilliWattData{
MeasurementData powerMilliWattData{ data.power_mW, 0, {}, MeasurementType::POWER_mA
data.power_mW, 0, {}, measurementTypeToString.at(MeasurementType::POWER_mA) };
}; MeasurementData loadVoltageData{
MeasurementData loadVoltageData{ data.loadVoltage_V, 0, {}, MeasurementType::LOAD_VOLTAGE_V
data.loadVoltage_V, 0, {}, measurementTypeToString.at(MeasurementType::LOAD_VOLTAGE_V) };
}; MeasurementData ina219OverflowData{
MeasurementData ina219OverflowData{ static_cast<double>(data.ina219_overflow), 0, {},
data.ina219_overflow, 0, {}, measurementTypeToString.at(MeasurementType::INA219_OVERFLOW) MeasurementType::INA219_OVERFLOW
}; };
messages.emplace_back(Message(shuntVoltageData, sensorInformation, 0)); messages.emplace_back(shuntVoltageData, sensorInformation, 0);
messages.emplace_back(Message(busVoltageData, sensorInformation,0)); messages.emplace_back(busVoltageData, sensorInformation, 0);
messages.emplace_back(Message(currentMilliAmpData, sensorInformation, 0)); messages.emplace_back(currentMilliAmpData, sensorInformation, 0);
messages.emplace_back(Message(powerMilliWattData, sensorInformation, 0)); messages.emplace_back(powerMilliWattData, sensorInformation, 0);
messages.emplace_back(Message(loadVoltageData, sensorInformation, 0)); messages.emplace_back(loadVoltageData, sensorInformation, 0);
messages.emplace_back(Message(ina219OverflowData, sensorInformation, 0)); messages.emplace_back(ina219OverflowData, sensorInformation, 0);
return messages; return messages;
} }
SensorInformation ForteINA219::getSensorInformation() const SensorInformation ForteINA219::getSensorInformation() const {
{ return sensorInformation;
return sensorInformation;
} }
...@@ -7,36 +7,31 @@ ...@@ -7,36 +7,31 @@
#include "Wire.h" #include "Wire.h"
#include "esp_log.h" #include "esp_log.h"
#include <INA219_WE.h> #include <INA219_WE.h>
#include <MeasurementTypes.h>
struct out_data_ina219 { struct out_data_ina219 {
float shuntVoltage_mV = 0.0; float shuntVoltage_mV = 0.0;
float loadVoltage_V = 0.0; float loadVoltage_V = 0.0;
float busVoltage_V = 0.0; float busVoltage_V = 0.0;
float current_mA = 0.0; float current_mA = 0.0;
float power_mW = 0.0; float power_mW = 0.0;
bool ina219_overflow = false; bool ina219_overflow = false;
}; };
class ForteINA219 : public ForteSensor<out_data_ina219> { class ForteINA219: public ForteSensor<out_data_ina219> {
public: public:
void setup() override; void setup() override;
out_data_ina219 readData() override; out_data_ina219 readData() override;
std::list<Message> buildMessages() override; std::list<Message> buildMessages() override;
[[nodiscard]] SensorInformation getSensorInformation() const override; [[nodiscard]] SensorInformation getSensorInformation() const override;
private: private:
INA219_WE ina219; INA219_WE ina219;
out_data_ina219 data; out_data_ina219 data;
const SensorInformation sensorInformation{"INA219", SensorProtocol::I2C}; const SensorInformation
enum class MeasurementType {SHUNT_VOLTAGE, BUS_VOLTAGE, CURRENT_mA, POWER_mA, LOAD_VOLTAGE_V, INA219_OVERFLOW}; sensorInformation{HardwareName::INA219, SensorProtocol::I2C};
std::map<MeasurementType, const char*> measurementTypeToString = {
{MeasurementType::SHUNT_VOLTAGE, "SHUNT_VOLTAGE"},
{MeasurementType::BUS_VOLTAGE, "BUS_VOLTAGE"},
{MeasurementType::CURRENT_mA, "CURRENT_mA"},
{MeasurementType::POWER_mA, "POWER_mA"},
{MeasurementType::LOAD_VOLTAGE_V, "LOAD_VOLTAGE_V"},
{MeasurementType::INA219_OVERFLOW, "INA219_OVERFLOW"}};
}; };
#endif #endif
\ No newline at end of file
...@@ -12,33 +12,42 @@ ...@@ -12,33 +12,42 @@
#include <optional> #include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <MeasurementTypes.h>
class MeasurementData { class MeasurementData {
public: public:
MeasurementData(double value, std::optional<int> channel, std::optional<int> i2cAddress, MeasurementData(double value,
std::string measurementType) std::optional<int> channel,
: value(value), measurementType(std::move(measurementType)), channel(channel), std::optional<int> i2cAddress,
i2cAddress(i2cAddress) { MeasurementType measurementType)
} : value(value), measurementType(measurementType), channel(channel),
i2cAddress(i2cAddress) {
MeasurementData(double value, std::string measurementType) }
: value(value), measurementType(std::move(measurementType)) {
} MeasurementData(double value, MeasurementType measurementType)
: value(value), measurementType(measurementType) {
[[nodiscard]] double getValue() const { return value; } }
[[nodiscard]] const std::string &getMeasurementType() const { return measurementType; } [[nodiscard]] double getValue() const { return value; }
[[nodiscard]] const std::optional<int> &getChannel() const { return channel; } [[nodiscard]] const MeasurementType &
getMeasurementType() const { return measurementType; }
[[nodiscard]] const std::optional<int> &getI2CAddress() const { return i2cAddress; }
[[nodiscard]] std::string getMeasurementTypeString() const {
private: return MeasurementTypes::measurementTypeToString(measurementType);
double value; }
std::string measurementType; // TODO: consider using an enum
// TODO: is it possible for a sensor to have both a channel and an i2cAddress? [[nodiscard]] const std::optional<int> &getChannel() const { return channel; }
std::optional<int> channel;
std::optional<int> i2cAddress; [[nodiscard]] const std::optional<int> &
getI2CAddress() const { return i2cAddress; }
private:
double value;
MeasurementType measurementType; // TODO: consider using an enum
// TODO: is it possible for a sensor to have both a channel and an i2cAddress?
std::optional<int> channel;
std::optional<int> i2cAddress;
}; };
#endif // CLIENT_MEASUREMENTDATA_HPP #endif // CLIENT_MEASUREMENTDATA_HPP
...@@ -7,19 +7,27 @@ ...@@ -7,19 +7,27 @@
#include "SensorProtocol.hpp" #include "SensorProtocol.hpp"
#include <string> #include <string>
#include <HardwareNames.h>
class SensorInformation { class SensorInformation {
public: public:
SensorInformation(std::string hardwareName, SensorProtocol sensorProtocol) : hardwareName(std::move(hardwareName)), sensorProtocol(sensorProtocol) SensorInformation(HardwareName hardwareName, SensorProtocol sensorProtocol)
{ : hardwareName(hardwareName), sensorProtocol(sensorProtocol) {
} }
[[nodiscard]] const std::string &getHardwareName() const { return hardwareName; } [[nodiscard]] const HardwareName &
[[nodiscard]] SensorProtocol getProtocol() const { return sensorProtocol; } getHardwareName() const { return hardwareName; }
[[nodiscard]] std::string getHardwareNameString() const {
return HardwareNames::hardwareNameToString(hardwareName);
}
[[nodiscard]] SensorProtocol getProtocol() const { return sensorProtocol; }
[[nodiscard]] std::string getProtocolString() const {
return SensorProtocols::sensorProtocolToString(sensorProtocol);
}
private: private:
std::string hardwareName; HardwareName hardwareName;
SensorProtocol sensorProtocol; SensorProtocol sensorProtocol;
}; };
#endif // CLIENT_SENSORINFORMATION_HPP #endif // CLIENT_SENSORINFORMATION_HPP
//
// Created by zoe on 10/5/22.
//
#ifndef CLIENT_PROTOCOL_HPP
#define CLIENT_PROTOCOL_HPP
#include <map>
enum class SensorProtocol { I2C, RS485, Analog, Mock, NULL_PROTOCOL };
// sensorProtocol to string
const static std::map<SensorProtocol, const char *> protocolToString = {
{SensorProtocol::I2C, "I2C"}, {SensorProtocol::RS485, "RS485"},
{SensorProtocol::Analog, "ANALOG"}, {SensorProtocol::Mock, "MOCK"},
{SensorProtocol::NULL_PROTOCOL, "NULL"}};
#endif // CLIENT_PROTOCOL_HPP
#include "MockSensor.hpp" #include "MockSensor.hpp"
#include "MeasurementTypes.h"
static const char *TAG = "MOCK"; static const char *TAG = "MOCK";
...@@ -24,7 +25,7 @@ void MockSensor::setChannel(int c) { ...@@ -24,7 +25,7 @@ void MockSensor::setChannel(int c) {
std::list<Message> MockSensor::buildMessages() { std::list<Message> MockSensor::buildMessages() {
std::list<Message> messages; std::list<Message> messages;
float data = readData() + static_cast<float>(DeepSleep::bootCount); float data = readData() + static_cast<float>(DeepSleep::bootCount);
MeasurementData MockData{data, channel, {}, "MOCK"}; MeasurementData MockData{data, channel, {}, MeasurementType::MOCK};
messages.emplace_back(MockData, messages.emplace_back(MockData,
sensorInformation, sensorInformation,
Time::getInstance().getEpochSeconds()); Time::getInstance().getEpochSeconds());
......
...@@ -19,7 +19,7 @@ class MockSensor: public ForteSensor<float> { ...@@ -19,7 +19,7 @@ class MockSensor: public ForteSensor<float> {
[[nodiscard]] SensorInformation getSensorInformation() const override; [[nodiscard]] SensorInformation getSensorInformation() const override;
private: private:
const SensorInformation sensorInformation{"MOCK", SensorProtocol::Mock}; const SensorInformation sensorInformation{HardwareName::MOCK, SensorProtocol::Mock};
int channel; int channel;
}; };
......
...@@ -13,72 +13,88 @@ static const char *TAG = "RS485"; ...@@ -13,72 +13,88 @@ static const char *TAG = "RS485";
// Configure sensors // Configure sensors
SolarRadiationSensor solarSensor(&RS485Serial, 1, RE_DE_PIN); SolarRadiationSensor solarSensor(&RS485Serial, 1, RE_DE_PIN);
RainGaugeSensor rainGauge = RainGaugeSensor(&RS485Serial, 2, RE_DE_PIN); // Give 2 Sensor Adress 2 RainGaugeSensor rainGauge = RainGaugeSensor(&RS485Serial,
SoilMoistureSensor soilSensor3 = SoilMoistureSensor(&RS485Serial, 3, RE_DE_PIN); //..... 2,
RE_DE_PIN); // Give 2 Sensor Adress 2
SoilMoistureSensor
soilSensor3 = SoilMoistureSensor(&RS485Serial, 3, RE_DE_PIN); //.....
SoilMoistureSensor soilSensor4 = SoilMoistureSensor(&RS485Serial, 4, RE_DE_PIN); SoilMoistureSensor soilSensor4 = SoilMoistureSensor(&RS485Serial, 4, RE_DE_PIN);
SoilMoistureSensor soilSensor5 = SoilMoistureSensor(&RS485Serial, 5, RE_DE_PIN); SoilMoistureSensor soilSensor5 = SoilMoistureSensor(&RS485Serial, 5, RE_DE_PIN);
void Forte_RS485::setup() void Forte_RS485::setup() {
{ // configure the pins to be output only
// configure the pins to be output only pinMode(RE_DE_PIN, OUTPUT);
pinMode(RE_DE_PIN, OUTPUT); pinMode(POWER_SWITCH_PIN_12V, OUTPUT);
pinMode(POWER_SWITCH_PIN_12V, OUTPUT); pinMode(POWER_SWITCH_PIN_5V, OUTPUT);
pinMode(POWER_SWITCH_PIN_5V, OUTPUT); RS485Serial.begin(4800, SERIAL_8N1, TXPin, RXPin);
RS485Serial.begin(4800, SERIAL_8N1, TXPin, RXPin);
} }
out_data_rs485 Forte_RS485::readData() out_data_rs485 Forte_RS485::readData() {
{ // Power on sensor
// Power on sensor digitalWrite(POWER_SWITCH_PIN_12V, HIGH);
digitalWrite(POWER_SWITCH_PIN_12V, HIGH); digitalWrite(POWER_SWITCH_PIN_5V, HIGH);
digitalWrite(POWER_SWITCH_PIN_5V, HIGH); // Wait for sensors to power up
// Wait for sensors to power up // TODO minimize delay
// TODO minimize delay delay(300);
delay(300); out_data_rs485 output;
out_data_rs485 output; unsigned long ts = millis();
unsigned long ts = millis(); output.solarRadiation = solarSensor.getSolarRadiation();
output.solarRadiation = solarSensor.getSolarRadiation(); output.soilTemperature3 = soilSensor3.getMoistureTemp();
output.soilTemperature3 = soilSensor3.getMoistureTemp(); output.soilTemperature4 = soilSensor4.getMoistureTemp();
output.soilTemperature4 = soilSensor4.getMoistureTemp(); output.soilTemperature5 = soilSensor5.getMoistureTemp();
output.soilTemperature5 = soilSensor5.getMoistureTemp(); output.soilMoisture3 = soilSensor3.getMoisture();
output.soilMoisture3 = soilSensor3.getMoisture(); output.soilMoisture4 = soilSensor4.getMoisture();
output.soilMoisture4 = soilSensor4.getMoisture(); output.soilMoisture5 = soilSensor5.getMoisture();
output.soilMoisture5 = soilSensor5.getMoisture(); output.precipitation = rainGauge.getInstantaneousPrecipitation();
output.precipitation = rainGauge.getInstantaneousPrecipitation(); digitalWrite(POWER_SWITCH_PIN_12V, LOW);
digitalWrite(POWER_SWITCH_PIN_12V, LOW); digitalWrite(POWER_SWITCH_PIN_5V, LOW);
digitalWrite(POWER_SWITCH_PIN_5V, LOW);
gpio_hold_en((gpio_num_t)POWER_SWITCH_PIN_12V); gpio_hold_en((gpio_num_t) POWER_SWITCH_PIN_12V);
gpio_hold_en((gpio_num_t)POWER_SWITCH_PIN_5V); gpio_hold_en((gpio_num_t) POWER_SWITCH_PIN_5V);
return output; return output;
} }
std::list<Message> Forte_RS485::buildMessages() std::list<Message> Forte_RS485::buildMessages() {
{ std::list<Message> messages;
std::list<Message> messages; out_data_rs485 output = readData();
out_data_rs485 output = readData(); MeasurementData
MeasurementData solarRadiation {output.solarRadiation, measurementTypeToString.at(MeasurementType::SOLAR_RADIATION)}; solarRadiation{output.solarRadiation, MeasurementType::SOLAR_RADIATION};
MeasurementData soilTemp3{output.soilTemperature3, measurementTypeToString.at(MeasurementType::SOIL_TEMPERATURE_3)}; MeasurementData
MeasurementData soilTemp4 {output.soilTemperature4, measurementTypeToString.at(MeasurementType::SOIL_TEMPERATURE_4)}; soilTemp3{output.soilTemperature3, MeasurementType::SOIL_TEMPERATURE_3};
MeasurementData soilTemp5 {output.soilTemperature5, measurementTypeToString.at(MeasurementType::SOIL_TEMPERATURE_5)}; MeasurementData
MeasurementData soilMoisture3 {output.soilMoisture3, measurementTypeToString.at(MeasurementType::SOIL_MOISTURE_3)}; soilTemp4{output.soilTemperature4, MeasurementType::SOIL_TEMPERATURE_4};
MeasurementData soilMoisture4 {output.soilMoisture4, measurementTypeToString.at(MeasurementType::SOIL_MOISTURE_4)}; MeasurementData
MeasurementData soilMoisture5 {output.soilMoisture5, measurementTypeToString.at(MeasurementType::SOIL_MOISTURE_5)}; soilTemp5{output.soilTemperature5, MeasurementType::SOIL_TEMPERATURE_5};
MeasurementData precipitation {output.precipitation, measurementTypeToString.at(MeasurementType::PRECIPITATION)}; MeasurementData
soilMoisture3{output.soilMoisture3, MeasurementType::SOIL_MOISTURE_3};
MeasurementData
soilMoisture4{output.soilMoisture4, MeasurementType::SOIL_MOISTURE_4};
MeasurementData
soilMoisture5{output.soilMoisture5, MeasurementType::SOIL_MOISTURE_5};
MeasurementData
precipitation{output.precipitation, MeasurementType::PRECIPITATION};
messages.emplace_back(Message{solarRadiation,sensorInformation, Time::getInstance().getEpochSeconds()}); messages.emplace_back(solarRadiation, sensorInformation,
messages.emplace_back(Message{soilTemp3,sensorInformation, Time::getInstance().getEpochSeconds()}); Time::getInstance().getEpochSeconds());
messages.emplace_back(Message{soilTemp4,sensorInformation, Time::getInstance().getEpochSeconds()}); messages.emplace_back(soilTemp3, sensorInformation,
messages.emplace_back(Message{soilTemp5,sensorInformation, Time::getInstance().getEpochSeconds()}); Time::getInstance().getEpochSeconds());
messages.emplace_back(Message{soilMoisture3,sensorInformation, Time::getInstance().getEpochSeconds()}); messages.emplace_back(soilTemp4, sensorInformation,
messages.emplace_back(Message{soilMoisture4,sensorInformation, Time::getInstance().getEpochSeconds()}); Time::getInstance().getEpochSeconds());
messages.emplace_back(Message{soilMoisture5,sensorInformation, Time::getInstance().getEpochSeconds()}); messages.emplace_back(soilTemp5, sensorInformation,
messages.emplace_back(Message(precipitation, sensorInformation, Time::getInstance().getEpochSeconds())); Time::getInstance().getEpochSeconds());
messages.emplace_back(soilMoisture3, sensorInformation,
Time::getInstance().getEpochSeconds());
messages.emplace_back(soilMoisture4, sensorInformation,
Time::getInstance().getEpochSeconds());
messages.emplace_back(soilMoisture5, sensorInformation,
Time::getInstance().getEpochSeconds());
messages.emplace_back(precipitation,
sensorInformation,
Time::getInstance().getEpochSeconds());
return messages; return messages;
} }
SensorInformation Forte_RS485::getSensorInformation() const SensorInformation Forte_RS485::getSensorInformation() const {
{ return sensorInformation;
return sensorInformation;
} }
\ No newline at end of file
#ifndef _RS485 #ifndef _RS485
#define _RS485 #define _RS485
#include <MeasurementTypes.h>
#include "Message.hpp" #include "Message.hpp"
#include "ForteSensor.hpp" #include "ForteSensor.hpp"
#include "SentecSensors.h" #include "SentecSensors.h"
struct out_data_rs485{ struct out_data_rs485 {
float solarRadiation; float solarRadiation;
float soilMoisture3; float soilMoisture3;
float soilTemperature3; float soilTemperature3;
float soilMoisture4; float soilMoisture4;
float soilTemperature4; float soilTemperature4;
float soilMoisture5; float soilMoisture5;
float soilTemperature5; float soilTemperature5;
float precipitation; float precipitation;
}; };
class Forte_RS485 : public ForteSensor <out_data_rs485> { class Forte_RS485: public ForteSensor<out_data_rs485> {
public: public:
void setup() override; void setup() override;
out_data_rs485 readData() override; out_data_rs485 readData() override;
std::list<Message> buildMessages() override; std::list<Message> buildMessages() override;
[[nodiscard]] SensorInformation getSensorInformation() const override; [[nodiscard]] SensorInformation getSensorInformation() const override;
private: private:
const SensorInformation sensorInformation{"RS485", SensorProtocol::RS485}; const SensorInformation
sensorInformation{HardwareName::RS485, SensorProtocol::RS485};
enum class MeasurementType {
SOLAR_RADIATION,
SOIL_MOISTURE_3,
SOIL_TEMPERATURE_3,
SOIL_MOISTURE_4,
SOIL_TEMPERATURE_4,
SOIL_MOISTURE_5,
SOIL_TEMPERATURE_5,
PRECIPITATION
};
std::map<MeasurementType, const char *> measurementTypeToString = {
{MeasurementType::SOLAR_RADIATION, "SOLAR_RADIATION"},
{MeasurementType::SOIL_MOISTURE_3, "SOIL_MOISTURE_3"},
{MeasurementType::SOIL_TEMPERATURE_3, "SOIL_TEMPERATURE_3"},
{MeasurementType::SOIL_MOISTURE_4, "SOIL_MOISTURE_4"},
{MeasurementType::SOIL_TEMPERATURE_4, "SOIL_TEMPERATURE_4"},
{MeasurementType::SOIL_MOISTURE_5, "SOIL_MOISTURE_5"},
{MeasurementType::SOIL_TEMPERATURE_5, "SOIL_TEMPERATURE_5"},
{MeasurementType::PRECIPITATION, "PRECIPATION"}
};
}; };
#endif #endif
\ No newline at end of file
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