/** * TODO file description */ #include #include #include #include #include #include "meteo_task.h" #include "ds18b20.h" #include "dht.h" #include "driver/gpio.h" #include "circbuf.h" static volatile uint32_t timestamp = 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) { if (cycle_count < 0xFFFF) { cycle_count++; } } void hw_timer_callback1s(void *arg) { 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); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); // start timer used for timebase 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; io_conf.mode = GPIO_MODE_INPUT; io_conf.pin_bit_mask = 1 << 14; io_conf.pull_down_en = 1; io_conf.pull_up_en = 0; gpio_config(&io_conf); gpio_install_isr_service(0); gpio_isr_handler_add(14, gpio_isr_handler, NULL); float dht_hum, dht_temp, ds_temp; while (1) { // this works ... ds_temp = ds18b20_measure_and_read(0, DS18B20_ANY); 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 avg %.1f RPM, gust %.1f RPM\n", ds_temp, dht_temp, dht_hum, rpm_average, rpm_gust); vTaskDelay(pdMS_TO_TICKS(500)); } vTaskDelete(NULL); }