MICS6814 - Typical Resistances


Is anyone successfully using the MICS6814 Breakout?

I’ve got it hooked up to a NodeMCU/ESP2866 (after many hours of stumbling around with code - thank god for Chris’s Arduino port of IOExpander)

However, my resistances don’t seem right compared to what others are reporting on their Enviro+

The breakout says 3-5v compatible, not sure how that works, doesn’t the sensor heaters require specific voltages? I have it on 3.3v currently.

My current reported resistances (using the formula r = (r * 56000/)(vadc - r) which I assume is correct as the PCB seems to have 3 56K resistors for the reading circuitry:

Reducing: 16K Ohms
NH3: 66K Ohms
Oxidising: 233K Ohms

Which seems to be reversed for what others report where Oxidising is typically the lowest and Reducing the highest. That would tie in with the sensor spec sheet.
Both my Oxidising and Reducing are outside the ranges the Spec Sheets says you should see at 23c 50% Hum, which is roughly what my room is at.

At the end of the day it won’t matter if the sensor is still sensitive to gas and I start to calculate a ratio to R0.

I’m currently running it with a BME280 to get some data to run regressions analysis to compensate for Temp/Hum/Baro based on the great work that @Roscoe27 has done.
Still need to get my head around that and how best to get calibration values with ESPHome/Home Assistant.

But first I wanted to check my sensor is running right.

The breakout says 3-5v compatible, not sure how that works, doesn’t the sensor heaters require specific voltages? I have it on 3.3v currently.

So the breakout board is 3-5v compatible, different microcontrollers/SBCs run at different voltages. The breakouts have a voltage regulator so it can be used with either, but it is probably running at 3v3.

My current reported resistances (using the formula r = (r * 56000/)(vadc - r)

At a glance at the library, it seems to already do that calculation before returning it to you?

Ahh cool, good to know about the voltage regulator.

I’m not using the Python library as I have it connected to an ESP2866 which is best done in C++
However I translated as best I could, and all the heavy lifting had been done by the port over of the IOExpander library (for the Microcontroller/ADC on the breakout).

But yes, I used whatever was in the Python library in my C++ one.

Here is what I cobbled together:

/***** Global Constants *****/

static const byte MICS6814_LED_R = 3;
static const byte MICS6814_LED_G = 7;
static const byte MICS6814_LED_B = 2;

static const byte MICS6814_VREF = 14;
static const byte MICS6814_RED = 12;
static const byte MICS6814_NH3 = 11;
static const byte MICS6814_OX = 13;

static const byte MICS6814_HEATER_EN = 1;

static constexpr float BRIGHTNESS = 0.5f; 
static constexpr unsigned int PERIOD = (unsigned int)(255.0f / BRIGHTNESS);  

static const bool INVERT_OUTPUT = true; //true for common cathode, false for common anode

/***** Global Variables *****/
IOExpander ioe(Wire, 0x19);

class mics6814 : public PollingComponent {
  Sensor *red_sensor = new Sensor();
  Sensor *nh3_sensor = new Sensor();
  Sensor *oxd_sensor = new Sensor();

  mics6814() : PollingComponent(60000) { }

  void setup() override {

  Wire.begin(D2, D1);
      Serial.println("Not Initialised");

  ioe.setMode(MICS6814_VREF, IOExpander::PIN_ADC);
  ioe.setMode(MICS6814_RED, IOExpander::PIN_ADC);
  ioe.setMode(MICS6814_NH3, IOExpander::PIN_ADC);
  ioe.setMode(MICS6814_OX, IOExpander::PIN_ADC);

  ioe.setMode(MICS6814_HEATER_EN, IOExpander::PIN_OUT);
  ioe.output(MICS6814_HEATER_EN, LOW);

  ioe.setPwmControl(2);  //PWM as fast as we can to avoid LED flicker

  ioe.setMode(MICS6814_LED_R, IOExpander::PIN_PWM, false, INVERT_OUTPUT);
  ioe.setMode(MICS6814_LED_G, IOExpander::PIN_PWM, false, INVERT_OUTPUT);
  ioe.setMode(MICS6814_LED_B, IOExpander::PIN_PWM, false, INVERT_OUTPUT);

  void update() override {

  float h = fmodf(((float)millis() * 360.0f) / 10000.0f, 360.0f);
  byte r, g, b;
  HSVtoRGB(h, 100.0f, 100.0f, r, g, b);
  ioe.output(MICS6814_LED_R, r);
  ioe.output(MICS6814_LED_G, g);
  ioe.output(MICS6814_LED_B, b);

  float ref = ioe.inputAsVoltage(MICS6814_VREF);
  float red = ioe.inputAsVoltage(MICS6814_RED);
  float nh3 = ioe.inputAsVoltage(MICS6814_NH3);
  float oxd = ioe.inputAsVoltage(MICS6814_OX);

  red = (red * 56000) / (ioe.getAdcVref() - red);
  nh3 = (nh3 * 56000) / (ioe.getAdcVref() - nh3);
  oxd = (oxd * 56000) / (ioe.getAdcVref() - oxd);

So I have just had a big dip in the Oxidising Sensor and the other sensors showed nothing so one might assume this was gas that triggered it.

However shouldn’t the Oxidising Sensor resistance increase in the presence of gas?

The Reducing and NH3 would decrease resistance in the presence of gas.

One scenario that fits here is that the Oxidising and Reducing sensors are actually ‘swapped’.
Then also my observations are in line with the sensor spec sheet.

You’ll see in my code above that I have the Pin Numbers for the MS51 IO Expander taken from the Python MICS6814 library (both the MICS6814 library itself and from the MICS6814 ‘example’ in the IO Expander Github repo). Are we sure these are correct?

I can’t compare to the Enviro+ implementation of the MICS6814 as that uses a different ADC.

Ah, sorry, I didn’t catch that you’d rolled your own library. Honestly, I’ve no idea, and you might be better off pinging Pimoroni’s support email (support[at]pimoroni[.com]) or opening an issue on their Github, unfortunately the staff aren’t very active here. It’s hard to tell what orientation the sensor is in and where it connects to the uC because the orientation dot seems to be on the back which is, uh, an interesting approach.

Thanks Shoe, yeah I tried tracing the PCB and gave up!
I’ll ping support.


Here’s a schematic for the breakout - indeed it looks like RED and OX pins have been swapped in our library, I’ll get that fixed. Thanks for letting us know! :)

Great, thanks Niko for the confirmation.