Alicat BASIS-2 Driver 1.0.0
API reference
Loading...
Searching...
No Matches
Public Member Functions | List of all members
alicat_basis2::Driver< UartT > Class Template Reference

Main BASIS-2 driver. More...

#include <alicat_basis2.hpp>

Public Member Functions

 Driver (UartT &uart, uint8_t address, uint16_t timeout_ms=kDefaultTimeoutMs) noexcept
 Construct a driver bound to one bus + one slave address.
 
 Driver (const Driver &)=delete
 
Driver & operator= (const Driver &)=delete
 
void SetTimeoutMs (uint16_t ms) noexcept
 Update the per-transaction timeout (ms).
 
uint16_t GetTimeoutMs () const noexcept
 
void SetBusBaudRate (uint32_t bps) noexcept
 Tell the driver the bus baud rate (default 38400, the factory rate).
 
uint32_t GetBusBaudRate () const noexcept
 
uint32_t GetInterFrameGapUs () const noexcept
 
void SetAddress (uint8_t addr) noexcept
 Switch the slave address this driver targets at runtime.
 
uint8_t GetAddress () const noexcept
 
DriverResult< InstantaneousData > ReadInstantaneous (uint8_t flow_decimals=3) noexcept
 Read all instantaneous registers (2100..2109) in one burst.
 
DriverResult< InstrumentIdentity > ReadIdentity () noexcept
 Pull the static identification of the instrument.
 
DriverResult< void > SetSetpoint (float value_in_user_units, uint8_t flow_decimals=3) noexcept
 Set the digital setpoint (controllers only).
 
DriverResult< void > SetSetpointSource (SetpointSource src) noexcept
 Switch the setpoint source (controllers only).
 
DriverResult< void > SetCommWatchdogMs (uint16_t ms) noexcept
 Configure the communication watchdog (controllers only).
 
DriverResult< void > SetMaxSetpointRamp (uint32_t pct_per_ms_x_10e7) noexcept
 
DriverResult< void > Tare () noexcept
 Force a tare (zero-flow reference) on the instrument.
 
DriverResult< void > SetAutotareEnabled (bool enabled) noexcept
 Enable / disable automatic taring (controllers only).
 
DriverResult< void > SetGas (Gas g) noexcept
 Select one of the 9 factory-calibrated gases.
 
DriverResult< void > ResetTotalizer () noexcept
 Reset the totalizer to zero.
 
DriverResult< void > SetTotalizerLimitMode (TotalizerLimitMode mode) noexcept
 Configure totalizer overflow behaviour.
 
DriverResult< void > SetTotalizerBatch (uint32_t value_scaled) noexcept
 Set the totalizer batch volume (controllers only).
 
DriverResult< void > SetFlowAveragingMs (uint16_t ms) noexcept
 Configure on-chip flow averaging (IIR-style time constant).
 
DriverResult< void > SetReferenceTemperatureC (float c) noexcept
 Set the reference temperature used for standard / normal flow.
 
DriverResult< void > ConfigureMeasurementTrigger (uint16_t trigger_bits) noexcept
 Configure when a new measurement window auto-restarts.
 
DriverResult< void > StartMeasurementSamples (uint16_t num_samples) noexcept
 Start a measurement window of num_samples samples.
 
DriverResult< MeasurementData > ReadMeasurement (uint8_t flow_decimals=3) noexcept
 Read the current / most-recent measurement window result.
 
DriverResult< void > SetModbusAddress (uint8_t new_address) noexcept
 Change the instrument's Modbus slave address.
 
DriverResult< void > SetAsciiUnitId (char id) noexcept
 Change the instrument's ASCII unit-id (used by the legacy ASCII serial protocol).
 
DriverResult< void > SetBaudRate (BaudRate br) noexcept
 Change the serial baud rate (instrument register 21).
 
DriverResult< void > FactoryRestore () noexcept
 Restore the instrument to factory defaults.
 
DriverResult< uint8_t > DiscoverPresentAddresses (uint8_t *present_bitmap, std::size_t bitmap_bytes, uint16_t probe_timeout_ms=30, uint8_t first_addr=1, uint8_t last_addr=kMaxModbusAddress) noexcept
 Probe the entire bus to find which addresses respond.
 
DriverError ReadHoldingRegisters (uint16_t reg_addr, uint16_t *out, uint8_t count) noexcept
 Function 03: read count holding registers starting at reg_addr.
 
DriverResult< void > WriteSingleRegister (uint16_t reg_addr, uint16_t value) noexcept
 Function 06: write one holding register.
 
DriverResult< void > WriteMultipleRegisters (uint16_t reg_addr, const uint16_t *regs, uint8_t count) noexcept
 Function 16: write count (1..32) consecutive holding registers.
 
ModbusExceptionCode GetLastException () const noexcept
 Exception code of the last transaction's exception reply.
 

Detailed Description

template<typename UartT>
class alicat_basis2::Driver< UartT >

Main BASIS-2 driver.

Template Parameters
UartTConcrete CRTP adapter inheriting UartInterface<UartT>.

The driver instance corresponds to one Modbus address on the shared RS-485 bus. Multiple driver instances can share the same UART adapter for different addresses; the host is responsible for serialising bus access (the hf-core handler wraps this in an RtosMutex).

Constructor & Destructor Documentation

◆ Driver() [1/2]

template<typename UartT >
alicat_basis2::Driver< UartT >::Driver ( UartT &  uart,
uint8_t  address,
uint16_t  timeout_ms = kDefaultTimeoutMs 
)
inlinenoexcept

Construct a driver bound to one bus + one slave address.

Parameters
uartReference to a CRTP adapter; must outlive Driver.
addressModbus address (1..247) of this slave. Use kBroadcastAddress (0) for unaddressed broadcast writes (response-less).
timeout_msPer-transaction response timeout (datasheet default ~200 ms is safe).

◆ Driver() [2/2]

template<typename UartT >
alicat_basis2::Driver< UartT >::Driver ( const Driver< UartT > &  )
delete

Member Function Documentation

◆ ConfigureMeasurementTrigger()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::ConfigureMeasurementTrigger ( uint16_t  trigger_bits)
inlinenoexcept

Configure when a new measurement window auto-restarts.

Parameters
trigger_bitsOR-combination of MeasurementTrigger::* flags (OnDigitalSetpointChange, OnHoldPercentChange, OnAverageFlowRead). 0 disables auto-trigger.
Returns
Success or transport / Modbus error.

◆ DiscoverPresentAddresses()

template<typename UartT >
DriverResult< uint8_t > alicat_basis2::Driver< UartT >::DiscoverPresentAddresses ( uint8_t *  present_bitmap,
std::size_t  bitmap_bytes,
uint16_t  probe_timeout_ms = 30,
uint8_t  first_addr = 1,
uint8_t  last_addr = kMaxModbusAddress 
)
inlinenoexcept

Probe the entire bus to find which addresses respond.

Parameters
[out]presentBitmap; bit N → instrument at address N.
probe_timeout_msPer-address timeout (defaults to short).
first_addr/ last_addr Sweep window (default full 1..247).

Issues a Function-03 read of register 25 (firmware version) to every address in [first_addr, last_addr]. Restores this driver's saved address on exit.

◆ FactoryRestore()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::FactoryRestore ( )
inlinenoexcept

Restore the instrument to factory defaults.

Writes the magic value 0x5214 to register 80. The datasheet recommends a power-cycle afterwards to make sure every cached value picks up the reset.

Returns
Success or transport / Modbus error.

◆ GetAddress()

template<typename UartT >
uint8_t alicat_basis2::Driver< UartT >::GetAddress ( ) const
inlinenoexcept
Returns
Current Modbus slave address (1..247) this driver is talking to.

◆ GetBusBaudRate()

template<typename UartT >
uint32_t alicat_basis2::Driver< UartT >::GetBusBaudRate ( ) const
inlinenoexcept
Returns
Bus baud rate used for the inter-frame gap.

◆ GetInterFrameGapUs()

template<typename UartT >
uint32_t alicat_basis2::Driver< UartT >::GetInterFrameGapUs ( ) const
inlinenoexcept
Returns
The idle gap left before each request, in microseconds (before rounding to ms).

◆ GetLastException()

template<typename UartT >
ModbusExceptionCode alicat_basis2::Driver< UartT >::GetLastException ( ) const
inlinenoexcept

Exception code of the last transaction's exception reply.

Returns
The code when the last request got an exception reply (the call returned DriverError::ModbusException), ModbusExceptionCode::None otherwise. Reset at the start of every request.

◆ GetTimeoutMs()

template<typename UartT >
uint16_t alicat_basis2::Driver< UartT >::GetTimeoutMs ( ) const
inlinenoexcept
Returns
Current per-transaction timeout in milliseconds.

◆ operator=()

template<typename UartT >
Driver & alicat_basis2::Driver< UartT >::operator= ( const Driver< UartT > &  )
delete

◆ ReadHoldingRegisters()

template<typename UartT >
DriverError alicat_basis2::Driver< UartT >::ReadHoldingRegisters ( uint16_t  reg_addr,
uint16_t *  out,
uint8_t  count 
)
inlinenoexcept

Function 03: read count holding registers starting at reg_addr.

Returns
None, or the transaction's error. An exception reply returns ModbusException as soon as its 5 bytes arrived; its code is in GetLastException().

◆ ReadIdentity()

template<typename UartT >
DriverResult< InstrumentIdentity > alicat_basis2::Driver< UartT >::ReadIdentity ( )
inlinenoexcept

Pull the static identification of the instrument.

Reads firmware version (reg 25), serial number (regs 26..31), Modbus address (reg 45), ASCII unit id (reg 46), full-scale flow in user units (regs 47..48) and the flow-units code (reg 49).

Returns
DriverResult<InstrumentIdentity> populated with all of the above on success; transport / Modbus error otherwise.

◆ ReadInstantaneous()

template<typename UartT >
DriverResult< InstantaneousData > alicat_basis2::Driver< UartT >::ReadInstantaneous ( uint8_t  flow_decimals = 3)
inlinenoexcept

Read all instantaneous registers (2100..2109) in one burst.

This is the canonical "live data" call — one round-trip on the bus, decoded into engineering units using the flow_decimals factor read once from the instrument.

Parameters
flow_decimalsThe factory-set number of decimals reported on this instrument's flow register; pulled at init time via ReadIdentity().
Returns
DriverResult<InstantaneousData> — value carries the decoded snapshot on success, error is DriverError::None. On failure value is default-constructed and error carries the underlying transport / Modbus error.

◆ ReadMeasurement()

template<typename UartT >
DriverResult< MeasurementData > alicat_basis2::Driver< UartT >::ReadMeasurement ( uint8_t  flow_decimals = 3)
inlinenoexcept

Read the current / most-recent measurement window result.

One request reads registers 4201..4215 (manual Rev 4, "Measurement Data Registers", pp. 22-23). The previous window's average flow is the signed 32-bit value at 4214-4215, high register first.

Parameters
flow_decimalsThe instrument's factory-set flow decimals, used for avg_flow (as in ReadInstantaneous()).
Returns
DriverResult<MeasurementData> populated with min / max / average temperature and flow on success; transport / Modbus error on failure.
Note
With MeasurementTrigger::OnAverageFlowRead set, reading the low register 4215 starts the next measurement window.

◆ ResetTotalizer()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::ResetTotalizer ( )
inlinenoexcept

Reset the totalizer to zero.

Writes 0xAA55 to register 53. Total volume since the last power-up / reset is cleared and any active totalizer-overrange (OVR) bit is also dropped.

Returns
Success or transport / Modbus error.

◆ SetAddress()

template<typename UartT >
void alicat_basis2::Driver< UartT >::SetAddress ( uint8_t  addr)
inlinenoexcept

Switch the slave address this driver targets at runtime.

◆ SetAsciiUnitId()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetAsciiUnitId ( char  id)
inlinenoexcept

Change the instrument's ASCII unit-id (used by the legacy ASCII serial protocol).

Parameters
idA capital letter ‘'A’..'Z'. @return Success or transport / Modbus error; DriverError::InvalidParameterifidis outsideA..Z`.

◆ SetAutotareEnabled()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetAutotareEnabled ( bool  enabled)
inlinenoexcept

Enable / disable automatic taring (controllers only).

When enabled, the instrument tares automatically after the setpoint has been at 0 for at least two seconds.

Parameters
enabledtrue to enable autotare, false to disable.
Returns
Success or transport / Modbus error.

◆ SetBaudRate()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetBaudRate ( BaudRate  br)
inlinenoexcept

Change the serial baud rate (instrument register 21).

Warning
The instrument switches to the new baud immediately after ack'ing the write. The host must reconfigure its UART to match before the next transaction. Per the datasheet this is a fundamentally racy operation; the host should:
  1. Issue this command,
  2. Drain the response on the OLD baud,
  3. Reconfigure its UART to the NEW baud,
  4. (Optional) Issue an identity read to confirm.

After the write the driver uses the new rate for its inter-frame gap (SetBusBaudRate()), whatever the result: the instrument switches as soon as it receives the request.

◆ SetBusBaudRate()

template<typename UartT >
void alicat_basis2::Driver< UartT >::SetBusBaudRate ( uint32_t  bps)
inlinenoexcept

Tell the driver the bus baud rate (default 38400, the factory rate).

Only used for the Modbus-RTU inter-frame gap: before every request the driver waits modbus::InterFrameGapMs(bps) through the port's delay_ms() (3.5 characters, 1.75 ms above 19200 baud; Modbus over Serial Line V1.02 section 2.5.1.1), so the request cannot start inside the idle gap that ends the previous frame. SetBaudRate() updates it. Several drivers on one port: set it on each.

◆ SetCommWatchdogMs()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetCommWatchdogMs ( uint16_t  ms)
inlinenoexcept

Configure the communication watchdog (controllers only).

Parameters
ms0..5000 ms; 0 disables. The instrument forces a zero setpoint and closes the valve if no Modbus traffic is seen within this window when the setpoint source is DigitalUnsaved (see datasheet "Communication Watchdog").
Returns
Success or transport / Modbus error; DriverError::InvalidParameter if ms > 5000.

◆ SetFlowAveragingMs()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetFlowAveragingMs ( uint16_t  ms)
inlinenoexcept

Configure on-chip flow averaging (IIR-style time constant).

Parameters
msTime constant in milliseconds, 0..2500. Higher values smooth fluctuations at the cost of response.
Returns
Success or DriverError::InvalidParameter if ms > 2500.

◆ SetGas()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetGas ( Gas  g)
inlinenoexcept

Select one of the 9 factory-calibrated gases.

Parameters
gOne of Gas::Air / Argon / CarbonDioxide / Nitrogen / Oxygen / NitrousOxide / Hydrogen / Helium / Methane.
Returns
Success or transport / Modbus error.

◆ SetMaxSetpointRamp()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetMaxSetpointRamp ( uint32_t  pct_per_ms_x_10e7)
inlinenoexcept

◆ SetModbusAddress()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetModbusAddress ( uint8_t  new_address)
inlinenoexcept

Change the instrument's Modbus slave address.

Parameters
new_addressNew slave address, 1..247 (kMaxModbusAddress).
Returns
Success or transport / Modbus error; DriverError::InvalidAddress if new_address is outside the legal range.
Note
After the slave acknowledges, this driver instance switches its target address automatically; subsequent calls keep working without further changes.

◆ SetReferenceTemperatureC()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetReferenceTemperatureC ( float  c)
inlinenoexcept

Set the reference temperature used for standard / normal flow.

Parameters
cTemperature in °C, 0..30.
Returns
Success or DriverError::InvalidParameter if out of range.

◆ SetSetpoint()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetSetpoint ( float  value_in_user_units,
uint8_t  flow_decimals = 3 
)
inlinenoexcept

Set the digital setpoint (controllers only).

Writes the signed 32-bit setpoint to registers 2053..2054. The datasheet defines the on-the-wire scaling as value × 1000 so the host passes the engineering value (e.g. 12.5 SLPM) and the driver does the multiplication.

Parameters
value_in_user_unitsReal setpoint, e.g. 12.5 SLPM.
flow_decimalsNumber of decimals for this instrument (call ReadIdentity once and cache).
Returns
DriverResult<void> — success or a Modbus / transport error. A meter (non-controller) instrument will return DriverError::ModbusException.

◆ SetSetpointSource()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetSetpointSource ( SetpointSource  src)
inlinenoexcept

Switch the setpoint source (controllers only).

Parameters
srcAnalog input pin / digital saved-to-flash / digital volatile.
Returns
Success or transport / Modbus error.

◆ SetTimeoutMs()

template<typename UartT >
void alicat_basis2::Driver< UartT >::SetTimeoutMs ( uint16_t  ms)
inlinenoexcept

Update the per-transaction timeout (ms).

◆ SetTotalizerBatch()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetTotalizerBatch ( uint32_t  value_scaled)
inlinenoexcept

Set the totalizer batch volume (controllers only).

Once the totalizer reaches the batch volume the controller closes the valve. Pass the value already pre-scaled per the instrument's factory-set decimal count.

Parameters
value_scaledBatch volume × 10^decimals (per datasheet).
Returns
Success or transport / Modbus error.

◆ SetTotalizerLimitMode()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::SetTotalizerLimitMode ( TotalizerLimitMode  mode)
inlinenoexcept

Configure totalizer overflow behaviour.

Parameters
modeSaturateNoError / ResetNoError / SaturateWithOvr / ResetWithOvr.
Returns
Success or transport / Modbus error.

◆ StartMeasurementSamples()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::StartMeasurementSamples ( uint16_t  num_samples)
inlinenoexcept

Start a measurement window of num_samples samples.

Each sample is taken at approximately a 2.5 ms interval. Writing the register cancels any in-progress window and shifts the accumulated data into the "previous measurement" slot.

Parameters
num_samplesNumber of samples to collect (unsigned 16-bit).
Returns
Success or transport / Modbus error.

◆ Tare()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::Tare ( )
inlinenoexcept

Force a tare (zero-flow reference) on the instrument.

Writes the magic value 0xAA55 to register 39. The instrument must be exposed to true zero flow with the actual process gas in the line for the result to be in-spec.

Returns
Success or transport / Modbus error.

◆ WriteMultipleRegisters()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::WriteMultipleRegisters ( uint16_t  reg_addr,
const uint16_t *  regs,
uint8_t  count 
)
inlinenoexcept

Function 16: write count (1..32) consecutive holding registers.

Returns
Success, or the transaction's error. An exception reply returns ModbusException as soon as its 5 bytes arrived; its code is in GetLastException().

◆ WriteSingleRegister()

template<typename UartT >
DriverResult< void > alicat_basis2::Driver< UartT >::WriteSingleRegister ( uint16_t  reg_addr,
uint16_t  value 
)
inlinenoexcept

Function 06: write one holding register.

Returns
Success, or the transaction's error. An exception reply returns ModbusException as soon as its 5 bytes arrived; its code is in GetLastException().

The documentation for this class was generated from the following file: