Wideband Oxygen Sensor Controller Report Jan. 20, 2014

Author: Karl Walter www.waltech.com

Target audience: Someone who wants learn about the details of controlling a Bosch wideband oxygen sensor, build and test a control circuit, then make improvements. Also anybody looking to make a simple shield for Arduino, or other educational microcontroller platform.


Several years ago we decided to offer an Open Design. We chose to build a controller for a wide band oxygen sensor because there didn’t seem to be a fully open microprocessor based design available on the Internet. After studying what we could find on the subject, we chose to investigate what can be achieved with a simple circuit and a common microcontroller.

With the information presented here, you can build a controller circuit that will function, and can be a useful tuning or diagnostic tool. We encourage building this circuit as an educational tool, or as a starting point to an improved version.

There are many possible higher performance components that can be used, but we feel building and characterizing this circuit first is crucial to making decisions about improvements. See recommended follow-up work section below.

Building this circuit is probably not substitute for purchasing a commercial device. Since we started this project, commercial controllers have come down in price and performance has improved. In it’s current form, response time, accuracy, and precision are not competitive with higher-end controllers.

Function Overview and Definitions:

Sensor: Bosch LSU 4.2.

The sensor has three elements that the controller interacts with.

The heater is straightforward: apply power and it warms the sensor.

The Pump transports oxygen into or out of the nernst cell area, depending on the direction of current flowing through it.

The Nernst cell is much like a narrow band sensor, it puts out about 0.45 volts when it is in a stoichiometric atmosphere.


By applying power to the Pump, the controller can move oxygen into or out of the cell until the Nernst respondes, indicating it is nearing stoichiometric. The Pump current is then measured and compared to the response curve provided by Bosch to determine the exhaust gas mixture ratio.

Vref is a common connection for the Pump and the Nernst cell. It can be ground, but then negative voltages must be generated in order to provide current to the Pump in both directions. in a 5 volt system, 1.8 volts provides the Pump with enough negative current for full range of operation, and still leave enough positive range to be able to measure the Nernst cell’s output.

There is also an Rcal terminal, that provides a factory trim resistor that can be used in parallel to the recommended series resistor for measuring the Pump current.

Some definitions, as applies to the methods we have used in our controller:

PWM: Pulse Width Modulated: This method is used to control the Heater power, as well as the analog signals for Pump current and user output voltage.

DAC: Digital to Analog Converter: We used PWM and a low pass filter to create analog signals.

ADC: Analog to Digital Converter: The microcontroller used has an 8 channel, 10 bit ADC. 2 channels are used to read the Nernst output, and the Pump current.

Exhaust Gasses: We refer to the tested gas stream, whether it be wood smoke, ambient air, or internal combustion engine exhaust.

Near-stoichiometric: This is the mixture ratio (or lambda value)of the exhaust gasses at which the Nernst cell responds quickly, as if it is a narrow band sensor.

Building the controller:

Bill of materials: ↓ Download

PCB layouts, Kicad format. Older version for refrence only: ↓ Download

Note: these schematics have Ra and Rb to apply gain to the Pump driver DAC. Leave Ra out, and should be a jumper for use with the firmware here.

Gerbers: ↓ Download

Sensor pin-outs

Color Connection: Sensor Terminal Name: Voltage:
Black: Nernst Vs  
Grey: Heater+ H+ 12 V
Yellow: Vref Vs/Ip 1.8 V
Green: Rcal Rcal  
White: Heater- H-  
Red: Pump Ip  


The source code is released here under the The MIT License (MIT)

Copyright (c) 2102 Karl Walter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.


Firmware with source code downloads:

Engine exhaust: ↓ Download

Wood exhaust: ↓ Download

Other versions, experimental ↓ Download

To program the microcontroller, we recommend a USBASP programmer available from many sources including ebay. http://www.fischl.de/usbasp/

Programming software that works with the USBASP: AvrDUDE http://www.nongnu.org/avrdude/

AvrDUDE command arguments to set “fuses” (one time): -U lfuse:w:0x63:m-U hfuse:w:0xd9:m

WinAVR can be used to modify and compile code: http://winavr.sourceforge.net/download.html



Recommended follow-up work:

These are the areas that we feel would be the first items to address in terms of improvements. Please read read the Design and Pitfalls section for more details.

Speed up response time: Add gain to the Pump current amplifierto maximize Pump current available.

Ra and Rb should be chosen to provide some gain to this amplifier. The value should be chosen based on the current provided in free air with no gain, then add gain to apply a little less than maximum allowed in the Bosch datasheet. The PID values will then have to be changed for the pump power calculations.


Avoid Nernst oscillations: Try different target Nernst values for the Pump current calculation. This may help prevent oscillations at near-stoichiometric because the Nernst will be operated at one side or the other of it’s oscillation range. The firmware offered above for engine exhaust does this and the other firmwares target the middle of the steep part of the curve.

The steep part of the curve only represents a change of 0.02 lambda, (“Gasoline Engine Management“ Robert Bosch GmbH, 1999) So the error introduced by not targeting the center 0.45 volts should be small, and may be corrected as an overall offset calibration.

Or abandon PID for the pump control alltogether. the pump control might be better handled by a lookup table, as the nonlinearity of the nernst curve makes PID feedback work poorly.

Improve Heater control: Try a 1 to 4khz square wave applied continuously to the Nernst terminal via PORTB2 and C14. Compare this to the single point measurement after a pulse used in this design. The heater control in the current design may be fine, but better heater control may be available by trying another method: Measure the voltage with Nernst ADC a (fixed) short time after the toggle. Compute the difference between high and low measurements. This should be used to determine Nernst resistance. Then the average of the two measurement pairs is the DC offset of this AC signal, and represents the Nernst’s dc output. Adjust R10 to correspond to the frequency chosen.



Schematic: Click for larger image


Program flow chart:


Temperature control:

According to the datasheet The nernst resistance is to be measured using an alternating current signal of 1 to 4 khz. [section 2.7 Bosch LSU 4.2 data sheet] The target resistance is 80 ohms. A resistor and capacitor are used to filter this AC signal, and a DC value can be read by one of the ADC channels.Instead of setting up a timer to feed a pulse train to the nernst cell, we just apply a single pulse to to port B2, and measure the DC voltage a short time later.

Using a thermocouple tucked inside the sensor shell, we could plot the temperature versus this ADC reading. Using the PID functions, this is used to achieve reasonable closed loop heater temperature control. It may be possible to achieve better heater control with a more sophisticated measurement technique.

DAC: We use a simple RC filter and an op amp to create a DC voltage. Pump driver and Vout are generated this way. Tests show that the Pump driver DAC can have more swing in order to drive the Pump harder and increase response time, and still be within the limits of the specifications. See recommended follow-up work section below.

Reading the Pump current: The voltage across R12 is measured by using a differential amplifier with a gain of 5.


Reference voltage, or virtual ground: R4 and R3 are a voltage divider providing 1.8v from 5v. The op-amp buffers this to create the Vref voltage



Nernst resistance versus temperature curve:

The change in resistance versus temperature decreases as the Nernst cell reaches operating temperature. The Nernst resistance is the important value, so even though temperature control by this method is not very accurate, Nernst resistance control is OK. Below is an approximate graph of the Nernst resistance.

PID tuning is not trivial:

The PID tuning functions we used come from Atmel application note AVR122. PID tuning can be a very involved subject. The PID tuning should be approached by measuring the response to a change, then calculating new relative factors. We did not do this, the tuning that was done was by trial and error. Much improvement in response can be gained in this area. To make things harder, any other changes made in parameters such as op amp gain, or target Nernst value require that the PID tuning be re-done.

The pump control might be better handled by a lookup table, as the nonlinearity of the nernst curve makes PID feedback work poorly.

Heater Control By PWM causes noise that is picked up by the ADC:

We chose to avoid the problem by letting the PWM pulses for the heater control free-run, and synchronize the sampling. This way the sampling doesn’t happen when the heater power is going from low to high or vice versa.

Other solutions:

Use a linear heater power control: This is the technique used in the Rauscher design above. It uses an adjustable voltage regulator. This is probably the best way to start with, verify all other functions work, then add PWM heater control. The downside is the heat created by the linear power controller.

Stop the PWM briefly while sampling: This is a patented method. Patent number: 6712054 If you are considering a producing a controller commercially, investigating licensing this method may be a good idea.

Filter all analog signals with both digital and analog low pass filters.This method adds external components and internal firmware code, but may be the most straightforward if converting from a linear heater power control.

Check the PWM state before and after sampling: If the state changed, then a transition happened during the sampling, and that datapoint is discarded. It is possible that the Bosch CJ series chips does this with the DIAH and DIAG pins. This method we recommend for further investigation.

Non-linear response of sensor, and free air calibration.

The sensor response curve is steep in the near-stoichiometric range and is a long shallow tail out to free air. This requires using floating point math or a lookup table to translate the Pump current into a linear output. This also makes it difficult to use free air as single calibration point and extrapolate to the stoichiometric range.

Bosch Datasheet Curve Shapes:

Approximate shape on a linear scale:

Rapid Nernst output changes affect Pump current:

If the Nernst output changes rapidly, the spike will show up in the measurement of Pump current. This becomes a challenge in the near-stoichiometric range where the nernst cell oscillates between rich and lean.

A simplified model:

Nernst oscillation near-stoichiometric:

In our implementation, the current Nernst cell reading and the target value are fed to the PID function. The result is used to set the Pump current. If exhaust gasses are near-stoichiometric, the Nernst cell will tend to oscillate between rich and lean levels.

Nernst response near-stoichiometric:

Nernst oscillation:

Some options to deal with this:

Set target Nernst value out of switching range.

At first we somewhat unintentionally set the target Nernst to approximately 0.2 volts. This worked fine for a range exhaust gas mixture around near-stoichiometric, as in automotive exhaust. Response time from free-air was somewhat slow. When the sensor was used on a wood-burning furnace, a wider, lean range was needed, as well as faster response time, so the target Nernst was changed to closer to 0.45 volts. With this setting, the oscillations showed up.

We have separate firmware that works for each range, but not both. An improvement would be to combine the two firmwares by changing the target Nernst value based on the latest Pump current value.

Average the readings when the oscillation occurs. We have a version of firmware where we attempted this. It’s complicated, and difficult to filter the oscillations without destroying response time. The firmware has not been thoroughly tested.

Plot showing Nernst and Pump current oscillation, and digital filtering result:

Two other possibilities we have not investigated:

Filter using an external low pass filter.

Use a different algorithm: measure cycle frequency when near-stoichiometric.

This patent: WO 2012136715 A1 suggests a way to do this by measuring the Pump voltage with the Pump current disconnected in order to determine if the exhaust gasses are near-stoichiometric, and then changing the parameters of the Pump current control.

Field calibration methods:

It is not practical for every user to have a series of calibration gases. An investigation into a combination of free air, stoichiometric range, and maybe pure butane or propane may yield an adequate calibration. It may also be possible to calibrate the ADCs with precision voltage references and yield an adequate calibration.

Alternative controller circuits to consider :

Bosch CJ series of chips: Bosch CJ series (link)

These chips take care of everything except the temperature control and the conversion of Pump current to lambda value. They were only available to OEM manufacturers until recently. Extensive information on implementing one of these is here: http://www.breitband-lambda.de/information.html

Other open designs available:

Silicon Chip Magazine: (link)

14point7 open design: (Design link)(discussion link)

An analog design by Robert Rauscher for the NTK sensor: (link)

An Arduino design for the LSU4.9 sensor : (link) 

Damien Chazel's masters thesis on wideband sensor control (link)


End of Document.