Hello,
I am a newbie. I am working with max30102 sensors(I assume they are I2C sensors). I want to read data from 3 Max sensors( placed at different positions to compare spO2 readings). I am using Nano RP 2040. I could get data from one sensor but was not able to get data from all three sensors simultaneously. I am not able to figure out how to connect and get the data out. kindly guide.
The I2C protocol requires that each address has a separate address to which commands are sent and data is received.
It appears that the sensor you have selected has only a fixed address, 0xAE for write operationsand 0xAF for read operations. Since it seems that the manufacturer has left no way to change the address to differentiate the sensors to the uController, you will need to make significant changes to your design.
This old video may explain it and a possible solution for you.
Anything seems possible when you don't know what you're talking about.
@snb @will FYI EDIT My bad, I see @will covered it. Hey, I haven't had my first coffee, just ignore the old man behind the curtain.
Another possible approach is an I2C multiplexor like
https://learn.adafruit.com/working-with-multiple-i2c-devices
or find a board that can house your board and provide multiple I2C. I am sure I have seen one but don't remember where and in any case is probably just a packaged multiplexor/rp2040 board.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
Thanks, @Will and @Ron for the super fast response. Will try out and revert.
@snb I assume that was supposed to be ... and report.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
Hi @snb,
I haven't watched them, but in addition to the video @will mentioned, there are others, probably all based on the device, although they may have different boards:
From this forum, Bill (aka @drone-workshop) 's excellent clear style and guaranteed to work approach:
...............
And for further views, since it sometimes it pays to watch more than one to pick up small details, etc.
'Randon Nerd Tutorials' crowd usually do their homework and worth a look:
https://randomnerdtutorials.com/tca9548a-i2c-multiplexer-esp32-esp8266-arduino/
And similarly, the "Guy with Swiss accent"
www.youtube.com/watch?v=QQLfzlPGjjE
Best wishes, Dave
Here is an update. I am using PCA9548A multiplexer. SDA of MUX is connected to A4, SCL is connected to A5 of Nano rp2040. PIN A0, A1, A2 of MUX are grounded. sensor 1 SDA and SCL are connected to SD0 and SC0, and Sensor 2 SDA and SCL are connected to SD1 and SC1 of MUX. The sensors are not getting detected. I tried running I2C scanner. As long as I connect only RP2040, the scanner detects two addresses 0x60 and 0x6A. when I connect the mux, the scanner gets into an infinite loop and doesn't display anything until I disconnect the MUX. where am I going wrong?
#include <Wire.h> #include "MAX30105.h" #include "spo2_algorithm.h" #include "heartrate.h" #include "WiFiNINA.h" MAX30105 sensor1; MAX30105 sensor2; const byte RATE_SIZE = 4; byte rates[RATE_SIZE]; byte rateSpot = 0; long lastBeat = 0; float beatsPerMinute; int beatAvg, perCent1, iroffset1 = 2100; #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) //Arduino Uno doesn't have enough SRAM to store 100 samples of IR led data and red led data in 32-bit format //To solve this problem, 16-bit MSB of the sampled data will be truncated. Samples become 16-bit data. uint16_t irBuffer[100]; //infrared LED sensor data uint16_t redBuffer[100]; //red LED sensor data #else uint32_t irBuffer[100]; //infrared LED sensor data uint32_t redBuffer[100]; //red LED sensor data #endif int32_t bufferLength; //data length int32_t spo2; //SPO2 value int8_t validSPO2; //indicator to show if the SPO2 calculation is valid int32_t heartRate; //heart rate value int8_t validHeartRate; //indicator to show if the heart rate calculation is valid void TCA9548A(uint8_t bus){ if(bus>7) return; Wire.beginTransmission(0x70); // TCA9548A address Wire.write(1 << bus); // send byte to select bus Wire.endTransmission(); Serial.print(bus); } void setup() { byte ledBrightness = 25; byte sampleAverage = 4; byte ledMode = 2; byte sampleRate = 400; int pulseWidth = 411; int adcRange =2048; Serial.begin(9600); //pinMode(A4, INPUT); //pinMode(A5, INPUT); Serial.println("Initializing..."); Wire.begin(); delay(0); //Sensor1 TCA9548A(0); if(!sensor1.begin(Wire, I2C_SPEED_FAST)) { Serial.println(F("SENSOR 1 NOT DETECTED!! 1......1.....1......1......1......1")); for(;;); } Serial.println("Place finger on sensor 1. ......1........1"); sensor1.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); sensor1.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running sensor1.setPulseAmplitudeGreen(0);//turn off Green LED //Sensor2 TCA9548A(1); if(!sensor2.begin(Wire, I2C_SPEED_FAST)) { Serial.println(F("SENSOR 2 NOT DETECTED!! 2......2.....2......2......2......2")); for(;;); } Serial.println("Place finger on sensor 2. ......2........2"); sensor2.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); sensor2.setPulseAmplitudeRed(0x0A); sensor2.setPulseAmplitudeGreen(0); } void loop() { //Sensor 1 TCA9548A(0); long irValue1 = sensor1.getIR(); Serial.print(irValue1*5000); Serial.print(" "); //Sensor 2 TCA9548A(1); long irValue2 = sensor2.getIR(); Serial.print(irValue2); Serial.print(" "); }
@snb My limited understanding of a multiplexor is it occupies one address on the MPU/MCU and by using a selector of some sort can connect the multiplexor to several I2C buses. That means the standard I2C scanner will not be able to 'see' the I2C devices connected to the mux, the scanner will only 'see' the mux which is itself not an I2C device.
I do not have detailed information or experience with a mux but would expect to see some code to cause the mux to select one of the downstream I2C devices at a time. I don't see anything like that.
I hope my naive observations spur you to more research and success.
Good luck.
EDIT Found a sample of how to select over on the nerds site, see pic, I recommend the randomnerds for inspiration.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
@zander Thanks a lot for the reply. I have included the bus selection method before setup(). also, I am switching between bus0 and 1.
@snb So it's working?
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
@zander no. Its not. I have connected the nano to laptop for power. I can measure 5V across nano, mux as well as sensor. If i connect Uno instead of nano, it works with following code. with Nano I tried with A4 and A5. but not able to get it working.
pinMode(11, OUTPUT); pinMode(13, OUTPUT);
@snb Maybe you should study their article and example and run their example on your board to make sure it's not a board problem, then you can modify that sketch to do whatever you want that is different.
Here is the link https://randomnerdtutorials.com/tca9548a-i2c-multiplexer-esp32-esp8266-arduino/
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
Dear @zander, The code looks different because of the sensor. I have followed the same code. I am able to read both sensor data through MUX if I am connecting Arduino Uno. but with nano, it fails. Even when I scan for I2C address, with Uno I get addresses 0x57 and 0x70. but Nano returns 0x60 and 0x6A. As I understand, these two (60 and 6A are reserved for the accelerometer and gyrometer). not able to understand the mistake.