mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
drivers: auav, read sensor eeprom to get cal range (#26294)
* drivers: auav, read sensor eeprom to get cal range * added review feedback
This commit is contained in:
parent
f98fdbc452
commit
273766a4ea
@ -77,6 +77,10 @@ AUAV::~AUAV()
|
||||
void AUAV::RunImpl()
|
||||
{
|
||||
switch (_state) {
|
||||
case STATE::READ_FACTORY_DATA:
|
||||
handle_state_read_factory_data();
|
||||
break;
|
||||
|
||||
case STATE::READ_CALIBDATA:
|
||||
handle_state_read_calibdata();
|
||||
break;
|
||||
@ -107,23 +111,6 @@ int AUAV::init()
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t hw_model = 0;
|
||||
param_get(param_find("SENS_EN_AUAVX"), &hw_model);
|
||||
|
||||
switch (hw_model) {
|
||||
case 1: /* AUAV L05D (+- 5 inH20) */
|
||||
_cal_range = 10.0f;
|
||||
break;
|
||||
|
||||
case 2: /* AUAV L10D (+- 10 inH20) */
|
||||
_cal_range = 20.0f;
|
||||
break;
|
||||
|
||||
case 3: /* AUAV L30D (+- 30 inH20) */
|
||||
_cal_range = 60.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
ScheduleClear();
|
||||
ScheduleNow();
|
||||
return PX4_OK;
|
||||
@ -148,6 +135,20 @@ int AUAV::probe()
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
void AUAV::handle_state_read_factory_data()
|
||||
{
|
||||
int status = read_factory_data();
|
||||
|
||||
if (status == PX4_OK) {
|
||||
/* Factory data read or sensor does not have any, move to next state */
|
||||
_state = STATE::READ_CALIBDATA;
|
||||
ScheduleNow();
|
||||
|
||||
} else {
|
||||
ScheduleDelayed(100_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void AUAV::handle_state_read_calibdata()
|
||||
{
|
||||
int status = PX4_OK;
|
||||
|
||||
@ -61,6 +61,7 @@ public:
|
||||
|
||||
protected:
|
||||
enum class STATE : uint8_t {
|
||||
READ_FACTORY_DATA,
|
||||
READ_CALIBDATA,
|
||||
REQUEST_MEASUREMENT,
|
||||
GATHER_MEASUREMENT
|
||||
@ -107,7 +108,9 @@ protected:
|
||||
virtual int64_t get_conversion_interval() const = 0;
|
||||
virtual calib_eeprom_addr_t get_calib_eeprom_addr() const = 0;
|
||||
virtual float process_pressure_dig(const float pressure_dig) const = 0;
|
||||
virtual int read_factory_data() = 0;
|
||||
|
||||
void handle_state_read_factory_data();
|
||||
void handle_state_read_calibdata();
|
||||
void handle_state_request_measurement();
|
||||
void handle_state_gather_measurement();
|
||||
@ -117,8 +120,7 @@ protected:
|
||||
float correct_pressure(const uint32_t pressure_raw, const uint32_t temperature_raw) const;
|
||||
float process_temperature_raw(const float temperature_raw) const;
|
||||
|
||||
float _cal_range{10.0f};
|
||||
STATE _state{STATE::READ_CALIBDATA};
|
||||
STATE _state{STATE::READ_FACTORY_DATA};
|
||||
calib_data_t _calib_data {};
|
||||
|
||||
perf_counter_t _sample_perf;
|
||||
|
||||
@ -77,3 +77,9 @@ float AUAV_Absolute::process_pressure_dig(const float pressure_dig) const
|
||||
const float pressure_mbar = 250.f + 1.25f * ((pressure_dig - (0.1f * (1 << 24))) / (1 << 24)) * 1000.f;
|
||||
return pressure_mbar * MBAR_TO_PA;
|
||||
}
|
||||
|
||||
int AUAV_Absolute::read_factory_data()
|
||||
{
|
||||
/* Absolute sensor doesn't need to read factory data */
|
||||
return PX4_OK;
|
||||
}
|
||||
|
||||
@ -68,6 +68,7 @@ private:
|
||||
int64_t get_conversion_interval() const override;
|
||||
calib_eeprom_addr_t get_calib_eeprom_addr() const override;
|
||||
float process_pressure_dig(const float pressure_dig) const override;
|
||||
int read_factory_data() override;
|
||||
|
||||
uORB::PublicationMulti<sensor_baro_s> _sensor_baro_pub{ORB_ID(sensor_baro)};
|
||||
};
|
||||
|
||||
@ -33,10 +33,38 @@
|
||||
|
||||
#include "AUAV_Differential.hpp"
|
||||
#include <parameters/param.h>
|
||||
#include <cctype>
|
||||
|
||||
AUAV_Differential::AUAV_Differential(const I2CSPIDriverConfig &config) :
|
||||
AUAV(config)
|
||||
{
|
||||
/* Initialize cal_range from parameter as fallback value */
|
||||
int32_t hw_model = 0;
|
||||
param_get(param_find("SENS_EN_AUAVX"), &hw_model);
|
||||
|
||||
switch (hw_model) {
|
||||
case 1: /* AUAV L05D (+- 5 inH20) */
|
||||
_cal_range = 10;
|
||||
break;
|
||||
|
||||
case 2: /* AUAV L10D (+- 10 inH20) */
|
||||
_cal_range = 20;
|
||||
break;
|
||||
|
||||
case 3: /* AUAV L30D (+- 30 inH20) */
|
||||
_cal_range = 60;
|
||||
break;
|
||||
|
||||
default:
|
||||
_cal_range = 10; /* Default fallback */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AUAV_Differential::print_status()
|
||||
{
|
||||
AUAV::print_status();
|
||||
PX4_INFO("cal range: %" PRId32, _cal_range);
|
||||
}
|
||||
|
||||
void AUAV_Differential::publish_pressure(const float pressure_p, const float temperature_c,
|
||||
@ -83,6 +111,52 @@ AUAV::calib_eeprom_addr_t AUAV_Differential::get_calib_eeprom_addr() const
|
||||
|
||||
float AUAV_Differential::process_pressure_dig(const float pressure_dig) const
|
||||
{
|
||||
const float pressure_in_h = 1.25f * ((pressure_dig - (1 << 23)) / (1 << 24)) * _cal_range;
|
||||
const float pressure_in_h = 1.25f * ((pressure_dig - (1 << 23)) / (1 << 24)) * static_cast<float>(_cal_range);
|
||||
return pressure_in_h * INH_TO_PA;
|
||||
}
|
||||
|
||||
int AUAV_Differential::read_factory_data()
|
||||
{
|
||||
/* The differential sensor needs the cal_range from the absolute sensor's EEPROM.
|
||||
* Temporarily switch to the absolute sensor's I2C address to read it, then switch back. */
|
||||
|
||||
uint8_t original_address = get_device_address();
|
||||
set_device_address(I2C_ADDRESS_ABSOLUTE);
|
||||
|
||||
/* Read the calibration range from the absolute sensor's EEPROM */
|
||||
uint16_t factory_data = 0;
|
||||
int status = read_calibration_eeprom(EEPROM_ABS_CAL_RNG, factory_data);
|
||||
|
||||
set_device_address(original_address);
|
||||
|
||||
if (status != PX4_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* If EEPROM data is 0, stop trying (sensor does not have factory data) */
|
||||
if (factory_data == 0) {
|
||||
PX4_INFO("Differential: cal range data is 0, using fallback value");
|
||||
return PX4_OK;
|
||||
}
|
||||
|
||||
/* Decode the two bytes as ASCII characters */
|
||||
uint8_t char_high = (factory_data >> 8) & 0xFF;
|
||||
uint8_t char_low = factory_data & 0xFF;
|
||||
|
||||
/* Validate that both characters are ASCII digits (0-9) */
|
||||
if (!isdigit(char_high) || !isdigit(char_low)) {
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
int32_t sensor_type = ((char_high - '0') * 10) + (char_low - '0');
|
||||
|
||||
/* Check if the detected sensor type is valid */
|
||||
if (sensor_type != AUAV_LD_05 && sensor_type != AUAV_LD_10 && sensor_type != AUAV_LD_30) {
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
_cal_range = sensor_type * 2;
|
||||
PX4_INFO("Differential: read cal range %" PRId32 " from absolute sensor EEPROM", _cal_range);
|
||||
|
||||
return PX4_OK;
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#include <uORB/topics/differential_pressure.h>
|
||||
|
||||
/* AUAV EEPROM addresses for differential channel */
|
||||
static constexpr uint8_t EEPROM_ABS_CAL_RNG = 0x25;
|
||||
static constexpr uint8_t EEPROM_DIFF_AHW = 0x2B;
|
||||
static constexpr uint8_t EEPROM_DIFF_ALW = 0x2C;
|
||||
static constexpr uint8_t EEPROM_DIFF_BHW = 0x2D;
|
||||
@ -57,17 +58,26 @@ static_assert(DIFF_CONVERSION_INTERVAL >= 7000, "Conversion interval is too fast
|
||||
/* Conversions */
|
||||
static constexpr float INH_TO_PA = 249.08f;
|
||||
|
||||
/* Valid AUAV types */
|
||||
static constexpr int32_t AUAV_LD_05 = 5;
|
||||
static constexpr int32_t AUAV_LD_10 = 10;
|
||||
static constexpr int32_t AUAV_LD_30 = 30;
|
||||
|
||||
class AUAV_Differential : public AUAV
|
||||
{
|
||||
public:
|
||||
explicit AUAV_Differential(const I2CSPIDriverConfig &config);
|
||||
~AUAV_Differential() = default;
|
||||
|
||||
void print_status() override;
|
||||
|
||||
private:
|
||||
void publish_pressure(const float pressure_p, const float temperature_c, const hrt_abstime timestamp_sample) override;
|
||||
int64_t get_conversion_interval() const override;
|
||||
calib_eeprom_addr_t get_calib_eeprom_addr() const override;
|
||||
float process_pressure_dig(const float pressure_dig) const override;
|
||||
int read_factory_data() override;
|
||||
|
||||
uORB::PublicationMulti<differential_pressure_s> _differential_pressure_pub{ORB_ID(differential_pressure)};
|
||||
int32_t _cal_range{10};
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user