correct wind calc & use dht22
This commit is contained in:
+66
-62
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user