Sparkfun SEN15901 aka PM1S analog/mechanic anemometer

pull/2/head
Mateusz Lubecki 2021-01-09 22:16:31 +01:00
rodzic 7279ceea26
commit 240a96902c
6 zmienionych plików z 89 dodań i 24 usunięć

Wyświetl plik

@ -4,8 +4,8 @@
#include "aprs/ax25.h"
#include "drivers/serial.h"
#define SW_VER "DF10"
#define SW_DATE "28122020"
#define SW_VER "DF11"
#define SW_DATE "09012021"
#define SYSTICK_TICKS_PER_SECONDS 100
#define SYSTICK_TICKS_PERIOD 10

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -139,7 +139,7 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) {
NVIC_ClearPendingIRQ(TIM1_TRG_COM_TIM17_IRQn);
TIM17->SR &= ~(1<<0);
#ifdef _ANEMOMETER_ANALOGUE
#if defined(_ANEMOMETER_ANALOGUE) || defined(_ANEMOMETER_ANALOGUE_SPARKFUN)
analog_anemometer_timer_irq();
#endif
}
@ -148,7 +148,7 @@ void DMA1_Channel7_IRQHandler() {
NVIC_ClearPendingIRQ(DMA1_Channel7_IRQn);
DMA_ClearITPendingBit(DMA1_IT_GL7);
#ifdef _ANEMOMETER_ANALOGUE
#if defined(_ANEMOMETER_ANALOGUE) || defined(_ANEMOMETER_ANALOGUE_SPARKFUN)
analog_anemometer_dma_irq();
#endif
}

Wyświetl plik

@ -458,7 +458,10 @@ int main(int argc, char* argv[]){
tx20_init();
#endif
#ifdef _ANEMOMETER_ANALOGUE
analog_anemometer_init(10, 38, 100, 1);
analog_anemometer_init(_ANEMOMETER_PULSES_IN_10SEC_PER_ONE_MS_OF_WINDSPEED, 38, 100, 1);
#endif
#ifdef _ANEMOMETER_ANALOGUE_SPARKFUN
analog_anemometer_init(_ANEMOMETER_PULSES_IN_10SEC_PER_ONE_MS_OF_WINDSPEED, 38, 100, 1);
#endif
#endif
@ -770,7 +773,7 @@ int main(int argc, char* argv[]){
//digi_pool_viscous();
#ifdef _ANEMOMETER_ANALOGUE
#if defined(_ANEMOMETER_ANALOGUE) || defined(_ANEMOMETER_ANALOGUE_SPARKFUN)
analog_anemometer_direction_handler();
#endif
@ -778,7 +781,7 @@ int main(int argc, char* argv[]){
}
else if (main_one_second_pool_timer < -10) {
#ifdef _ANEMOMETER_ANALOGUE
#if defined(_ANEMOMETER_ANALOGUE) || defined(_ANEMOMETER_ANALOGUE_SPARKFUN)
analog_anemometer_direction_reset();
#endif

Wyświetl plik

@ -21,7 +21,10 @@ typedef enum analog_wind_qf {
AN_WIND_QF_UNKNOWN
} analog_wind_qf_t;
#ifdef _ANEMOMETER_ANALOGUE
#define DIRECTION_REGULAR 1
#define DIRECTION_SPARKFUN 2
#if defined(_ANEMOMETER_ANALOGUE) || defined(_ANEMOMETER_ANALOGUE_SPARKFUN)
extern uint16_t analog_anemometer_windspeed_pulses_time[ANALOG_ANEMOMETER_SPEED_PULSES_N];
extern uint16_t analog_anemometer_time_between_pulses[ANALOG_ANEMOMETER_SPEED_PULSES_N];
@ -39,6 +42,7 @@ void analog_anemometer_timer_irq(void);
void analog_anemometer_dma_irq(void);
uint32_t analog_anemometer_get_ms_from_pulse(uint16_t inter_pulse_time);
int16_t analog_anemometer_direction_handler(void);
int16_t analog_anemometer_direction_sparkfun(uint32_t timer_value);
void analog_anemometer_direction_reset(void);
analog_wind_qf_t analog_anemometer_get_qf(void);

Wyświetl plik

@ -7,7 +7,7 @@
#include "station_config.h"
#ifdef _ANEMOMETER_ANALOGUE
#if defined(_ANEMOMETER_ANALOGUE_SPARKFUN) || defined(_ANEMOMETER_ANALOGUE)
#define WIND_DEBUG
@ -75,6 +75,34 @@ int8_t analog_anemometer_direction_pol = 1;
uint16_t analog_anemometer_last_direction_cnt = 0;
#ifdef _ANEMOMETER_ANALOGUE
int8_t analog_anemometer_direction_mode = DIRECTION_REGULAR;
#endif
#ifdef _ANEMOMETER_ANALOGUE_SPARKFUN
int8_t analog_anemometer_direction_mode = DIRECTION_SPARKFUN;
#endif
// this array consists voltage ranges to calculate
const int16_t analog_anemometer_direction_sparkfun_ranges[16][3] = {
{4018, 4112, 112},
{4112, 4182, 67},
{4182, 4296, 90},
{4296, 4537, 157},
{4537, 4840, 135},
{4840, 5107, 202},
{5107, 5529, 180},
{5529, 5982, 22},
{5982, 6490, 45},
{6490, 6935, 247},
{6935, 7201, 225},
{7201, 7607, 337},
{7607, 7932, 0},
{7932, 8349, 292},
{8349, 8746, 270},
{8746, 9276, 315}
};
void analog_anemometer_init(uint16_t pulses_per_meter_second, uint8_t anemometer_lower_boundary,
uint8_t anemometer_upper_boundary, uint8_t direction_polarity) {
@ -376,6 +404,8 @@ int16_t analog_anemometer_direction_handler(void) {
TIM_Cmd(TIM3, DISABLE);
uint16_t downscaled_angle;
// getting current counter value
uint16_t current_value = TIM_GetCounter(TIM3);
@ -406,27 +436,35 @@ int16_t analog_anemometer_direction_handler(void) {
return rte_wx_winddirection_last;
}
// upscaling by factor of 1000 to omit usage of the floating point arithmetics
uint32_t upscaled_frequecy = current_value * 100;
if (analog_anemometer_direction_mode == DIRECTION_REGULAR) {
// upscaling by factor of 1000 to omit usage of the floating point arithmetics
uint32_t upscaled_frequecy = current_value * 100;
// calculating the ratio between the current input frequency and the maximum one
uint16_t ratio_of_upscaled_frequency = upscaled_frequecy / UF_MAXIMUM_FREQUENCY; // this val is * 100 from physical ratio
// calculating the ratio between the current input frequency and the maximum one
uint16_t ratio_of_upscaled_frequency = upscaled_frequecy / UF_MAXIMUM_FREQUENCY; // this val is * 100 from physical ratio
// converting the upscaled ratio into the upscaled angle
uint32_t upscaled_angle = ratio_of_upscaled_frequency * 360; // this val is * 100 from physical
// converting the upscaled ratio into the upscaled angle
uint32_t upscaled_angle = ratio_of_upscaled_frequency * 360; // this val is * 100 from physical
// rescaling the angle according to lower and higher limit
int32_t angle_adjusted_to_real_freq_borders = analog_anemometer_a_coeff *
upscaled_angle + 1000 * analog_anemometer_b_coeff;
// rescaling the angle according to lower and higher limit
int32_t angle_adjusted_to_real_freq_borders = analog_anemometer_a_coeff *
upscaled_angle + 1000 * analog_anemometer_b_coeff;
if (angle_adjusted_to_real_freq_borders < 0)
angle_adjusted_to_real_freq_borders = 0;
if (angle_adjusted_to_real_freq_borders < 0)
angle_adjusted_to_real_freq_borders = 0;
// downscaling the angle
uint16_t downscaled_angle = angle_adjusted_to_real_freq_borders / 10000;
// downscaling the angle
downscaled_angle = angle_adjusted_to_real_freq_borders / 10000;
// adjusting to polarity of the signal
downscaled_angle *= analog_anemometer_direction_pol;
// adjusting to polarity of the signal
downscaled_angle *= analog_anemometer_direction_pol;
}
else if (analog_anemometer_direction_mode == DIRECTION_SPARKFUN) {
downscaled_angle = analog_anemometer_direction_sparkfun(current_value);
}
else {
;
}
analog_anemometer_last_direction_cnt = 0;
@ -447,6 +485,26 @@ int16_t analog_anemometer_direction_handler(void) {
return downscaled_angle;
}
int16_t analog_anemometer_direction_sparkfun(uint32_t timer_value) {
int16_t out = -1;
// iterate through table which consist ranges of valid timer counter values
// for each wind direction
for (int i = 0; i < 16; i++) {
if (timer_value >= analog_anemometer_direction_sparkfun_ranges[i][0] &&
timer_value < analog_anemometer_direction_sparkfun_ranges[i][1] ) {
out = analog_anemometer_direction_sparkfun_ranges[i][2];
// exit from the loop and then from the function if the angle has been found.
break;
}
}
return out;
}
void analog_anemometer_direction_reset(void) {
// stopping the timer