Initial commit.
This commit is contained in:
100
include/baro_channel.h
Normal file
100
include/baro_channel.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ms5611_crc.h"
|
||||
|
||||
//
|
||||
// One validated MS5611 measurement channel.
|
||||
//
|
||||
// The class owns everything that is identical for both sensors - reset and
|
||||
// PROM/CRC handshake, per-poll validation, error accounting and the 1 second
|
||||
// error LED pulse. Only the five driver calls at the bottom are virtual, and
|
||||
// they are implemented once for the I2C part and once for the SPI part.
|
||||
//
|
||||
|
||||
enum class BaroStatus : uint8_t
|
||||
{
|
||||
NotInitialised = 0,
|
||||
Ok,
|
||||
InitFailed, // reset/handshake did not complete
|
||||
PromCrcError, // factory calibration failed its CRC-4 or is implausible
|
||||
ReadError, // the driver reported a bus/ADC failure
|
||||
OutOfRange, // values outside the MS5611 operating envelope
|
||||
Stale, // sensor answers but has stopped producing new samples
|
||||
};
|
||||
|
||||
// Short, log-friendly name for a status - never returns NULL.
|
||||
const char *baroStatusName(BaroStatus status);
|
||||
|
||||
|
||||
class BaroChannel
|
||||
{
|
||||
public:
|
||||
BaroChannel(const char *name, uint8_t ledPin)
|
||||
: _name(name), _ledPin(ledPin) {}
|
||||
|
||||
// Configures the LED pin and makes the first initialisation attempt.
|
||||
void begin(uint32_t now);
|
||||
|
||||
// One acquisition cycle: read, validate, update status and LED.
|
||||
// Blocks for roughly 2x the ADC conversion time of the configured OSR.
|
||||
void poll(uint32_t now);
|
||||
|
||||
// Releases the error LED once its hold time has elapsed. Cheap, call often.
|
||||
void updateLed(uint32_t now);
|
||||
|
||||
const char *name() const { return _name; }
|
||||
BaroStatus status() const { return _status; }
|
||||
bool isOk() const { return _status == BaroStatus::Ok; }
|
||||
float pressure() const { return _pressure; } // mbar
|
||||
float temperature() const { return _temperature; } // degrees C
|
||||
uint32_t errorCount() const { return _errorCount; }
|
||||
|
||||
protected:
|
||||
// Not deleted through this type - keeps the vtable free of a destructor
|
||||
// slot and avoids dragging in operator delete.
|
||||
~BaroChannel() = default;
|
||||
|
||||
// Reset the part and apply the configured oversampling.
|
||||
virtual bool driverBegin() = 0;
|
||||
// Fill prom[0..7] with the factory calibration words.
|
||||
virtual void driverReadProm(uint16_t *prom) = 0;
|
||||
// True when the driver reported MS5611_READ_OK.
|
||||
virtual bool driverRead() = 0;
|
||||
virtual float driverPressure() = 0;
|
||||
virtual float driverTemperature() = 0;
|
||||
|
||||
private:
|
||||
bool tryInit(uint32_t now);
|
||||
void fail(BaroStatus status, uint32_t now);
|
||||
|
||||
const char *_name;
|
||||
uint8_t _ledPin;
|
||||
|
||||
BaroStatus _status = BaroStatus::NotInitialised;
|
||||
bool _initialised = false;
|
||||
uint32_t _lastInitAttempt = 0;
|
||||
|
||||
float _pressure = NAN;
|
||||
float _temperature = NAN;
|
||||
|
||||
uint8_t _repeatCount = 0;
|
||||
uint8_t _errorStreak = 0;
|
||||
uint32_t _errorCount = 0;
|
||||
|
||||
bool _ledOn = false;
|
||||
uint32_t _ledOffAt = 0;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// The two concrete channels are built in their own translation units on
|
||||
// purpose: MS5611.h and MS5611_SPI.h each define `enum osr_t` and their own
|
||||
// MS5611_READ_OK, so including both in one file does not compile. These
|
||||
// accessors hand out the instances without leaking either driver header.
|
||||
//
|
||||
BaroChannel &baroI2cChannel();
|
||||
BaroChannel &baroSpiChannel();
|
||||
Reference in New Issue
Block a user