Introduction: Using the Pimoroni Enviro+ FeatherWing With the Adafruit Feather NRF52840 Express

The Pimoroni Enviro+ FeatherWing is a board packed full of sensors designed to work with the Adafruit Feather series of boards. It's a useful place to start for anyone interested in environmental monitoring, atmospheric pollution and data munging. It features:

  • Bosch BME280 - temperature, pressure, humidity sensor;
  • Lite-On LTR-559 - light and proximity sensor;
  • SensorTech MiCS-6814 - oxidising gases, reducing gases and ammonia sensor;
  • Analogue microphone - measuring noise pollution;
  • Connector for Plantower PMS5003 particulate matter sensor (not included).

The trio of metal-oxide sensors on the MiCS-6814 include a less common sensor for oxidising gases. This is useful for its sensitivity to nitrogen dioxide (NO2), a pollutant common in cities and near major roads.

Pimoroni recommend either the Adafruit

  • Feather M4 Express (120MHz, 192kB ram) or
  • Feather nRF52840 Express (64MHz, 256kB ram).

The nRF52840 was chosen for this guide as it supports Bluetooth Low Energy (BLE) which gives the board the potential to send data to another device.

The Feather and FeatherWing both come with unattached male headers. Female headers are required to stack the boards. This guide shows the use of "stacking headers" which allows the Feather board to also be inserted into a breadboard facilitating experimentation with extra sensors. The headers need to be soldered to the boards but this is reasonably straightforward.

The Enviro+ FeatherWing has one subtle difference compared to its cousin, the Enviro+ Air Quality for Raspberry Pi. The FeatherWing version appears to be designed to work with voltages below 5V allowing a single lithium polymer (LiPo) battery producing 3.7V-4.3V to be used. It has a DC-DC converter to provide 5V for the optional PMS5003 and it may power the MiCS-6814 internal heaters individually to deal with these lower voltages.

The main picture shows the Enviro+ FeatherWing displaying the PM2.5 and PM10 data from the PMS5003. A Swan Vestas match has been struck half way through the plot to light the candle.

A second article covers Plotting Carbon Dioxide Levels With the Pimoroni Enviro+ FeatherWing and Adafruit SCD-30.


  • Pimoroni Enviro+ FeatherWing - Pimoroni | Adafruit - (another similar board exists for the Raspberry Pi)
  • Adafruit nRF52840 Feather Express - Pimoroni | Adafruit
  • Feather Stacking Headers - Pimoroni | Adafruit - normal female headers or FeatherWing doubler/tripler could also be used
  • Solder
  • Optional: Plantower PMS5003 particulate matter sensor - Pimoroni | Adafruit

Step 1: Upgrading the Bootloader

The Feather board can be checked before it's soldered by connecting it to a computer using USB. This is a useful time to check the bootloader - old versions can produce confusing but harmless errors on Windows.

Double-clicking the Feather's reset button causes a drive called FTHR840BOOT to be presented to the host computer. A file called INFO_UF2.TXT can be opened to inspect the version, the example below shows the content indicating version 0.2.6:

F2 Bootloader 0.2.6 lib/nrfx (v1.1.0-1-g096e770) lib/tinyusb (legacy-525-ga1c59649) s140 6.1.1
Model: Adafruit Feather nRF52840 Express
Board-ID: NRF52-Bluefruit-v0
Bootloader: s140 6.1.1
Date: Dec 21 2018

Versions before 0.2.9 suffer from the aforementioned bug. The slightly fiddly upgrade process is described in Adafruit Learn: Introducing the Adafruit nRF52840 Feather: Update Bootloader and discussed in Adafruit Forums: Windows errors copy CircuitPython UF2 to FTHR840BOOT.

Step 2: Soldering the Headers

The Enviro+ FeatherWing needs its male headers attached and the Feather needs the stacking female headers attached.

A common technique to locate the pins in the correct position while soldering is to insert them into a breadboard. Some caution is required with this FeatherWing as the picoblade connector on the underside is taller than the plastic spacers on the header. This could cause the board to be unintentionally soldered at an angle. The picture above shows the angle. This is easily solved by raising the headers uniformly by 2-3mm (0.1in) from the breadboard.

The stacking female headers must be perpendicular to the board. This can be achieved by placing them on a flat surface and ensuring the Feather board is pressed firmly against them. The picture above shows pressure being applied with a pencil with an out-of-shot helping hands device putting weight on the pencil. Some spare headers are providing some additional help in maintaining the spacing.

The MiCS-6814 datasheet states:

The sensor must be reflow soldered in a neutral atmosphere, without soldering flux vapours.
The sensor must not be exposed to high concentrations of organic solvents, silicone vapours or cigarette smoke in order to avoid poisoning the sensitive layer.

A small piece of masking tape covering the gas sensor is a wise precaution during soldering and flux cleaning. The screen protector can also be left on at this stage to deal with the inevitable tiny splashes of flux from soldering with an iron. The microphone would also benefit from protection with masking tape during any flux clean-up.

The long rows of pins can be easily be bent when removing them from a breadboard or other socket. Take care to avoid levering the board up at one end.

Adafruit have a guide on soldering stacking headers, Pimoroni have a general soldering guide which includes headers and there's a nice video on YouTube showing how to solder headers onto a similar style board, GurgleApps: Raspberry Pi Pico Upgrade Number1 - Snazzy Header Pins!

Step 3: Installing CircuitPython and Combined Plotter Example

If you are not familiar with CircuitPython then it's worth reading the Welcome to CircuitPython guide first.

The installation steps below are based on the pimoroni / EnviroPlus-FeatherWing README and the Getting Started guide with a later library to cater for CircuitPython 6.x.

  1. Install the latest version of CircuitPython (6.0.0 in December 2020) from - this process is described in CircuitPython for Feather nRF52840.
  2. Verify the installation by connecting to the serial console over USB. The REPL prompt shows the version. The version can also be checked by inspecting boot_out.txt on the CIRCUITPY drive.
  3. Install these libraries from a bundle from into the lib directory on CIRCUITPY:
    1. adafruit_bus_device
    2. adafruit_bme280 (not adafruit_bmp280)
    3. adafruit_st7735r (not adafruit_st7735)
    4. adafruit_display_text
  4. Install these libraries from the file from GiHub: pimoroni/EnviroPlus-FeatherWing: Version 1.0 into the lib directory on CIRCUITPY:
    1. i2cdevice (not to be confused with Adafruit's i2c_device library)
    2. pimoroni_envirowing
    3. pimoroni_ltr559
    4. pimoroni_physical_feather_pins
    5. pimoroni_pms5003
    6. Do not install pimoroni_circuitpython_adapter from here
  5. Install the latest Pimoroni CircuitPython adapter library by downloading the file into a newly created lib/pimoroni_circuitpython_adapter directory on CIRCUITPY.
  6. Download the combined plotter example program to CIRCUITPY by clicking Save link as... on
  7. Rename or delete any existing file on CIRCUITPY, then rename the to This file is run when the CircuitPython interpreter starts or reloads.

The versions used for this guide were:

  • CircuitPython 6.0.0
  • CircuitPython library bundle
  • EnviroPlus-FeatherWing library Version 1.0
  • pimoroni_circuitpython_adapter library 9-Dec-2020 f062036

Step 4: The Combined Plotter

The combined plotter has four screens:

  1. Sound and Light.
  2. PM2.5 and PM10.
  3. Temperature, pressure and humidity.
  4. OX, RED and NH3.

The particulate matter (PM) screen only appears if the Plantower PMS5003 is attached. The program checks for its presence at the start and prints this informational message if it's not connected:

PMS5003 Read Timeout: Failed to read start of frame byte
You probably don't have a pms5003 connected, continuing without particulate logging

The plot interval is set to 540 seconds at the top of the program. This can be adjusted to control the plot rate.

Step 5: Enviro+ FeatherWing Pins

The Enviro+ FeatherWing uses a large number of the Feather's pins. The following ones are used, the names in brackets are from Pimoroni's naming scheme:

  • A0 (pin5) - MiCS6814 ammonia gas sensor
  • A1 (pin6) - MiCS8614 reducing gas sensor
  • A2 (pin7) - MiCS6814 oxidising gas sensor
  • A3 (pin8) - analogue microphone
  • A4 (pin9) - MiCS6814 enable
  • D5 (pin19) - SPI bus screen command
  • D6 (pin20) - SPI bus screen chip select
  • D9 (pin21) - backlight (PWM)
  • D10 (pin22) - PMS5003 enable
  • D11 (pin23) - PMS5003 reset
  • D12 (pin24) - LTR-559 interrupt (not supported in CircuitPython library)
  • SCK (pin11) - SPI bus clock
  • MO (pin12) - SPI bus master out slave in
  • MI (pin13) - SPI bus master in slave out
  • RX (pin14) - PMS5003 transmit (receive by Feather)
  • TX (pin15) - PMS5003 receive (transmit from Feather)
  • SCL (pin18) - I2C clock
  • SDA (pin 17) - I2C data

This leaves the following pins available to use:

  • A5 - analogue-capable;
  • AREF - this is not used by CircuitPython for ADC which means it can be used as an analogue input but the presence of a 100uF capacitor limits its use to slowly changing signals;
  • D2 (marked DFU on some nRF-based boards) - there are issues with using this as an input discussed in Adafruit Forums: Feather D2 pin as input vs DFU / FTHR840BOOT ;
  • D13.

A spare analogue input with a suitable potential divider could be used to monitor the output voltage of solar cells in a solar/battery-based project.

The board monitors VBAT with a potential divider halving the voltage. In CircuitPython, this can be accessed using:

>>> import board, analogio
>>> vbat = analogio.AnalogIn(board.VOLTAGE_MONITOR)
>>> vbat.value * vbat.reference_voltage / 65535.0 * 2.0

The i2c bus is used to communicate with the LTR-559 and BME280 sensors on addresses 0x23 and 0x76, respectively. The Enviro+ board appears to have 10k pull-up resistors on SDA and SCL.

Step 6: Power Consumption

The power consumption is well within the USB specification even if a LiPo battery is attached and is recharging. The usage is more relevant for planning a move to battery power. Some very approximate measurements of the current are:

  • 100mA idle, backlight off;
  • 100mA plotter running, backlight low;
  • 120mA plotter running, backlight high.

The datasheet for the Plantower PMS5003 states the current is less than 100mA, this would be in addition to the above numbers. The use of DC-DC converter on the Enviro+ FeatherWing may increase this number slightly.

The Feather nRF52840 Express board has a NeoPixel (RGB LED) but the brightness levels for its default use as an indicator of program state only adds a tiny amount to the consumption. The Feather board itself is below 10mA on its own, the FeatherWing is the power hungry board.

Step 7: Adding the Plantower PMS5003 Particular Matter Sensor

The Met One Instruments BAM 1020 is a common sight around the world measuring particulate matter in cities. A range of more affordable devices exist and the Enviro+ FeatherWing comes with a connector for the Plantower PMS5003 particulate matter sensor.

The Pimoroni library code for this sensor currently appears fragile. A simple and quick improvement is to catch exceptions in the program. The program can be improved by adding this at the top:

import pimoroni_pms5003

And replacing this line in the main while loop

# take readings
pms_reading =


# take readings
    pms_reading =
except pimoroni_pms5003.ChecksumMismatchError:
    print("checksum error")

Step 8: Going Further

There are a number of areas to explore once you've got the Enviro+ FeatherWing running.

  • Adding an external temperature sensor. The temperature sensor in the BME280 is subject to both internal heating and heating from nearby components and is intended to calibrate the other BME280 sensors. The value can be processed to provide an approximate measure of ambient air temperature but there are plenty of affordable, superior external options.
  • Calibrating the sensors. The pressure is easy using weather observations or short-term forecasts (these will be at 0 ft amsl), the rest are difficult.
  • Correcting the PMS5003 output for relative humidity. A formula is presented on page 8 of PDF on EPA: PurpleAir PM2.5 U.S. Correction and Performance During Smoke Events 4/2020
  • Adding code to broadcast the sensor data over Bluetooth Low Energy to other devices.
  • Investigating how to minimise the power consumption. Some of the sensors have enable lines, these may remove power from the sensors or put them into a low power mode. For sensors with a warm-up time periodically sampling may not be practical.
  • Buying, adapting or making a case suitable for mounting outside with carefully designed internal air flow and suitable precautions for direct sunlight. The SensorTech MiCS-6814 gas sensor works best with a constant, low-rate flow of air across it.
  • Examining how weather conditions influence pollution at ground level. Hint: inversions are significant.
  • Converting to battery power or solar with battery power. Solar power is more challenging than simply adding a photovoltaic solar panel, see the Design Notes section in Adafruit Learn: USB, DC & Solar Lipoly Charger.
  • Adding other sensors to measure common pollutants like Ozone (O3) and sulphur dioxide (SO2) or greenhouse gases like carbon dioxide (CO2). A few sensors measure "eCO2" and are not suitable for measuring atmospheric CO2. Adafruit now sell the great value Sensirion SCD-30 NDIR CO2 sensor on a board with STEMMA QT i2c connectors.
  • If you want to investigate sending the data over the Internet using Wi-Fi then the FeatherS2 board with ESP32-S2 microcontroller appears to be compatible with the Enviro+ FeatherWing. There is a problematic limitation with the ESP32-S2 analogue to digital converters (ADC) which prevents proper measurement of the gas sensors. See Adafruit Forums: Feather ADC comparison including 2.6V limited ESP32-S2 for more information.

Related projects:

Further reading: