BME280 BMP280 on Wemos Lolin32 with Mongoose OS

The weekend IoT warrior is back again!

I bought a pack of 5 BME280s from ebay, unfortunately they sent BMP280s instead and wouldn’t offer a refund. A colleague at work had the same issue, it’s actually really hard to get the BME and not get fobbed off with the BMP. Another colleague mentioned to buy them from this seller on Aliexpress as they’re legit (he had a pack of them in his hand, the right ones!). Anyway, I haven’t ordered them yet so I’ll play with the BMP280 for now, same interface, just lacks the humidity sensor.

I ordered the BME280s but got sent the BMP280s, annoying!

Finding the I2C pins

Every board has the potential to use different SDA/SCL pins, fortunately for me, it was printed on the reverse of the board, but you might have to hunt around in the specification sheet of your board to find them.

Wemos Lolin32 board

Finding the I2C device

You can have many devices on the I2C bus, think of it like a public highway with many cars (devices) travelling on it at any time. Each device will have it’s own ID which you’ll need to know to communicate with it in your application. If the manufacturer doesn’t specify the device ID, fortunately there is an easy way to find it using the I2C scanner that Arduino provide, run this sketch and you should see something like the following

Arduino code for the I2C Scanner

Note that I had to override the I2C pins on the Wire.begin(), you might need to do that too.

I2C device found at address 0x76  !

Writing some code to read data from the sensor

Now I know the I2C pins, and the device address, I can start to write some code. I started off by looking at the example from Mongoose OS, but it seems theres an issue with the Arduino compat library, fortunately theres an answer on the forums.

Here’s where I ended up

#include <mgos.h>
#include <Adafruit_BME280.h>

#define SENSOR_ADDR 0x76

static Adafruit_BME280 *s_bme = nullptr;

// Couldn't get bme280 example app to work due to arduino compat
// here's a modified version 
// Credit to nliviu from MOS Forums for help with this 

void readTimerCB(void *arg)
    printf("Temperature: %.2f *C\n", s_bme->readTemperature());
    // Humidity will only work on BME280, not BMP280
    printf("Humidity: %.2f %%RH\n", s_bme->readHumidity());
    printf("Pressure: %.2f kPa\n\n", s_bme->readPressure() / 1000.0);
    (void) arg;

enum mgos_app_init_result mgos_app_init(void)
    s_bme = new Adafruit_BME280();

    // Initialize sensor
    if (!s_bme->begin(SENSOR_ADDR)) {
        printf("Can't find a sensor\n");
        return MGOS_APP_INIT_ERROR;

    mgos_set_timer(2000, 1, readTimerCB, NULL);


Grab the full source here


Once again, Mongoose OS makes it REALLY easy to get started, the hardest part was figuring out the I2C connections but there’s plenty of resources online for helping with that.

My plan is to have a few of these setup, 2 inside my lizard enclosure (for hot and cool sides), a few around the house (humidity would be great, had a few issues with mould) and one for outside temperature readings. The next challenge I have is understanding how I can deploy the same application to multiple devices but with different config, so I can name the MQTT topics for each board. Time to get reading!

Exporting data from Enphase APIs

I bought an Enphase solar powered system in early 2017, one of the major appeals of the Enphase brand was that is has developer APIs, so I could track my systems power generation and even household usage.

My aim is to get this data out of the Enphase APIs then try to make sense of it, possibly bringing in weather data and water usage from IoT systems on my ever increasing to-do list.

There doesn’t seem to be a way of bulk exporting data, and with rate limiting on the free tier I figured I could write a script that hits the stats API for each day, grabs a whole days data then persist it, wait a period of time, then hit the next day. By delaying, I don’t break the rate limit, I can just kick the script off and have a coffee!

import pendulum
import time
import requests
import json
import os

userId = os.environ['ENHPASE_USER_ID']
key = os.environ['ENPHASE_KEY']
systemId = os.environ['ENPHASE_SYSTEM_ID']
# set tz code from
tzCode = os.environ['TIME_ZONE']
# free tier only allows so many requests per minute, space them out with delays
sleepBetweenRequests = int(os.environ['SLEEP_BETWEEN_REQUESTS'])
# Start/end dates to export
startDate = pendulum.parse(os.environ["START_DATE"], tzinfo=tzCode)
endDate = pendulum.parse(os.environ["END_DATE"], tzinfo=tzCode)
# Shouldn't need to modify this
url = '' % systemId

print('Starting report between %s and %s' % (startDate.to_date_string(), endDate.to_date_string()))

period = pendulum.period(startDate, endDate)

for dt in period.range('days'):

print('date [%s] START [%s] END [%s]' % (dt, dt.start_of('day'), dt.end_of('day')))
# HTTP Params
params = {'user_id': userId,
'key': key,
'datetime_format': 'iso8601',
'start_at': dt.start_of('day').int_timestamp,
'end_at': dt.end_of('day').int_timestamp}

r = requests.get(url=url, params=params)

if r.status_code == 200:
filename = "out/%s.json" % dt.to_date_string()
os.makedirs(os.path.dirname(filename), exist_ok=True)
with open(filename, 'w') as outfile:
json.dump(r.json(), outfile, indent=2)
print('Success %s' % dt.to_date_string())
print('Failed to get data for %s' % dt.to_date_string())

Run that using python and it’ll dump out a json file in /out/ per day. I’ve only got the stats API setup so far, but feel free to pull request in the others!

Also keen an eye on my github project, I’ll be adding more to it, the plan is to get it running in AWS with scheduled lambdas to pull in data on an hourly basis, mash in data from weather APIs, and any IoT systems I build.