8 #include "baro_spl06.h"
9 #include "baro_bmp280.h"
10 //#include "baro_bmp085.h"
12 #define BARO_STARTUP_INTERVAL 100
14 /* Shameful externs */
15 extern Telemetry telemetry
;
18 static BaroBase
*baro
;
19 static eBaroReadState BaroReadState
;
21 extern bool i2c_enabled
;
23 static bool Baro_Detect()
31 DBGLN("Detected baro: SPL06");
37 DBGLN("Detected baro: BMP280");
42 // if (BMP085::detect())
44 // DBGLN("Detected baro: BMP085");
45 // baro = new BMP085();
48 // DBGLN("No baro detected");
54 static int Baro_Init()
57 if (baro
->isInitialized())
59 // Slow down Vbat updates to save bandwidth
60 Vbat_enableSlowUpdate(true);
61 BaroReadState
= brsReadTemp
;
62 return DURATION_IMMEDIATELY
;
65 // Did not init, try again later
66 return BARO_STARTUP_INTERVAL
;
69 static void Baro_PublishPressure(uint32_t pressuredPa
)
71 static int32_t last_altitude_cm
;
72 static int16_t verticalspd_smoothed
;
73 int32_t altitude_cm
= baro
->pressureToAltitude(pressuredPa
);
74 int32_t altitude_diff_cm
= altitude_cm
- last_altitude_cm
;
75 last_altitude_cm
= altitude_cm
;
77 static uint32_t last_publish_ms
;
78 uint32_t now
= millis();
79 uint32_t dT_ms
= now
- last_publish_ms
;
80 last_publish_ms
= now
;
82 //DBGLN("%udPa %dcm", pressuredPa, altitude_cm);
84 if (baro
->getAltitudeHome() == BaroBase::ALTITUDE_INVALID
)
86 baro
->setAltitudeHome(altitude_cm
);
87 // skip sending the first reading because the VSpd will be bonkers
91 CRSF_MK_FRAME_T(crsf_sensor_baro_vario_t
) crsfBaro
= {0};
94 int32_t relative_altitude_dm
= (altitude_cm
- baro
->getAltitudeHome()) / 10;
95 if (relative_altitude_dm
> (0x7FFF - 10000))
97 // If the altitude would be 0x8000 or higher, send it in meters with the high bit set
98 crsfBaro
.p
.altitude
= 0x8000 | (uint16_t)(relative_altitude_dm
/ 10);
102 // Else it is in decimeters + 10000 (-1000m max negative alt)
103 crsfBaro
.p
.altitude
= relative_altitude_dm
+ 10000;
105 crsfBaro
.p
.altitude
= htobe16(crsfBaro
.p
.altitude
);
108 int16_t vspd
= altitude_diff_cm
* 1000 / (int32_t)dT_ms
;
109 verticalspd_smoothed
= (verticalspd_smoothed
* 3 + vspd
) / 4; // Simple smoothing
110 crsfBaro
.p
.verticalspd
= htobe16(verticalspd_smoothed
);
111 //DBGLN("diff=%d smooth=%d dT=%u", altitude_diff_cm, verticalspd_smoothed, dT_ms);
113 // if no external vario is connected output internal Vspd on CRSF_FRAMETYPE_BARO_ALTITUDE packet
114 if (!telemetry
.GetCrsfBaroSensorDetected())
116 CRSF::SetHeaderAndCrc((uint8_t *)&crsfBaro
, CRSF_FRAMETYPE_BARO_ALTITUDE
, CRSF_FRAME_SIZE(sizeof(crsf_sensor_baro_vario_t
)), CRSF_ADDRESS_CRSF_TRANSMITTER
);
117 telemetry
.AppendTelemetryPackage((uint8_t *)&crsfBaro
);
125 BaroReadState
= brsUninitialized
;
126 return BARO_STARTUP_INTERVAL
;
129 BaroReadState
= brsNoBaro
;
130 return DURATION_NEVER
;
135 if (connectionState
>= MODE_STATES
)
136 return DURATION_NEVER
;
138 switch (BaroReadState
)
140 default: // fallthrough
142 return DURATION_NEVER
;
144 case brsUninitialized
:
149 int32_t temp
= baro
->getTemperature();
150 if (temp
== BaroBase::TEMPERATURE_INVALID
)
151 return DURATION_IMMEDIATELY
;
157 uint8_t pressDuration
= baro
->getPressureDuration();
158 BaroReadState
= brsWaitingPress
;
159 if (pressDuration
!= 0)
161 baro
->startPressure();
162 return pressDuration
;
167 case brsWaitingPress
:
169 uint32_t press
= baro
->getPressure();
170 if (press
== BaroBase::PRESSURE_INVALID
)
171 return DURATION_IMMEDIATELY
;
172 Baro_PublishPressure(press
);
178 uint8_t tempDuration
= baro
->getTemperatureDuration();
179 if (tempDuration
== 0)
181 BaroReadState
= brsReadPres
;
182 return DURATION_IMMEDIATELY
;
184 BaroReadState
= brsWaitingTemp
;
185 baro
->startTemperature();
191 device_t Baro_device
= {
192 .initialize
= nullptr,