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

Possibility to send 4 messages with one ESPNow-send action

parent de64ec6e
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
...@@ -6,6 +6,7 @@ monitor_speed = 115200 ...@@ -6,6 +6,7 @@ monitor_speed = 115200
lib_ldf_mode = deep lib_ldf_mode = deep
lib_extra_dirs = lib_extra_dirs =
../libs ../libs
../../shared-libs
; C++17 https://community.platformio.org/t/esp32-c-17-toolchain-missing-std-optional/25850/6 ; C++17 https://community.platformio.org/t/esp32-c-17-toolchain-missing-std-optional/25850/6
; we use c++17 features (i.e. optionals in ClientDataPackage.hpp) ; we use c++17 features (i.e. optionals in ClientDataPackage.hpp)
build_flags = build_flags =
......
...@@ -15,112 +15,121 @@ MockSensor mock_channel2; ...@@ -15,112 +15,121 @@ MockSensor mock_channel2;
MockSensor mock_channel3; MockSensor mock_channel3;
void send_msgs(const std::__cxx11::list<Message> msgs) { void send_msgs(const std::__cxx11::list<Message> msgs) {
for (const Message &msg: msgs) { for (const Message &msg: msgs) {
if (msg.send() != ESP_OK) { if (msg.send() != ESP_OK) {
RtcMemory::store(msg.getMessageAsMinifiedJsonString()); RtcMemory::store(msg.getMessageAsMinifiedJsonString());
} }
unsigned long ts = millis(); unsigned long ts = millis();
// it takes ~110ms for receiving an acknowledgement by the host in perfect conditions // it takes ~110ms for receiving an acknowledgement by the host in perfect conditions
uint16_t message_timeout = 2000; uint16_t message_timeout = 2000;
while (!was_msg_received()) { while (!was_msg_received()) {
if ((millis() - ts) > message_timeout) { if ((millis() - ts) > message_timeout) {
RtcMemory::store(msg.getMessageAsMinifiedJsonString()); RtcMemory::store(msg.getMessageAsMinifiedJsonString());
ESP_LOGE(TAG, "Timeout: Host not available\n"); ESP_LOGE(TAG, "Timeout: Host not available\n");
break; break;
} }
}
ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts);
} }
ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts);
}
} }
// one loop takes ~2200 ms // one loop takes ~2200 ms
void setup() { void setup() {
// disable brownout // disable brownout
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
unsigned long ts = millis(); unsigned long ts = millis();
Serial.begin(115200); Serial.begin(115200);
DeepSleep::print_wakeup_reason(); DeepSleep::print_wakeup_reason();
DeepSleep::bootCount++; DeepSleep::bootCount++;
ESP_LOGD(TAG, "Boot number: %d", DeepSleep::bootCount); ESP_LOGD(TAG, "Boot number: %d", DeepSleep::bootCount);
// delay(100); // delay(100);
mock_channel0.setup(); mock_channel0.setup();
mock_channel1.setup(); mock_channel1.setup();
mock_channel2.setup(); mock_channel2.setup();
mock_channel3.setup(); mock_channel3.setup();
mock_channel0.setChannel(0); mock_channel0.setChannel(0);
mock_channel1.setChannel(1); mock_channel1.setChannel(1);
mock_channel2.setChannel(2); mock_channel2.setChannel(2);
mock_channel3.setChannel(3); mock_channel3.setChannel(3);
ESP_LOGD(TAG, "Setup took %ld ms", millis() - ts); ESP_LOGD(TAG, "Setup took %ld ms", millis() - ts);
try { try {
// FIXME: put me into seperate trys? No data will be sent when 1 exception occurs // FIXME: put me into seperate trys? No data will be sent when 1 exception occurs
ts = millis(); ts = millis();
auto messages0 = mock_channel0.buildMessages(); auto messages0 = mock_channel0.buildMessages();
auto messages1 = mock_channel1.buildMessages(); auto messages1 = mock_channel1.buildMessages();
auto messages2 = mock_channel2.buildMessages(); auto messages2 = mock_channel2.buildMessages();
auto messages3 = mock_channel3.buildMessages(); auto messages3 = mock_channel3.buildMessages();
// roughly takes 500ms, ~120ms for each adc channel, barely anything for battery monitor // roughly takes 500ms, ~120ms for each adc channel, barely anything for battery monitor
ESP_LOGD(TAG, "Reading data and building messages took %ld ms", millis() - ts); ESP_LOGD(TAG,
gpio_set_level(GPIO_NUM_32, 0); "Reading data and building messages took %ld ms",
millis() - ts);
ESP_LOGD(TAG, "Size of message to be sent: %d", sizeof(messages0.front())); gpio_set_level(GPIO_NUM_32, 0);
ESP_LOGD(TAG, "Size of Message class: %d", sizeof(Message));
ESP_LOGD(TAG, "Size of ClientDataPackage class: %d", sizeof(ClientDataPackage)); ESP_LOGD(TAG, "Size of message to be sent: %d", sizeof(messages0.front()));
// sizeof string ESP_LOGD(TAG, "Size of Message class: %d", sizeof(Message));
ESP_LOGD(TAG, "Size of string: %d", sizeof(std::string)); ESP_LOGD(TAG,
// sizeof string with 5 char "Size of ClientDataPackage class: %d",
ESP_LOGD(TAG, "Size of string with 5 char: %d", sizeof(char[5])); sizeof(ClientDataPackage));
// sizeof optional int // sizeof string
ESP_LOGD(TAG, "Size of optional int: %d", sizeof(std::optional<int>)); ESP_LOGD(TAG, "Size of string: %d", sizeof(std::string));
// sizeof int // sizeof string with 5 char
ESP_LOGD(TAG, "Size of int: %d", sizeof(int)); ESP_LOGD(TAG, "Size of string with 5 char: %d", sizeof(char[5]));
// sizeof double // sizeof optional int
ESP_LOGD(TAG, "Size of double: %d", sizeof(double)); ESP_LOGD(TAG, "Size of optional int: %d", sizeof(std::optional<int>));
// sizeof float // sizeof int
ESP_LOGD(TAG, "Size of float: %d", sizeof(float)); ESP_LOGD(TAG, "Size of int: %d", sizeof(int));
// list of 5 compresseddatapackage // sizeof double
CompressedDataPackage compresseddatapackage{}; ESP_LOGD(TAG, "Size of double: %d", sizeof(double));
ESP_LOGD(TAG, "Size of list of 4 CompressedDataPackage: %d", sizeof(std::list<CompressedDataPackage>) + (sizeof(CompressedDataPackage) * 4)); // sizeof float
// sizeof compresseddatapackage ESP_LOGD(TAG, "Size of float: %d", sizeof(float));
ESP_LOGD(TAG, "Size of CompressedDataPackage: %d", sizeof(CompressedDataPackage)); // list of 5 compresseddatapackage
// sizeof list CompressedDataPackage compresseddatapackage{};
ESP_LOGD(TAG, "Size of list: %d", sizeof(std::list<CompressedDataPackage>)); ESP_LOGD(TAG,
// sizeof vector "Size of list of 4 CompressedDataPackage: %d",
ESP_LOGD(TAG, "Size of vector: %d", sizeof(std::vector<CompressedDataPackage>)); sizeof(std::list<CompressedDataPackage>)
+ (sizeof(CompressedDataPackage) * 4));
// FIXME: put this outside the try loop? // sizeof compresseddatapackage
ts = millis(); ESP_LOGD(TAG,
espnow_setup(); "Size of CompressedDataPackage: %d",
ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts); sizeof(CompressedDataPackage));
// make a list of messages // sizeof list
std::list<Message> messages; ESP_LOGD(TAG, "Size of list: %d", sizeof(std::list<CompressedDataPackage>));
messages.insert(messages.end(), messages0.begin(), messages0.end()); // sizeof vector
messages.insert(messages.end(), messages1.begin(), messages1.end()); ESP_LOGD(TAG,
messages.insert(messages.end(), messages2.begin(), messages2.end()); "Size of vector: %d",
messages.insert(messages.end(), messages3.begin(), messages3.end()); sizeof(std::vector<CompressedDataPackage>));
ts = millis(); // FIXME: put this outside the try loop?
// Message::sendMessages(messages); ts = millis();
send_msgs(messages0); espnow_setup();
ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts);
// make a list of messages
std::array<Message, 4> messages =
{messages0.front(), messages1.front(), messages2.front(),
Message::nullMessage()};
ts = millis();
Message::sendMessages(messages);
// send_msgs(messages0);
// send_msgs(messages1); // send_msgs(messages1);
// send_msgs(messages2); // send_msgs(messages2);
// send_msgs(messages3); // send_msgs(messages3);
// roughly takes 3s in ideal conditions // roughly takes 3s in ideal conditions
ESP_LOGD(TAG, "Sending messages took %ld ms", millis() - ts); ESP_LOGD(TAG, "Sending messages took %ld ms", millis() - ts);
} catch (const NoDataAvailableException &e) { } catch (const NoDataAvailableException &e) {
std::cerr << e.what() << '\n'; std::cerr << e.what() << '\n';
} }
// battery protection: go to deep sleep for unlimited time when voltage less than 3.2V // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V
DeepSleep::deep_sleep(5); DeepSleep::deep_sleep(5);
} }
......
...@@ -4,75 +4,85 @@ ...@@ -4,75 +4,85 @@
static const char *TAG = "MESSAGE"; static const char *TAG = "MESSAGE";
esp_err_t Message::send() const { esp_err_t Message::send() const {
ESP_LOGD(TAG, "Sending message"); ESP_LOGD(TAG, "Sending message");
esp_err_t success; esp_err_t success;
auto messageData = getCompressedDataPackage(); auto messageData = getCompressedDataPackage();
// conversion from std::string to c_str adds null terminator, which is why we add 1 to message length // conversion from std::string to c_str adds null terminator, which is why we add 1 to message length
success = esp_now_send(recipient, (uint8_t * ) & messageData, sizeof(CompressedDataPackage)); success = esp_now_send(recipient,
if (success != ESP_OK) { (uint8_t *) &messageData,
ESP_LOGE(TAG, "Error sending the data"); sizeof(CompressedDataPackage));
// Removed caching from here, better do this in main if (success != ESP_OK) {
} ESP_LOGE(TAG, "Error sending the data");
// Removed caching from here, better do this in main
}
// ESP_LOGD(TAG, "Sent data: %s", messageData.c_str()); // ESP_LOGD(TAG, "Sent data: %s", messageData.c_str());
ESP_LOGD(TAG, "Timestamp sent: %ld", 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;
} }
esp_err_t Message::sendMessages(const std::list<Message> &messages) { esp_err_t Message::sendMessages(const std::array<Message, 4> &messages) {
// recipient // recipient
uint8_t rec[6]{}; uint8_t rec[6]{};
get_host_mac(rec); get_host_mac(rec);
ESP_LOGD(TAG, "Sending messages"); ESP_LOGD(TAG, "Sending messages");
esp_err_t success; esp_err_t success;
// list of compressed data // list of compressed data. Sending 4 at a time
std::list<CompressedDataPackage> compressedDataPackages; std::array<CompressedDataPackage, 4> compressedDataPackages{};
// max 4 messages // max 4 messages
int i = 0; for (int i = 0; i < 4; i++) {
for (const auto &message: messages) { compressedDataPackages[i] = messages[i].getCompressedDataPackage();
i++; if (messages[i].clientDataPackage.getTimestamp() == NULL_TIMESTAMP) {
compressedDataPackages.push_back(message.getCompressedDataPackage()); compressedDataPackages[i].errorType = ErrorTypes::NULL_MESSAGE;
if (i == 4) {
break;
}
} }
}
// conversion from std::string to c_str adds null terminator, which is why we add 1 to message length // conversion from std::string to c_str adds null terminator, which is why we add 1 to message length
success = esp_now_send(rec, (uint8_t * ) & compressedDataPackages, success = esp_now_send(rec, (uint8_t *) &compressedDataPackages,
sizeof(std::list<CompressedDataPackage>) + sizeof(std::array<CompressedDataPackage, 4>));
4 * sizeof(CompressedDataPackage)); if (success != ESP_OK) {
if (success != ESP_OK) { ESP_LOGE(TAG, "Error sending the data");
ESP_LOGE(TAG, "Error sending the data"); // Removed caching from here, better do this in main
// Removed caching from here, better do this in main }
unsigned long ts = millis();
// it takes ~110ms for receiving an acknowledgement by the host in perfect conditions
uint16_t message_timeout = 2000;
while (!was_msg_received()) {
if ((millis() - ts) > message_timeout) {
ESP_LOGE(TAG, "Timeout: Host not available\n");
break;
} }
}
ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts);
// ESP_LOGD(TAG, "Sent data: %s", messageData.c_str()); // ESP_LOGD(TAG, "Sent data: %s", messageData.c_str());
// ESP_LOGD(TAG, "Timestamp sent: %ld", 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;
} }
std::string Message::getMessageAsMinifiedJsonString() const { std::string Message::getMessageAsMinifiedJsonString() const {
return clientDataPackage.getDataPackageAsMinifiedJsonString(); return clientDataPackage.getDataPackageAsMinifiedJsonString();
} }
CompressedDataPackage Message::getCompressedDataPackage() const { CompressedDataPackage Message::getCompressedDataPackage() const {
return clientDataPackage.getCompressedDataPackage(); return clientDataPackage.getCompressedDataPackage();
} }
Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) { Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) {
// check for existing host mac address, use broadcast otherwise // check for existing host mac address, use broadcast otherwise
get_host_mac(recipient); get_host_mac(recipient);
} }
Message::Message(MeasurementData const &data, const SensorInformation &information, Message::Message(MeasurementData const &data,
const SensorInformation &information,
unsigned long timestamp) unsigned long timestamp)
: clientDataPackage(data, information, timestamp) { : clientDataPackage(data, information, timestamp) {
// check for existing host mac address, use broadcast otherwise // check for existing host mac address, use broadcast otherwise
get_host_mac(recipient); get_host_mac(recipient);
} }
...@@ -14,19 +14,29 @@ ...@@ -14,19 +14,29 @@
// Format of the message sent from host to client_satellite // Format of the message sent from host to client_satellite
// if more things are sent from the host the name might not be accurate anymore // if more things are sent from the host the name might not be accurate anymore
class Message { class Message {
public: public:
explicit Message(ClientDataPackage data); explicit Message(ClientDataPackage data);
Message(MeasurementData const &data, const SensorInformation &information, unsigned long timestamp); Message(MeasurementData const &data,
esp_err_t send() const; const SensorInformation &information,
[[nodiscard]] std::string getMessageAsMinifiedJsonString() const; unsigned long timestamp);
esp_err_t send() const;
[[nodiscard]] std::string getMessageAsMinifiedJsonString() const;
static Message nullMessage() {
return Message{MeasurementData(ERROR_VALUE,
std::nullopt,
std::nullopt,
"null"),
SensorInformation("null", SensorProtocol::NULL_PROTOCOL),
NULL_TIMESTAMP};
}
static esp_err_t sendMessages(const std::list<Message>& messages); static esp_err_t sendMessages(const std::array<Message, 4> &messages);
private: private:
ClientDataPackage clientDataPackage; ClientDataPackage clientDataPackage;
uint8_t recipient[6]{}; uint8_t recipient[6]{};
CompressedDataPackage getCompressedDataPackage() const; CompressedDataPackage getCompressedDataPackage() const;
}; };
//
// Created by zoe on 1/27/23.
//
#ifndef CLIENT_SATELLITE_ERRORTYPES_H
#define CLIENT_SATELLITE_ERRORTYPES_H
enum ERROR_TYPES {
SENSOR_DOES_NOT_RETURN_DATA = 1,
BATTERY_VOLTAGE_TOO_LOW = 2,
INVALID_VALUE = 3,
SENSOR_NOT_CONNECTED = 4,
};
#endif //CLIENT_SATELLITE_ERRORTYPES_H
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
#define CLIENT_PROTOCOL_HPP #define CLIENT_PROTOCOL_HPP
#include <map> #include <map>
enum class SensorProtocol { I2C, RS485, Analog, Mock }; enum class SensorProtocol { I2C, RS485, Analog, Mock, NULL_PROTOCOL };
// sensorProtocol to string // sensorProtocol to string
const static std::map<SensorProtocol, const char *> protocolToString = { const static std::map<SensorProtocol, const char *> protocolToString = {
{SensorProtocol::I2C, "I2C"}, {SensorProtocol::RS485, "RS485"}, {SensorProtocol::Analog, "ANALOG"}, {SensorProtocol::Mock, "MOCK"}}; {SensorProtocol::I2C, "I2C"}, {SensorProtocol::RS485, "RS485"},
{SensorProtocol::Analog, "ANALOG"}, {SensorProtocol::Mock, "MOCK"},
{SensorProtocol::NULL_PROTOCOL, "NULL"}};
#endif // CLIENT_PROTOCOL_HPP #endif // CLIENT_PROTOCOL_HPP
...@@ -4,31 +4,33 @@ static const char *TAG = "MOCK"; ...@@ -4,31 +4,33 @@ static const char *TAG = "MOCK";
void MockSensor::setup() { void MockSensor::setup() {
ESP_LOGD(TAG, "MOCK Sensor initialized"); ESP_LOGD(TAG, "MOCK Sensor initialized");
delay(100); delay(100);
channel = 0; channel = 0;
} }
float MockSensor::readData() { float MockSensor::readData() {
// generate a random float value between 0 and 100 // generate a random float value between 0 and 100
float randomValue = (float)rand() / (float)RAND_MAX * 100.0; float randomValue = (float) rand() / (float) RAND_MAX * 100.0;
ESP_LOGD(TAG, "MOCK Sensor read value: %f", randomValue); ESP_LOGD(TAG, "MOCK Sensor read value: %f", randomValue);
return randomValue; return randomValue;
} }
void MockSensor::setChannel(int c) { void MockSensor::setChannel(int c) {
channel = c; channel = c;
} }
std::list<Message> MockSensor::buildMessages() { std::list<Message> MockSensor::buildMessages() {
std::list<Message> messages; std::list<Message> messages;
float data = readData(); float data = readData() + static_cast<float>(DeepSleep::bootCount);
MeasurementData MockData{data, channel, {}, "MOCK"}; MeasurementData MockData{data, channel, {}, "MOCK"};
messages.emplace_back(MockData, sensorInformation, Time::getInstance().getEpochSeconds()); messages.emplace_back(MockData,
return messages; sensorInformation,
Time::getInstance().getEpochSeconds());
return messages;
} }
SensorInformation MockSensor::getSensorInformation() const { SensorInformation MockSensor::getSensorInformation() const {
return sensorInformation; return sensorInformation;
} }
...@@ -7,18 +7,20 @@ ...@@ -7,18 +7,20 @@
#include "Pinout.hpp" #include "Pinout.hpp"
#include "esp_log.h" #include "esp_log.h"
#include <Wire.h> #include <Wire.h>
#include <f_deep_sleep.hpp>
class MockSensor : public ForteSensor<float> {
public:
void setup() override;
float readData() override;
void setChannel(int channel);
std::list<Message> buildMessages() override;
[[nodiscard]] SensorInformation getSensorInformation() const override;
private: class MockSensor: public ForteSensor<float> {
const SensorInformation sensorInformation{"MOCK", SensorProtocol::Mock}; public:
int channel; void setup() override;
float readData() override;
void setChannel(int channel);
std::list<Message> buildMessages() override;
[[nodiscard]] SensorInformation getSensorInformation() const override;
private:
const SensorInformation sensorInformation{"MOCK", SensorProtocol::Mock};
int channel;
}; };
#endif #endif
\ No newline at end of file
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#ifndef HOST_CENTRAL_MAST_UTILITIES_H #ifndef HOST_CENTRAL_MAST_UTILITIES_H
#define HOST_CENTRAL_MAST_UTILITIES_H #define HOST_CENTRAL_MAST_UTILITIES_H
#include "../../../client/libs/espnow/src/CompressedDataPackage.hpp"
#include "ArduinoJson.h" #include "ArduinoJson.h"
#include "CompressedDataPackage.hpp"
#include "SD.h" #include "SD.h"
#include "SDCardException.h" #include "SDCardException.h"
#include "SDSetupException.h" #include "SDSetupException.h"
...@@ -35,6 +35,7 @@ String getMacAddressAsString(const uint8_t *mac); ...@@ -35,6 +35,7 @@ String getMacAddressAsString(const uint8_t *mac);
String documentToLineProtocolString(const DynamicJsonDocument &doc); String documentToLineProtocolString(const DynamicJsonDocument &doc);
DynamicJsonDocument parseReceivedJsonData(char *data); DynamicJsonDocument parseReceivedJsonData(char *data);
String documentToServerReadableString(const DynamicJsonDocument &doc); String documentToServerReadableString(const DynamicJsonDocument &doc);
String compressedDataPackageToServerReadableString(CompressedDataPackage compressedDataPackage, const String& clientMacAddress); String compressedDataPackageToServerReadableString(CompressedDataPackage compressedDataPackage,
const String &clientMacAddress);
#endif // HOST_CENTRAL_MAST_UTILITIES_H #endif // HOST_CENTRAL_MAST_UTILITIES_H
...@@ -16,6 +16,8 @@ monitor_speed = 115200 ...@@ -16,6 +16,8 @@ monitor_speed = 115200
lib_ldf_mode = deep lib_ldf_mode = deep
monitor_port = /dev/ttyACM0 monitor_port = /dev/ttyACM0
upload_port = /dev/ttyACM0 upload_port = /dev/ttyACM0
lib_extra_dirs =
../../shared-libs
build_flags = build_flags =
-I include -I include
-DCORE_DEBUG_LEVEL=5 -DCORE_DEBUG_LEVEL=5
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#define TINY_GSM_MODEM_SIM7000 #define TINY_GSM_MODEM_SIM7000
#include "../../../client/libs/espnow/src/CompressedDataPackage.hpp" #include "CompressedDataPackage.hpp"
#include "ConnectionManager.h" #include "ConnectionManager.h"
#include "MessageType.h" #include "MessageType.h"
#include "SDCardLogger.h" #include "SDCardLogger.h"
...@@ -56,15 +56,13 @@ void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) { ...@@ -56,15 +56,13 @@ void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) {
// go to sleep // go to sleep
} }
/**
* @brief ESPNOW callback function that is called when data is received
* @param mac
* @param incomingData
* @param len length of the incoming data in bytes
*/
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) {
esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Message recieved\n");
// copy received data to a char array
CompressedDataPackage compressedDataPackage{};
memcpy(&compressedDataPackage, incomingData, sizeof(CompressedDataPackage));
// esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Raw received Data: %s\n", data);
// log received data
esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Received Data: %s\n", compressedDataPackage.toString().c_str());
if (!esp_now_is_peer_exist(mac)) { if (!esp_now_is_peer_exist(mac)) {
esp_now_peer_info_t client = {}; esp_now_peer_info_t client = {};
...@@ -78,30 +76,45 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) { ...@@ -78,30 +76,45 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) {
} }
} }
// TODO: Respond to the client. Maybe do that before parsing anything
response response = {}; response response = {};
response.type = dataAck; response.type = dataAck;
esp_read_mac(response.mac, ESP_MAC_WIFI_STA); esp_read_mac(response.mac, ESP_MAC_WIFI_STA);
response.time = rtc.getEpoch(); response.time = rtc.getEpoch();
esp_err_t success = esp_now_send(mac, (uint8_t *)&response, sizeof(response)); esp_err_t success = esp_now_send(mac, (uint8_t *)&response, sizeof(response));
esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Message recieved\n");
esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, (success == ESP_OK) ? "Response sent\n" : "Failed to respond\n"); esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, (success == ESP_OK) ? "Response sent\n" : "Failed to respond\n");
// copy received data to a char array
std::array<CompressedDataPackage, 4> compressedDataPackage{};
memcpy(&compressedDataPackage, incomingData, sizeof(std::array<CompressedDataPackage, 4>));
// esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Raw received Data: %s\n", data);
String macAddress = getMacAddressAsString(mac); String macAddress = getMacAddressAsString(mac);
auto doc = compressedDataPackageToServerReadableString(compressedDataPackage, macAddress); for (auto &data : compressedDataPackage) {
// serialize json document again // ignore padding messages
std::string dataString{}; if (data.timestamp == NULL_TIMESTAMP && data.errorType == NULL_MESSAGE) {
continue;
}
try { // log received data
SDUtilities::saveStringToSDCard(dataString); esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Received Data: %s\n", data.toString().c_str());
} catch (const std::exception &e) { auto doc = compressedDataPackageToServerReadableString(data, macAddress);
esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW, "Failed to save data to SD card: %s", e.what());
}
xSemaphoreTake(xMutex, portMAX_DELAY); // serialize json document again
queue.emplace(dataString.c_str()); std::string dataString{};
xSemaphoreGive(xMutex);
try {
SDUtilities::saveStringToSDCard(dataString);
} catch (const std::exception &e) {
esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW, "Failed to save data to SD card: %s", e.what());
}
xSemaphoreTake(xMutex, portMAX_DELAY);
queue.emplace(dataString.c_str());
xSemaphoreGive(xMutex);
}
} }
[[noreturn]] void esp_loop() { [[noreturn]] void esp_loop() {
......
...@@ -10,11 +10,15 @@ ...@@ -10,11 +10,15 @@
#include <string> #include <string>
#include <utility> #include <utility>
constexpr double ERROR_VALUE = -999.99;
constexpr unsigned long NULL_TIMESTAMP = 0; // null timestamp
enum ErrorTypes : short { enum ErrorTypes : short {
SENSOR_NOT_FOUND, SENSOR_NOT_FOUND,
SENSOR_NOT_CONNECTED, SENSOR_NOT_CONNECTED,
NO_DATA, NO_DATA,
DATA_OK, DATA_OK,
NULL_MESSAGE, // message that is sent as padding, should be thrown away
}; };
struct CompressedDataPackage { struct CompressedDataPackage {
......
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