One NW Schema 1 device on the I2C bus: identity gates, the reading handshake, batches, faults. More…

#include <NW_Device.h>

Public Functions

  Name
bool begin(uint8_t address, const char * name, uint8_t minPatch, unsigned long bootTimeoutMs =0)
Open the device and check that it is what the library expects.
String beginFailure() const
Why the last begin() refused, as one word for a data-table note: “NotAnswering”, “ReadFailed”, “NotSchema1”, “WrongName”, “OldFirmware”; “None” after a successful begin().
uint8_t address() const
uint8_t hardwareMajor() const
uint8_t hardwareMinor() const
uint8_t firmwareVersion() const
bool setI2CAddress(uint8_t newAddress)
Write a new I2C address to Page 0 (0x1F); the device uses it from its next boot.
size_t printSnapshot(Print & out, const char *const * chipNames, uint8_t nChips, bool boot =false, const char * lib =””, const char * libCommit =””)
Print one status line for a logger’s status file: the device as it is now.
void setTimeout(unsigned long ms)
Ceiling on the wait for a reading [ms]. Not a delay: waitReading() returns as soon as the counter moves. Must exceed the device’s slowest path to ready, which is its fault path (see the device appendix); default 500.
unsigned long timeout() const
bool ready()
Status bit 0: the data registers hold a complete reading.
uint16_t readCounter()
The reading counter (0x42-0x43).
bool newReading()
The counter differs from the last captured reading’s (true before any capture).
bool requestReading(uint8_t chips)
Trigger a reading of the given chips.
bool waitReading()
Wait until the counter moves past the value seen at the last request (or the last capture), within timeout().
bool captureReading()
Read Block 0 after a reading: status and the Report register into report(); notes the counter.
bool takeReading(uint8_t chips)
requestReading() + waitReading() + captureReading(). false on bus error or timeout.
bool writeBatch(uint16_t n)
Declare how many readings follow, so the device holds its chips powered for exactly that many.
void resetBatch()
Forget a previous batch’s absent chips without writing the size (single readings).
bool beginBatch(uint16_t n)
Start a batch of n readings: writeBatch(n) when n > 1, else resetBatch().
template <typename F >
uint16_t
takeReadings(uint8_t chips, uint16_t n, F readOne)
Take up to n readings of the given chips, one at a time, through readOne().
bool batchFaulted(uint8_t chips =0x3F) const
Any of the given chips reported, earlier in this batch, that it is not coming (no acknowledge or not initialised). Per chip: an absent accelerometer does not stop the range readings of the same batch.
const NW_Report & report() const
bool faulted(uint8_t chip) const
bool anyFault() const
uint8_t reportChip() const
uint8_t reportKind() const
bool readBytes(uint8_t reg, uint8_t * buf, uint8_t n)
Read n bytes from reg; reads longer than NW_WIRE_CHUNK are split into several transactions.
bool readData(uint8_t reg, uint8_t * buf, uint8_t n)
Read a reading’s data registers and check that they belong to the captured reading.
bool dataMoved() const
The last readData() gave up: the device committed a new reading during every attempt.
const NW_Report & bootReport() const
The report begin() captured before the first trigger cleared it (unit reset 0xE6, Page 0 check 0xE3, …), kept until clearBootReport(); code 0 once cleared or if none.
void clearBootReport()
bool writeByte(uint8_t reg, uint8_t value)
uint8_t readConfig()
bool writeConfig(uint8_t value)
bool sleep()
Ask the device to enter its lowest-power state (Control bit 7); it wakes on its next address match.

Detailed Description

class NW_Device;

One NW Schema 1 device on the I2C bus: identity gates, the reading handshake, batches, faults.

A sensor library holds one of these and forwards to it. The handshake is three steps so that a library can trigger a reading and come back for it later: requestReading(chips), waitReading(), captureReading(); takeReading(chips) does all three. Readings started by the device itself (a free-running device) are seen through the counter: newReading() and waitReading() work without a request.

Public Functions Documentation

function begin

bool begin(
    uint8_t address,
    const char * name,
    uint8_t minPatch,
    unsigned long bootTimeoutMs =0
)

Open the device and check that it is what the library expects.

Parameters:

  • address 7-bit I2C address
  • name the device’s name as the spec spells it (up to 7 characters)
  • minPatch lowest firmware patch (Page 0 byte 0x0A) this library accepts
  • bootTimeoutMs how long to keep retrying the first acknowledge (0 = one try)

Return: true if the device answered and passed the three gates

Starts Wire, waits for an acknowledge at the address for up to bootTimeoutMs (a logger often calls begin() the instant it powers the sensor rail), reads Page 0 bytes 0x00-0x0F, stores the hardware and firmware versions, then refuses the device unless the schema byte is 0x01, the 7-byte name matches, and the firmware patch is at least minPatch. The versions are stored before any refusal so a sketch can report why. Then reads Block 0 once, before any write, so the reports the device made at boot (reset, invalid Page 0) are in report() before the first trigger acknowledges them.

function beginFailure

String beginFailure() const

Why the last begin() refused, as one word for a data-table note: “NotAnswering”, “ReadFailed”, “NotSchema1”, “WrongName”, “OldFirmware”; “None” after a successful begin().

function address

inline uint8_t address() const

function hardwareMajor

inline uint8_t hardwareMajor() const

function hardwareMinor

inline uint8_t hardwareMinor() const

function firmwareVersion

inline uint8_t firmwareVersion() const

function setI2CAddress

bool setI2CAddress(
    uint8_t newAddress
)

Write a new I2C address to Page 0 (0x1F); the device uses it from its next boot.

function printSnapshot

size_t printSnapshot(
    Print & out,
    const char *const * chipNames,
    uint8_t nChips,
    bool boot =false,
    const char * lib ="",
    const char * libCommit =""
)

Print one status line for a logger’s status file: the device as it is now.

Parameters:

  • chipNames the device’s chip table for the note word; nullptr for “ChipN”
  • boot print the boot report (bootReport()) in the code and note columns instead of report()
  • lib the version of the library that read the device (its _LIBRARY_VERSION)
  • libCommit that library’s build commit (_LIBRARY_COMMIT; blank in an IDE build)

Return: bytes written

Columns, comma separated, no newline: name, serial (Page 0 Block 2 as four hex groups), HW version (major.minor), FW patch, FW build commit (Page 0 bytes 0x18-0x1B as 8 hex characters, “+” appended when 0x1C bit 0 says the tree was dirty; blank when the firmware carried none), the library’s version and commit as given, the last report captured as code (0xNN) and as note word, then Pages 0, 1 and 2 as hex, each page four 8-byte blocks with a space between them. One value per column, so a logger’s status file is a table: Time,Trigger,Device,Serial,HW,FW,FWCommit,Lib,LibCommit,Code,Note,Page0,Page1,Page2. Three page reads, no write: the report is not acknowledged. A logger prints its timestamp, calls this, ends the line. Meant for whenever reportKind() is not zero, and for any moment worth a record (boot, a visit).

function setTimeout

inline void setTimeout(
    unsigned long ms
)

Ceiling on the wait for a reading [ms]. Not a delay: waitReading() returns as soon as the counter moves. Must exceed the device’s slowest path to ready, which is its fault path (see the device appendix); default 500.

function timeout

inline unsigned long timeout() const

function ready

bool ready()

Status bit 0: the data registers hold a complete reading.

function readCounter

uint16_t readCounter()

The reading counter (0x42-0x43).

function newReading

bool newReading()

The counter differs from the last captured reading’s (true before any capture).

function requestReading

bool requestReading(
    uint8_t chips
)

Trigger a reading of the given chips.

Parameters:

  • chips bit n = chip n (0..5); the control byte gets trigger chips « 1

function waitReading

bool waitReading()

Wait until the counter moves past the value seen at the last request (or the last capture), within timeout().

function captureReading

bool captureReading()

Read Block 0 after a reading: status and the Report register into report(); notes the counter.

function takeReading

bool takeReading(
    uint8_t chips
)

requestReading() + waitReading() + captureReading(). false on bus error or timeout.

function writeBatch

bool writeBatch(
    uint16_t n
)

Declare how many readings follow, so the device holds its chips powered for exactly that many.

Also clears batchFaulted(). 0 or 1 means one reading per trigger, powered down after each.

function resetBatch

inline void resetBatch()

Forget a previous batch’s absent chips without writing the size (single readings).

function beginBatch

inline bool beginBatch(
    uint16_t n
)

Start a batch of n readings: writeBatch(n) when n > 1, else resetBatch().

Return: false if the batch word could not be written

The library’s loop then calls takeReading() n times, appending each successful reading to its NW_Readings, and stops early on batchFaulted(chips). One reading is a batch of one (n = 0 or 1), which writes nothing to the device.

function takeReadings

template <typename F >
inline uint16_t takeReadings(
    uint8_t chips,
    uint16_t n,
    F readOne
)

Take up to n readings of the given chips, one at a time, through readOne().

Return: how many calls to readOne() returned true

beginBatch(n), then readOne() n times; stops early once a selected chip has reported absent (batchFaulted(chips)), so a dead chip costs one reading, not n. readOne is any callable returning bool: true when it stored a reading (a library’s updateRange(), updatePressure(), …).

function batchFaulted

inline bool batchFaulted(
    uint8_t chips =0x3F
) const

Any of the given chips reported, earlier in this batch, that it is not coming (no acknowledge or not initialised). Per chip: an absent accelerometer does not stop the range readings of the same batch.

Parameters:

  • chips bit n = chip n; default: any chip

Set by captureReading() for a selected chip; a library skips that chip’s remaining readings instead of waiting out each one.

function report

inline const NW_Report & report() const

function faulted

inline bool faulted(
    uint8_t chip
) const

function anyFault

inline bool anyFault() const

function reportChip

inline uint8_t reportChip() const

function reportKind

inline uint8_t reportKind() const

function readBytes

bool readBytes(
    uint8_t reg,
    uint8_t * buf,
    uint8_t n
)

Read n bytes from reg; reads longer than NW_WIRE_CHUNK are split into several transactions.

function readData

bool readData(
    uint8_t reg,
    uint8_t * buf,
    uint8_t n
)

Read a reading’s data registers and check that they belong to the captured reading.

Return: true with buf holding one complete reading, the one report() describes

The device commits data and counter together with interrupts off, and serves each page as a snapshot (NW-Device-Specification, atomic rewrite), but nothing stops it committing between two of the controller’s transactions: a free-running device can do so, and a read longer than NW_WIRE_CHUNK is several transactions. So: readBytes(), then the counter again. Equal to the counter captureReading() saw, every byte is that reading’s. Otherwise capture the new Block 0 and read again, at most NW_DATA_RETRIES times, then give up with dataMoved() set, so a device that commits faster than it can be read never holds the controller. Use it for the data after takeReading() or captureReading(); readBytes() is for Page 0 and single registers.

function dataMoved

inline bool dataMoved() const

The last readData() gave up: the device committed a new reading during every attempt.

function bootReport

inline const NW_Report & bootReport() const

The report begin() captured before the first trigger cleared it (unit reset 0xE6, Page 0 check 0xE3, …), kept until clearBootReport(); code 0 once cleared or if none.

function clearBootReport

inline void clearBootReport()

function writeByte

bool writeByte(
    uint8_t reg,
    uint8_t value
)

function readConfig

uint8_t readConfig()

function writeConfig

inline bool writeConfig(
    uint8_t value
)

function sleep

inline bool sleep()

Ask the device to enter its lowest-power state (Control bit 7); it wakes on its next address match.


Updated on 2026-09-23 at 22:42:22 +0000