So I want to use multiple BME280 sensors for a project and I want it to be scalable. I was previously using a i2c multiplexer where I could add sensors to the multiplexer and have a single sensor object for all the sensors on the multiplexer and just switch the MUX pin through a for loop. You can see the code below.
#include "Wire.h"
#include "SparkFunBME280.h"
#define i2cmux 0x70
BME280 sensor;
#define sensor_number 4
float temp[sensor_number], hum[sensor_number];
const unsigned int DELAY = 2000;
unsigned long prevMillis = 0;
void setup(){
Wire.begin();
Serial.begin(9600);
for (byte i=0; i < sensor_number; i++){
muxport(i);
set_sensor();
delay(5);
}
delay(500);
}
void loop(){
if(millis() - prevMillis > DELAY){
read_sensor();
print_sensor("Temp", temp, 1);
print_sensor("Hum", hum, 0);
Serial.println();
prevMillis = millis();
}
}
void muxport(byte i){ //MUX port selector
if (i > 7) return;
Wire.beginTransmission(i2cmux);
Wire.write(1 << i);
Wire.endTransmission();
}
void read_sensor(){ //Reads values from sensors connected to the MUX in order
for (byte i=0; i < sensor_number; i++){
muxport(i);
temp[i] = sensor.readTempC();
hum[i] = sensor.readFloatHumidity();
}
}
void print_sensor(String type, float value[], byte decimal){ //Prints values from sensors in order
Serial.print(" ");
Serial.print(type);
Serial.print(": ");
for (byte i=0; i < sensor_number; i++){
Serial.print(value[i], decimal);
Serial.print(" | ");
}
}
This has worked okay for some time however I have noticed calibration errors between the sensors and when I swap sensor places, the values change randomly. For example when temperature reads were like 24 24 23 25 , and I swap sensors 1 and 3 the expected readings should be 23 24 24 25 but it becomes something like 22 23 24 24 (I have simplified the results, I know they change depending on time however this also happens to the average over time values.) Anyways I have switched to SPI connection and get rid of the multiplexer and the swapping errors decreased significantly and I am getting more stable results from the sensors, but now I have to set each sensor by hand, and read values from then one at a time instead of just looping them.
#include "SparkFunBME280.h"
#define SENSOR_NUMBER 4
BME280 sensor0, sensor1, sensor2, sensor3;
float temp[SENSOR_NUMBER], hum[SENSOR_NUMBER], pres[SENSOR_NUMBER];
const unsigned int DELAY = 2000;
unsigned long prevMillis = 0;
void setup(){
Serial.begin(9600);
sensor0.beginSPI(10);
sensor1.beginSPI(9);
sensor2.beginSPI(8);
sensor3.beginSPI(7);
}
void loop(){
if(millis() - prevMillis > DELAY){
read_sensor();
print_sensor("Temp", temp, 1);
print_sensor("Hum", hum, 1);
print_sensor("Pres", pres, 0);
Serial.println();
prevMillis = millis();
}
}
void read_sensor(){
temp[0] = sensor0.readTempC();
temp[1] = sensor1.readTempC();
temp[2] = sensor2.readTempC();
temp[3] = sensor3.readTempC();
hum[0] = sensor0.readFloatHumidity();
hum[1] = sensor1.readFloatHumidity();
hum[2] = sensor2.readFloatHumidity();
hum[3] = sensor3.readFloatHumidity();
pres[0] = sensor0.readFloatPressure();
pres[1] = sensor1.readFloatPressure();
pres[2] = sensor2.readFloatPressure();
pres[3] = sensor3.readFloatPressure();
}
void print_sensor(String type, float value[], byte decimal){
Serial.print(" ");
Serial.print(type);
Serial.print(": ");
for (byte i=0; i < SENSOR_NUMBER; i++){
Serial.print(value[i], decimal);
Serial.print(" | ");
}
}
I want to apply the scalability of the i2c multiplexer to the SPI connection however I haven't found a way to do that while there are multiple sensor objects. Can it be done or am I stuck with manually writing each line for each sensor when I go from 4 sensors to 8?