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

refactor client, add json library

- move data_struct to ClientDataPackage.hpp
- move Message definition to Message.hpp
- move Message code to Message.cpp
- move global time variable to its own namespace called esptime
  - time accessible via esptime::rtc
- Message now uses ClientDataPackage instead of data_struct
- ram_caching now uses ClientDataPackage instead of data_struct
- switched from pointer definition of Message to default constructor
- move headers to hpp files where applicable
- added ArduinoJson library (does not increase space by a lot)
parent 352d03e0
No related branches found
No related tags found
5 merge requests!39Merge Develop into Main,!19development into master,!17Inital Host, initial Client,!3Merge Branch `develop` into `sensor_readout`,!1Espnow
#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
#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
#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
};
#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
#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
#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);
// }
#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
#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
......@@ -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
#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
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