Skip to content
Snippets Groups Projects
Commit 1d34a1af authored by Bilal Hassan's avatar Bilal Hassan
Browse files

adding missing libary

parent c26b689d
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,!2Draft: Read Sensors on ESP32 Client device
Showing
with 552 additions and 0 deletions
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html
#include <Arduino.h>
#include "espnow.hpp"
RTC_DATA_ATTR int cachedAmount = -1;
RTC_DATA_ATTR data_struct backup[10];
data_struct ram_cache_pop(){
return backup[cachedAmount--];
}
void ram_cache_push(data_struct data){
backup[++cachedAmount] = data;
}
bool ram_cache_is_empty(){
return cachedAmount == -1;
}
bool ram_cache_is_full(){
return cachedAmount == 9;
}
\ No newline at end of file
#ifndef _RAM_CACHE
#define _RAM_CACHE
#include "espnow.hpp"
bool ram_cache_is_empty();
bool ram_cache_is_full();
void ram_cache_push(data_struct data);
data_struct ram_cache_pop();
#endif
\ No newline at end of file
#include <drs26.hpp>
/*
It happens for some reason that the sensor cant get reached every 2 time
Because the sensor use sdi12 protocoll we have to wait aproxemettly 1 secound between the commands
It is not known how lond the response takes so we use a while loop which can be a risk wehre the programm can get stuck
*/
void Forte_DRS26 ::setup()
{
drs26.begin(SDI_DATA);
}
out_data_drs26 *Forte_DRS26 ::read_data()
{
String sdiResponse = "";
String measurement_command="1M!"; //The drs26 sensor uses the sdi12 protocoll , in the sdi12 protocoll is the measurement command is specified as 1M!=Sebsir measurement request at adress 1
String data_command="1D0!"; //and the followed data command 1D0! = Sensor data request at adress 1
drs26.sendCommand(measurement_command);
delay(1000);
drs26.sendCommand(data_command);
while (drs26.available())
{
char next_character = drs26.read();
if ((next_character != '\n') && (next_character != '\r'))
{
sdiResponse += next_character;
delay(10); // 1 character ~ 7.5ms
}
}
// Serial.println(sdiResponse);
if (sdiResponse.length() > 1)
{
data.id = sdiResponse.substring(0, 7).toInt();
data.circumference = sdiResponse.substring(8, 14).toFloat();
data.temperatur = sdiResponse.substring(15,21).toFloat();
return &data;
}
return 0;
}
void Forte_DRS26 ::print(out_data_drs26* data_drs26)
{
Serial.println("******************************DRS26********************Tree-size**********************************");
if(data_drs26==0)
{
Serial.println("Waiting for data!");
Serial.println();
}
else{
Serial.print("Sensor ID "); Serial.println(data_drs26->id);
Serial.print("Cicumfence "); Serial.println(data_drs26->circumference,4);
Serial.print("Temperature "); Serial.println(data_drs26->temperatur,4);
Serial.println();
}
delay(1000);
}
\ No newline at end of file
#ifndef _DRS26
#define _DRS26
#include <forte_sensor.hpp>
#include <SDI12.h>
#include <pinout.hpp>
#include "Wire.h"
struct out_data_drs26 {
int id;
float circumference;
float temperatur;
};
class Forte_DRS26 : public Forte_Sensor{
public:
void setup();
out_data_drs26* read_data();
void print(out_data_drs26*);
private:
SDI12 drs26;
out_data_drs26 data;
};
#endif
\ No newline at end of file
#ifndef _FORTE_SENSOR
#define _FORTE_SENSOR
class Forte_Sensor {
public:
virtual void* read_data() = 0;
virtual void setup() = 0;
private:
};
#endif
\ No newline at end of file
#ifndef _FORTE_PINOUT
#define _FORTE_PINOUT
// Pins for SDI12
#define SDI_DATA 4
#endif
\ No newline at end of file
# basic usage
To send data using espnow, create a new Message object,
then use the add_data(value, identifier) method for every value
to fill the message.
when every value is added, use the send() method to send the data
to the host (fipy). If the esp client has never recieved a config
message from the host, it will instead broadcast the message.
---
right now, it is not possible to add more than 10 values.
#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
}
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.print("identifier: ");
Serial.print(data.identifiers[i]);
Serial.print(" value: ");
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];
};
esp_err_t espnow_setup();
bool is_host_defined();
#endif
\ No newline at end of file
#include "f_deep_sleep.h"
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){//Increment boot number and print it every reboot
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
#ifndef _FORTE_SENSOR
#define _FORTE_SENSOR
class Forte_Sensor {
public:
virtual void* read_data() = 0;
virtual void setup() = 0;
private:
};
#endif
\ No newline at end of file
#include "ina219.hpp"
void Forte_INA219 :: setup(){
Wire.begin(I2C_SDA, I2C_SCL);
if(!ina219.init()){
// Sensor init went wrong
return;
}
}
out_data_ina219* Forte_INA219 :: read_data(){
if(!ina219.getOverflow())
{
data.shuntVoltage_mV = ina219.getShuntVoltage_mV();
data.busVoltage_V= ina219.getBusVoltage_V();
data.current_mA= ina219.getCurrent_mA();
data.power_mW= ina219.getBusPower();
data.loadVoltage_V = data.busVoltage_V + (data.shuntVoltage_mV/1000);
data.ina219_overflow=ina219.getOverflow();
return &data;
}
else
return 0;
}
void Forte_INA219 :: print(out_data_ina219* data_ina219){
Serial.println("******************************INA219********************Power-Consumption**********************************");
if(data_ina219==0)
{
Serial.println("Waiting for data!");
Serial.println();
}
else{
Serial.print("Shunt Voltage [mV]: "); Serial.println(data_ina219->shuntVoltage_mV);
Serial.print("Bus Voltage [V]: "); Serial.println(data_ina219->busVoltage_V);
Serial.print("Load Voltage [V]: "); Serial.println(data_ina219->loadVoltage_V);
Serial.print("Current[mA]: "); Serial.println(data_ina219->current_mA);
Serial.print("Bus Power [mW]: "); Serial.println(data_ina219->power_mW);
data_ina219->ina219_overflow== false ? Serial.println("Values OK - no overflow") : Serial.println("Overflow! Choose higher PGAIN");
Serial.println();
}
delay(1000);
}
\ No newline at end of file
#ifndef _INA219
#define _INA219
#include <forte_sensor.hpp>
#include <pinout.hpp>
#include <INA219_WE.h>
#include <Wire.h>
//TwoWire I2Cone = TwoWire(0);
//TwoWire I2Ctwo = TwoWire(1);
struct out_data_ina219 {
float shuntVoltage_mV = 0.0;
float loadVoltage_V = 0.0;
float busVoltage_V = 0.0;
float current_mA = 0.0;
float power_mW = 0.0;
bool ina219_overflow = false;
};
class Forte_INA219 : public Forte_Sensor{
public:
void setup();
out_data_ina219* read_data();
void print(out_data_ina219*);
private:
INA219_WE ina219;
out_data_ina219 data;
};
#endif
\ No newline at end of file
#ifndef _FORTE_PINOUT
#define _FORTE_PINOUT
// Pins for I2C Protocol (for digital communication between ESP and the Sensor)
#define I2C_SCL 7
#define I2C_SDA 6
#endif
\ No newline at end of file
#ifndef _FORTE_SENSOR
#define _FORTE_SENSOR
class Forte_Sensor {
public:
virtual void* read_data() = 0;
virtual void setup() = 0;
private:
};
#endif
\ No newline at end of file
#ifndef _FORTE_PINOUT
#define _FORTE_PINOUT
// Pins for I2C Proctocol (for digital communication between ESP and the Sensor)
#define I2C_SCL 9
#define I2C_SDA 8
#endif
\ No newline at end of file
#include "scd30.hpp"
void Forte_SCD30 :: setup(){
Wire.begin(I2C_SDA, I2C_SCL);
if(!airSensor.begin()){
// Sensor init went wrong
return;
}
}
out_data_scd30* Forte_SCD30 :: read_data(){
if(airSensor.dataAvailable())
{
data.C02= airSensor.getCO2();
data.Temperature = airSensor.getTemperature();
data.Humidity = airSensor.getHumidity();
return &data;
}
else
return 0;
}
\ No newline at end of file
#ifndef _SCD30
#define _SCD30
#include <forte_sensor.hpp>
#include <Wire.h>
#include <pinout.hpp>
#include <SparkFun_SCD30_Arduino_Library.h>
struct out_data_scd30
{
float C02;
float Temperature;
float Humidity;
};
class Forte_SCD30 : public Forte_Sensor{
public:
void setup();
out_data_scd30* read_data();
private:
SCD30 airSensor;
out_data_scd30 data;
};
#endif
\ 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