src/Apis.h
Classes
| Name | |
|---|---|
| class | Apis Arduino library for the Apis board, which manages a LiDAR Lite unit (roll/pitch, firmware lock/reset, power supply). |
Types
| Name | |
|---|---|
| enum uint8_t | SensitivityMode { SENSITIVITY_BALANCED = 0, SENSITIVITY_HIGH = 1, SENSITIVITY_LOW = 2, SENSITIVITY_MAX_RANGE = 3} Sensitivity mode for the LiDAR Lite acquisition pipeline. |
Defines
Types Documentation
enum SensitivityMode
| Enumerator | Value | Description |
|---|---|---|
| SENSITIVITY_BALANCED | 0 | Default. SIG_COUNT_VAL=0x80, THRESHOLD_BYPASS=0x00. Balanced range and noise performance. |
| SENSITIVITY_HIGH | 1 | THRESHOLD_BYPASS=0x80. Lower detection threshold; detects weaker returns at the cost of more false positives. |
| SENSITIVITY_LOW | 2 | THRESHOLD_BYPASS=0xB0. Higher detection threshold; fewer false positives at the cost of reduced range. |
| SENSITIVITY_MAX_RANGE | 3 | SIG_COUNT_VAL=0xFF. More acquisitions per measurement; longer maximum range, slower throughput. |
Sensitivity mode for the LiDAR Lite acquisition pipeline.
Written to REG_CONFIG (0x46) by begin(); applied on every loop() iteration when the firmware reinitialises the LiDAR Lite via InitLiDAR(). Two LiDAR Lite registers drive the behaviour:
- SIG_COUNT_VAL (0x02): maximum acquisition count per measurement. Higher values average more returns, extending usable range but slowing throughput.
- THRESHOLD_BYPASS (0x1C): signal detection threshold. Lower values detect weaker returns (higher sensitivity, more false positives); higher values suppress weak returns (fewer false positives, less range).
Macros Documentation
define M_PI
#define M_PI 3.14159265358979323846
define APIS_FW_MIN_PATCH
#define APIS_FW_MIN_PATCH 5
define APIS_LIBRARY_VERSION
#define APIS_LIBRARY_VERSION "0.1.0"
define APIS_LIBRARY_COMMIT
#define APIS_LIBRARY_COMMIT ""
define APIS_RANGE_CAPACITY
#define APIS_RANGE_CAPACITY 64
define APIS_ACCEL_M_PER_S2_PER_DIGIT
#define APIS_ACCEL_M_PER_S2_PER_DIGIT (9.80665e-3f)
define APIS_ORIENT_CAPACITY
#define APIS_ORIENT_CAPACITY 8
define APIS_ERROR
#define APIS_ERROR NW_ERROR
Sentinel returned by all getters and printed by printDataRow() when a measurement fails due to hardware fault, I2C failure, or out-of-range reading. Applies to all measurement types: range, pitch, roll, and all derived statistics (mean, std, sterr). The same value as NW_ERROR, which every NW library uses; APIS_ERROR is the Apis spelling of it.
define APIS_NOT_MEASURED
#define APIS_NOT_MEASURED -9998
Sentinel returned by all getters and printed by printDataRow() when begin() has been called but no successful updateMeasurements() (or updateDistance()/updateOrientation()) has yet completed. Distinct from APIS_ERROR so callers can tell the difference between “the sensor failed” and “we haven’t asked yet.”
define NW_READING_ALL
#define NW_READING_ALL Apis::ALL
define NW_READING_PRIMARY
#define NW_READING_PRIMARY Apis::RANGE
define NW_READING_SECONDARY
#define NW_READING_SECONDARY Apis::ORIENT
define NW_READING_RANGE
#define NW_READING_RANGE NW_READING_PRIMARY
define NW_READING_ORIENT
#define NW_READING_ORIENT NW_READING_SECONDARY
define ADR_DEFAULT
#define ADR_DEFAULT Apis::DEFAULT_ADDRESS
Deprecated:
Use Apis::DEFAULT_ADDRESS. Every NW library defined this same macro with a different value, so a sketch including two of them got the last one. Removed at the next major version.
Source code
/******************************************************************************
Apis.h
Library for the Apis interface board for a LiDAR Lite unit.
Andrew Wickert
Based loosely on early code by Bobby Schulz, including
https://github.com/NorthernWidget/Project-Apis/tree/master/Software/LiDARLite_I2CParse
Started 2020.05.01
Hardware located at:
https://github.com/NorthernWidget/Project-Apis
License: GNU GPL v3. You should find a copy in the repository.
******************************************************************************/
#ifndef Apis_h
#define Apis_h
#include <Arduino.h>
#include <Wire.h>
#include <NW_Core.h> // NW_Core: NW_Device (Schema 1 protocol), NW_Readings (statistics), NW_Report
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// Minimum firmware patch (Page 0 byte 0x0A) this library accepts. Patch 1 is
// the first firmware serving the Schema 1 register map; patch 5 serves the
// zero generation with every reading, which this library reads.
#define APIS_FW_MIN_PATCH 5
// Build identity: this library's version (held equal to library.properties by
// NW-Tests/version_check.py) and its build commit, set by the NW-Build wrapper from
// git and blank in an Arduino IDE build. Both go into a logger's status file.
#define APIS_LIBRARY_VERSION "0.1.0"
#ifndef APIS_LIBRARY_COMMIT
#define APIS_LIBRARY_COMMIT ""
#endif
// Register addresses and bit masks are implementation details and live in
// Apis.cpp (NW convention: no public names for them). Sketches use the API.
// Reading arrays: each measurement keeps its readings from the last
// updateMeasurements() in a statically sized array so that median and
// two-pass statistics can be computed. Capacity is per measurement group;
// a sketch may override before including this header, e.g.
// #define APIS_RANGE_CAPACITY 200
// No heap is ever used; a request above capacity is clamped to it.
#ifndef APIS_RANGE_CAPACITY
#define APIS_RANGE_CAPACITY 64
#endif
// Digits to m/s^2 for the accelerometer. The firmware sets CTRL_REG4 = 0x88,
// which is full scale +/-2 g with high resolution, and LIS3DH Table 4 gives
// that configuration a sensitivity of 1 mg per digit; the firmware right-
// shifts the 12-bit word into place before serving it, so a served digit is
// one milli-g. Standard gravity is 9.80665 m/s^2.
#define APIS_ACCEL_M_PER_S2_PER_DIGIT (9.80665e-3f)
#ifndef APIS_ORIENT_CAPACITY
#define APIS_ORIENT_CAPACITY 8
#endif
enum SensitivityMode : uint8_t {
SENSITIVITY_BALANCED = 0,
SENSITIVITY_HIGH = 1,
SENSITIVITY_LOW = 2,
SENSITIVITY_MAX_RANGE = 3
};
#define APIS_ERROR NW_ERROR
#define APIS_NOT_MEASURED -9998
// Deprecated component selectors. Use the class-scoped Apis::ALL, Apis::RANGE,
// Apis::ORIENT instead (see Apis::Component). Kept so existing sketches compile;
// values match the enum and will be removed in a future major version.
class Apis : public NW_Sensor {
public:
static constexpr uint8_t DEFAULT_ADDRESS = 0x41;
enum Component : uint8_t {
RANGE = 0x01,
ORIENT = 0x02,
ALL = 0x03
};
Apis(uint16_t nRangeReadings = 1, bool rangeStats = false,
uint16_t nOrientReadings = 1, bool orientStats = false);
bool begin(uint8_t address = DEFAULT_ADDRESS,
SensitivityMode sensitivity = SENSITIVITY_BALANCED);
uint8_t getHardwareMajor();
uint8_t getHardwareMinor();
uint8_t getFirmwareVersion();
// --- Configuration setters ---
uint16_t setDistanceReadings(uint16_t n);
void setDistanceStats(bool enable);
uint16_t setOrientationReadings(uint16_t n);
void setAccelerationColumns(bool enable);
void setMagnitudeColumns(bool enable);
void setTiltColumns(bool enable);
void setOrientationStats(bool enable);
void setRangefinderSensitivity(SensitivityMode mode);
void setI2CAddress(uint8_t newAddress);
// --- Handshake (NW-Device-Specification Page 2 Block 0) ---
bool ready();
bool newReading();
bool requestReading(uint8_t component = ALL);
// --- Faults (status byte, live; Report register, latched) ---
bool faulted(uint8_t chip);
bool anyFault();
uint8_t reportChip();
uint8_t reportKind();
size_t printReport(Print& out);
size_t printStatus(Print& out, bool boot = false) override;
// --- NW_Sensor: the logger's view (Margay::watch) ---
const char* name() const override {
return "Apis";
}
bool reportIsFault() override;
uint8_t bootReportKind() override;
void clearBootReport() override;
bool updateDistance();
bool updateOrientation();
bool updateMeasurements(uint8_t component = ALL);
uint16_t getDistanceCount();
uint16_t getOrientationCount();
// --- Single-value getters ---
float getDistance();
float getRoll();
float getPitch();
float getAccelerationX();
float getAccelerationY();
float getAccelerationZ();
float getAccelerationMagnitude();
float getTilt();
uint8_t getSignalStrength();
int16_t getAccelerometerTemperatureADC();
float getAccelerometerTemperatureChange();
int16_t getZeroTemperatureADC();
uint16_t getZeroGeneration();
bool zeroChanged();
size_t dumpZeros(Print& out);
// --- Statistics getters ---
// Computed two-pass in 32-bit float over the readings stored by the last
// updateMeasurements(). Adequate for N up to the array capacities
// (tens to a few hundred); at N in the thousands the sum of squared
// deviations would want double precision, which the AVR lacks.
float getDistanceMean();
float getDistanceMedian();
float getAccelerationMagnitudeMedian();
float getTiltMedian();
float getPitchMedian();
float getRollMedian();
float getDistanceStd();
float getDistanceSterr();
float getAccelerationMagnitudeStd();
float getAccelerationMagnitudeSterr();
float getTiltStd();
float getTiltSterr();
float getPitchStd();
float getPitchSterr();
float getRollStd();
float getRollSterr();
size_t printDataHeader(Print& out) override;
size_t printDataRow(Print& out) override;
uint8_t defaultAddress() const override;
bool wake(uint8_t address) override;
bool acquire() override;
size_t printNote(Print& out, bool beginFailed = false) override;
// --- Reading interface (NW standard) ---
size_t printHeader(Print& out);
size_t printReading(Print& out);
size_t logReading(Print& out);
void beginReadings(uint8_t component = ALL, uint16_t n = 0);
void endReadings();
// --- Deprecated raw-reading interface (v0.1.x names) ---
[[deprecated("Use beginReadings()")]] void beginRawReadings(uint8_t component = ALL);
[[deprecated("Use logReading(Print&)")]] uint16_t takeRawReading(char* buf, uint16_t offset);
[[deprecated("Use endReadings()")]] void endRawReadings();
private:
// The Schema 1 device protocol (identity gates, handshake, batches, faults): NW_Core.
NW_Device _dev;
static uint8_t _chips(uint8_t component);
// Configuration
NW_ReadingsConfig _distanceCfg; // readings per updateMeasurements() and stats columns, LiDAR
NW_ReadingsConfig _orientationCfg; // accelerometer
bool _accelerationColumns = false; // the g vector's components: off unless asked for
bool _magnitudeColumns = false;
bool _tiltColumns = false;
// Stored measurements and statistics.
// All initialised to APIS_NOT_MEASURED; set to APIS_ERROR on error.
float _distance = APIS_NOT_MEASURED;
float _pitch = APIS_NOT_MEASURED;
float _roll = APIS_NOT_MEASURED;
float _accelX = APIS_NOT_MEASURED; // last reading, m/s^2
float _accelY = APIS_NOT_MEASURED;
float _accelZ = APIS_NOT_MEASURED;
float _magnitude = APIS_NOT_MEASURED; // burst mean, m/s^2
float _tilt = APIS_NOT_MEASURED; // burst mean, deg
// Range statistics
// Orientation statistics
// Readings behind the current statistics (set by updateMeasurements):
// one array per measurement, native type, oldest first, and the count
// of valid entries.
// One storage path: every acquisition appends here (updateDistance(),
// updateOrientation(), whether from updateMeasurements() or logReading());
// the statistics getters read the arrays; updateMeasurements() and
// beginReadings() start a fresh set. (NW_Core)
NW_Readings<int16_t, APIS_RANGE_CAPACITY> _distanceReadings;
NW_Readings<float, APIS_ORIENT_CAPACITY> _pitchReadings;
NW_Readings<float, APIS_ORIENT_CAPACITY> _rollReadings;
NW_Readings<float, APIS_ORIENT_CAPACITY> _magnitudeReadings;
NW_Readings<float, APIS_ORIENT_CAPACITY> _tiltReadings;
// LiDAR Lite signal strength; updated by updateDistance()
uint8_t _signalStrength = 0;
// Accelerometer temperature digits (relative); updated by updateOrientation()
int16_t _accelerometerTemp = APIS_NOT_MEASURED;
int16_t _zeroTemp = APIS_NOT_MEASURED;
// Zero generation carried by the last orientation reading (begin() seeds it
// from Page 1), and whether it moved between the last two readings
uint16_t _zeroGen = 0;
bool _zeroChanged = false;
// Sensor sensitivity; set initially to default "balanced" mode
SensitivityMode _sensitivity = SENSITIVITY_BALANCED;
// Chips covered by the current run of readings (beginReadings)
uint8_t _rawComponent = ALL;
};
// Deprecated component selectors (v0.1.x): the class-scoped Apis::ALL,
// Apis::RANGE, Apis::ORIENT replace them. Kept so existing sketches compile.
#ifndef NW_READING_ALL
#define NW_READING_ALL Apis::ALL
#define NW_READING_PRIMARY Apis::RANGE
#define NW_READING_SECONDARY Apis::ORIENT
#endif
#define NW_READING_RANGE NW_READING_PRIMARY
#define NW_READING_ORIENT NW_READING_SECONDARY
#define ADR_DEFAULT Apis::DEFAULT_ADDRESS
#endif
Updated on 2026-10-04 at 04:51:39 +0000