Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
meteo_stick.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014 Gautier Hattenberger
3 *
4 * This file is part of paparazzi
5
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
19 *
20 */
21
23
24#include "modules/core/abi.h"
25#include "peripherals/ads1220.h"
27#include "generated/airframe.h"
28#include "pprzlink/messages.h"
30
34#ifndef MS_PRESSURE_OFFSET
35#define MS_PRESSURE_OFFSET 0.0f
36#endif
37#ifndef MS_PRESSURE_SCALE
38#define MS_PRESSURE_SCALE 1.0f
39#endif
40#ifndef MS_TEMPERATURE_OFFSET
41#define MS_TEMPERATURE_OFFSET 0.0f
42#endif
43#ifndef MS_TEMPERATURE_SCALE
44#define MS_TEMPERATURE_SCALE 1.0f
45#endif
46#ifndef MS_HUMIDTY_OFFSET
47#define MS_HUMIDTY_OFFSET 0.0f
48#endif
49#ifndef MS_HUMIDTY_SCALE
50#define MS_HUMIDTY_SCALE 1.0f
51#endif
52#ifndef MS_DIFF_PRESSURE_OFFSET
53#define MS_DIFF_PRESSURE_OFFSET 0.0f
54#endif
55#ifndef MS_DIFF_PRESSURE_SCALE
56#define MS_DIFF_PRESSURE_SCALE 1.0f
57#endif
58
59// Test if pressure sensor is configured and/or should send ABI message
60#ifdef MS_PRESSURE_SLAVE_IDX
61#ifndef USE_MS_PRESSURE
62#define USE_MS_PRESSURE TRUE
63#endif
64#endif
65
66// Test if diff pressure sensor is configured and/or should send ABI message
67#ifdef MS_DIFF_PRESSURE_SLAVE_IDX
68#ifndef USE_MS_DIFF_PRESSURE
69#define USE_MS_DIFF_PRESSURE TRUE
70#endif
71#endif
72
73// Test if temperature sensor is configured and/or should send ABI message
74#ifdef MS_TEMPERATURE_SLAVE_IDX
75#ifndef USE_MS_TEMPERATURE
76#define USE_MS_TEMPERATURE TRUE
77#endif
78#endif
79
80// Test if EEPROM slave index is configured
81// if not, don't use EEPROM
82#ifndef MS_EEPROM_SLAVE_IDX
83#undef USE_MS_EEPROM
84#endif
85
88
89
93static const float maxAdc = 8388608.0f; // 2 ** 23
94
95static inline float get_pressure(uint32_t raw)
96{
97 const float uncal_abs = ((raw / maxAdc) + 0.095f) / 0.0009f;
98
99#if USE_MS_EEPROM
101#else
103#endif
104}
105
106static inline float get_temp(uint32_t raw)
107{
108 const float coeff_A = 3.9083e-3f;
109 const float coeff_B = -5.775e-7f;
110 const float R0 = 1000.0f;
112 const float pga_factor = 1.0f;
113 const float Rref = 6.8e3f;
114 const float Rt = (raw * Rref) / (gain_factor * pga_factor * maxAdc);
115 const float uncal_temp = ((-R0 * coeff_A) + (sqrtf(powf((R0 * coeff_A), 2.0f) +
116 (4.0f * R0 * coeff_B * (Rt - R0))))) / (2.0f * R0 * coeff_B);
117
118#if USE_MS_EEPROM
120#else
122#endif
123}
124
125static float pitot_offset;
126static int pitot_counter;
127// number of measures for averaging initial offset
128#define MS_PITOT_COUNTER 20
129// filtering coefficient (0 no filter, 1 constant value)
130#define MS_PITOT_FILTER 0.6
131
132static inline float get_diff(uint32_t raw)
133{
135 const uint32_t raw_diff = raw > pitot_offset ? raw - pitot_offset : 0;
136 const float uncal_diff = ((raw_diff / maxAdc) * 5000.f / gain_factor);
137
138#if USE_MS_EEPROM
140#else
142#endif
143}
144
145static inline float get_pitot(uint32_t raw)
146{
147 return sqrtf((2.0f * get_diff(raw)) / 1.293f);
148}
149
150static inline float get_humidity(uint32_t raw)
151{
152 const float icu_freq = 42e6f; // Freq
153 const float Ra = 390e3f;
154 const float Rb = 680e3f;
155 const float S1 = 0.3e-12f; // pico farad by % of relative humidity
156 const float calib_raw_period = 17800.f;
157 const float calib_humidity = 45.f;
158 const float k = 2.f * logf(2.f) * (Ra + Rb + Rb);
159 const float uncal_hum = calib_humidity + ((raw - calib_raw_period) / (k * icu_freq * S1));
160
161#if USE_MS_EEPROM
163#else
165#endif
166}
167
182
187#ifndef SEND_MS_SYNC
188#define SEND_MS_SYNC FALSE
189#endif
190
191
196#ifndef LOG_MS
197#define LOG_MS TRUE
198#endif
199
200#if LOG_MS
202#include "modules/gps/gps.h"
203static bool log_ptu_started;
204
205static inline void meteo_stick_log_data_ascii(void)
206{
207 if (pprzLogFile != -1) {
208 if (!log_ptu_started) {
209#if USE_MS_EEPROM
210 if (meteo_stick.eeprom.data_available) {
211 // Print calibration data in the log header
212 sdLogWriteLog(pprzLogFile, "# Calibration data (UUID: %s)\n#\n", meteo_stick.calib.uuid);
213 int i, j, k;
214 for (i = 0; i < MTOSTK_NUM_SENSORS; i++) {
215 sdLogWriteLog(pprzLogFile, "# Sensor: %d, time: %ld, num_temp: %d, num_coeff: %d\n", i,
216 meteo_stick.calib.params[i].timestamp,
217 meteo_stick.calib.params[i].num_temp,
218 meteo_stick.calib.params[i].num_coeff);
219 if (meteo_stick.calib.params[i].timestamp == 0) {
220 continue; // No calibration
221 }
222 for (j = 0; j < meteo_stick.calib.params[i].num_temp; j++) {
223 sdLogWriteLog(pprzLogFile, "# Reference temp: %.2f\n", meteo_stick.calib.params[i].temps[j]);
224 sdLogWriteLog(pprzLogFile, "# Coeffs:");
225 for (k = 0; k < meteo_stick.calib.params[i].num_coeff; k++) {
226 sdLogWriteLog(pprzLogFile, " %.5f", meteo_stick.calib.params[i].coeffs[j][k]);
227 }
229 }
230 }
233 "P(adc) T(adc) H(ticks) P_diff(adc) P(hPa) T(C) H(%%) CAS(m/s) FIX TOW(ms) WEEK Lat(1e7rad) Lon(1e7rad) HMSL(mm) GS(cm/s) course(1e7rad) VZ(cm/s)\n");
234 log_ptu_started = true;
235 }
236#else
238 "P(adc) T(adc) H(ticks) P_diff(adc) P(hPa) T(C) H(%%) CAS(m/s) FIX TOW(ms) WEEK Lat(1e7rad) Lon(1e7rad) HMSL(mm) GS(cm/s) course(1e7rad) VZ(cm/s)\n");
239 log_ptu_started = true;
240#endif
241 } else {
242 sdLogWriteLog(pprzLogFile, "%lu %lu %lu %lu %.2f %.2f %.2f %.2f %d %lu %d %lu %lu %lu %d %lu %lu\n",
247 gps.fix, gps.tow, gps.week,
250 }
251 }
252}
253
254#endif
255
260#ifndef LOG_MS_FLIGHTRECORDER
261#define LOG_MS_FLIGHTRECORDER FALSE
262#endif
263
264// log to flight recorder by default
265#ifndef MS_LOG_FILE
266#define MS_LOG_FILE flightrecorder_sdlog
267#endif
268
269#if LOG_MS_FLIGHTRECORDER
272static bool log_tagged;
273
274static inline void meteo_stick_log_data_fr(void)
275{
276 if (MS_LOG_FILE.file != NULL && *(MS_LOG_FILE.file) != -1) {
277 if (log_tagged == false && GpsFixValid()) {
278 // write at least once ALIVE and GPS messages
279 // to log for correct extraction of binary data
281 // Log GPS for time reference
282 uint8_t foo_u8 = 0;
283 int16_t foo_16 = 0;
284 uint16_t foo_u16 = 0;
286 int32_t east = utm.east * 100;
287 int32_t north = utm.north * 100;
290 &gps.week, &gps.tow, &utm.zone, &foo_u8);
291 log_tagged = true;
292 }
293 meteo_stick_send_data(&pprzlog_tp.trans_tx, &(MS_LOG_FILE).device);
294 }
295}
296#endif
297
301{
302#ifdef MS_PRESSURE_SLAVE_IDX
303 // Init absolute pressure
314#endif
315
316#ifdef MS_DIFF_PRESSURE_SLAVE_IDX
317 // Init differential pressure
328#endif
329
330#ifdef MS_TEMPERATURE_SLAVE_IDX
331 // Init temperature
342#endif
343
344 // Init humidity
346
347 // Initial conditions
352
353#if USE_MS_EEPROM
354 // Set number of calibration to 0 for all sensors
355 int i;
356 for (i = 0; i < MTOSTK_NUM_SENSORS; i++) {
357 meteo_stick.calib.params[i].num_temp = 0;
358 }
359 // Init eeprom
361#endif
362
363 // Number of measurements before setting pitot offset
366
367#if LOG_MS
368 log_ptu_started = false;
369#endif
370#if LOG_MS_FLIGHTRECORDER
371 log_tagged = false;
372#endif
373}
374
378{
379 // Read ADC
380#ifdef MS_PRESSURE_SLAVE_IDX
382#endif
383#ifdef MS_DIFF_PRESSURE_SLAVE_IDX
385#endif
386#ifdef MS_TEMPERATURE_SLAVE_IDX
388#endif
389 // Read PWM
390#ifdef MS_HUMIDITY_PWM_INPUT
393#endif
394
395#if USE_MS_EEPROM
396 if (meteo_stick.eeprom.data_available) {
397 // Extract calibration data
398 if (!mtostk_populate_cal_from_buffer(&meteo_stick.calib, (uint8_t *)(meteo_stick.eeprom.rx_buf + 3))) {
399 // Extraction failed
400 // Force number of calibration to 0 for all sensors
401 int i;
402 for (i = 0; i < MTOSTK_NUM_SENSORS; i++) {
403 meteo_stick.calib.params[i].num_temp = 0;
404 }
405 }
406 } else if (meteo_stick.eeprom.spi_trans.status == SPITransDone) {
407 // Load reading request (reading 1Kb from address 0x0)
408 eeprom25AA256_read(&meteo_stick.eeprom, 0x0, 1024);
409 }
410#endif
411
412 // Log data
413#if LOG_MS
415#endif
416#if LOG_MS_FLIGHTRECORDER
418#endif
419
420 // Send data synch to reading
421#if SEND_MS_SYNC
422 meteo_stick_send_data(&(DefaultChannel).trans_tx, &(DefaultDevice).device);
423#endif
424
425 // Check if DP offset reset is required
429 }
430}
431
435{
436#ifdef MS_PRESSURE_SLAVE_IDX
438#endif
439#ifdef MS_DIFF_PRESSURE_SLAVE_IDX
441#endif
442#ifdef MS_TEMPERATURE_SLAVE_IDX
444#endif
445
446#ifdef MS_PRESSURE_SLAVE_IDX
447 // send absolute pressure data over ABI as soon as available
451#if USE_MS_PRESSURE
453#endif
455 }
456#endif
457
458#ifdef MS_DIFF_PRESSURE_SLAVE_IDX
459 // send differential pressure data over ABI as soon as available
461 if (pitot_counter > 0) {
463 // set initial value
465 } else {
467 }
469 }
470 else {
471#if USE_MS_DIFF_PRESSURE
474#endif
477 }
478 }
479#endif
480
481#ifdef MS_TEMPERATURE_SLAVE_IDX
482 // send temperature data over ABI as soon as available
485#if USE_MS_TEMPERATURE
487#endif
489 }
490#endif
491
492#if USE_MS_EEPROM
494#endif
495}
496
498{
499 // send meteo_stick data at a different frequency
500 meteo_stick_send_data(&(DefaultChannel).trans_tx, &(DefaultDevice).device);
501}
502
Main include for ABI (AirBorneInterface).
#define METEO_STICK_SENDER_ID
void ads1220_event(struct Ads1220 *ads)
Definition ads1220.c:130
void ads1220_init(struct Ads1220 *ads, struct spi_periph *spi_p, uint8_t slave_idx)
Definition ads1220.c:49
Driver for the ADS1220 24-bits ADC from TI SPI communication.
enum Ads1220VRef vref
voltage ref
Definition ads1220.h:136
@ ADS1220_IDAC_250_uA
Definition ads1220.h:110
@ ADS1220_IDAC_OFF
Definition ads1220.h:106
@ ADS1220_CONTINIOUS_CONVERSION
Definition ads1220.h:93
@ ADS1220_VREF_VDD
Definition ads1220.h:101
@ ADS1220_VREF_EXTERNAL_REF
Definition ads1220.h:99
static void ads1220_periodic(struct Ads1220 *ads)
convenience function: read or start configuration if not already initialized
Definition ads1220.h:171
enum Ads1220Imux i1mux
IDAC routing 1.
Definition ads1220.h:138
enum Ads1220Idac idac
IDAC config.
Definition ads1220.h:137
enum Ads1220Imux i2mux
IDAC routing 2.
Definition ads1220.h:139
volatile bool data_available
data ready flag
Definition ads1220.h:161
enum Ads1220Gain gain
gain
Definition ads1220.h:132
static const float Ads1220GainTable[]
Definition ads1220.h:78
enum Ads1220SampleRate rate
data output rate
Definition ads1220.h:134
@ ADS1220_RATE_45_HZ
Definition ads1220.h:85
struct Ads1220Config config
configuration
Definition ads1220.h:158
@ ADS1220_MUX_AIN0_AVSS
Definition ads1220.h:56
@ ADS1220_MUX_AIN0_AIN1
Definition ads1220.h:48
uint32_t data
raw ADC value
Definition ads1220.h:160
enum Ads1220ConvMode conv
conversion mode
Definition ads1220.h:135
bool pga_bypass
bypass PGA (PGA enabled = 0)
Definition ads1220.h:133
@ ADS1220_GAIN_1
Definition ads1220.h:67
@ ADS1220_GAIN_2
Definition ads1220.h:68
@ ADS1220_GAIN_4
Definition ads1220.h:69
@ ADS1220_IMUX_OFF
Definition ads1220.h:118
@ ADS1220_IMUX_A0_RP1
Definition ads1220.h:119
enum Ads1220Mux mux
input multiplexer
Definition ads1220.h:131
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
static bool log_tagged
void eeprom25AA256_event(struct Eeprom25AA256 *eeprom)
Event function.
void eeprom25AA256_init(struct Eeprom25AA256 *eeprom, struct spi_periph *spi_p, uint8_t slave_idx)
Init function.
void eeprom25AA256_read(struct Eeprom25AA256 *eeprom, uint16_t addr, uint16_t length)
Read function.
struct GpsState gps
global GPS state
Definition gps.c:74
Device independent GPS code (interface)
uint32_t tow
GPS time of week in ms.
Definition gps.h:109
int32_t hmsl
height above mean sea level (MSL) in mm
Definition gps.h:94
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition gps.h:92
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
Definition gps.h:99
struct NedCoor_i ned_vel
speed NED in cm/s
Definition gps.h:96
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition gps.h:97
#define GpsFixValid()
Definition gps.h:168
uint16_t week
GPS week.
Definition gps.h:108
uint8_t fix
status of fix
Definition gps.h:107
int32_t lat
in degrees*1e7
int32_t z
Down.
int32_t lon
in degrees*1e7
@ SPITransDone
Definition spi.h:101
static struct LlaCoor_i * stateGetPositionLla_i(void)
Get position in LLA coordinates (int).
Definition state.h:812
static struct UtmCoor_f * stateGetPositionUtm_f(void)
Get position in UTM coordinates (float).
Definition state.h:821
#define S1
Definition board.h:70
uint16_t foo
Definition main_demo5.c:58
#define MS_HUMIDTY_OFFSET
Definition meteo_stick.c:47
#define MS_PRESSURE_OFFSET
Default scale and offset Only used if calibration from EEPROM is not used/available.
Definition meteo_stick.c:35
void meteo_stick_init(void)
Init function.
#define MS_TEMPERATURE_SCALE
Definition meteo_stick.c:44
struct MeteoStick meteo_stick
General structure.
Definition meteo_stick.c:87
static float pitot_offset
static float get_temp(uint32_t raw)
static int pitot_counter
void meteo_stick_periodic(void)
Periodic function.
#define MS_DIFF_PRESSURE_OFFSET
Definition meteo_stick.c:53
#define MS_PITOT_COUNTER
static float get_humidity(uint32_t raw)
static float get_diff(uint32_t raw)
#define MS_PITOT_FILTER
#define MS_DIFF_PRESSURE_SCALE
Definition meteo_stick.c:56
#define MS_TEMPERATURE_OFFSET
Definition meteo_stick.c:41
static float get_pitot(uint32_t raw)
#define MS_LOG_FILE
static const float maxAdc
Prescaling of data according to datasheets.
Definition meteo_stick.c:93
static float get_pressure(uint32_t raw)
Definition meteo_stick.c:95
void meteo_stick_report(void)
void meteo_stick_event(void)
Event function.
static void meteo_stick_send_data(struct transport_tx *trans, struct link_device *device)
Funnction to send over different transport and device.
#define MS_PRESSURE_SCALE
Definition meteo_stick.c:38
#define MS_HUMIDTY_SCALE
Definition meteo_stick.c:50
Data acquisition module for ENAC PTU board.
float current_pressure
calibrated pressure
Definition meteo_stick.h:65
uint32_t humidity_period
humidity (in ticks)
Definition meteo_stick.h:63
struct Ads1220 temperature
temperature
Definition meteo_stick.h:62
struct Ads1220 pressure
absolute pressure
Definition meteo_stick.h:60
float current_temperature
calibrated temperature
Definition meteo_stick.h:64
struct Ads1220 diff_pressure
differential pressure
Definition meteo_stick.h:61
bool reset_dp_offset
reset differential pressure offset
Definition meteo_stick.h:72
float current_airspeed
calibrated airspeed
Definition meteo_stick.h:67
float current_humidity
calibrated humidity
Definition meteo_stick.h:66
Raw sensors structure.
Definition meteo_stick.h:59
bool mtostk_populate_cal_from_buffer(Calibration_params *cp, uint8_t *_eeprom_buffer)
Initializes a Calibration_params structure from memory buffer.
float mtostk_get_calibrated_value(Calibration_params *cp, Mtostk_sensors type, float uncal, float temp)
get calibrated value for a sensor according to current temperature
@ MTOSTK_DIF_PRESS
@ MTOSTK_TEMP
@ MTOSTK_HUMIDITY
@ MTOSTK_ABS_PRESS
@ MTOSTK_NUM_SENSORS
float east
in meters
float north
in meters
position in UTM coordinates Units: meters
struct pprzlog_transport pprzlog_tp
PPRZLOG transport structure.
Definition pprzlog_tp.c:29
Initialize pprzlog transport.
volatile uint32_t pwm_input_period_tics[PWM_INPUT_NB]
Definition pwm_input.c:36
arch independent PWM input capture API
FileDes pprzLogFile
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
int int32_t
Typedef defining 32 bit int type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.