Thanks, ejlane.
No, I have combined the code from the BME280 sensor example into the gateway code to have a local sensor on the gateway, which is supposed to be supported now. Btw, I'm using MySensors v2.3.2, not development branch. I have not started using any nodes so far, so just the ESP32 board is running.
platformio.ini
[env:lolin32]
platform = espressif32
board = lolin32
framework = arduino
monitor_speed = 115200
lib_deps =
mysensors/MySensors@^2.3.2
adafruit/Adafruit BME280 Library@^2.2.2
main.cpp
// Set Static Node ID
#define MY_NODE_ID 12
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_MQTT_CLIENT
#define MY_GATEWAY_ESP32
// Set this node's subscribe and publish topic prefix
//#define MY_MQTT_PUBLISH_TOPIC_PREFIX "mygateway1-out"
//#define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "mygateway1-in"
// Set MQTT client id
//#define MY_MQTT_CLIENT_ID "mysensors-1"
// Enable these if your MQTT broker requires usenrame/password
//#define MY_MQTT_USER "username"
//#define MY_MQTT_PASSWORD "password"
// Set WIFI SSID and password
//#define MY_WIFI_SSID "MySSID"
//#define MY_WIFI_PASSWORD "MyVerySecretPassword"
// Set the hostname for the WiFi Client. This is the hostname
// passed to the DHCP server if not static.
//#define MY_HOSTNAME "ESP32_MQTT_GW"
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192,168,178,87
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// MQTT broker ip address.
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 1, 5
// The MQTT broker port to to open
#define MY_PORT 1883
#include <Arduino.h>
#include <secrets.h>
#include <MySensors.h>
#include <SPI.h> // A communication backbone, the Serial Peripheral Interface.
#include <Wire.h> // Enables the Wire communication protocol.
#include <Adafruit_BME280.h> // alternative library you could try (DIY; no code for this is in here yet).
// VARIABLES YOU CAN CHANGE
const float ALTITUDE = 160; // Change this value to your location's altitude (in m). Use your smartphone GPS to get an accurate value, or use an online map.
unsigned long BME280measurementInterval = 60000; // Sleep time between reads for the BME sensor (in ms). Keep this value at 60000 if you have enabled the forecast feature, as the forecast algorithm needs a sample every minute.
#define COMPARE_TEMP 0 // Send temperature only if it changed? 1 = Yes 0 = No. Can save battery.
float tempThreshold = 0.1; // How big a temperature difference has to minimally be before an update is sent. Makes the sensor less precise, but also less jittery, and can save battery.
#define COMPARE_HUM 0 // Send humidity only if changed? 1 = Yes 0 = No. Can save battery.
float humThreshold = 0.1; // How big a humidity difference has to minimally be before an update is sent. Makes the sensor less precise, but also less jittery, and can save battery.
#define COMPARE_BARO 0 // Send barometric pressure only if changed? 1 = Yes 0 = No. Can save battery.
float presThreshold = 0.1; // How big a barometric difference has to minimally be before an update is sent. Makes the sensor less precise, but also less jittery, and can save battery.
// VARIABLES YOU PROBABLY SHOULDN'T CHANGE
#define TEMP_CHILD_ID 1 // for MySensors. Within this node each sensortype should have its own ID number.
#define HUM_CHILD_ID 2 // for MySensors. Within this node each sensortype should have its own ID number.
#define BARO_CHILD_ID 3 // for MySensors. Within this node each sensortype should have its own ID number.
float lastTemperature = -1; // Stores the previous measurement, so it can be compared with a new measurement.
float lastHumidity = -1; // Stores the previous measurement, so it can be compared with a new measurement.
float lastPressure = -1; // Stores the previous measurement, so it can be compared with a new measurement.
unsigned long BME280measurementSleepTime = 0; // variable to store the calculated Sleep time if the node is battery powered.
bool metric = true; // Variable that stores if the sensor will output the temperature in Fahrenheit of Celsius. The gateway sends this preference to the node, so you dont need to change it here.
bool receivedConfig = false; // The MySensors gateway will tell the node if it should output in metric or not.
// MYSENSORS COMMUNICATION VARIABLES
MyMessage temperatureMsg(TEMP_CHILD_ID, V_TEMP);
MyMessage humidityMsg(HUM_CHILD_ID, V_HUM);
MyMessage pressureMsg(BARO_CHILD_ID, V_PRESSURE);
#ifdef GENERATE_FORECAST
MyMessage forecastMsg(BARO_CHILD_ID, V_FORECAST);
#endif
Adafruit_BME280 bme; //I2C
void setup() {
Wire.begin(); // Wire.begin(sda, scl) // starts the wire communication protocol, used to chat with the BME280 sensor.
Serial.begin(115200); // for serial debugging over USB.
Serial.println("Hello world, I am a Gateway with sensor.");
}
void presentation() {
// Send the sketch version information to the gateway and Controller
sendSketchInfo("Gateway_with_Sensor", "1.1");
// Tell the MySensors gateway what kind of sensors this node has, and what their ID's on the node are, as defined in the code above.
present(BARO_CHILD_ID, S_BARO);
present(TEMP_CHILD_ID, S_TEMP);
present(HUM_CHILD_ID, S_HUM);
}
void loop() {
// You should not change these variables:
static unsigned long previousBME280Millis = 0; // Used to remember the time that the BME280 sensor was asked for a measurement.
unsigned long currentMillis = millis(); // The time since the sensor started, counted in milliseconds. This script tries to avoid using the Sleep function, so that it could at the same time be a MySensors repeater.
static boolean BME280shouldAsk = true; // This is true when the time is right for a new measurement to be made.
static boolean BME280justAsked = false; // This indicates whether we have just asked the sensor module for a measurement, so the receiving part of the code (part 2) should be primed. This two-part construction helps to bridge the time where the BME280 module is busy, without blocking the entire node from doing anything else (like being a repeater, or working with other connected sensor modules).
// PART 1. If enough time has passed, a new measurement should be taken:
if (BME280shouldAsk == true && currentMillis - previousBME280Millis >= BME280measurementInterval) {
previousBME280Millis = currentMillis; // store the current time as the previous measurement start time.
BME280shouldAsk = false;
Serial.println("");
Serial.println("BME280 - Requesting new data from sensor module.");
// bme.readCoefficients(); // Read NVM compensation parameters
// BME280.readCompensationParams(); // Need to read the NVM compensation parameters.
// Normal mode for regular automatic samples
Serial.println("Just before setSampling");
bme.setSampling(Adafruit_BME280::MODE_NORMAL, //normal mode
Adafruit_BME280::SAMPLING_X8, //temperature x8
Adafruit_BME280::SAMPLING_X16, //pressure x16
Adafruit_BME280::SAMPLING_X8, //humidity x8
Adafruit_BME280::FILTER_OFF, //IIR Filter coefficient
Adafruit_BME280::STANDBY_MS_0_5); //tsb = 0.5ms
// BME280.writeStandbyTime(tsb_0p5ms); // tsb = 0.5ms
// BME280.writeFilterCoefficient(fc_off); // IIR Filter coefficient 16
// BME280.writeOversamplingPressure(os1x); // pressure x16
// BME280.writeOversamplingTemperature(os1x); // temperature x8
// BME280.writeOversamplingHumidity(os1x); // humidity x8
// BME280.writeMode(smNormal);
// As we exit part 1, in theory BME280.isMeasuring() should now be true.
Serial.println("Just after setSampling");
BME280justAsked = true;
}
// Part 2. This will trigger if the sensor has just been asked for a measurement, and is also just done figuring out those measurements.
// if(BME280justAsked == true && BME280.isMeasuring() == false) { //
Serial.println("Just before isMeasuring");
if(BME280justAsked == true && bme.isMeasuring() == false) { //
Serial.println("After isMeasuring");
BME280justAsked = false; // makes sure we don't do this part again in the next pass through the main loop.
Serial.println("BME280 - Sensor module has some new values ready:");
// Read out the data - must do this before calling the getxxxxx routines
float temperature = bme.readTemperature(); // Must get the temperature first.
float humidity = bme.readHumidity(); // Get the humidity.
float pressure_local = bme.readPressure(); // Get pressure at current location
// float temperature = BME280.getTemperatureMostAccurate(); // Must get the temperature first.
// float humidity = BME280.getHumidityMostAccurate(); // Get the humidity.
// float pressure_local = BME280.getPressureMostAccurate(); // Get pressure at current location
float pressure = pressure_local/pow((1.0 - ( ALTITUDE / 44330.0 )), 5.255); // Adjust to sea level pressure using user altitude
// Now, let's send the measurements to the gateway.
// Send temperature
if (COMPARE_TEMP == 1 && abs(temperature - lastTemperature) < tempThreshold) { // is the temperature difference bigger than the threshold?
Serial.print(temperature - lastTemperature);
Serial.print("- BME280 - Temperature difference too small, so not sending the new measurement to the gateway.\n");
} else {
Serial.print("BME280 - Sending the new temperature to the gateway.\n");
send(temperatureMsg.set(temperature, 1));
lastTemperature = temperature; // Save new temperatures to be able to compare in the next round.
}
// Send humidity
if (COMPARE_HUM == 1 && abs(humidity - lastHumidity) < humThreshold) { // is the humidity difference bigger than the threshold?
Serial.print(humidity - lastHumidity);
Serial.println("- BME280 - Humidity difference too small, so not sending the new measurement to the gateway.");
} else {
Serial.println("BME280 - Sending the new humidity to the gateway.");
send(humidityMsg.set(humidity, 1));
lastHumidity = humidity; // Save new humidity to be able to compare in the next round.
}
// Send pressure
if (COMPARE_BARO == 1 && abs(pressure - lastPressure) < presThreshold) { // is the pressure difference bigger than the threshold?
Serial.print(pressure - lastPressure);
Serial.println("- BME280 - Pressure difference too small, so not sending the new measurement to the gateway.");
} else {
Serial.println("BME280 - Sending the new pressure to the gateway.");
send(pressureMsg.set(pressure, 1));
lastPressure = pressure; // Save new pressure to be able to compare in the next round.
}
Serial.println("BME280 - Measurement complete. Going to wait until next measurement.");
BME280shouldAsk = true; // Ready for the new round.
}
}
Some of the Serial.println are for debugging purposes to find where the code is crashing...
Not sure if I should have a static node ID for the gateway. If so, it would probably be ID 1.
The various usernames and passwords, etc. are included in the secrets.h-file, which I think should have been default with MySensors.