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
airspeed_ms45xx_i2c.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014 Freek van Tienen <freek.v.tienen@gmail.com>
3 * 2014 Felix Ruess <felix.ruess@gmail.com>
4 *
5 * This file is part of paparazzi
6 *
7 * paparazzi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * paparazzi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with paparazzi; see the file COPYING. If not, write to
19 * the Free Software Foundation, 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
28#include "std.h"
29#include "mcu_periph/i2c.h"
32#include "modules/core/abi.h"
33
34#include "mcu_periph/uart.h"
35#include "pprzlink/messages.h"
37
38#if PERIODIC_TELEMETRY
40#endif
41
42/* Enable ABI sending */
43#ifndef AIRSPEED_MS45XX_SEND_ABI
44#define AIRSPEED_MS45XX_SEND_ABI true
45#endif
46
49#ifndef MS45XX_I2C_DEV
50#define MS45XX_I2C_DEV i2c2
51#endif
52
55#ifndef MS45XX_I2C_ADDR
56#define MS45XX_I2C_ADDR 0x50
57#endif
58
62#ifndef MS45XX_PRESSURE_OUTPUT_TYPE_InH2O
63#define MS45XX_PRESSURE_OUTPUT_TYPE_InH2O 0
64#endif
65
70#ifndef MS45XX_PRESSURE_RANGE
71#define MS45XX_PRESSURE_RANGE 1
72#endif
73
76#ifndef MS45XX_PRESSURE_TYPE
77#define MS45XX_PRESSURE_TYPE 0
78#endif
79
82#ifndef USE_AIRSPEED_LOWPASS_FILTER
83#define USE_AIRSPEED_LOWPASS_FILTER TRUE
84#endif
85
90#ifndef MS45XX_OUTPUT_TYPE
91#define MS45XX_OUTPUT_TYPE 0
92#endif
93
95#define InH2O_TO_PA 249.08891
96
98#define PSI_TO_PA 6894.75729
99
100#if MS45XX_PRESSURE_OUTPUT_TYPE_InH2O
101#define OutputPressureToPa InH2O_TO_PA
102#else
103#define OutputPressureToPa PSI_TO_PA
104#endif
105
106#if MS45XX_OUTPUT_TYPE == 0
107/* Offset and scaling for OUTPUT TYPE A:
108 * p_raw = (0.8*16383)/ (Pmax - Pmin) * (pressure - Pmin) + 0.1*16383
109 * For differential sensors Pmax = MS45XX_PRESSURE_RANGE = -Pmin.
110 *
111 * p_diff = (p_raw - 0.1*16383) * 2*RANGE/(0.8*16383) - RANGE
112 * p_diff = p_raw * 2*RANGE/(0.8*16383) - (RANGE + (0.1 * 16383) * 2*RANGE/(0.8*16383)
113 * p_diff = p_raw * 2*RANGE/(0.8*16383) - (1.25 * RANGE)
114 * p_diff = (p_raw - offset) * scale
115 * then convert to Pascal
116 */
117#ifndef MS45XX_PRESSURE_SCALE
118#define MS45XX_PRESSURE_SCALE (2 * MS45XX_PRESSURE_RANGE / (0.8 * 16383) * OutputPressureToPa)
119#endif
120#ifndef MS45XX_PRESSURE_OFFSET
121#define MS45XX_PRESSURE_OFFSET (16383 / 2)
122#endif
123#else /* Can still be improved using another if statment with MS45XX_PRESSURE_TYPE etc. */
124/* Offset and scaling for OUTPUT TYPE B:
125 * p_raw = (0.9*16383)/ (Pmax - Pmin) * (pressure - Pmin) + 0.05*16383
126 */
127#ifndef MS45XX_PRESSURE_SCALE
128#define MS45XX_PRESSURE_SCALE (MS45XX_PRESSURE_RANGE/(0.9*16383)*OutputPressureToPa)
129#endif
130#ifndef MS45XX_PRESSURE_OFFSET
131#define MS45XX_PRESSURE_OFFSET (0.05*16383)
132#endif
133#endif
134
140
141
142
147#ifdef MS45XX_AIRSPEED_SCALE
148PRINT_CONFIG_MSG("MS45XX changed air density. PS: Use MS45XX_PRESSURE_SCALE to calibrate the MS45XX.");
149#endif
150
151#define MS45XX_RHO_DIV_2 1.6327
152
153
157#ifndef MS45XX_LOWPASS_TAU
158#define MS45XX_LOWPASS_TAU 0.15
159#endif
160
163#ifdef USE_AIRSPEED_LOWPASS_FILTER
165#endif
166
167#if PREFLIGHT_CHECKS
168/* Preflight checks */
171
172static void ms45xx_preflight(struct preflight_result_t *result) {
173 if(ms45xx.offset_set) {
174 preflight_success(result, "Airspeed sensor succesfully nulled (MS45XX)");
175 } else {
176 preflight_error(result, "Airspeed sensor not nulled (MS45XX)");
177 }
178}
179#endif // PREFLIGHT_CHECKS
180
181static void ms45xx_downlink(struct transport_tx *trans, struct link_device *dev)
182{
183 uint8_t dev_id = MS45XX_SENDER_ID;
184 float temp = ((float)ms45xx.temperature) * 0.1f;
186 &dev_id,
187 &ms45xx.raw_p,
190 &temp,
192}
193
195{
196 ms45xx.pressure = 0.;
198 ms45xx.airspeed = 0.;
199 ms45xx.raw_p = 0;
204 ms45xx.offset_set = false;
205
207 // setup low pass filter with time constant and 100Hz sampling freq
208#ifdef USE_AIRSPEED_LOWPASS_FILTER
211#endif
212
213#if PERIODIC_TELEMETRY
215#endif
216
217 /* Register preflight checks */
218#if PREFLIGHT_CHECKS
220#endif
221}
222
223
232
233
235{
236 // Initiate next read
239 }
240}
241
242#define AUTOSET_NB_MAX 200
243
245{
246 static int autoset_nb = 0;
247 static float autoset_offset = 0.f;
248
249 /* Check if transaction is succesfull */
251
252 /* 2 MSB of data are status bits, 0 = good data, 2 = already fetched, 3 = fault */
253 uint8_t status = (0xC0 & ms45xx_trans.buf[0]) >> 6;
254
255 if (status == 0) {
256 /* 14bit raw pressure */
257 uint16_t p_raw = 0x3FFF & (((uint16_t)(ms45xx_trans.buf[0]) << 8) | (uint16_t)(ms45xx_trans.buf[1]));
259
260 /* 11bit raw temperature, 5 LSB bits not used */
261 uint16_t temp_raw = 0xFFE0 & (((uint16_t)(ms45xx_trans.buf[2]) << 8) |
263 temp_raw = temp_raw >> 5;
264
265 /* Reject any values that are the absolute minimum or maximums these
266 can happen due to gnd lifts or communication errors on the bus */
267 if(p_raw == 0x3FFF || p_raw == 0 || temp_raw == 0x7FF || temp_raw == 0) {
269 return;
270 }
271
272 /* For type Diff
273 * Output is proportional to the difference between Port 1 and Port 2. Output
274 * swings positive when Port 1> Port 2. Output is 50% of total counts
275 * when Port 1=Port 2.
276 * For type Gauge
277 * p_out = (p_raw - offset) * scale
278 */
279
281
282 /* 0 = -50degC, 20147 = 150degC
283 * ms45xx_temperature in 0.1 deg Celcius
284 */
285 ms45xx.temperature = ((uint32_t)temp_raw * 2000) / 2047 - 500;
286
287 // if(electrical.vboard != 0) {
288 // float volt_diff = electrical.vboard - 5.0f;
289 // Bound(volt_diff, -0.7f, 0.5f);
290
291 // p_out -= 65.0f * volt_diff;
292 // ms45xx.temperature -= 8.87f * volt_diff;
293 // }
294#ifdef USE_AIRSPEED_LOWPASS_FILTER
296#else
298#endif
299
302 autoset_offset += p_raw;
303 autoset_nb++;
304 } else {
305 ms45xx.pressure_offset = autoset_offset / (float)autoset_nb;
306 autoset_offset = 0.f;
307 autoset_nb = 0;
308 ms45xx.autoset_offset = false;
309 ms45xx.offset_set = true;
310 }
311 }
312
313 // Send (differential) pressure via ABI
314 #if AIRSPEED_MS45XX_SEND_ABI
316
317 // Send temperature as float in deg Celcius via ABI
318 float temp = ms45xx.temperature / 10.0f;
319
321 #endif
322
323 // Compute airspeed
324 float sign = 1.0f;
325 if (ms45xx.pressure < 0.0f) {
326 sign = -1.0f;
327 }
329
330 }
331
332 // Set to done
334 } else if (ms45xx_trans.status == I2CTransFailed) {
335 // Just retry if failed
337 }
338}
Main include for ABI (AirBorneInterface).
#define MS45XX_SENDER_ID
#define MS45XX_LOWPASS_TAU
Time constant for second order Butterworth low pass filter Default of 0.15 should give cut-off freq o...
#define MS45XX_RHO_DIV_2
Quadratic scale factor for indicated airspeed.
#define MS45XX_PRESSURE_RANGE
MS45xx pressure range in PSI or InH2O The sensor is available in many ranges, the datasheet of your p...
void ms45xx_i2c_event(void)
#define MS45XX_OUTPUT_TYPE
MS45xx output Type.
void ms45xx_i2c_periodic(void)
#define MS45XX_I2C_DEV
Default I2C device.
#define MS45XX_I2C_ADDR
Sensor I2C slave address (existing defaults 0x50, 0x6C and 0x8C)
void airspeed_ms45xx_i2c_change_tau(float new_tau)
struct AirspeedMs45xx ms45xx
static void ms45xx_downlink(struct transport_tx *trans, struct link_device *dev)
#define MS45XX_PRESSURE_TYPE
Pressure Type 0 = Differential, 1 = Gauge note there are theoretical more types than 2,...
#define MS45XX_PRESSURE_OFFSET
static struct i2c_transaction ms45xx_trans
static Butterworth2LowPass ms45xx_filter
#define AUTOSET_NB_MAX
#define MS45XX_PRESSURE_SCALE
void ms45xx_i2c_init(void)
Airspeed driver for the MS45xx pressure sensor via I2C.
float pressure_scale
Scaling factor from raw measurement to Pascal.
bool autoset_offset
Set offset value from current filtered value.
float pressure_offset
Offset in Pascal.
uint16_t raw_p
Raw pressure.
bool offset_set
Offset is set once.
bool pressure_type
Pressure type Differential of Gauge.
float pressure
(differential) pressure in Pascal
int16_t temperature
Temperature in 0.1 deg Celcius.
float lowpass_tau
Time constant for low pass filter.
float airspeed
Airspeed in m/s estimated from (differential) pressure.
static uint8_t status
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition i2c.h:122
enum I2CTransactionStatus status
Transaction status.
Definition i2c.h:126
bool i2c_receive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint16_t len)
Submit a read only transaction.
Definition i2c.c:212
@ I2CTransSuccess
transaction successfully finished by I2C driver
Definition i2c.h:57
@ I2CTransFailed
transaction failed
Definition i2c.h:58
@ I2CTransDone
transaction set to done by user level
Definition i2c.h:59
I2C transaction structure.
Definition i2c.h:93
Architecture independent I2C (Inter-Integrated Circuit Bus) API.
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
Simple first order low pass filter with bilinear transform.
static float get_butterworth_2_low_pass(Butterworth2LowPass *filter)
Get current value of the second order Butterworth low pass filter.
static void init_butterworth_2_low_pass(Butterworth2LowPass *filter, float tau, float sample_time, float value)
Init a second order Butterworth filter.
static float update_butterworth_2_low_pass(Butterworth2LowPass *filter, float value)
Update second order Butterworth low pass filter state with a new value.
Second order low pass filter structure.
uint16_t foo
Definition main_demo5.c:58
static float sign(float x)
sign function
Definition nav_fish.c:232
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
void preflight_error(struct preflight_result_t *result, const char *fmt,...)
Register a preflight error used inside the preflight checking functions.
void preflight_success(struct preflight_result_t *result, const char *fmt,...)
Register a preflight success used inside the preflight checking functions.
void preflight_check_register(struct preflight_check_t *check, preflight_check_f func)
Register a preflight check and add it to the linked list.
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.