How to get decimal place from int32_t value?

Hi all,

Some advice would be appreciated.

I’m constructing a simple weather station, writing the temperature and pressure to an LCD screen.
I know it’s been done a million times but I wanted to do one from the ground up to learn some things.

The parts I’m using are:
Lolin HP303B sensor (LINK)
ST7735 SPI 128x128 LCD screen (LINK)
Wemos D1 mini (LINK)

It’s working fine, only thing is the temperature shows up as a whole number e.g. 25C
I would like it to show to one decimal place i.e. 25.3C

Having googled, I ‘think’ I need to float the temperature value, I have tried several things but nothing works.

I still don’t really understand the “int32_t temperature” line or how the values are being read from the sensor.

Here is the current code:

//v2 of Indoor Outdoor Weather monitor with LCD screen
//
//this version is just LCD screen with temperature &barometric pressure written at bottom of screen in yellow
//
//Lolin HP303B sensor
//
//TFT is 128x128 SPI ST7735 (ebay) , 8 lines x 16pixels high.

#include <LOLIN_HP303B.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SimpleTimer.h>
//#include <SPI.h>

//TFT ST7735 pin setup 128x128 SPI Ebay
#define TFT_CS        D4
#define TFT_RST       D3 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC        D8
 
// HP303B Opject
LOLIN_HP303B HP303BPressureSensor;

//Setup simple timer
SimpleTimer timer;

//Setup TFT
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);




 void setup()
{
  tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab
  tft.setRotation(2);   //where 0=0; 1=90; 2=180; 3=270degrees
  tft.fillScreen(ST77XX_BLACK);
  HP303BPressureSensor.begin();

   // Setup a function to be called every second
  timer.setInterval(1000L, sendSensor);
}


void loop ()
{
  timer.run(); // Initiates SimpleTimer
  
}


void sendSensor()
{
  int32_t temperature;
  int32_t pressure;
  int16_t oversampling = 7;
  int16_t ret;


  //Read temperature sensor
  ret = HP303BPressureSensor.measureTempOnce(temperature, oversampling);
 
  if (ret != 0)
  {
    //Something went wrong.
    //Look at the library code for more information about return codes
     tft.setTextColor(ST7735_RED, ST7735_BLACK);
     tft.setTextSize(2);
     tft.setCursor(0,96);
     tft.print("Temp Error ");
  }
  else
  {
     tft.setTextColor(ST7735_RED, ST7735_BLACK);
     tft.setTextSize(2);
     tft.setCursor(0,96);
     tft.print("Temp:");
     tft.print(temperature);      //HOW TO MAKE THIS TO ONE DECIMAL PLACE? i.e. 20.5 
     tft.print("c");
  }


   //Read pressure sensor
  ret = HP303BPressureSensor.measurePressureOnce(pressure, oversampling);

  if (ret != 0)
  {
    //Something went wrong.
    //Look at the library code for more information about return codes
     tft.setTextColor(ST7735_RED, ST7735_BLACK);
     tft.setTextSize(2);
     tft.setCursor(0,112);
     tft.print("mBar Error ");
   }
  else
  {
    tft.setTextColor(ST7735_RED, ST7735_BLACK);
    tft.setTextSize(2);
    tft.setCursor(0,112);
    tft.print(pressure/100);   // 1 Bar = 100'000 Pascal
    tft.println(" mBar");
  }
  
 }
 int16_t measurePressureOnce(int32_t &result, uint8_t oversamplingRate);

The library only reports the temperature as an integer. If you want to get the temperature as a float, you'll need to define, and implement, an overload that does what you want (return the temperature as a float).

But, before you exert the effort, is the temperature sensor you are using sensitive enough to discern the difference between 25.3C and 25.4C?

The type ‘int32_t’ is an integer. It has no fractional part.

If you look in ‘LOLIN_HP303B.h’, you’ll see the prototypes that are available for the ‘measureTempOnce()’ function.

int16_t measureTempOnce(int32_t &result);
int16_t measureTempOnce(int32_t &result, uint8_t oversamplingRate);
int16_t startMeasureTempOnce(void);
int16_t startMeasureTempOnce(uint8_t oversamplingRate);

None of them provide a floating point value for the temperature. So, either the sensor is not capable of reporting fractional degrees or the the library’s author did not implement it. I’d start by reading the sensor’s datasheet and seeing what it can do.

PaulS:

 int16_t measurePressureOnce(int32_t &result, uint8_t oversamplingRate);

The library only reports the temperature as an integer. If you want to get the temperature as a float, you'll need to define, and implement, an overload that does what you want (return the temperature as a float).

But, before you exert the effort, is the temperature sensor you are using sensitive enough to discern the difference between 25.3C and 25.4C?

Hi Paul,

After my reading I thought a float might be needed, I tried several things but got stuck.

As for the sensor resolution, I 'think' it can output tenths of a degree, I can't see anything to say otherwise. Whether it is accurate is another matter.

I will actually use two SHT30's long term, and use the HP303B just for pressure. This just got me stumped in the meantime and I wanted to understand it if possible.

Thanks

They claim that the temperature sensor is capable of 0.5 degree resolution, and provide a (link to a) library that gets the data as an integer. Hmm...

gfvalvo:
The type ‘int32_t’ is an integer. It has no fractional part.

If you look in ‘LOLIN_HP303B.h’, you’ll see the prototypes that are available for the ‘measureTempOnce()’ function.

int16_t measureTempOnce(int32_t &result);

int16_t measureTempOnce(int32_t &result, uint8_t oversamplingRate);
int16_t startMeasureTempOnce(void);
int16_t startMeasureTempOnce(uint8_t oversamplingRate);




None of them provide a floating point value for the temperature. So, either the sensor is not capable of reporting fractional degrees or the the library's author did not implement it. I'd start by reading the sensor's datasheet and seeing what it can do.

I did look in the .h and .cpp but did not pick up on that, it makes perfect sense. I will do some more reading on the sensor as it might not be capable as you both suggested. I did see it had 0.5C resolution.

To understand, why would the temp and pressure values need to be set as 32bit integers and not normal integers, on even 8/16bits? It’s only small values after all?

Many thanks guys!!

PS darn 5minute posting time out for newbies :slight_smile:

To understand, why would the temp and pressure values need to be set as 32bit integers

I’d guess that they were planning to use the thing on the surface of the sun. How they expect the temperature sensor to survive when the temperature exceeds 65,536C I do not know.

PaulS:
I'd guess that they were planning to use the thing on the surface of the sun. How they expect the temperature sensor to survive when the temperature exceeds 65,536C I do not know.

Or at the bottom of the ocean :slight_smile:

I was curious and just replaced int32_t with int and it works the same...
Probably obvious to you guys.

The device is claimed capable of 0.01 degC temperature resolution (but still only +/-0.5 degC accuracy). Higher resolution is achieved by taking multiple readings before it reports the results. The raw results are 24-bit integers that the library code processes with the calibration factors applicable to the chosen over-sample rate.

The library’s author chose a fixed over-sample rate. The code processes the raw value using double-precision floats (On an AVR, really just single-precision) and the returns an integer.

You can learn a lot with a quick stroll through the datasheet and source code.

You can increase sensor resolution by oversampling and averaging, starting with the library you have.

Measure the temperature 100 times, sum the readings and divide by 10 instead of 100. That will give you an estimation of the temperature in units of 0.1 degrees.

To improve the accuracy, you need to calibrate the sensor against known standards.

gfvalvo:
You can learn a lot with a quick stroll through the datasheet and source code.

Yes, if you can understand it :slight_smile: Thanks for the information!

jremington:
You can increase sensor resolution by oversampling and averaging, starting with the library you have.

Measure the temperature 100 times, sum the readings and divide by 10 instead of 100. That will give you an estimation of the temperature in units of 0.1 degrees.

To improve the accuracy, you need to calibrate the sensor against known standards.

Will give that a try thanks. I have been messing with calibration lately, used the salt method for humidity but it gave spurious results, so I have ordered a kit. Also was going to try and calibrate temperature, I read that icy water gives close to zero degrees.

Thanks!

Also was going to try and calibrate temperature, I read that icy water gives close to zero degrees.

That is the definition of zero degrees Celsius.

jremington:
That is the definition of zero degrees Celsius.

Yes obvious I suppose :slight_smile:

Only problem is it's just one calibration point, so it needs to assume any error is linear. Not sure how I could calibrate at another temperature that's not boiling point.

I know with humidity different solutions give different RH points, I've gone for a 75% kit as it's the easiest for now.

Don't want to get too caught up in the finer details, but I find this strangely very interesting..

Not sure how I could calibrate at another temperature that's not boiling point.

The usual approach uses an accurate thermometer as a reference.

jremington:
You can increase sensor resolution by oversampling and averaging, starting with the library you have.

No, you CANNOT "increase sensor resolution". Period. It is what it is. All you're doing is averaging, which fabricates fractional digits, which does nothing to increase precision.
Regards,
Ray L.

No, you CANNOT “increase sensor resolution”.

Wrong. Please educate yourself by reading this technical note, written by people who actually understand the approach.

jremington:
Wrong. Please educate yourself by reading this technical note, written by people who actually understand the approach.

Or read the data sheet for the actual device in question, where it’s assumed this is what’s happening (ie. Figure 5).