Home | pfodApps/pfodDevices | WebStringTemplates | Java/J2EE | Unix | Torches | Superannuation | | About Us

Forward Logo (image)      

BLE Low Power Indoor/Outdoor Weather Station
Sensors run for 4 1/2 Years on Coin cell

by Matthew Ford 27th May 2022 (originally posted 20th May 2022)
© Forward Computing and Control Pty. Ltd. NSW Australia
All rights reserved.

Indoor/Outdoor Weather Station
using Simple, Very Low Power, BLE Sensors


This indoor/outdoor Weather Station is the third in a series of Very Low Power BLE - 2022 projects. The very low power BLE temperature, relative humidity and barometric pressure sensor is an extension of the Very Simple, Very Low Power BLE Temperature Sensor The sensors are simple to make and run for ~4 ½ years on a coin cell.

The project consists if 3 parts:-
1) the Weather Station display.
2) the BLE to WiFi bridge
3) the Very Low Power BLE sensors


The Weather Station Display
    The Display Gauges
The BLE to WiFi bridge
The Very Low Power BLE Sensors
    Component Selection and Construction

Outline of the Project parts

The Weather Station Display

There are a number of options for the Weather Station Display :-

In this project, pfodApp will be used to display the Weather Station. pfodApp keeps all the display code in your Arduino sketch. No Android coding is required. Once you design the graphical gauges (see Custom Arduino Controls for Android), you can easily position and scale them on the screen. Since all the code is in your Arduino sketch you can modify the Weather Station display as you require. pfodApp also allows for simplified plotting. If you save the readings in your Arduino, you can add a TouchZone to your display that will open a plot of the readings versus date and time. See BLE Room Temperature controlled Heater and Arduino Date and Time using millis() and pfodApp This project has a TouchZone example, but does not add the plots.

You will know when you have the display/gauges setup correctly when other household members complain when the Weather Station is not running.

The BLE to WiFi bridge

To connect the BLE sensors to the Weather Station a BLE to WiFi bridge is used. This project use the simple hardware from Simple WiFi to Bluetooth Low Energy (BLE) Bridge and programs it to work as a BLE to WiFi bridge instead.

The Very Low Power BLE Sensor

There are a number of options for the BLE sensors. This project covers a simple temperature sensor, a temperature + relative humidity + barometric pressure sensor and a a temperature + relative humidity + barometric pressure + light level sensor. Each of these sensors are simple to construct and will run for four (4) years on a CR2032 coin cell. You can read multiple sensors with the one BLE to WiFi bridge and you can read the same sensor with multiple BLE to WiFi bridges.

Components Used

This project used the following parts:-

The Display – An old Nexus 7 tablet (2015) API V5.1.1 and USB supply and cable

BLE to WiFi Bridge
Adafruit Feather nRF52 Bluefruit LEnRF52832 – ~US$25 https://www.adafruit.com/product/3406
Adafruit HUZZAH ESP8266 Breakout
- ~US$10 https://www.adafruit.com/product/2471
2 x 100 ohm resistors
~US$1 https://www.sparkfun.com/products/13761
USB power supply (500mA or more)
~US$6 https://www.sparkfun.com/products/12890 OR ~US$7 https://www.adafruit.com/product/1994 OR similar
USB A to Micro B cable~US$4 https://breadfruit/product/2008 (3 foot long) OR ~US$3 https://www.adafruit.com/product/898 (6 inches long) OR ~US$2 https://www.sparkfun.com/products/13244 (6 inches long) OR ~US$5 https://www.sparkfun.com/products/10215 (6 foot long) OR similar
For Programming –
USB to TTL 3V3 Serial Cable~US$10 https://www.sparkfun.com/products/12977 (Preferred as it has the pins labelled) OR https://www.adafruit.com/product/954 (pins are NOT labelled)

The Very Low Power BLE Sensors
2 x GT832E_01 ~US$15.90 each, mounted on vero board
2 x Sparkfun BME280 board ~US$21.50 each
2 x Sparkfun coin cell holder PRT-00783 US$1.60 each and
2 x CR2032 coin cell PRT-00338 ~US$2.10 each
Optional -- 1 x Sparkfun VELM7700 (~US$6 and 10 x 22uF capacitors 445-173294-1-ND ~US$10 for 10 off

Hook up wire and vero board and plastic sheet/cases

The Weather Station Display

Programming the HUZZAH ESP8266

To program the shield follow the instructions given on https://github.com/esp8266/Arduino under Installing With Boards Manager. When opening the Boards Manager from the Tools → Board menu and select Type Contributed and install the esp8266 platform. This project was compiled using the ESP8266 version 2.3.0. Other versions will have their own set of bugs and may not work with this code.

NOTE: DO NOT use the Adafruit Board install as the sketch used here will not compile under that code.

Close and re-open the Arduino IDE and you can now select “Adafruit HUZZAH ESP8266” from the Tools → Board menu. (see the Simple WiFi to Bluetooth Low Energy (BLE) Bridge )
Other ESP8266 or ESP32 modules can also be used for the WiFi module. For ESP32 modules follow the instructions given on https://github.com/espressif/arduino-esp32 under Installing (Windows, Linux and macOS) and adjust the #includes and the ESPAutoWiFiConfig settings accordingly.

The WeatherStation_WiFi.ino sketch for the first display at the top of this page is in WeatherStationRH_W_1_WL_1_ESP8266.zip file. Unzip it to your Arduino Sketch directory and open the WeatherStation_WiFi.ino sketch in the WeatherStation_WiFi sub-directory. You also need to install the SafeString library using the Arduino library manager and the pfodParser library, V3.54+, from here and the ESPAutoWiFiConfig library from here.

The Display Gauges

The Adafruit HUZZAH ESP8266 is programmed as a pfodDevice to serve up the Weather Station's graphical display to pfodApp on an Android mobile/tablet or PC or Mac running Andy . The Weather Station Display in this project is an old Android tablet. pfodApp will run on Android versions back to Lollipop (API 5), Nov 2014, so you probably have an old Android mobile lying around that you can use for the display.

There are lots of options for the layout and gauges used for the Weather Station. See Custom Arduino Controls for Android for a tutorial on creating pfodApp controls in your Arduino sketch. The WeatherStation_WiFi.ino in WeatherStationRH_W_1_WL_1_ESP8266.zip creates the first display below. The display refreshes every 20 seconds. For degsF temperatures use the WeatherStation_WiFi_degF.zip file. You can set your own range of temperatures. If the temperature exceeds the range the correct temperature is displayed with the pointer at the top/bottom of the scale. For dual in/out RH gauge and hPa gauge and lux gauge use dualRH_hPa_lux.zip

The sensors advertise the readings for 10sec every 100sec. If the Adafruit nRF52832 BLE scanner misses a reading due to interference, out-of-range, low battery, etc then the display will update with the time since the last reading was received e.g. Outside WL_1 will update to Outside WL_1 4 mins ago.

WeatherStationRH_W_1_WL_1_ESP8266.zip, and the other zip files, also include the following gauges. To test these gauges you need pfodApp installed. Then program the example and then from the Arduino Serial Monitor (at 115200) enter the sensor data, i.e. W_1,22.5,55,1024 (for inside gauges) or WL_1,15.5,66,1023,35 (for outside gauges)

Note: The WeatherStation WiFi sketch filters it input and only decodes the sensors it is interested in. You need to ensure the BLE scanner (see below) filters for the sensors your WeatherStation WiFi is interested in.

Inside/Outside Temperature Gauges

InOutTempGauge_C.zip This gauge is a combination of two deg C gauges with labels suppressed on each gauge and the labels written separately in the middle.

TempGauge_C inside_temp(&dwgs, false, 0, 35, false); // scale points on right, current temp on left  0 to 35degC range, no labels, need to call drawScale() for labels
TempGauge_C outside_temp(&dwgs, true, 0, 35, false); // scale points on left, current temp on right  0 to 35degC range, no labels
// to set the scale use TempGauge_C outside_temp(&dwgs, true/false, minTemp,maxTemp);

The Inside / Outside labels are added separately (see the code in sendDrawing_z2() and sendDrawing_z3() ). The temperature gauges include an indicator for the range of temperatures over the last 24hrs.

Temperature Gauge


TempGauge_C.zip This is just one temperature gauge that can face left or right. This example has the scale points on the right and the current temperature on the left.

TempGauge_C temp(&dwgs, false, 0, 35); // scale points on right, current temp on left  0 to 35degC range

TempGauge_F.zip There is also a degF version of the temperature individual and dual gauges. Although the sensor input is still expected to be in degsC. You will need to change the code if your sensor sends degsF.

TempGauge_F temp(&dwgs, false, 32, 100); // scale points on right, current temp on left 32 to 100degF range

The Relative Humidity Gauges

The Relative Humidity Gauge code usage is illustrated in the WeatherStationRH_W_1_WL_1_ESP8266.zip and WeatherStation_WiFi_degF.zip files

dualRH_hPa_lux.zip There is also a dual in/out relative humidity gauge

The Lux Gauge

dualRH_hPa_lux.zip also has a lux gauge

The outside sensor includes a light sensor. This returns a lux reading. However the outside sensor is placed in the shade to prevent direct sun from effecting the temperature reading. This reduces the lux reading. To compensate for this the code in the WeatherStation_WiFi.ino scales the reading by x 2 before storing it for display. This factor was estimated from another VEML7700 sensor in full sun. For the next project ,which intends to use the lux reading to turn the hall night lights on and off, the actual true lx value is not important as the switching set point can be set as necessary, however the x 2 factor gives a “Sunset” reading at sunset.

The Barometric Pressure Gauge

dualRH_hPa_lux.zip also has a barometric pressure gauge

The barometric gauge has a TouchZone defined. If you turn on the Debug Log, in the pfodApp connection screen, it will display the size of the touch zone and the command that is sent when that zone is touched.
There are a number of touch filters that can be applied to the zone :- TOUCH, finger DOWN, finger DRAG, finger UP, CLICK, PRESS, finger Enters zone, finger Exits zone, finger DOWN then UP, DISABLE
In this case the filter is PRESS. i.e. touch and hold. This sends the menu 'A' command together with the dwg sub-command 'h'. The Arduino code then freezes the hPa pointer at the current pressure.
See Custom Arduino Controls for Android for a tutorial on TouchZones.

The pointer freeze is released after 99hrs or updated when the gauge is next Pressed.

Gauge Construction and Display

The WeatherStation_WiFi sub-directory includes a number of graphical components. The simplest is the relative humidity, rh_Gauge. It has a draw() and update() methods and a setValue(int ) method it inherits from its pfodControl base class. The draw() method sends all the static components and then calls the update() method to send the dynamic parts. Thereafter only the dynamic parts need to sent, using the update() method. The dynamic parts, like value text and pointers are assigned unique indices by the sketch which allows pfodApp to identify and update just that graphical component. The index also controls the order in which the graphical components are drawn. Static first and then indexed smallest index to largest index overlaying any components underneath. (See Custom Arduino Controls for Android)

When the sketch sends the rh_Gauge, it first repositions the display's x,y zero and scales size to suit using pushZero (similar to the way postscript works)

  rh_Gauge outside_rh(&dwgs);
  . . . 

  dwgs.pushZero(38.5, 45, 1.35f); // scale defaults to 1.0f if omitted, i.e. pushZero(10,15);
  outside_rh.draw();  //  gauge

If you want the gauge in a different position on the screen, just change the pushZero statement. This gauge displays the outside RH%.

The Inside / Outside temperature gauges can be in either deg C, TempGauge_C, or deg F, TempGauge_F. This project uses the TempGauge_C gauge. The constructor
TempGauge_C(pfodDwgs *_dwgsPtr, bool _left = true, int minTemp = 0, int maxTemp = 35, bool addScaleLabels = true);
lets you set the scale range and which side of the vertical bar the scale is on. For the combined inside/outside temperature gauges, the last argument, addScaleLabels is false so that the actual scale numbers are not drawn by the draw() method. They are added later by calling the drawScale() method to add them just once between the two gauges. e.g.

  dwgs.pushZero(20, 32.5); // scale by 1.0f,  scale defaults to 1.0f if omitted, i.e. pushZero(10,15);
  inside_temp.draw();  //  gauge
  dwgs.pushZero(25, 32.5); // scale by 1.0f,  scale defaults to 1.0f if omitted, i.e. pushZero(10,15);
  inside_temp.drawScale(); // draw scale numbers in center.
  . . . 
  dwgs.pushZero(30, 32.5); // scale by 1.0f,  scale defaults to 1.0f if omitted, i.e. pushZero(10,15);
  outside_temp.draw();  //  gauge

The temperature range over the last 24hrs is accumulated by the Temp24hrMaxMin class. That class keeps track of the max and min temperatures over 15min blocks and rotates the blocks over 24hrs to avoid having to keep all the readings.
However if you add plotting and store all the readings to plot, you can just use the max/min of those values. The max and min values are used to add the max/min text and to draw a thicker RED bar on the scale to indicate the range of temperatures over the last 24hrs.

The barometric pressure gauge has a TouchZone included which when pressed will send a command to the sketch to freeze the pointer at the current pressure so that you can see the change over time. Pressing again will reset the pointer to the current pressure. The freeze is removed by the sketch code after 99 hrs. You can display the TouchZones and their associated commands by enabling the Debug Log in pfodApp for this connection.

TouchZones can respond and their command filtered by a number of different types of touches:- TOUCH, finger DOWN, finger DRAG, finger UP, CLICK, PRESS, finger Enters zone, finger Exits zone, finger DOWN then UP, DISABLE. TouchZones can also have a pre-loaded TouchAction associated with them which gives immediate response on the screen when touched. Again see Custom Arduino Controls for Android. All of these actions/settings are controlled by the messages sent by your Arduino sketch.

The BLE to WiFi bridge

The BLE to WiFi Bridge is used to collect the data, from all devices within range, and make the measurement available via a webpage/data server or push the measurements out to the cloud for control or monitoring. The project Simple WiFi to Bluetooth Low Energy (BLE) Bridge covers the hardware construction. The circuit is trivial.

The Wifi2BLE circuit is shown above. A pdf version is here. As you can see the circuit is very simple. Just 4 wires and two 100 ohm protection resistors. The protection resistors are in case you miss-connect the TX / RX lines after programming the HUZZAH ESP8266 or the Feather nRF52.

NOTE: The Feather nRF52 board marking for the TX and RX pins are in-correct. The TX pin is actually the one next to the DFU pin and the RX pin is the one next to the MISO pin.

Make sure you connect the TX/RX lines as shown above. Fortunately the protection resistors did their job and boards were not damaged while I sorted out why the boards were not taking to each other.

Programming the Adafruit Feather nRF52832

To program the Adafruit Feather nRF52832, follow the instructions on downloading and installing the Arduino Board support for the Feather nRF52. Check you can connect to, and program the board via the USB cable.

The WeatherStation_BLE.ino sketch for the Adafruit Feather nRF52832 is in WeatherStation.zip file. Unzip it to your Arduino Sketch directory and open the WeatherStation_BLE.ino sketch in the WeatherStation_BLE sub-directory. You also need to install the SafeString library using the Arduino library manager.
Disconnect the ESP8266 Tx/Rx connections when programming the Adafruit Feather nRF52832 or the ESP

The WeatherStation_BLE.ino sketch scans for all BLE devices nearby but only outputs to the Serial connection the advertised name of the devices it is interested in. The following code, in setup(), specifies which devices to forward to the ESP8266.

  LastSeen *devicePtr = new LastSeen("W_1,"); // note MUST use new since pfodLinkedPointerList uses delete when remove() called
  // add other devices here that you want to scan for
  devicePtr = new LastSeen("WL_1,");

A Weather sensor (W_1, ) Temperature + RH + hPa, and a Weather + Lux sensor (WL_1, ) are picked up. See Naming Sensors, below, for how the devices are named depending on their capabilities. If you use different sensors with other names you should change the code here accordingly and also the corresponding code in the WeatherStation_WiFi.ino. The sketch simply continually scans for BLE devices and check if their advertised name starts with one of those we are interested in. A linked list is used to hold the names we are interested in as well as when they were last scanned. Once a device of interest has been found, its advertised name is output to Serial and further scans of it are ignored for the next 11secs since the sensors only advertise for 10secs every 100secs

Note: The WeatherStation WiFi sketch filters it input and only decodes the sensors it is interested in. You need to ensure the BLE scanner (see below) filters for the sensors your WeatherStation WiFi is interested in.

The Very Low Power BLE Sensors

Component Selection

The two basic components are a nRF52832 'bare' module and a coin cell (in a holder).

The following nRF52832 'bare' modules available from Aliexpress can be used. They include:-
GT832E_01 ~US$15.90 mounts on vero board
Jessinie XL52832-D01 nRF52832 module ~US4.90 and Jessinie Test Board Adapter Plate for NRF52832 ~US$1.70 – Total ~US$5.60
BLM-KTB522 ~US$6.30 (no crystal) pin for pin replacement for Skylab SKB369, needs to be mounted on PCB

Those 'bare' nRF52832 do not have any extra components or power regulators that will used extra current.

Add to this a CR2032 coin cell and holder, e.g.
Sparkfun coin cell holder PRT-00783 US$1.60 and CR2032 coin cell PRT-00338 ~US$2.10 – Total US$3.70

So using the Jessinie module and adapter and a coin cell and holder the total cost (excluding shipping) is < US$10

A Simple BLE Temp Sensor for Beginners shows you how to use just these two components to get a usable BLE temperature sensor.
For the relative humidity and barometric pressure, you need to add a Sparkfun BME280 board (~US$21.50) Adding this very low power board gives about 4 and a half years of run time on a CR2032 coin cell. It also avoids the time consuming temperature calibration so you may choose to used it just for the temperature sensor also.
This project also includes a light sensor, Sparkfun VELM7700 (~US$6) . Sparkfun VELM6030 (~US$6) also looks suitable, but was not tested. Because the light sensor only works down to 2.5V, you do cannot access the full capacity of the coin cell (down to 2V). This reduces the run time to about 3 and a quarter years.

Note: the Adafruit versions of these boards Adafruit BME280 and Adafruit VEML7700 Lux Sensor are NOT suitable, because they include additional components that increase the supply current.


The WL_1 sensor which includes a temperature, relative humidity, barometric pressure and light sensor, is placed outside and the W_1 sensor, without the light sensor, is used inside. If you don't want the light sensor, use the simpler W_.. sensor (see below) and modify the Weather Station Bridge code (below) to filter for W_.., instead of WL_1, e.g filter for W_2 for example if the sensor's name is W_2

Naming Sensors

Since these sensors are so simple and inexpensive to make, you may well end up with a number of them advertising the temperature and/or other measurements, from various locations. To distinguish between them, the lp_BLE_Temp_uC.ino sketch uses the following convention. The temperature sensors advertised name starts with T_ followed by a number, e.g T_1, followed by a comma and the temperature value. This design will also be the basis for other sensors which add a very low power, temperature/humidity sensor or a temperature/humidity/barometric pressure sensor and/or a lux sensor.

This project used the following name format

Format of advertised name, e.g. T_5,25.5
LOCAL_NAME prefix T_.. devices
LOCAL_NAME prefix H_.. devices
LOCAL_NAME prefix W_.. devices
LOCAL_NAME prefix WL_.. devices

Set LOCAL_NAME, at the top of the sensor sketches and then use the prefix to parse the advertised data.

Sensor Construction

Follow the instructions in Easy Very Low Power BLE in Arduino -- Part 1 2022 to setup the Very Low Power BLE support for nRF52832 boards and programmers.

T_1 – Temperature Sensor

The construction and calibration of the T_1 sensor is described in Simple BLE Temp Sensor for Beginners. Because the nRF52832 on-board temperature measurement is not very accurate, the T_1 sensor requires calibration before use.
After determining the calibration correction the nRF52832 is programmed with the lp_BLE_Temp_uC.ino sketch. This sketch only has constant correction. You may need a formula as described Multi-point Calibration . The sketch is set to advertise for 10 secs every 100sec and T_1 should run for about 5 years on a CR2032 cell.

W_1 – Temperature, Humidity and Barometric Pressure Sensor

To avoid doing a multi-point calibration, can instead fit a Sparkfun BME280 temperature, humidity and barometric pressure sensor. Again the circuit is trivial (pdf version)
If you don't need the sensor including the light sensor, WL_1, below, then this sensor can be used outside as well, but with a different LOCAL_NAME, say W_2.

This sensor, named W_1, is programmed with the lp_BLE_GT832E_01_BME.ino sketch. Unzip lp_BLE_GT832E_01_BME.zip to your Arduino sketch directory.
This sensor will run for about 4 ½ years on a CR2032 coin cell.

WL_1 – Temperature, Humidity Sensor, Barometric Pressure and Lux level Sensor

In preparation for a future project that will turn the hall night lights on at sunset and off at sunrise, the outside sensor used here for the Weather Station includes a light sensor, SparkFun VEML7700.

The VEML7700 light sensor has a minimum operating voltage of 2.5V. The 10 off, 22uF 16V ceramic capacitors supply the pulses of current the VEML7700 needs as the coin cell's voltage falls and its internal resistance increases. However even with these capacitors, the 2.5V cut off means a shorter effective operating life from a CR2032 coin cell, approximately 3 ¼ years. This sensor is named WL_1, following the naming convention established above. In the construction the backing plastic was folded over the top of the board to protect against dust etc settling on the circuit. The rest of the cover is open on the other 3 sides. In a more extreme climate, a more protective case would be needed.


This tutorial has presented a Indoor/Outdoor Weather Station using two very simple, very low power BLE temperature/RH/hPa sensors using only three components, a nRF52832 'bare' module a temperature/RH/hPa sensor and a coin cell. The sensors run for ~4 ½ years a CR2032 coin cell.

The display uses an old Android tablet and pfodApp. The gauges are fully customizable in the Arduino sketch. Plots of the values could also be added using a TouchZone, or another menu item, to open the plot page. pfodApp makes it easy to plot values against date and time.

AndroidTM is a trademark of Google Inc. For use of the Arduino name see http://arduino.cc/en/Main/FAQ

The General Purpose Android/Arduino Control App.
pfodDevice™ and pfodApp™ are trade marks of Forward Computing and Control Pty. Ltd.

Forward home page link (image)

Contact Forward Computing and Control by
©Copyright 1996-2020 Forward Computing and Control Pty. Ltd. ACN 003 669 994