Skip to content

Troubleshooting

Symptoms you may see while bringing up an FDO2-G2, their causes and the fix for each.

Start with the DriverError of the failing call (fdo2::ToString(result.error)): Timeout points at wiring, baud rate or power; ProtocolError and CrcMismatch at what arrives on RX; DeviceError at the command, with the module's code in LastDeviceErrorCode().

No reply: every call returns Timeout

Cause Check Fix
TX and RX not crossed MCU TX must go to pin 3 (RXD), MCU RX to pin 2 (TXD) Swap the two lines, or the pins in your port
Wrong baud rate The module runs at 19200 after every power-up Set 19200, 8N1, no flow control
Module still booting First command less than 1 s after power-up Wait kFdo2G2PowerUpSettleMs (1100 ms)
No supply or no common ground VCC at pin 4 between 3.3 V and 5.0 V, GND shared with the MCU Fix the harness; a 40 mA peak must not pull VCC below 3.3 V
Port read() never returns a line A logic analyser shows the reply, but the call times out The port must return at the CR (Porting)
Only FlashLogo() times out The LED flashes, but the #LOGO echo comes about 1 s later Keep SetSlowCommandTimeoutMs() above 1000 ms (default 12000 ms)

Replies that do not parse: ProtocolError

Cause Check Fix
Broadcast mode left on #MRAW lines arrive without a command Send #BCST 0 once from a terminal; it is stored in flash
Port returns partial lines Errors come and go, worse at low timeouts; a line without its CR is rejected Return one whole line, CR included, per read()
Noise or a 5 V signal on RXD Garbled characters on a logic analyser Level-shift the MCU's TX; shorten or shield the cable

The datasheet's advice for a garbled reply is to send the command again.

Checksum errors: CrcMismatch

The module has the CRC on (#CRCE 1) and a reply's checksum did not match what arrived, or SetCrcRequired(true) is set and a reply came without one. A wrong checksum means the reply was corrupted on the line: send the command again, and look for noise or a level problem on RXD if it happens often. If every reply fails while the module's CRC is off, clear SetCrcRequired() (UART protocol).

DeviceError after #ERRO

Read LastDeviceErrorCode() right after the failing call. Codes -21, -22 and -23 are transmission errors: repeat the command. Code -26 means the module did not recognise the command. Any code not in the error table is potentially fatal: the datasheet says to replace the sensor and contact PyroScience.

Status is not 0 or 1

The call succeeded but MoxyStatusOkForOxygen() is false: do not use the oxygen or temperature reading.

Bit set Likely cause Fix
2 or 4 (signal or ambient light too high) Sunlight or a lamp on the sensing membrane Shade the sensor; check ambient_light_mv with #MRAW
1 or 3 (signal too low) Membrane damaged or contaminated, condensation Inspect the membrane; keep the dew point out of it
5 (temperature sensor) Sensor fault Replace the sensor
7 (humidity above 90 %RH, warning) Moisture reaching the housing through the back side Keep the back side dry and non-condensing
9 or 10 (pressure or humidity sensor) Housing sensor fault; pO2 still valid MoxyStatusOkForOxygen() rejects these too; decide in your code whether to accept pO2

The reading is plausible but off

Symptom Cause Fix
Drifts during the first minutes Warm-up: 3 min to full accuracy Discard readings for 3 min after power-up
Volume percent wrong while pO2 is right The membrane and the back of the housing are at different pressures Compute % O2 from a pressure measured at the membrane
Extra noise at one or two temperatures between 8 °C and 15 °C Firmware 3.55 erratum Firmware 3.57 fixes it; #SETM trades noise for drift (Hardware)
Readings creep after exposure to solvents, NO2, Cl2 or heat above 60 °C Cross-sensitivity or ageing See section 3 of the datasheet; recalibrate or replace

Calls take longer than the measurement

Each MeasureMoxy() takes the full timeout (250 ms by default) instead of about 150 ms: the port's read() waits for max bytes or for the timeout instead of returning at the CR. Use the line-based port on Porting, or the ESP32 example port, which returns at the CR.

Still stuck

Open an issue with a capture of the UART traffic, the #VERS reply (firmware revision) and the driver version from fdo2::GetDriverVersion().