AM-057 - Max30205 gives negative body temperature values

Hi,

I have tried quite a lot of stuff to configure MAX30205 which is attached with my Artemis nano board via QWIIC connector, But couldn’t make the sensor work.
All physical connections are fine, I2C address is properly working, (tested if i put wrong address(0x48 working one), or remove any of the four I2C wire from sensor end it gives “error reading sensor”)

I have tried ProtoCentral libs and other libs but no luck.

It is giving my negative values
”
20:49:38.326 -> -38.39'c
20:49:38.452 -> -38.38'c
”
Anybody has any solution or any secret configuration I am missing.

Thanks

Regards,
Usman C

There might be a problem in the code that you forgot to post.

The data sheet shows the device ONLY sends unsigned digital values, so negative temperatures are NOT POSSIBLE!

When you remove one of the wires you get what is expected. They put 4 wires there because that is what is needed. SCL is the clock, SDA is the return data, Ground is the common reference point and of course it does not harvest energy from the air so the + powers it. Now looking at the schematic you forgot to post and comparing it to the non posted code you are using I have determined I cannot figure out your problem either. Keep guessing you may get lucky.

If these body temperature readings do in fact turn out to be correct, then mention it to your doctor if there is an opportunity at the next visit.

This is a 3V3 logic board. The docs in the ProtoCentral library says their breakout board default is 5V and need a solder jumper change to work on 3V3. It’s a guess, but as already said, that’s all we can do without code and schematics…

If bit 5 of the configuration register is set, the "extended" temperature range is enabled, which uses the sign bit. In that case the library code might make a conversion error.

After reading the "How to get the best out of this forum" post (linked at the head of every forum category), post the required information.

#include <Wire.h>

#include "Protocentral_MAX30205.h"

MAX30205 tempSensor;

void setup() {

Serial.begin(9600);

Wire.begin();

//scan for temperature in every 30 sec untill a sensor is found. Scan for both addresses 0x48 and 0x49

while(!tempSensor.scanAvailableSensors()){

Serial.println("Couldn't find the temperature sensor, please connect the sensor." );

delay(30000);

}

Serial.print("sensorAddress is:");

Serial.println(tempSensor.sensorAddress);

tempSensor.begin();   // set continuos mode, active mode

delay(100);

}

void loop() {

float temp = tempSensor.getTemperature(); // read temperature for every 100ms

Serial.print(temp ,2);

Serial.println("'c" );

delay(100);

}


My apologies.
Now I have posted the code along with output and actual sensor pictures.
Let me know if anything else is needed.

I’ve found your breakout board in Google. It works from 2.7V to 3.3V. So it seems to be ok.

Nothing wrong with the sketch too. So, clue seems to be on post #7 .

This site brings a sketch that uses only wire library. Maybe you can use it to make a test.

Running 8 bit Arduino code on a 32 bit processor may be the problem.

Hi, @uc-mani

Have you soldered the headers to the module PCB?

Can you post some images of your project?
So we can see your component layout.

Specifically the solder side of the PCBs.

Thanks.. Tom.... :smiley: :+1: :coffee: :australia:

It sounds like a library problem, you should report it at their repo

Yes i have soldered it. Please see the other picture attached

It works but with a twist.
I am forced to use extended mode D5=1. And according to spec you have to add 64’c with the temperature value. Which somehow is giving me the accurate results.

here is the code snippet

void begin(void) {
	I2CwriteByte(sensorAddress, CONFIGURATION_REG, 0x20);  //mode config, setting D5 = 1 Extended mode (–64 °C → +191 °C)
	I2CwriteByte(sensorAddress, THYST_REG, 0x00);          // set threshold
	I2CwriteByte(sensorAddress, TOS_REG, 0x00);            //
}
float getTemperature(void) {
	uint8_t buf[2];
	I2CreadBytes(sensorAddress, TEMPERATURE_REG, buf, 2);

	int16_t raw = (int16_t)((buf[0] << 8) | buf[1]);
	float temp = (raw * 0.00390625) + 64.0;

	return temp;
}

Output:

14:58:04.220 -> 31.88'c
14:58:05.236 -> 31.93'c
14:58:06.265 -> 32.00'c
14:58:07.281 -> 32.03'c
14:58:08.283 -> 32.07'c
14:58:09.278 -> 32.12'c
14:58:10.302 -> 32.15'c
14:58:11.302 -> 32.19'c

uc-mani could you share your final code? I am have some issues with the same sensor. Thanks.

This problem has not been solved, it's just been worked around with the above mentioned "use extended mode and add 64.0 to the intermediate result".
What the datasheet does not say is that in normal data format mode the high order two bits are set but should be ignored. If after creating the 16 bit integer you mask the high order two bits when in normal mode with something like "raw = raw & 0x3fff" then cast to float and multiply the remaining value by 0.00390625 you will see the correct temperature. I'll see if I can get a message to Analog Devices requesting an update to their datasheet. In my opinion they don't have any defense for setting these two high bits in normal data format mode, but I expect them to tell me something like "Well we say in normal mode the range is 0 to 50C, so neither the sign bit nor the next bit signifying 64C can have any meaning!" So I'll beg for them to be merciful. :-)

To fix the GitHub - Protocentral/Protocentral_MAX30205: Arduino library and hardware for the ProtoCentral MAX30205 body temperature sensor breakout board · GitHub repo (as it exists today, May 1, 2026) edit src/Protocentral_MAX30205.cpp line 26 that has this:
int16_t raw = readRaw[0] << 8 | readRaw[1]; //combine two bytes
but should be like this:
int16_t raw = (readRaw[0] << 8 | readRaw[1]) & 0x3fff; //combine two bytes and ignore top two bits