Skip to content

Gases and part families

Which gas tables each part carries, why the driver needs to know the part before it starts some gases, and how the SF06 and SFx6000 families differ.

Gas tables by variant

A thermal flow sensor is calibrated per gas. Measuring CO2 with the air table gives a reading that is plausible and wrong. The driver therefore refuses a gas the known variant is not calibrated for, with DriverError::UnsupportedGas.

Variant Range Calibrated gases
SFM4300-20-B, -O, -P 0 to 20 slm O2, air, N2O, CO2, air/O2, N2O/O2, CO2/O2
SFM4300-50-B, -O, -P 0 to 50 slm O2, air, air/O2
SFM3003-300-CL, -CE -30 (CE: -150) to 300 slm O2, air, air/O2
SFM3013-300-CL -30 to 300 slm O2, air, air/O2
SFM3013-300-CLM -30 to 300 slm O2, air, air/O2, HeOx 80/20, HeOx/O2
SFM3019 -10 to 240 slm O2, air, air/O2
SFM3119-240-CL -10 to 240 slm O2, air, air/O2
SFM6000D-50, -20, -5 50, 20, 5 slm (air, O2) O2, air, N2O, CO2, Ar, air/O2
Unknown O2, air

The SF06 rows come from each part's datasheet (sections 2.1, 4.3.1 and 4.5). On the SFM3013-300-CLM the codes 0x3615 and 0x3639 select HeOx and HeOx/O2 (Gas::HeOx, Gas::HeOxO2Mix), not N2O. sfm::SupportsGas() encodes the table; sfm::FullScaleSlm() gives the air / O2 full scale of a known variant.

Why the part has to be known

The two families share the framing and most command codes, but two start codes mean different gases:

Start code SF06 (SFM4300, SFM3xxx) SFx6000 (SFM6000D)
0x3603 O2 O2
0x3608 Air Air
0x3615 N2O CO2
0x361E CO2 N2O

So until the driver knows the family, it starts only O2 and air, the two codes that mean the same gas on both. Any other gas returns DriverError::VariantUnknown. Learn the part in one of two ways:

  • ReadProductIdentifier(), in idle mode: it decodes the variant and sets the family.
  • AssumeVariant(), when the identifier cannot be read (the sensor is already measuring) and the board fixes the part (Configuration).

The constructor's family argument only sets the assumption used before either of those.

Never pick a start code yourself: sfm::StartCommandFor(family, gas) returns the right one, and a static_assert in the header pins the CO2 codes of both families.

SF06 and SFx6000 compared

SF06 SFx6000
Parts SFM4300, SFM3003, SFM3013, SFM3019, SFM3119 SFM6000D
Measurement frame flow, temperature, status flow, reserved, status
Temperature In every frame ReadTemperature(), through an output-buffer pointer
Sample period 0.5 ms 1 ms
Scaling read Three words Five words through pointer 0xE151: adds full-scale flow and the SEMI gas ID
Averaging, sleep Yes No: ConfigureAveraging(), EnterSleep(), ExitSleep() return NotSupported
Soft-reset wait 20 ms 30 ms
Default address 0x2A (SFM4300) 0x24

The SFx6000 values come from Sensirion's SFC6xxx / SFM6xxx I2C interface reference (v1.1), as implemented in inc/sfm_commands.hpp. The SFM6000D product identifiers are preliminary in that document; the driver decodes 0x060211xx, 0x060212xx and 0x060214xx.

Other SF06 parts

SFM3003, SFM3013, SFM3019 and SFM3119 speak the same command set at their own addresses (sfm::addr). Pass the part's address to the constructor (for example sfm::addr::kSfm3019); ReadProductIdentifier() then decodes the variant from the product numbers in each datasheet:

Product number Variant sfm::Variant Address
0x040201xx SFM3003-300-CL Sfm3003_300_CL 0x28
0x040207xx SFM3003-300-CE Sfm3003_300_CE 0x2D
0x040205xx SFM3013-300-CL Sfm3013_300_CL 0x2F
0x040202xx SFM3013-300-CLM Sfm3013_300_CLM 0x2F
0x040206xx SFM3019 Sfm3019_240 0x2E
0x040401xx SFM3119-240-CL Sfm3119_240_CL 0x29

The scale factor (170 per slm on these parts, offset -24576) is read from the sensor as on the SFM4300.

Next: API guide.