Hey!
I am designing a monitoring station that includes cameras and meteorological data. I consider myself a beginner, and so I would like to have some tips on how I can improve my code and logic to be a more reliable system. I am using an ESP32 to gather the data and a Raspberry Pi Zero 2W to send the data to my Onedrive. The communication is made via UART. The key points of the data acquisition are:
- I am using this [system] for wind a rain(https://www.lampamania.pt/ImgGalery/Img1/PORT_destination/Návod%20k%20obsluze/Hadex/HD0202_all.pdf), which I am gathering each 10 minutes;
- A sensor for temperature, pressure, and humidity (digital);
- A sensor for soil moisture (analog);
What I am more doubtful about is the way that I am measuring the wind and rain. I am using a pulse counter to count pulses for a time range of 10 minutes. After those 10 minutes, a flag is set, and the other sensors measure the other data. I don't know if this is the best way to do it or the more reliable. I would like to know your advice!
The code is shown below:
#include "M5UnitENV.h"
#include <driver/pcnt.h>
#include <HardwareSerial.h>
// Data Transmission
#define TX 1
#define RX 3
// Sensor
#define RAIN 25
#define WINDS 18
#define RECORD_TIME 20.0f // seconds
#define WIND_SPEED_ARRAY_SIZE 30 // 30 moments of data acquisition == 10-minute period
#define WIND_SPEED_CONVERSION 2.4f
// Temperature, pressure and humidity sensor library constants
SHT3X sht3x;
QMP6988 qmp;
// Sensor variables
float pSum=0;
float pRead=0;
int pCountSums=0;
int pNoSums=10;
float pAvg=0;
float pAvgHist=0;
float tRead=0;
float hRead=0;
// Data
bool dataSent = false;
// Configuration for the counters
void configurePCNT(int pulsePin, pcnt_unit_t unit, pcnt_channel_t channel);
// Wind
void Windspeed(void *pvParameters) {
int16_t count = 0;
float windSpeedValues[WIND_SPEED_ARRAY_SIZE] = {0};
int windSpeedIndex = 0;
for (;;) {
pcnt_counter_clear(PCNT_UNIT_0);
vTaskDelay(RECORD_TIME * 1000 / portTICK_PERIOD_MS);
pcnt_get_counter_value(PCNT_UNIT_0, &count);
float kph = WIND_SPEED_CONVERSION * ((float)count / 2 / RECORD_TIME);
windSpeedValues[windSpeedIndex++] = kph;
if (windSpeedIndex >= WIND_SPEED_ARRAY_SIZE) {
float maxWindSpeed = 0;
float sumWindSpeed = 0;
for (int i = 0; i < WIND_SPEED_ARRAY_SIZE; i++) {
if (windSpeedValues[i] > maxWindSpeed) {
maxWindSpeed = windSpeedValues[i];
}
sumWindSpeed += windSpeedValues[i];
}
Serial2.print(maxWindSpeed);
Serial2.print(",");
Serial2.print(sumWindSpeed / WIND_SPEED_ARRAY_SIZE);
Serial2.print(",");
windSpeedIndex = 0;
}
}
}
// Rain
void Rain(void *pvParameters) {
int16_t rain_count = 0;
pcnt_counter_clear(PCNT_UNIT_1);
while (true) {
uint32_t start_time = millis();
uint32_t end_time = start_time + (10 * 60 * 1000); // 10 minutes
//uint32_t end_time = start_time + (40 * 1000);
while (millis() < end_time) {
pcnt_get_counter_value(PCNT_UNIT_1, &rain_count);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
float volume = rain_count * 0.3f;
Serial2.print(volume);
Serial2.print(",");
dataSent = true;
}
}
void setup() {
Serial.begin(9600);
Serial2.begin(115200, SERIAL_8N1, RX, TX);
pinMode(WINDS, INPUT);
pinMode(RAIN, INPUT);
configurePCNT(WINDS, PCNT_UNIT_0, PCNT_CHANNEL_0); // contador do vento
configurePCNT(RAIN, PCNT_UNIT_1, PCNT_CHANNEL_1); // contador da chuva
// Humidity sensor (I2C)
if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 26, 13, 400000U)) {
Serial.println("Couldn't find QMP6988");
while (1) delay(1);
}
// Temperature and pressure sensor (I2C)
if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 26, 13, 400000U)) {
Serial.println("Couldn't find SHT3X");
while (1) delay(1);
}
xTaskCreatePinnedToCore(Windspeed, "Windspeed", 10000, NULL, 2, NULL, 1); // Higher priority
xTaskCreatePinnedToCore(Rain, "Rain", 10000, NULL, 1, NULL, 1); // Lower priority
}
void loop() {
// Other sensor readings
if (dataSent) {
Pressure();
Serial2.print(",");
Temperature();
Serial2.print(",");
Humidity();
Serial2.print(",");
Winddirection();
Serial2.print(",");
Soilmoisture();
Serial2.println();
dataSent = false;
}
}
void configurePCNT(int pulsePin, pcnt_unit_t unit, pcnt_channel_t channel) {
int16_t PCNT_H_LIM_VAL = 3000;
int16_t PCNT_L_LIM_VAL = -10;
pcnt_config_t pcnt_config = {};
pcnt_config.pulse_gpio_num = pulsePin;
pcnt_config.ctrl_gpio_num = PCNT_PIN_NOT_USED;
pcnt_config.channel = channel;
pcnt_config.unit = unit;
pcnt_config.pos_mode = PCNT_COUNT_INC;
pcnt_config.neg_mode = PCNT_COUNT_DIS;
pcnt_config.lctrl_mode = PCNT_MODE_KEEP;
pcnt_config.hctrl_mode = PCNT_MODE_KEEP;
pcnt_config.counter_h_lim = PCNT_H_LIM_VAL;
pcnt_config.counter_l_lim = PCNT_L_LIM_VAL;
pcnt_unit_config(&pcnt_config);
pcnt_filter_enable(unit);
pcnt_counter_clear(unit);
}
Thank you in advance!
Cheers!