Hopfully someone on here can assist with an odd problem I have run into. I am using a TCA9548A i2c multiplexer with 3 MAX30102 sensors. I have everything wired up and my code works when testing the infrared and red lights on each sensor. My issue is when I try to change the code to read other signals using these infrared and red lights. My code will only read the last sensor. I have the first sensor reading heart rate, the second senor reading blood oxygen saturation, and the third sensor reading temperature. When I test the code the output is all 3 reading from the third sensor and not one from each. Has anyone else came across this problem? My code is attached.
#include <Wire.h>
#include "MAX30105.h"
#include "heartRate.h"
MAX30105 sensor1;
MAX30105 sensor2;
MAX30105 sensor3;
const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
int perCent1;
int irOffset1 = 2100;
#define TCAADDR 0x70
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
void setup()
{
Serial.begin(9600);
Serial.println("Initializing...");
Wire.begin();
delay(0);
// Initialize sensor One
tcaselect(0);
if (!sensor1.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
}
Serial.println("Place your index finger on the sensor with steady pressure.");
sensor1.setup(); //Configure sensor with default settings
sensor1.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
sensor1.setPulseAmplitudeGreen(0); //Turn off Green LED
// Initialize sensor Two
tcaselect(1);
if (!sensor2.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
}
Serial.println("Place your index finger on the sensor with steady pressure.");
byte ledBrightness2 = 25; //Options: 0=Off to 255=50mA=0xFF hexadecimal. 100=0x64; 50=0x32 25=0x19
byte sampleAverage2 = 4; //Options: 1, 2, 4, 8, 16, 32
byte ledMode2 = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
int sampleRate2 = 400; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth2 = 411; //Options: 69, 118, 215, 411
int adcRange2 = 2048; //Options: 2048, 4096, 8192, 16384
sensor2.setup(ledBrightness2, sampleAverage2, ledMode2, sampleRate2, pulseWidth2, adcRange2); //Configure sensor with default settings
sensor2.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
sensor2.setPulseAmplitudeGreen(0); //Turn off Green LED
// Initialize sensor Three
tcaselect(2);
if (!sensor3.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
}
Serial.println("Place your index finger on the sensor with steady pressure.");
sensor3.setup(); //Configure sensor with default settings
sensor3.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
sensor3.setPulseAmplitudeGreen(0); //Turn off Green LED
}
//*******************************************************************************************//
void loop()
{
long irValue1 = sensor1.getIR();
if (checkForBeat(irValue1) == true)
{
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute < 255 && beatsPerMinute > 50)
{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}
tcaselect(0);
Serial.print(", BPM=");
Serial.print(beatsPerMinute);
Serial.print(", Avg BPM=");
Serial.print(beatAvg);
tcaselect(1);
long irValue2 = sensor2.getIR();
Serial.print(" ");
perCent1 = irValue1 / irOffset1; //offset provides percent
Serial.print("Oxygen=");
Serial.print(perCent1);
Serial.print("%");
tcaselect(2);
float temperatureF3 = sensor3.readTemperatureF(); //Because I am a bad global citizen
Serial.print(" temperatureF=");
Serial.print(temperatureF3, 4);
Serial.println();
delay(300);
}
// Initialize sensor Three
tcaselect(2);
if (!sensor3.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
}
Serial.println("Place your index finger on the sensor with steady pressure.");
sensor3.setup(); //Configure sensor with default settings
sensor3.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
sensor3.setPulseAmplitudeGreen(0); //Turn off Green LED
}
At the start of the loop the code calculates information to determine heart rate from sensor 1:
void loop()
{
long irValue1 = sensor1.getIR();
if (checkForBeat(irValue1) == true)
{
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute < 255 && beatsPerMinute > 50)
{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}
Lastly, I select the multiplexer ports again to print the readings:
tcaselect(0);
Serial.print(", BPM=");
Serial.print(beatsPerMinute);
Serial.print(", Avg BPM=");
Serial.print(beatAvg);
tcaselect(1);
long irValue2 = sensor2.getIR();
Serial.print(" ");
perCent1 = irValue1 / irOffset1; //offset provides percent
Serial.print("Oxygen=");
Serial.print(perCent1);
Serial.print("%");
tcaselect(2);
float temperatureF3 = sensor3.readTemperatureF(); //Because I am a bad global citizen
Serial.print(" temperatureF=");
Serial.print(temperatureF3, 4);
Serial.println();
delay(300);
My issue is that all of these readings are being read from sensor 3 instead of each sensor. I believe the issue in my code has something to do with the tcaselect() but I have not been able to determine where. My code seems to not be selecting the correct ports on the multiplexer.
Which library and which multiplexer do you use ? Please give links to them.
I suppose the Sparkfun hardware and libraries are used. That might be a problem.
In the file MAX30105.cpp is struct with arrays used called 'sense'. I think only one 'sense' is used for every class. That means that the library can not be used for multiple MAX30105 ? I'm not sure, perhaps someone else can look into it.
HALOBEAST999, user TheMemberFormerlyKnownAsAWOL was trying to tell you that you do something with a sensor at the beginning of the loop() without setting the multiplexer. The multiplexer was still set for sensor3 at the end of the loop(), yet you try to communicate with sensor1 at the beginning of the loop().
Why don't you organize it in a normal way, for example: