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

Merge branch 'espnow' into develop

# Conflicts:
#	client/client/src/main.cpp
parents 859d306a 81b58350
No related branches found
No related tags found
5 merge requests!39Merge Develop into Main,!19development into master,!17Inital Host, initial Client,!10merge serial comm and sd write into espnow,!5fipy host broadcasts its mac + timestamp on start, main function of client...
......@@ -15,6 +15,7 @@ downloads/
eggs/
.eggs/
lib/
!host/fipy/lib
!client/client/lib
lib64/
parts/
......
#include "f_deep_sleep.hpp"
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
}
}
void deep_sleep(int time_in_sec){
esp_sleep_enable_timer_wakeup(time_in_sec * 1000000);
esp_deep_sleep_start();
}
#ifndef F_DEEP_SLEEP_H
#define F_DEEP_SLEEP_H
#include <Arduino.h>
void deep_sleep(int time_to_sleep);
void print_wakeup_reason();
#endif
......@@ -7,7 +7,7 @@ Preferences preferences;
void get_host_mac(uint8_t *destination)
{
preferences.begin("config", true);
if (preferences.isKey("host")) {
if (!preferences.isKey("host")) {
preferences.getBytes("host", destination, sizeof(uint8_t) * 6);
} else {
memcpy(destination, BROADCAST_MAC, sizeof(BROADCAST_MAC));
......@@ -31,11 +31,15 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len)
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
} else{
Serial.println("host mac already exists");
}// host change shouldn't be an issue
preferences.end();
// sync time
esptime::rtc.setTime(
Time::getInstance().setTime(
new_config.time_millis); // see https://www.esp32.com/viewtopic.php?t=9965, maybe this needs an offset
Serial.println("Saved Time: " + (String) new_config.time_millis);
Serial.flush();
}
esp_err_t espnow_setup()
......@@ -59,3 +63,29 @@ esp_err_t espnow_setup()
return ESP_OK;
}
esp_err_t espnow_send_message(const Message& message){
Serial.println("sending Message");
esp_err_t success;
ClientDataPackage dataP = message.get_client_data_package();
uint8_t recipient;
get_host_mac(&recipient);
success = esp_now_send(&recipient, (uint8_t *) &dataP, sizeof(ClientDataPackage));
// if(success != ESP_OK){
// if(!ram_cache_is_full()){
// ram_cache_push(*data);
// }
// }
for (int i = 0; i < dataP.amountData; i++) {
Serial.println(dataP.values[i]);
}
Serial.println((String) "time sent: " + dataP.timestamp);
Serial.println((String) "Send status: " + success);
Serial.println();
Serial.println("done");
Serial.flush();
return success;
}
......@@ -16,6 +16,7 @@ typedef struct config {
} config;
esp_err_t espnow_setup();
esp_err_t espnow_send_message(const Message& message);
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);
......
......@@ -9,39 +9,21 @@ void Message::add_data(float value, int identifier)
}
}
esp_err_t Message::send()
ClientDataPackage Message ::get_client_data_package() const
{
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;
return data;
}
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
data.timestamp = Time::getInstance().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>
......@@ -14,9 +13,8 @@ class Message {
Message();
Message(ClientDataPackage old_data);
void add_data(float value, int identifier);
esp_err_t send();
ClientDataPackage get_client_data_package() const;
private:
ClientDataPackage data;
uint8_t recipient[6];
};
\ No newline at end of file
#include "Time.hpp"
#include <utility>
void Time::setTime(long epoch, int ms)
{
this->rtc.setTime(epoch, ms);
}
tm Time::getTimeStruct()
{
return this->rtc.getTimeStruct();
}
String Time::getDateTime(bool mode)
{
return this->rtc.getDateTime(mode);
}
String Time::getTime(String format)
{
return this->rtc.getTime(std::move(format));
}
long Time::getEpochSeconds()
{
return this->rtc.getEpoch();
}
long Time::getMillis()
{
return this->rtc.getMillis();
}
#pragma once
#ifndef ESPTIME
#define ESPTIME
#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
// namespace esptime
class Time {
public:
static Time &getInstance()
{
static Time instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
/*!
@brief set the internal RTC time
@param epoch
epoch time in seconds
@param ms
microseconds (optional)
*/
void setTime(long epoch, int ms = 0);
/*!
@brief get the internal RTC time as a tm struct
*/
tm getTimeStruct();
/*!
@brief get the time and date as an Arduino String object
@param mode
true = Long date format
false = Short date format
*/
String getDateTime(bool mode);
/*!
@brief get the time as an Arduino String object with the specified format
@param format
time format
http://www.cplusplus.com/reference/ctime/strftime/
*/
String getTime(String format = "%H:%M:%S");
/*!
@brief get the current epoch seconds as long
*/
long getEpochSeconds();
/*!
@brief get the current milliseconds as long
*/
long getMillis();
private:
Time() {} // Constructor? (the {} brackets) are needed here.
ESP32Time rtc = ESP32Time{};
// C++ 11
// =======
// We can use the better technique of deleting the methods
// we don't want.
public:
Time(Time const &) = delete;
void operator=(Time const &) = delete;
// Note: Scott Meyers mentions in his Effective Modern
// C++ book, that deleted functions should generally
// be public as it results in better error messages
// due to the compilers behavior to check accessibility
// before deleted status
};
#endif
\ No newline at end of file
#include "ESPNow.hpp"
#include "ram_caching.hpp"
#include <Arduino.h>
#include <scd30.hpp>
#include <dr26.hpp>
#include <drs26.hpp>
#include <ina219.hpp>
#include <ArduinoJson.h>
#include "Time.hpp"
#include "f_deep_sleep.hpp"
// Forte_SCD30 scd30;
void setup() {
Serial.begin(9600);
// scd30.setup();
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
while (!Serial)
;
Serial.flush();
void loop() {
void* data;
// data = scd30.read_data();
if(data==0)
{
Serial.println("Waiting for data !");
Serial.println();
}
// else{
// Serial.print("Sensor CO2 "); Serial.println(data->C02);
// Serial.print("Humidity "); Serial.println(data->Humidity);
// Serial.print("Temperature "); Serial.println(data->Temperature);
// Serial.println();
// }
delay(5000);
esp_err_t result = espnow_setup();
}
int counter = 0;
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);
espnow_send_message(new_data);
// if(!ram_cache_is_empty()){
// ClientDataPackage old_data = ram_cache_pop();
// Message* resend_message = new Message(old_data);
// resend_message->send();
// delete resend_message;u
// }
Serial.println("Saved Time Loop: " + Time::getInstance().getTime("%c"));
Serial.println("delaying...");
Serial.flush();
delay(5000); // 5 second receive window
// deep_sleep(900); // go to sleep for 15 mins (900s)
}
\ No newline at end of file
import network
from network import ESPNOW
import time
from lib.rtc_time import RTCTime
import struct
w = network.WLAN()
self_mac, sta = w.mac()
peer_list = []
class Forte_ESPNOW:
def __init__(self):
ESPNOW.init()
ESPNOW.on_recv(espnow_recv)
def add_peer(mac):
peer_list.append(ESPNOW.add_peer(mac))
def espnow_respond(mac):
msg = struct.pack("<6sl", self_mac, time.time())
print(int(time.time()))
ESPNOW.send(mac, msg)
print("response sent")
def espnow_recv(result):
print("message recv")
mac, peer, msg = result
data = bytes_to_data(msg)
try:
print("amount data: " + str(data["amountData"]))
# print(data["timestamp"])
# print(data["data"])
except Exception as error:
print(error)
if(peer not in peer_list):
Forte_ESPNOW.add_peer(mac)
espnow_respond(mac)
def bytes_to_data(msg):
# turn bytes from message into 22-tuple of integers(identifiers), floats(values), integer(amount) and long(timestamp)
data = struct.unpack("<10i10fil", bytes(msg))
amountData = data[20]
timestamp = data[21]
identifiers = data[0:amountData]
values = data[10 : (10 + amountData)]
return {
"amountData": amountData,
"timestamp": timestamp,
"data": dict(zip(identifiers, values)),
}
from time import sleep
from machine import RTC
class RTCTime:
# def __init__(
# self,
# main_ntp_server: str = "pool.ntp.org",
# backup_ntp_server: str = "time.nist.gov",
# update_interval_seconds: int = 3600,
# ):
# self.rtc = RTC()
# self._setup_ntp(main_ntp_server, backup_ntp_server, update_interval_seconds)
def __init__(self, datetime):
self.rtc = RTC()
self.rtc.init(datetime)
def _setup_ntp(
self, main_ntp_server: str, backup_ntp_server: str, update_interval_seconds: int
):
print("Setting up NTP")
self.rtc.ntp_sync(main_ntp_server, update_interval_seconds, backup_ntp_server)
while not self.rtc.synced():
print(self.rtc.synced())
sleep(1)
def get_time(self):
return self.rtc.now()
def is_synchronized(self):
return self.rtc.synced()
# main.py -- put your code here!
from network import WLAN
from network import ESPNOW
import binascii
import struct
# from network import ESPNOW
from time import sleep
from lib.server_transfer import DataTransferWiFi
def bytes_to_data(msg):
# turn bytes from message into 22-tuple of integers(identifiers), floats(values), integer(amount) and long(timestamp)
data = struct.unpack("<10i10fil", bytes(msg))
amountData = data[20]
timestamp = data[21]
identifiers = data[0:amountData]
values = data[10 : (10 + amountData)]
return {
"amountData": amountData,
"timestamp": timestamp,
"data": dict(zip(identifiers, values)),
}
def espnow_recv(result):
mac, peer, msg = result
data = bytes_to_data(msg)
try:
print(data["amountData"])
print(data["timestamp"])
print(data["data"])
print(str(binascii.hexlify(mac), "ascii"))
except Exception as error:
print(error)
from lib.espnow import Forte_ESPNOW
from lib.rtc_time import RTCTime
# data = DataTransferWiFi()
# data.connect("Z", "AbsoluteSandwich")
......@@ -41,15 +11,9 @@ def espnow_recv(result):
# "airSensors,sensor_id=TLM0201 temperature=73.97038159354763,humidity=35.23103248356096,co=0.4844531056779361 1661175680\nairSensors,sensor_id=TLM0202 temperature=75.30007505999716,humidity=35.65192991869171,co=0.5141876544505826 1661175680\nairSensors,sensor_id=TLM0202 temperature=75.30007505999756,humidity=35.65192991869171,co=0.5141876544505826 1661175680"
# )
# data.disconnect()
w = WLAN()
ESPNOW.init()
p = ESPNOW.add_peer("58cf79043c84")
ESPNOW.on_recv(espnow_recv)
#
rtc_time = RTCTime((2014, 5, 1, 4, 13, 0, 0, 0))
espnow = Forte_ESPNOW()
while True:
print("...")
sleep(5)
pass
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