Skip to content
Snippets Groups Projects
Commit 80dce242 authored by Zoe Pfister's avatar Zoe Pfister :speech_balloon:
Browse files

merge power-management-satellite into develop

parents 8859a166 8edbd031
No related branches found
No related tags found
3 merge requests!39Merge Develop into Main,!19development into master,!18Power management satellite
Showing with 1288 additions and 677 deletions
...@@ -293,3 +293,6 @@ node_modules/ ...@@ -293,3 +293,6 @@ node_modules/
CMakeLists.txt CMakeLists.txt
CmakeListsPrivate.txt CmakeListsPrivate.txt
forte.code-workspace
client/client_satellite/.vscode/extensions.json
client/client_satellite/.vscode/settings.json
#include "dr26.hpp" #include "ESPNow.hpp"
#include "LC709203F.h"
#include "NoDataAvailableException.hpp" #include "NoDataAvailableException.hpp"
#include "dr26.hpp"
#include "f_deep_sleep.hpp" #include "f_deep_sleep.hpp"
#include <Arduino.h> #include <Arduino.h>
#include "ESPNow.hpp"
#include "LC709203F.h"
// FIXME: Use descriptive names for the constants below. // Execution time:
LC709203F gg; // FIXME: Boot: needs to be measured with oscilloscope and optimised. should be around a few hundres ms, can be <100ms
static const std::string TAG = "MAIN"; // https://github.com/makermoekoe/Picoclick-C3#speed-up-boot-process
// Part [ms]
// First setup: 150
// Data aquisition: 500
// ESPNow setup: 220
// Sending 1200
// TOTAL: 2200
static const char *TAG = "MAIN";
LC709203F battery_monitor;
ForteDR26 dr26_channel0;
ForteDR26 dr26_channel3; ForteDR26 dr26_channel3;
ForteDR26 dr26_channel1; ForteDR26 dr26_channel1;
ForteDR26 dr26_channel2; ForteDR26 dr26_channel2;
ForteDR26 dr26_channel0_power;
void setup() { void send_msgs(const std::__cxx11::list<Message> msgs)
Serial.begin(115200); {
//Set the GPIO which conrtols the step up to OUTPUT for (const Message &msg : msgs) {
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT);
if (msg.send() != ESP_OK) {
gg.begin(); RtcMemory::store(msg.getMessageAsMinifiedJsonString());
gg.setCellCapacity(LC709203F_APA_1000MAH); }
unsigned long ts = millis();
// it takes ~110ms for receiving an acknowledgement by the host in perfect conditions
DeepSleep::print_wakeup_reason(); uint16_t message_timeout = 2000;
DeepSleep::bootCount++; while (!was_msg_received()) {
ESP_LOGD(TAG.c_str(), "Boot number: %d", DeepSleep::bootCount); if ((millis() - ts) > message_timeout) {
RtcMemory::store(msg.getMessageAsMinifiedJsonString());
gpio_set_level(GPIO_NUM_32, 1); ESP_LOGE(TAG, "Timeout: Host not available\n");
dr26_channel1.setup(); break;
dr26_channel3.setChannel(3); }
dr26_channel1.setChannel(1); }
dr26_channel2.setChannel(2); ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts);
dr26_channel0_power.setChannel(0); }
gpio_set_level(GPIO_NUM_32, 0);
espnow_setup();
// log_e("Setup complete.");
} }
// one loop takes ~2200 ms
void loop() { void setup()
gpio_set_level(GPIO_NUM_32, 1); {
Serial.println( unsigned long ts = millis();
"***********************1-DRS26 NOT YET CONNECTED**********************************"); Serial.begin(115200);
Serial.println(dr26_channel1.readData(), 5); // Set the GPIO which conrtols the step up to OUTPUT
Serial.println("***********************2-DRS26**********************************"); gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT);
Serial.println(dr26_channel2.readData(), 5);
Serial.println("***********************3-DRS26 *********************************"); // blinking led for debug
Serial.println(dr26_channel3.readData(), 5); // gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT);
// gpio_set_level(GPIO_NUM_17, 1);
Serial.println("***********************0-Voltage-Battery**********************************"); battery_monitor.begin();
dr26_channel3.changeGain(GAIN_TWOTHIRDS);
Serial.println(dr26_channel0_power.readData(), 5); DeepSleep::print_wakeup_reason();
DeepSleep::bootCount++;
Serial.println("***********************REAL-Voltage-Battery**********************************"); ESP_LOGD(TAG, "Boot number: %d", DeepSleep::bootCount);
Serial.println(gg.cellVoltage_mV() / 1000.0);
gpio_set_level(GPIO_NUM_32, 1);
try { // delay(100);
dr26_channel1.setup();
auto messages = dr26_channel0_power.buildMessages(); dr26_channel0.setChannel(0);
dr26_channel1.setChannel(1);
dr26_channel2.setChannel(2);
for (const Message &message: messages) { dr26_channel3.setChannel(3);
if (message.send() != ESP_OK) {
RtcMemory::store(message.getMessageAsMinifiedJsonString()); ESP_LOGD(TAG, "Setup took %ld ms", millis() - ts);
}
delay(5000); try {
if (!was_msg_received()) { // FIXME: put me into seperate trys? No data will be sent when 1 exception occurs
RtcMemory::store(message.getMessageAsMinifiedJsonString());
} ts = millis();
} auto messages0 = dr26_channel0.buildMessages();
auto messages1 = dr26_channel1.buildMessages();
dr26_channel3.changeGain(GAIN_ONE); auto messages2 = dr26_channel2.buildMessages();
auto messages2 = dr26_channel1.buildMessages(1, "CIRCUMFERENCE_INCREMENT"); auto messages3 = dr26_channel3.buildMessages();
auto messages4 = battery_monitor.buildMessages();
for (const Message &message2: messages2) { // roughly takes 500ms, ~120ms for each adc channel, barely anything for battery monitor
if (message2.send() != ESP_OK) { ESP_LOGD(TAG, "Reading data and building messages took %ld ms", millis() - ts);
RtcMemory::store(message2.getMessageAsMinifiedJsonString()); gpio_set_level(GPIO_NUM_32, 0);
}
delay(5000); // FIXME: put this outside the try loop?
if (!was_msg_received()) { ts = millis();
RtcMemory::store(message2.getMessageAsMinifiedJsonString()); espnow_setup();
} ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts);
} ts = millis();
send_msgs(messages0);
auto messages3 = dr26_channel2.buildMessages(2, "CIRCUMFERENCE_INCREMENT"); send_msgs(messages1);
send_msgs(messages2);
for (const Message &message3: messages3) { send_msgs(messages3);
if (message3.send() != ESP_OK) { send_msgs(messages4);
RtcMemory::store(message3.getMessageAsMinifiedJsonString()); // roughly takes 3s in ideal conditions
} ESP_LOGD(TAG, "Sending messages took %ld ms", millis() - ts);
delay(5000);
if (!was_msg_received()) { } catch (const NoDataAvailableException &e) {
RtcMemory::store(message3.getMessageAsMinifiedJsonString()); std::cerr << e.what() << '\n';
} }
} // just to be safe in case exception happens above
gpio_set_level(GPIO_NUM_32, 0);
auto messages4 = gg.buildMessages(); // keep it in deep sleep
for (const Message &message4: messages4) { gpio_hold_en((gpio_num_t)GPIO_NUM_32);
if (message4.send() != ESP_OK) {
RtcMemory::store(message4.getMessageAsMinifiedJsonString()); battery_monitor.setPowerMode(LC709203F_POWER_SLEEP);
} // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V
delay(5000); if (battery_monitor.cellVoltage_mV() > 3200) {
if (!was_msg_received()) { DeepSleep::deep_sleep(10 * 60);
RtcMemory::store(message4.getMessageAsMinifiedJsonString()); } else {
} esp_deep_sleep_start();
} }
} catch (const NoDataAvailableException &e) {
std::cerr << e.what() << '\n';
}
Serial.print("This device: ");
Serial.println("\n");
gpio_set_level(GPIO_NUM_32, 0);
delay(5000);
DeepSleep::deep_sleep(100);
} }
void loop() {}
\ No newline at end of file
...@@ -31,21 +31,21 @@ LC709203F::LC709203F(void) {} ...@@ -31,21 +31,21 @@ LC709203F::LC709203F(void) {}
LC709203F::~LC709203F(void) {} LC709203F::~LC709203F(void) {}
uint8_t i2c_address = LC709203F_I2C_ADDR ; uint8_t i2c_address = LC709203F_I2C_ADDR;
/*! /*!
* @brief Sets up the hardware and initializes I2C * @brief Sets up the hardware and initializes I2C
* @param * @param
* @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_500MAH) ; setTemperatureMode(LC709203F_TEMPERATURE_I2C);
setTemperatureMode(LC709203F_TEMPERATURE_THERMISTOR) ; setCellProfile(LC709203_NOM3p7_Charge4p2);
return true; return true;
} }
...@@ -53,11 +53,10 @@ bool LC709203F::begin( void ) ...@@ -53,11 +53,10 @@ bool LC709203F::begin( void )
* @brief Get IC version * @brief Get IC version
* @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,9 +64,8 @@ uint16_t LC709203F::getICversion(void) ...@@ -65,9 +64,8 @@ uint16_t LC709203F::getICversion(void)
* @brief Initialize the RSOC algorithm * @brief Initialize the RSOC algorithm
* @return * @return
*/ */
void LC709203F::initRSOC(void) void LC709203F::initRSOC(void) {
{ write16(LC709203F_WO_INITRSOC, 0xAA55);
write16(LC709203F_WO_INITRSOC, 0xAA55);
} }
...@@ -75,11 +73,10 @@ void LC709203F::initRSOC(void) ...@@ -75,11 +73,10 @@ void LC709203F::initRSOC(void)
* @brief Get battery voltage * @brief Get battery voltage
* @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 ) ;
} }
...@@ -87,22 +84,20 @@ uint16_t LC709203F::cellVoltage_mV(void) ...@@ -87,22 +84,20 @@ uint16_t LC709203F::cellVoltage_mV(void)
* @brief Get cell remaining charge in percent (0-100%) * @brief Get cell remaining charge in percent (0-100%)
* @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 ;
} }
/*! /*!
* @brief Get battery state of charge in percent (0-100%) * @brief Get battery state of charge in percent (0-100%)
* @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 ;
} }
...@@ -110,11 +105,10 @@ uint16_t LC709203F::cellStateOfCharge(void) ...@@ -110,11 +105,10 @@ uint16_t LC709203F::cellStateOfCharge(void)
* @brief Get battery thermistor temperature * @brief Get battery thermistor temperature
* @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 ;
} }
...@@ -123,9 +117,8 @@ uint16_t LC709203F::getCellTemperature(void) ...@@ -123,9 +117,8 @@ uint16_t LC709203F::getCellTemperature(void)
* @param t The desired mode: LC709203F_TEMPERATURE_I2C or * @param t The desired mode: LC709203F_TEMPERATURE_I2C or
* 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);
} }
...@@ -133,9 +126,8 @@ void LC709203F::setTemperatureMode(lc709203_tempmode_t t) ...@@ -133,9 +126,8 @@ void LC709203F::setTemperatureMode(lc709203_tempmode_t t)
* @brief Set the cell capacity, * @brief Set the cell capacity,
* @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);
} }
...@@ -143,9 +135,8 @@ void LC709203F::setCellCapacity(lc709203_adjustment_t apa) ...@@ -143,9 +135,8 @@ void LC709203F::setCellCapacity(lc709203_adjustment_t apa)
* @brief Set the alarm pin to respond to an RSOC percentage level * @brief Set the alarm pin to respond to an RSOC percentage level
* @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);
} }
...@@ -153,9 +144,8 @@ void LC709203F::setAlarmRSOC(uint8_t percent) ...@@ -153,9 +144,8 @@ void LC709203F::setAlarmRSOC(uint8_t percent)
* @brief Set the alarm pin to respond to a battery voltage level * @brief Set the alarm pin to respond to a battery voltage level
* @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);
} }
...@@ -165,9 +155,8 @@ void LC709203F::setAlarmVoltage(float voltage) ...@@ -165,9 +155,8 @@ void LC709203F::setAlarmVoltage(float voltage)
* @param t The power mode desired * @param t The power mode desired
* @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);
} }
/*! /*!
...@@ -175,20 +164,18 @@ void LC709203F::setPowerMode(lc709203_powermode_t t) ...@@ -175,20 +164,18 @@ void LC709203F::setPowerMode(lc709203_powermode_t t)
* @param t The profile, Table 8. Normally 1 for 3.7 nominal 4.2V Full carge cells * @param t The profile, Table 8. Normally 1 for 3.7 nominal 4.2V Full carge cells
* @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);
} }
/*! /*!
* @brief Get the thermistor Beta value //For completeness since we have to write it. * @brief Get the thermistor Beta value //For completeness since we have to write it.
* @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;
} }
...@@ -197,19 +184,18 @@ uint16_t LC709203F::getThermistorBeta(void) ...@@ -197,19 +184,18 @@ uint16_t LC709203F::getThermistorBeta(void)
* @param b The value to set it to * @param b The value to set it to
* @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, {},"Voltage-Batterie"}; measurementTypeToString.at(MeasurementType::BATTERY_VOLTAGE)};
messages.emplace_back(IncrementData, sensorInformation, Time::getInstance().getEpochSeconds()); messages.emplace_back(IncrementData, sensorInformation, Time::getInstance().getEpochSeconds());
return messages; return messages;
} }
...@@ -229,56 +215,53 @@ std::list<Message> LC709203F::buildMessages() ...@@ -229,56 +215,53 @@ 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, 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 );
} }
...@@ -19,54 +19,54 @@ ...@@ -19,54 +19,54 @@
// Registers per datasheet Table 6 // Registers per datasheet Table 6
#define LC709203F_WO_BEFORE_RSOC 0x04 // Executes RSOC initialization with sampled maximum voltage when 0xAA55 is set #define LC709203F_WO_BEFORE_RSOC 0x04 // Executes RSOC initialization with sampled maximum voltage when 0xAA55 is set
#define LC709203F_RW_THERMISTORB 0x06 // Sets B−constant of the thermistor to be measured. #define LC709203F_RW_THERMISTORB 0x06 // Sets B−constant of the thermistor to be measured.
#define LC709203F_WO_INITRSOC 0x07 // Executes RSOC initialization when 0xAA55 is set. #define LC709203F_WO_INITRSOC 0x07 // Executes RSOC initialization when 0xAA55 is set.
#define LC709203F_RW_CELLTEMPERATURE 0x08 // Read or Write Cell Temperature For ESP32-Bar-Rev2 must write temperature, no thermistor on board #define LC709203F_RW_CELLTEMPERATURE 0x08 // Read or Write Cell Temperature For ESP32-Bar-Rev2 must write temperature, no thermistor on board
#define LC709203F_RO_CELLVOLTAGE 0x09 // Read cell voltage #define LC709203F_RO_CELLVOLTAGE 0x09 // Read cell voltage
#define LC709203F_RW_CURRENTDIRECTION 0x0A // Selects Auto/Charge/Discharge mode 0x0000: Auto mode, 0x0001: Charge mode, 0xFFFF: Discharge mode #define LC709203F_RW_CURRENTDIRECTION 0x0A // Selects Auto/Charge/Discharge mode 0x0000: Auto mode, 0x0001: Charge mode, 0xFFFF: Discharge mode
#define LC709203F_RW_APA 0x0B // APA Register, Table 7 #define LC709203F_RW_APA 0x0B // APA Register, Table 7
#define LC709203F_RW_APTHERMISTOR 0x0C // Sets a value to adjust temperature measurement delay timing. Defaults to0x001E #define LC709203F_RW_APTHERMISTOR 0x0C // Sets a value to adjust temperature measurement delay timing. Defaults to0x001E
#define LC709203F_RW_RSOC 0x0D // Read cell indicator to empty in 1% steps #define LC709203F_RW_RSOC 0x0D // Read cell indicator to empty in 1% steps
#define LC709203F_RO_ITE 0x0F // Read cell indicator to empty in 0.1% steps #define LC709203F_RO_ITE 0x0F // Read cell indicator to empty in 0.1% steps
#define LC709203F_RO_ICVERSION 0x11 // Contains the ID number of the IC #define LC709203F_RO_ICVERSION 0x11 // Contains the ID number of the IC
#define LC709203F_RW_PROFILE 0x12 // Adjusts the battery profile for nominal and fully charged voltages, see Table 8 #define LC709203F_RW_PROFILE 0x12 // Adjusts the battery profile for nominal and fully charged voltages, see Table 8
#define LC709203F_RW_ALARMRSOC 0x13 // Alarm on percent threshold #define LC709203F_RW_ALARMRSOC 0x13 // Alarm on percent threshold
#define LC709203F_RW_ALARMVOLT 0x14 // Alarm on voltage threshold #define LC709203F_RW_ALARMVOLT 0x14 // Alarm on voltage threshold
#define LC709203F_RW_POWERMODE 0x15 // Sets sleep/power mode 0x0001: Operational mode 0x0002: Sleep mode #define LC709203F_RW_POWERMODE 0x15 // Sets sleep/power mode 0x0001: Operational mode 0x0002: Sleep mode
#define LC709203F_RW_STATUSBIT 0x16 // Temperature method, 0x0000: I2C mode, 0x0001: Thermistor mode #define LC709203F_RW_STATUSBIT 0x16 // Temperature method, 0x0000: I2C mode, 0x0001: Thermistor mode
#define LC709203F_RO_CELLPROFILE 0x1A // Displays battery profile code #define LC709203F_RO_CELLPROFILE 0x1A // Displays battery profile code
static uint8_t crc8(uint8_t *data, int len); 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;
/*! /*!
...@@ -75,38 +75,56 @@ typedef enum { ...@@ -75,38 +75,56 @@ typedef enum {
*/ */
class LC709203F { class LC709203F {
public: public:
LC709203F(); LC709203F();
~LC709203F();
bool begin( void ); ~LC709203F();
void initRSOC(void);
void setPowerMode(lc709203_powermode_t t); bool begin(void);
void setCellCapacity(lc709203_adjustment_t apa);
void setCellProfile(lc709203_cell_profile_t t);
uint16_t getICversion(void);
uint16_t cellVoltage_mV(void); void initRSOC(void);
uint16_t 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); void setPowerMode(lc709203_powermode_t t);
void setThermistorB(uint16_t beta);
void setTemperatureMode(lc709203_tempmode_t t); void setCellCapacity(lc709203_adjustment_t apa);
uint16_t getCellTemperature(void);
void setAlarmRSOC(uint8_t percent); void setCellProfile(lc709203_cell_profile_t t);
void setAlarmVoltage(float voltage);
std::list<Message> buildMessages(); uint16_t getICversion(void);
uint16_t cellVoltage_mV(void);
uint16_t 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);
void setThermistorB(uint16_t beta);
void setTemperatureMode(lc709203_tempmode_t t);
uint16_t getCellTemperature(void);
void setAlarmRSOC(uint8_t percent);
void setAlarmVoltage(float voltage);
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{"DR26", Protocol::Analog}; const SensorInformation sensorInformation{"LC709203", Protocol::I2C};
enum class MeasurementType {
BATTERY_VOLTAGE,
};
std::map<MeasurementType, const char *> measurementTypeToString = {
{MeasurementType::BATTERY_VOLTAGE, "BATTERY_VOLTAGE"}};
}; };
#endif #endif
...@@ -26,7 +26,7 @@ void print_wakeup_reason() ...@@ -26,7 +26,7 @@ void print_wakeup_reason()
ESP_LOGD(TAG.c_str(), "Wakeup caused by ULP program"); ESP_LOGD(TAG.c_str(), "Wakeup caused by ULP program");
break; break;
default: default:
ESP_LOGD(TAG.c_str(), "Wakeup was not caused by deep sleep: %d\n", wakeup_reason); ESP_LOGD(TAG.c_str(), "Wakeup was not caused by deep sleep: %d", wakeup_reason);
break; break;
} }
} }
......
#include "dr26.hpp" #include "dr26.hpp"
static const char *TAG = "DR26";
void ForteDR26::setup() { void ForteDR26::setup() {
// This was changed by Bilal on november 25th from
// Wire.begin(6,7);
pinMode(2, OUTPUT);
Wire.begin(); Wire.begin();
// ads.setGain(GAIN_ONE);
// ads.begin() ? Serial.println("ADS initialized") : Serial.println("failed to initialize ADS");
ads1.setGain(GAIN_ONE); ads1.setGain(GAIN_ONE);
ads1.begin() ? Serial.println("ADS initialized") : Serial.println("failed to initialize ADS"); ads1.setDataRate(RATE_ADS1115_8SPS);
ads1.begin() ? ESP_LOGD(TAG, "ADS initialized") : ESP_LOGE(TAG, "failed to initialize ADS");
delay(100); delay(100);
channel = 0; channel = 0;
} }
float ForteDR26::readData() { float ForteDR26::readData() {
float volts = 0; float volts = 0;
for (int i = 0; i < 10; i++) {
int16_t adc = 0;
float volt = 0;
try {
adc = ads1.readADC_SingleEnded(channel);
volt = ads1.computeVolts(adc);
}
catch (NoDataAvailableException &e) {
throw NoDataAvailableException(); //propagate exception
}
volts += volt;
}
volts /= 10; // 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
// for (int i = 0; i < 10; i++) {
// int16_t adc = 0;
// float volt = 0;
// try {
// adc = ads1.readADC_SingleEnded(channel);
// volt = ads1.computeVolts(adc);
// }
// catch (NoDataAvailableException &e) {
// throw NoDataAvailableException(); //propagate exception
// }
// volts += volt;
// }
// volts /= 10;
int16_t adc = 0;
try {
adc = ads1.readADC_SingleEnded(channel);
volts = ads1.computeVolts(adc);
}
catch (NoDataAvailableException &e) {
throw NoDataAvailableException(); //propagate exception
}
return volts; return volts;
} }
...@@ -60,14 +69,13 @@ void ForteDR26::setChannel(int c) { ...@@ -60,14 +69,13 @@ void ForteDR26::setChannel(int 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, 0, {}, "CIRCUMFERENCE_INCREMENT"}; MeasurementData IncrementData{data, channel, {}, "CIRCUMFERENCE_INCREMENT"};
messages.emplace_back(IncrementData, sensorInformation, Time::getInstance().getEpochSeconds()); messages.emplace_back(IncrementData, sensorInformation, Time::getInstance().getEpochSeconds());
return messages; return messages;
} }
// FIXME: Channel shadows a member variable, we don't need it, just take the member variable instead
// 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(int channel, std::string measurementType) { std::list<Message> ForteDR26::buildMessages(std::string 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};
......
...@@ -16,7 +16,7 @@ class ForteDR26 : public ForteSensor<float> { ...@@ -16,7 +16,7 @@ class ForteDR26 : public ForteSensor<float> {
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(int channel,std::string mesurment_type); std::list<Message> buildMessages(std::string mesurment_type);
[[nodiscard]] SensorInformation getSensorInformation() const override; [[nodiscard]] SensorInformation getSensorInformation() const override;
static Adafruit_ADS1115 ads1; static Adafruit_ADS1115 ads1;
......
...@@ -38,13 +38,8 @@ esp_err_t add_host_to_peers(config received){ ...@@ -38,13 +38,8 @@ esp_err_t add_host_to_peers(config received){
void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status)
{ {
ESP_LOGE(TAG, "Message sent to"); ESP_LOGE(TAG, "Message sent to %02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0],
for(int i=0; i<6; i++){ mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print(mac_addr[i], HEX);
Serial.print(":");
}
Serial.println();
// go to sleep
} }
void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len)
...@@ -52,28 +47,14 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) ...@@ -52,28 +47,14 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len)
// is msg host -> yes -> set bool // is msg host -> yes -> set bool
// assume host change not happening, rare event // assume host change not happening, rare event
// => on host change, broadcast // => on host change, broadcast
ESP_LOGE(TAG, "Message recieved"); ESP_LOGD(TAG, "Message received");
config received_msg; config received_msg;
memcpy(&received_msg, incomingData, sizeof(received_msg)); // TODO: check for valid mac memcpy(&received_msg, incomingData, sizeof(received_msg)); // TODO: check for valid mac
// all the esp32 macs so far use the same first 3(?) bytes so maybe use that // all the esp32 macs so far use the same first 3(?) bytes so maybe use that
// First three bytes of MACs are always vendor specific. But vendors have a range of them.
// all Espressif registered MAC starting bytes: https://maclookup.app/vendors/espressif-inc
// you can also set your own MAC https://randomnerdtutorials.com/get-change-esp32-esp8266-mac-address-arduino/
switch (received_msg.type){ switch (received_msg.type){
case dataAck:{
ESP_LOGI(TAG, "dataAck received.");
msg_recv = true;
Time::getInstance().setTime(
received_msg.epoch_seconds); // see https://www.esp32.com/viewtopic.php?t=9965, maybe this needs an offset
Serial.println(Time::getInstance().getEpochSeconds());
preferences.begin("config", false);
if (!preferences.isKey("host")) {
if(preferences.putBytes("host", received_msg.host, sizeof(received_msg.host)) > 0){;
ESP_LOGI(TAG, "host MAC address saved to flash");
}
// add host to peers
add_host_to_peers(received_msg);
}
preferences.end();
}
case hostChange:{ case hostChange:{
ESP_LOGI(TAG, "hostChange received"); ESP_LOGI(TAG, "hostChange received");
Time::getInstance().setTime(received_msg.epoch_seconds); Time::getInstance().setTime(received_msg.epoch_seconds);
...@@ -89,7 +70,8 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) ...@@ -89,7 +70,8 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len)
// add new host // add new host
preferences.begin("config", false); preferences.begin("config", false);
if(preferences.putBytes("host", received_msg.host, sizeof(received_msg.host)) > 0){ if(preferences.putBytes("host", received_msg.host, sizeof(received_msg.host)) > 0){
ESP_LOGI(TAG, "Host Mac address saved to flash:"); ESP_LOGI(TAG, "Host MAC address saved to flash %02X:%02X:%02X:%02X:%02X:%02X", received_msg.host[0],
received_msg.host[1],received_msg.host[2],received_msg.host[3],received_msg.host[4],received_msg.host[5]);
} }
else{ else{
ESP_LOGI(TAG, "Couldn't save Host Mac to flash"); ESP_LOGI(TAG, "Couldn't save Host Mac to flash");
...@@ -97,6 +79,26 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) ...@@ -97,6 +79,26 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len)
preferences.end(); preferences.end();
add_host_to_peers(received_msg); add_host_to_peers(received_msg);
} }
case dataAck:{
ESP_LOGI(TAG, "dataAck received.");
Time::getInstance().setTime(
received_msg.epoch_seconds); // see https://www.esp32.com/viewtopic.php?t=9965, maybe this needs an offset
ESP_LOGI(TAG, "Timestamp received: %ld", Time::getInstance().getEpochSeconds());
preferences.begin("config", false);
if (!preferences.isKey("host")) {
if(preferences.putBytes("host", received_msg.host, sizeof(received_msg.host)) > 0){
ESP_LOGI(TAG, "host MAC address saved to flash %02X:%02X:%02X:%02X:%02X:%02X", received_msg.host[0],
received_msg.host[1],received_msg.host[2],received_msg.host[3],received_msg.host[4],received_msg.host[5]);
}
// add host to peers
add_host_to_peers(received_msg);
}
preferences.end();
// delay(50);
msg_recv = true;
}
default:{ default:{
break; break;
} }
...@@ -111,6 +113,7 @@ esp_err_t espnow_setup() ...@@ -111,6 +113,7 @@ esp_err_t espnow_setup()
result = esp_now_init(); result = esp_now_init();
if (result != ESP_OK) { if (result != ESP_OK) {
// initialization failed // initialization failed
ESP_LOGE(TAG, "ESPNow setup failed");
return result; // not sure about this return result; // not sure about this
} }
...@@ -127,5 +130,6 @@ esp_err_t espnow_setup() ...@@ -127,5 +130,6 @@ esp_err_t espnow_setup()
esp_now_register_recv_cb(on_data_recv); esp_now_register_recv_cb(on_data_recv);
esp_now_register_send_cb(on_data_sent); esp_now_register_send_cb(on_data_sent);
ESP_LOGI(TAG, "ESPNow started. MAC: %s", WiFi.macAddress().c_str());
return ESP_OK; return ESP_OK;
} }
...@@ -4,7 +4,7 @@ static const char *TAG = "MESSAGE"; ...@@ -4,7 +4,7 @@ static const char *TAG = "MESSAGE";
esp_err_t Message::send() const esp_err_t Message::send() const
{ {
ESP_LOGI(TAG, "Sending message"); ESP_LOGD(TAG, "Sending message");
esp_err_t success; esp_err_t success;
auto messageData = getMessageAsMinifiedJsonString(); auto messageData = getMessageAsMinifiedJsonString();
...@@ -12,12 +12,11 @@ esp_err_t Message::send() const ...@@ -12,12 +12,11 @@ esp_err_t Message::send() const
success = esp_now_send(recipient, (uint8_t *)messageData.c_str(), (messageData.length() + 1) * sizeof(char)); success = esp_now_send(recipient, (uint8_t *)messageData.c_str(), (messageData.length() + 1) * sizeof(char));
if (success != ESP_OK) { if (success != ESP_OK) {
ESP_LOGE(TAG, "Error sending the data"); ESP_LOGE(TAG, "Error sending the data");
Serial.println(success, HEX);
// Removed caching from here, better do this in main // Removed caching from here, better do this in main
} }
ESP_LOGE(TAG, "Sent data: %s", messageData.c_str()); ESP_LOGD(TAG, "Sent data: %s", messageData.c_str());
ESP_LOGD(TAG, "time sent: %l", clientDataPackage.getTimestamp()); ESP_LOGD(TAG, "Timestamp sent: %ld", clientDataPackage.getTimestamp());
ESP_LOGD(TAG, "send status: %d", success); ESP_LOGD(TAG, "send status: %d", success);
return success; return success;
......
#include "Arduino.h"
#include <SoftwareSerial.h> // RS485 setup with ESP32
// THIS SNIPPET APPLIES ONLY TO SOIL SENSORS!!!
// Other RS485 sensors will have to use other commands as well
/*
TODO It would be better to have one class for ALL RS485 sensors since they
all send/receive data in the same way, and then specific classes for individual
sensors (soil moisture, rain gauge, radiation) with sensor-specific commands.
*/
/* TODO The address of the sensor (first byte of the query frame) is
hard-coded now - it should be passed as an argument instead since
we have three sensors with different addresses now.
The last two values of the queryFrame don't matter, they will be changed
later to confrom to the CRC check.
The length of the sent message will always be 8 bytes.
*/
const byte bufferSize = 6;
byte queryFrame[bufferSize + 2] = {0x05, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00};
// 0: sensor address (differs per sensor)
// 1: function code (03 = get data for all sensors)
// 2+3: register start (0x00 0x00 for all sensors)
// 4+5: register length (0x01 for radiation+rain, 0x02 for soil)
// 6+7: CRC check (calculated later per sensor and message)
/*
TODO the length of the answer frame should NOT be hard-coded, it's going to be either
8 bytes (radiation, rain) or 9 bytes (soil)
*/
byte answerFrame[9];
#define RXPin 4 // Serial Receive pin
#define TXPin 5 // Serial Transmit pin
// RS485 control
// this will change once we get different hardware
#define SERIAL_COMMUNICATION_CONTROL_PIN 6 // Transmission set pin
#define RS485_TX_PIN_VALUE HIGH
#define RS485_RX_PIN_VALUE LOW
SoftwareSerial RS485Serial(RXPin, TXPin); // RX, TX
unsigned int calculateCRC()
// TODO pass the query/answer frame into this and return the changed frame
// to make things neater maybe? Apparently there are also libraries for this...
// Change the last two bytes of the queryFrame to conform to a CRC check
// Yes, this is necessary. No, I don't know exactly what it does.
{
unsigned int tmp1, tmp2, flag;
tmp1 = 0xFFFF;
for (unsigned char i = 0; i < bufferSize; i++)
{
tmp1 = tmp1 ^ queryFrame[i];
for (unsigned char j = 1; j <= 8; j++)
{
flag = tmp1 & 0x0001;
tmp1 >>= 1;
if (flag)
tmp1 ^= 0xA001;
}
}
// Reverse byte order.
tmp2 = tmp1 >> 8;
tmp1 = (tmp1 << 8) | tmp2;
tmp1 &= 0xFFFF;
queryFrame[bufferSize + 1] = tmp1;
queryFrame[bufferSize] = tmp1 >> 8;
return tmp1; // the returned value is already swapped - CRC_L byte is first & CRC_H byte is last
}
void setup() {
// configure the pin to be output only
pinMode(SERIAL_COMMUNICATION_CONTROL_PIN, OUTPUT);
// Set data rates: Serial baud rate has to be WAY HIGHER than RS485Serial!
Serial.begin(115200);
RS485Serial.begin(4800);
// Calculate the check bytes: changes the last two bytes of queryFrame
calculateCRC();
// Print the message that's sent to the sensor
Serial.println("Query bytes:");
for (int i = 0; i < sizeof(queryFrame); i++){
Serial.print(queryFrame[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.println();
}
void loop() {
// Index for the readout while loop
int idx = 0;
int byteReceived;
float vwc; // volumetric waetr content, i.e. soil moisture
float temp; // soil temperature
// Initialize the transmitter
Serial.println("Sending data");
digitalWrite(SERIAL_COMMUNICATION_CONTROL_PIN, RS485_TX_PIN_VALUE);
// Send message: request a reading from the sensor
RS485Serial.write(queryFrame, sizeof(queryFrame));
// Initialize the receiver
digitalWrite(SERIAL_COMMUNICATION_CONTROL_PIN, RS485_RX_PIN_VALUE);
// Read out data: this works ONLY when the Serial baud rate >> RS485Serial baud rate
// TODO add some logic for when there's no data and we get a timeout
while (idx < sizeof(answerFrame)) {
if(RS485Serial.available()) {
byteReceived = RS485Serial.read();
// Serial.println(byteReceived, HEX);
answerFrame[idx] = byteReceived;
idx++;
}
}
// Print out answer bytes
/*
Byte 0: sensor address
Byte 1: Function code
Byte 2: valid bytes (2 valid bytes per read variable)
Byte 3+4: 1st read variable
Byte 5+6: 2nd read variable
Byte n-1 + n: CRC checks
*/
Serial.println(" ");
Serial.println("Answer bytes:");
for(int i = 0; i < sizeof(answerFrame); i++){
Serial.print(answerFrame[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.println();
Serial.print("Sensor number: ");
Serial.println(answerFrame[0], HEX);
Serial.print("Number of read variables: ");
Serial.println(answerFrame[2] / 2, DEC);
vwc = word(answerFrame[3], answerFrame[4]); // word = 2 bytes, high byte first
Serial.print("vwc: ");
Serial.println(vwc / 10 , DEC);
temp = word(answerFrame[5], answerFrame[6]);
Serial.print("soil T: ");
Serial.println(temp / 10, DEC);
Serial.println(" ");
// Get reading every 5 seconds
delay(5000);
/* TODO add a CRC check for the received data, i.e. take n-2 bytes of the answer,
calculate CRC, and then compare if it fist with the CRC bytes that were received.
*/
}
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32-c3-devkitm-1]
platform = espressif32
board = esp32-c3-devkitm-1
framework = arduino
<<<<<<<< HEAD:code-snippets/espnow/espNowTest/platformio.ini
monitor_speed = 115200
lib_deps = makuna/NeoPixelBus@^2.7.0
========
monitor_speed = 115000
lib_deps = EspSoftwareSerial
>>>>>>>> origin/power-management-satellite:code-snippets/client/soil_sensor_sentec/platformio.ini
...@@ -12,5 +12,11 @@ ...@@ -12,5 +12,11 @@
platform = espressif32 platform = espressif32
board = esp32-c3-devkitm-1 board = esp32-c3-devkitm-1
framework = arduino framework = arduino
<<<<<<<< HEAD:host/mock/platformio.ini
lib_deps =
bblanchon/ArduinoJson@^6.19.4
fbiego/ESP32Time@^2.0.0
========
monitor_speed = 115200 monitor_speed = 115200
lib_deps = makuna/NeoPixelBus@^2.7.0 lib_deps = makuna/NeoPixelBus@^2.7.0
>>>>>>>> origin/power-management-satellite:code-snippets/espnow/espNowTest/platformio.ini
This diff is collapsed.
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