correct wind calc & use dht22

This commit is contained in:
2023-01-13 00:39:59 +01:00
parent 6d1bfc68e8
commit 24152cbc0b
6 changed files with 493 additions and 63 deletions
+66 -62
View File
@@ -11,77 +11,80 @@
#include "ds18b20.h"
#include "dht.h"
#include "driver/gpio.h"
#include "circbuf.h"
static volatile uint32_t timestamp_ms = 0;
static volatile uint32_t last_revolution_ts = 0;
static volatile uint32_t timestamp = 0;
#define RPM_BUFFER_LEN 10
static volatile uint16_t rpm_buffer[RPM_BUFFER_LEN] = {};
static volatile int rpm_buffer_next = 0;
static volatile int num_valid_average = 0;
#define RPS_BUFFER_LEN (60*10)
static volatile uint16_t history[RPS_BUFFER_LEN] = {};
static CircBuf rps_cb;
static volatile float rpm_average = 0;
static volatile float rpm_gust = 0;
static volatile uint16_t cycle_count = 0;
void calculate_wind();
static void gpio_isr_handler(void *arg)
{
uint32_t ts = timestamp_ms;
uint32_t cycle_ms = ts - last_revolution_ts;
last_revolution_ts = ts;
if (cycle_ms > 0xFFFF) {
cycle_ms = 0xFFFF;
}
rpm_buffer[rpm_buffer_next++] = (uint16_t) cycle_ms;
if (rpm_buffer_next == RPM_BUFFER_LEN) {
rpm_buffer_next = 0;
}
if (num_valid_average < RPM_BUFFER_LEN) {
num_valid_average++;
if (cycle_count < 0xFFFF) {
cycle_count++;
}
}
float get_rpm() {
float res;
float current = (float)(timestamp_ms - last_revolution_ts);
if (num_valid_average > 0) {
// we write num_valid_average only from here, so its safe to assume it stays nonzero
float average = 0;
int pos = rpm_buffer_next;
for (int i = 0; i < num_valid_average; i++) {
average += (float) rpm_buffer[pos];
pos--;
if (pos < 0) {
pos = RPM_BUFFER_LEN - 1;
}
}
average /= (float) (num_valid_average);
// now we have ms per revolution
if (current > average * 10.0f) {
// if wind stopped, invalidate the averaging buffer and use the current time from the last hall event
res = current;
num_valid_average = 0; // invalidate average results
} else {
res = average;
}
} else {
res = current;
}
float rpm = 60000.0f / res;
if (rpm < 1) {
rpm = 0;
}
return rpm; // RPM
}
void hw_timer_callback1(void *arg)
void hw_timer_callback1s(void *arg)
{
timestamp_ms++;
timestamp++;
// FIXME use a freertos queue and pass this to a thread!
if (cbuf_full(&rps_cb)) {
cbuf_pop_back(&rps_cb, NULL);
}
cbuf_push(&rps_cb, (void*) &cycle_count);
cycle_count = 0;
calculate_wind();
}
void calculate_wind()
{
// Wind speed is average from 10 minutes
// Gust is max 3-second average anywhere within the 10 minutes
float max_gust = 0;
uint32_t tenmin_sum = 0;
uint32_t numsecs = cbuf_count(&rps_cb);
uint16_t threesec1 = 0, threesec2 = 0;
for(size_t i = 0; i < numsecs; i++) {
uint16_t *slot = cbuf_ptr_nth(&rps_cb, i);
if (!slot) {
continue;
}
uint16_t slotval = *slot;
tenmin_sum += (uint32_t) slotval;
// gust is max avg from 3 seconds within the 10 minutes
uint32_t gust_sum = (uint32_t) threesec1 + (uint32_t) threesec2 + (uint32_t) slotval;
threesec1 = threesec2;
threesec2 = slotval;
float gust_avg = (float)gust_sum * (float)20.0f;
if (gust_avg > max_gust) {
max_gust = gust_avg;
}
}
rpm_gust = max_gust;
rpm_average = ((float)tenmin_sum / (float)numsecs) * 60.0f;
}
void meteo_task(void* pvParameters)
{
cbuf_init(&rps_cb, (void*)history, RPS_BUFFER_LEN, 2); // uint16 fields
// Try to unfuck GPIOs
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13);
@@ -89,8 +92,8 @@ void meteo_task(void* pvParameters)
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15);
// start timer used for timebase
hw_timer_init(hw_timer_callback1, NULL);
hw_timer_alarm_us(1000, true); // 1 ms timer
hw_timer_init(hw_timer_callback1s, NULL);
hw_timer_alarm_us(1000000, true); // 1s timer
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_POSEDGE;
@@ -107,11 +110,12 @@ void meteo_task(void* pvParameters)
// this works ...
ds_temp = ds18b20_measure_and_read(0, DS18B20_ANY);
if (!dht_read_float_data(DHT_TYPE_DHT11, 12, &dht_hum, &dht_temp)) {
if (!dht_read_float_data(DHT_TYPE_DHT22, 12, &dht_hum, &dht_temp)) {
dht_hum = dht_temp = NAN;
}
printf("Dallas: %.2f °C, DHT %.2f °C, %.1f %%r.H, HALL %.1f RPM\n", ds_temp, dht_temp, dht_hum, get_rpm());
printf("Dallas: %.2f °C, DHT %.2f °C, %.1f %%r.H, HALL avg %.1f RPM, gust %.1f RPM\n",
ds_temp, dht_temp, dht_hum, rpm_average, rpm_gust);
vTaskDelay(pdMS_TO_TICKS(500));
}