diff --git a/client/client/lib/caching/src/ram_caching.cpp b/client/client/lib/caching/src/ram_caching.cpp index 7b3e4372177608b2392c703dbd352e6a7b47cabb..9325e7c7909473c998d2a113779d94480fa3589c 100644 --- a/client/client/lib/caching/src/ram_caching.cpp +++ b/client/client/lib/caching/src/ram_caching.cpp @@ -1,21 +1,24 @@ -#include <Arduino.h> -#include "espnow.hpp" +#include "ram_caching.hpp" RTC_DATA_ATTR int cachedAmount = -1; -RTC_DATA_ATTR data_struct backup[10]; +RTC_DATA_ATTR ClientDataPackage backup[NUM_SENSORS]; -data_struct ram_cache_pop(){ - return backup[cachedAmount--]; +ClientDataPackage ram_cache_pop() +{ + return backup[cachedAmount--]; } -void ram_cache_push(data_struct data){ - backup[++cachedAmount] = data; +void ram_cache_push(ClientDataPackage data) +{ + backup[++cachedAmount] = data; } -bool ram_cache_is_empty(){ - return cachedAmount == -1; +bool ram_cache_is_empty() +{ + return cachedAmount == -1; } -bool ram_cache_is_full(){ - return cachedAmount == 9; +bool ram_cache_is_full() +{ + return cachedAmount == 9; } \ No newline at end of file diff --git a/client/client/lib/caching/src/ram_caching.hpp b/client/client/lib/caching/src/ram_caching.hpp index 979e8496faf9599c0621300b8714fd359321f05b..466668ba65578e0a9aa3f0af9bf20174889b0eb2 100644 --- a/client/client/lib/caching/src/ram_caching.hpp +++ b/client/client/lib/caching/src/ram_caching.hpp @@ -1,10 +1,11 @@ #ifndef _RAM_CACHE #define _RAM_CACHE -#include "espnow.hpp" +#include "ClientDataPackage.hpp" +#include <ESP32Time.h> bool ram_cache_is_empty(); bool ram_cache_is_full(); -void ram_cache_push(data_struct data); -data_struct ram_cache_pop(); +void ram_cache_push(ClientDataPackage data); +ClientDataPackage ram_cache_pop(); #endif \ No newline at end of file diff --git a/client/client/lib/espnow/src/ClientDataPackage.hpp b/client/client/lib/espnow/src/ClientDataPackage.hpp new file mode 100644 index 0000000000000000000000000000000000000000..52f2be6032a190e6346bef71457cb78c983b0038 --- /dev/null +++ b/client/client/lib/espnow/src/ClientDataPackage.hpp @@ -0,0 +1,14 @@ +#pragma once + +#define NUM_SENSORS 10 +// packing the struct without padding, makes reading it on the fipy easier +#pragma pack(1) + +// having the data be a struct of basic types makes sending easier, +// otherwise we would have to serialize the data before sending +struct ClientDataPackage { + int identifiers[NUM_SENSORS]; + float values[NUM_SENSORS]; + int amountData; + long timestamp; // maybe make this array +}; diff --git a/client/client/lib/espnow/src/Message.cpp b/client/client/lib/espnow/src/Message.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c4bfb3f765350c6ad51aa28ad605a7a13ae9c2e4 --- /dev/null +++ b/client/client/lib/espnow/src/Message.cpp @@ -0,0 +1,47 @@ +#include "Message.hpp" + +void Message::add_data(float value, int identifier) +{ + if (data.amountData < NUM_SENSORS) { + data.values[data.amountData] = value; + data.identifiers[data.amountData] = identifier; + data.amountData++; + } +} + +esp_err_t Message::send() +{ + Serial.println("sending Message"); + esp_err_t success; + success = esp_now_send(recipient, (uint8_t *)&data, sizeof(data)); + // if(success != ESP_OK){ + // if(!ram_cache_is_full()){ + // ram_cache_push(*data); + // } + // } + for (int i = 0; i < data.amountData; i++) { + Serial.println(data.values[i]); + } + Serial.println((String) "time sent: " + data.timestamp); + Serial.println((String) "Send status: " + success); + Serial.println(); + Serial.flush(); + Serial.println("done"); + return success; +} + +Message ::Message() +{ + // check for existing host mac address, use broadcast otherwise + get_host_mac(recipient); + + data.amountData = 0; + data.timestamp = esptime::rtc.getMillis(); // I am assuming we are not sending data from Unix Epoch +} + +Message ::Message(ClientDataPackage old_data) +{ + data = old_data; + // memcpy(&data, &old_data, sizeof(data)); + get_host_mac(recipient); +} \ No newline at end of file diff --git a/client/client/lib/espnow/src/Message.hpp b/client/client/lib/espnow/src/Message.hpp new file mode 100644 index 0000000000000000000000000000000000000000..54099ac974b98f10a841966f5c676cc78cba007b --- /dev/null +++ b/client/client/lib/espnow/src/Message.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "ClientDataPackage.hpp" +#include "espnow.hpp" +#include "time.hpp" +#include <Arduino.h> +#include <ESP32Time.h> +#include <esp_now.h> + +// Format of the message sent from host to client +// if more things are sent from the host the name might not be accurate anymore +class Message { + public: + Message(); + Message(ClientDataPackage old_data); + void add_data(float value, int identifier); + esp_err_t send(); + + private: + ClientDataPackage data; + uint8_t recipient[6]; +}; \ No newline at end of file diff --git a/client/client/lib/espnow/src/espnow.cpp b/client/client/lib/espnow/src/espnow.cpp index 718764ec756d3a66992a072ec1ada3a499161610..2d9aef44851371ab2844f92b60d7242e8fce824e 100644 --- a/client/client/lib/espnow/src/espnow.cpp +++ b/client/client/lib/espnow/src/espnow.cpp @@ -1,112 +1,61 @@ -#include <esp_now.h> -#include <Preferences.h> -#include <ESP32Time.h> -#include "WiFi.h" #include "espnow.hpp" -#include "ram_caching.hpp" uint8_t BROADCAST_MAC[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; esp_now_peer_info_t hostInfo; Preferences preferences; -ESP32Time rtc; -void get_host_mac(uint8_t* destination){ - preferences.begin("config", true); - if(preferences.isKey("host")){ - preferences.getBytes("host", destination, sizeof(uint8_t) * 6); - } - else{ - memcpy(destination, BROADCAST_MAC, sizeof(BROADCAST_MAC)); - Serial.println("backup mac used"); - } - preferences.end(); -} -void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status){ - // go to sleep -} - -void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len){ - Serial.println("message recieved"); - config new_config; - memcpy(&new_config, incomingData, sizeof(new_config)); // TODO: check for valid mac - // put the host address in flash mem - preferences.begin("config", false); - if(!preferences.isKey("host")){ - preferences.putBytes("host", new_config.host, sizeof(new_config.host)); - Serial.println("host mac saved to flash"); - }// host change shouldn't be an issue - preferences.end(); - // sync time - rtc.setTime(new_config.time_millis); // see https://www.esp32.com/viewtopic.php?t=9965, maybe this needs an offset +void get_host_mac(uint8_t *destination) +{ + preferences.begin("config", true); + if (preferences.isKey("host")) { + preferences.getBytes("host", destination, sizeof(uint8_t) * 6); + } else { + memcpy(destination, BROADCAST_MAC, sizeof(BROADCAST_MAC)); + Serial.println("backup mac used"); + } + preferences.end(); +} +void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) +{ + // go to sleep +} + +void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) +{ + Serial.println("message recieved"); + config new_config; + memcpy(&new_config, incomingData, sizeof(new_config)); // TODO: check for valid mac + + // put the host address in flash mem + preferences.begin("config", false); + if (!preferences.isKey("host")) { + preferences.putBytes("host", new_config.host, sizeof(new_config.host)); + Serial.println("host mac saved to flash"); + } // host change shouldn't be an issue + preferences.end(); + // sync time + esptime::rtc.setTime( + new_config.time_millis); // see https://www.esp32.com/viewtopic.php?t=9965, maybe this needs an offset +} + +esp_err_t espnow_setup() +{ + esp_err_t result; + WiFi.mode(WIFI_STA); + result = esp_now_init(); + if (result != ESP_OK) { + // initialization failed + return result; // not sure about this + } + + get_host_mac(hostInfo.peer_addr); // check if there is a host saved in flash mem, broadcast otherwise + + hostInfo.channel = 0; + hostInfo.encrypt = 0; + esp_now_add_peer(&hostInfo); + + esp_now_register_recv_cb(on_data_recv); + esp_now_register_send_cb(on_data_sent); + + return ESP_OK; } - - - -esp_err_t espnow_setup(){ - esp_err_t result; - WiFi.mode(WIFI_STA); - result = esp_now_init(); - if(result != ESP_OK){ - //initialization failed - return result; // not sure about this - } - - get_host_mac(hostInfo.peer_addr); // check if there is a host saved in flash mem, broadcast otherwise - - hostInfo.channel = 0; - hostInfo.encrypt = 0; - esp_now_add_peer(&hostInfo); - - esp_now_register_recv_cb(on_data_recv); - esp_now_register_send_cb(on_data_sent); - - return ESP_OK; -} - -void Message::add_data(float value, int identifier){ - if(data.amountData < NUM_SENSORS){ - data.values[data.amountData] = value; - data.identifiers[data.amountData] = identifier; - data.amountData++; - } -} - -esp_err_t Message::send(){ - Serial.println("sending Message"); - esp_err_t success; - success = esp_now_send(recipient, (uint8_t * ) &data , sizeof(data)); - // if(success != ESP_OK){ - // if(!ram_cache_is_full()){ - // ram_cache_push(*data); - // } - // } - for(int i=0; i<data.amountData; i++){ - Serial.println(data.values[i]); - } - Serial.println((String) "time sent: " + data.timestamp); - Serial.println((String) "Send status: " + success); - Serial.println(); - Serial.flush(); - Serial.println("done"); - return success; -} - -Message :: Message(){ - // data = (data_struct*) malloc(sizeof(data_struct)); - - // check for existing host mac address, use broadcast otherwise - get_host_mac(recipient); - - data.amountData = 0; - data.timestamp = rtc.getMillis(); // I am assuming we are not sending data from Unix Epoch -} - -Message :: Message(data_struct old_data){ - memcpy(&data, &old_data, sizeof(data)); - get_host_mac(recipient); -} - -// Message :: ~Message(){ -// free((void*) data); -// } - diff --git a/client/client/lib/espnow/src/espnow.hpp b/client/client/lib/espnow/src/espnow.hpp index ea20ce2993ae066b24c0f4e5becf2faf95a6dda6..26e90b864fd3da10b091091d3bff1cd840eadb19 100644 --- a/client/client/lib/espnow/src/espnow.hpp +++ b/client/client/lib/espnow/src/espnow.hpp @@ -1,41 +1,24 @@ #ifndef _ESPNOW #define _ESPNOW -#define NUM_SENSORS 10 -//packing the struct without padding, makes reading it on the fipy easier -#pragma pack(1) - -// having the data be a struct of basic types makes sending easier, -// otherwise we would have to serialize the data before sending -typedef struct data_struct{ - int identifiers[NUM_SENSORS]; - float values[NUM_SENSORS]; - int amountData; - long timestamp; //maybe make this array -}data_struct; - -// Format of the message sent from host to client -// if more things are sent from the host the name might not be accurate anymore -typedef struct config{ - uint8_t host[6]; - long time_millis; -}config; - -class Message{ - public: - Message(); - Message(data_struct old_data); - // ~Message(); - void add_data(float value, int identifier); - esp_err_t send(); - - private: - data_struct data; - uint8_t recipient[6]; - -}; +#include "Message.hpp" +#include "WiFi.h" +#include "ram_caching.hpp" +#include "time.hpp" +#include <ClientDataPackage.hpp> +#include <ESP32Time.h> +#include <Preferences.h> +#include <esp_now.h> + +typedef struct config { + uint8_t host[6]; + long time_millis; +} config; esp_err_t espnow_setup(); bool is_host_defined(); +void get_host_mac(uint8_t *destination); +void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status); +void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len); #endif \ No newline at end of file diff --git a/client/client/lib/time/src/time.hpp b/client/client/lib/time/src/time.hpp new file mode 100644 index 0000000000000000000000000000000000000000..318bfda6148dcbd50040d2e8986ba49b93c9424f --- /dev/null +++ b/client/client/lib/time/src/time.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include <ESP32Time.h> + +namespace esptime { +// internal linkage only +static ESP32Time rtc; // global variable for the RTC (i don't think this is good practice) +} // namespace esptime diff --git a/client/client/platformio.ini b/client/client/platformio.ini index 52babbdf3455a57a865a49423f3649dca83977ae..72fbedb2a3fadf885ac030f693513bd753f26172 100644 --- a/client/client/platformio.ini +++ b/client/client/platformio.ini @@ -13,4 +13,6 @@ platform = espressif32 board = esp32-c3-devkitm-1 framework = arduino monitor_speed = 115200 -lib_deps = fbiego/ESP32Time@^1.1.0 +lib_deps = + fbiego/ESP32Time@^1.1.0 + bblanchon/ArduinoJson@^6.19.4 diff --git a/client/client/src/main.cpp b/client/client/src/main.cpp index eea5a029e872ffcba46fd3c040390a9b9d5fe195..22228f3c6fff5a974bb188e05098f4f4d2b970da 100644 --- a/client/client/src/main.cpp +++ b/client/client/src/main.cpp @@ -1,34 +1,45 @@ -#include <Arduino.h> #include "espnow.hpp" #include "ram_caching.hpp" +#include <Arduino.h> +#include <ArduinoJson.h> + +void setup() +{ -void setup() { - - // put your setup code here, to run once: - Serial.begin(115200); - while(!Serial); - Serial.flush(); + // put your setup code here, to run once: + Serial.begin(115200); + while (!Serial) + ; + Serial.flush(); - esp_err_t result = espnow_setup(); + esp_err_t result = espnow_setup(); + StaticJsonDocument<96> doc; + + doc["sensor"] = "gps"; + doc["time"] = 1351824120; + + JsonArray data = doc.createNestedArray("data"); + data.add(48.75608); + data.add(2.302038); } int counter = 0; -void loop() { - // put your main code here, to run repeatedly: - Message* new_data = new Message(); - new_data->add_data(++counter * 1.1, 0); - new_data->add_data(counter * 1.2, 1); - new_data->add_data(counter * 1.3, 2); - new_data->send(); - delete new_data; - - // if(!ram_cache_is_empty()){ - // data_struct old_data = ram_cache_pop(); - // Message* resend_message = new Message(old_data); - // resend_message->send(); - // delete resend_message; - // } - delay(5000); +void loop() +{ + // put your main code here, to run repeatedly: + Message new_data = Message{}; + new_data.add_data(++counter * 1.1, 0); + new_data.add_data(counter * 1.2, 1); + new_data.add_data(counter * 1.3, 2); + new_data.send(); + + // if(!ram_cache_is_empty()){ + // ClientDataPackage old_data = ram_cache_pop(); + // Message* resend_message = new Message(old_data); + // resend_message->send(); + // delete resend_message; + // } + delay(5000); } \ No newline at end of file