I have a few BME280 weather stations in and around the house. My devices connect to the local wifi network and start a web server that my data collector server polls every few minutes to collect data into a database.
This runs very reliably until the device loses the wifi connection, for instance when the router is being rebooted. I have no clue about C programming and have just collected and combined a few code snippets to make it work.
However, I don't seem to be using the statement "if (WiFi.status() != WL_CONNECTED)" at the beginning of loop() correctly to jump back to the setup() function and re-establish the wifi connection in case it's gone.
Does anyone have a tipp? My code:
// INIT WIFI
#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
IPAddress ip(10, 10, 23, 46);
int status = WL_IDLE_STATUS;
WiFiServer server(80);
// INIT BME280
#include <Arduino.h>
#include <Wire.h>
#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76
//create a BMx280I2C object using the I2C interface with I2C Address 0x76
BMx280I2C bmx280(I2C_ADDRESS);
void setup() {
// SETUP WIFI AND WEB-SERVER
// Assign fixed IP
WiFi.config(ip);
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
server.begin();
// SETUP BME280
Wire.begin();
//begin() checks the Interface, reads the sensor ID (to differentiate between BMP280 and BME280)
//and reads compensation parameters.
if (!bmx280.begin())
{
while (1);
}
//reset sensor to default parameters.
bmx280.resetToDefaults();
//by default sensing is disabled and must be enabled by setting a non-zero
//oversampling setting.
//set an oversampling setting for pressure and temperature measurements.
bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
//if sensor is a BME280, set an oversampling setting for humidity measurements.
if (bmx280.isBME280())
bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}
void loop() {
// Reset connection if it disappears
if (WiFi.status() != WL_CONNECTED)
{
setup();
}
// listen for incoming clients
WiFiClient client = server.available();
if (client) {
// an HTTP request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the HTTP request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard HTTP response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println();
// Output the measurement values
delay(1000);
//start a measurement
if (!bmx280.measure())
{
return;
}
//wait for the measurement to finish
do
{
delay(100);
} while (!bmx280.hasValue());
// Output BME280 Readings
client.print(bmx280.getTemperature());
client.print(";");
client.print(bmx280.getPressure());
client.print(";");
client.print(bmx280.getHumidity());
client.print(";");
//Output voltage from A0
int sensorReading = analogRead(0);
client.print(sensorReading);
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
Calling setup is not advised....Put the code in setup in a separate function.
Something like this should work....
#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
IPAddress ip(10, 10, 23, 46);
int status = WL_IDLE_STATUS;
WiFiServer server(80);
// INIT BME280
#include <Arduino.h>
#include <Wire.h>
#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76
//create a BMx280I2C object using the I2C interface with I2C Address 0x76
BMx280I2C bmx280(I2C_ADDRESS);
void setup() {
// SETUP WIFI AND WEB-SERVER
setup_WIFI();
// SETUP BME280
Wire.begin();
//begin() checks the Interface, reads the sensor ID (to differentiate between BMP280 and BME280)
//and reads compensation parameters.
if (!bmx280.begin())
{
while (1);
}
//reset sensor to default parameters.
bmx280.resetToDefaults();
//by default sensing is disabled and must be enabled by setting a non-zero
//oversampling setting.
//set an oversampling setting for pressure and temperature measurements.
bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
//if sensor is a BME280, set an oversampling setting for humidity measurements.
if (bmx280.isBME280())
bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}
void loop() {
// Reset connection if it disappears
if (WiFi.status() != WL_CONNECTED)
{
setup_WIFI();
}
// listen for incoming clients
WiFiClient client = server.available();
if (client) {
// an HTTP request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the HTTP request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard HTTP response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println();
// Output the measurement values
delay(1000);
//start a measurement
if (!bmx280.measure())
{
return;
}
//wait for the measurement to finish
do
{
delay(100);
} while (!bmx280.hasValue());
// Output BME280 Readings
client.print(bmx280.getTemperature());
client.print(";");
client.print(bmx280.getPressure());
client.print(";");
client.print(bmx280.getHumidity());
client.print(";");
//Output voltage from A0
int sensorReading = analogRead(0);
client.print(sensorReading);
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
void setup_WIFI() {
// SETUP WIFI AND WEB-SERVER
// Assign fixed IP
WiFi.config(ip);
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
server.begin();
}
Thanks a lot! I understand and yes, it looks cleaner. Unfortunately the connection still is not being restored though. Is the location at the beginning of the loop() function correct? Does this get executed even if no client has polled the web server data? Or should I put it within the while loop? Or maybe my if statement itself is buggy?
No success. I check this out and tried connection lost and that too fails. I think I will play around with those some more and put them in different places. Thanks a lot for your help!
Success! @gcjr your comment got me to rethink the order in which things are happening. Thanks for the mental floss! I do indeed have to put WiFi.begin() into the loop as otherwise it won't work if the wifi downtime is too long. Also, server.begin() (starting the web server) had to go to setup() as that may only be used once, otherwise something blocks the web server.
So now I'm testing long term but so far it's looking good. Code below for reference. Thanks everyone for your time and help!
#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
IPAddress ip(10, 10, 23, 46);
int status = WL_IDLE_STATUS;
WiFiServer server(80);
// INIT BME280
#include <Arduino.h>
#include <Wire.h>
#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76
//create a BMx280I2C object using the I2C interface with I2C Address 0x76
BMx280I2C bmx280(I2C_ADDRESS);
void setup() {
// SETUP BME280
Wire.begin();
//begin() checks the Interface, reads the sensor ID (to differentiate between BMP280 and BME280)
//and reads compensation parameters.
if (!bmx280.begin())
{
while (1);
}
//reset sensor to default parameters.
bmx280.resetToDefaults();
//by default sensing is disabled and must be enabled by setting a non-zero
//oversampling setting.
//set an oversampling setting for pressure and temperature measurements.
bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
//if sensor is a BME280, set an oversampling setting for humidity measurements.
if (bmx280.isBME280())
bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
setup_WIFI();
server.begin();
}
void loop() {
// Reset connection if it disappears
if (WiFi.status() != WL_CONNECTED)
{
setup_WIFI();
}
// listen for incoming clients
WiFiClient client = server.available();
if (client) {
// an HTTP request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the HTTP request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard HTTP response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println();
// Output the measurement values
delay(1000);
//start a measurement
if (!bmx280.measure())
{
return;
}
//wait for the measurement to finish
do
{
delay(100);
} while (!bmx280.hasValue());
// Output BME280 Readings
client.print(bmx280.getTemperature());
client.print(";");
client.print(bmx280.getPressure());
client.print(";");
client.print(bmx280.getHumidity());
client.print(";");
//Output voltage from A0
int sensorReading = analogRead(0);
client.print(sensorReading);
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
void setup_WIFI() {
// Assign fixed IP
WiFi.config(ip);
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
// don't continue
while (true);
}
// String fv = WiFi.firmwareVersion();
while (WiFi.status() != WL_CONNECTED)
{
WiFi.begin(ssid, pass);
delay(5000);
}
}