Open Source Wireless Environmental Sensor HW, Part 2: Prototyping

Suru Dissanaike
HiMinds
Published in
4 min readOct 8, 2019

The source code for this article is located here.

In our previous article (link can be found above) we introduced our wireless environmental sensor project; which is a rechargeable battery-operated wireless sensor that can measure:

  • Temperature with ±1.0°C accuracy
  • Barometric pressure with 1 hPa absolute accuracy
  • Humidity with ±3% accuracy

This article is about reducing the risk in the project. When you want to reduce the risk in a project you typically do a pre-study; in our prestudy, we hook up everything using eval boards and develop a bit of software. As mentioned in the previous article we are using:

We bought evaluation boards for the BME280 and the fuel gauge and hooked it up; it does not look that nice but the important part is that we can evaluate the functionality. Going forward I will refer to the BME280 and the BQ27441-G1 fuel gauge as sensors.

The main objective of the prestudy is to interface the sensors and extract information from them. Electrically you can choose between SPI or I2C for the BME280 and I2C for communication with the fuel gauge. We have chosen to interface both sensors using I2C and place them on the same bus. Initially, we thought that it would be an issue that the BME280 runs on 3.3V and the BQ27441-G1 on 1.8V so we added an I2C level shifter. The design looked like this:

I2C level shifter between BQ27441 and ESP32 GPIO pins

There are several application notes describing Level shifting techniques; for example this one from NXP. Digging deeper into the datasheet we (⭐️Johan) found that it can handle 3.3 V so we removed the design above. Next step was to try it out!

This is how everything is connected:

GPIO configuration for functional prototype

After spending some time hooking things up we got the following:

ESP32 Dev board connected to BME280 and BQ27441-G1 via I2C

As you can see in the photograph above the Lithium battery is not powering the ESP32 Dev board. We are using the same I2C interface to communicate with both the BME280 and the BQ27441-G1.

One simple way to verify that everything is connected correctly from the software is to use the Mongoose OS RPC Service — I2C.

If I create a project and add the RPC Service and I2C driver (in your mos.yml)

- origin: https://github.com/mongoose-os-libs/i2c

- origin: https://github.com/mongoose-os-libs/rpc-service-i2c

This will enable you to run the mos call I2C.Scan command.

So what does the 85 and 118 below mean?

$ mos call I2C.Scan [   
85,
118
]
Command completed.

If we look in the schematics for the “SparkFun Battery Babysitter — LiPo Battery Manager” it says I2C ADDR: 0x55 i.e. 85 in decimal format and 118 expressed in hex format is 0x76; which is the default I2C address of the BME280. This means that we have found both devices on the I2C bus! 🙌

If we want to do a read; we can do the following:

$ mos call I2C.ReadRegW '{"addr": 85, "reg": 2}' {   
"value": 32523
}
Command completed.

The value 32523 does not make sense… and what is “reg”: 2?

To answer this question you need to read the BQ27441-G1 datasheet; have a look at the “Standard Data Commands” on page 11. Reg 2 is the command for Temperature() which is return in the value 0.1 °K and little-endian format.

  1. 32523 = 7f0b, little-endian
  2. 0x0b7f to decimal = 2943
  3. 2943 * 0.1 = 294.3
  4. 294,3K − 273.15 = 21,15°C

For the BM280 there is a supernice library called “api_arduino_bme280.js” if you want to do JavaScript on the ESP32 with Mongoose OS. For this article, I created some code to test both the BME280 and BQ27441.

The output from the program looks like this when the 🔋 is fully depleted:

getSystemInfo message: {“data”:{“firmware”:”1.0.1a”,”model”:”env ib-1",”uptime”:1601.954630,”freeRAM”:207072,”totalRAM”:289116,”deviceId”:”esp32_EE7B2D”}}getBME280Info message: {“data”:{“pressure”:1013.052700,”humidity”:37,”temperature”:22.020000}} [Oct 7 20:40:14.980] Voltage: 3.124000 Celsius: 26.658500 [Oct 7 20:40:14.997] Full Available Capacity: 1.197000 [Oct 7 20:40:15.005] Remaining Capacity: 0 getBQ27441Info message: {“data” {“remainingCapacity”:0,”fullAvailableCapacity”:1.197000,”batteryLevel”:0,”temperature”:26.658500,”voltage”:3.124000}}

The output from the program looks like this when the 🔋 is fully charged 💯 :

getSystemInfo message: {“data”:{“firmware”:”1.0.1a”,”model”:”env ib-1",”uptime”:51.837370,”freeRAM”:207060,”totalRAM”:289124,”deviceId”:”esp32_EE7B2D”}} getBME280Info message: {“data” {“pressure”:1006.853700,”humidity”:32.660000,”temperature”:22.300000}} [Oct 8 06:46:56.331] Voltage: 4.136000 [Oct 8 06:46:56.339] Celsius: 21.350000 Full Available Capacity: 1.236000 [Oct 8 06:46:56.356] Remaining Capacity: 1.185000 getBQ27441Info message: {“data” {“remainingCapacity”:1.185000,”fullAvailableCapacity”:1.236000,”batteryLevel”:100,”temperature”:21.350000,”voltage”:4.136000}}

The code looks like this (for complete version go to GitHub)

Datasheets are a fountain of wisdom but it is easy to miss something crucial. Hopefully, we have reduced the risk in the project by hooking up the sensors and extracting information from them. In the next article, we will start to design our “Open Source Wireless Environmental Sensor HW”. The source code for this article is located here.

Thank you for reading! Take care and hope to see you soon. 🙏🏽

This article is a living document please reach out to me if you want to contribute or see anything inaccurate here. This article is part of our “Boosting Innovation” project.

--

--