"Round" float to one decimal place for printing to OLED

I would have thought rounding or truncating a number like 71.4323523 to 71.4 would be easy but I've failed to find a short solution.

Is float to string (dtostrf() ) is the only way I can think of. I'm sending the value to an OLED so my understanding sprintf is not applicable.

Is there another solution that is more streamlined?

Thanks

Can you post a link to the OLED so we know which one it is; and say which arduino you are using; and post your code?

if your unknown OLED Library for your unknown OLED in your unknown Code is based on print, you can do a simple

oled.print(unknownFloat, 1);

to get a rounded float printed to the display with one decimal.

3 Likes

There are other solutions, but I don't know if you will find them more streamlined or not. Making a buffer with dtostrf() is quite streamlined in my view.

However:
First, you have to decide whether you want rounding or truncating, because they are not the same thing. Then, you can take an approach along these lines:

  1. Multiply the float by 10 and cast it to an integer called foo (this will truncate it).
  2. Compute the integer part as int integer = foo / 10
  3. Compute the decimal part as int decimal = foo % 10
  4. Print integer, followed by the decimal separator of your choice (point or comma), followed by decimal.

If you require rounding, you'll have to take extra steps. Also consider whether your floats will always be positive or if they may be negative too.

Note: You can combine steps 2-4 by sprintf()-ing everything into a buffer but at this point... just use dtostrf() and it will also round the number for you.

I don't understand why you are saying that. I realise there are some limitations using sprintf on some Arduino platforms (not sure what they are), but assuming you can use sprintf then use sprintf. Print to a char array then use the OLED's print function to send the resulting text to the OLED.

Multiply it by 10, round it to an int then divide that by 10 to get your float?

-jim lee

1 Like

I found at my own expenses what they are. What I thought was a bug in my code that was really bugging me (pun intended), was a silly limitation of the IDE's version of sprintf(): it won't take a float for an argument. Hence, the necessity of an intermediate buffer generated by dtostrf() that is then passed to sprintf() as a string.

The fact that the OP is sending the string to an OLED is irrelevant, of course: the problem is upstream.

i'm told support for floats in sprintf() is removed on Arduino.

dtostrf() can be used

  f =   1.3

char s [80];
char t [10];

void setup () {
    Serial.begin (9600);

    float f = 1.27;

    dtostrf (f, 5, 1, t);
    sprintf (s, "  f = %s", t);
    Serial.println (s);
}

void loop () {
}

I'm aware there are some limits to its use, but I don't know what they are. I have used sprintf with Arduino successfully so, whatever the limits are I am yet to come up against them. However, @JohnRob commented that he didn't think he could use sprintf with and OLED, not that he couldn't use it with an Arduino. My point is that providing the limits on using it with Arduino don't apply then it is perfectly possible to use it with an OLED in the way I suggested.

i have no problem passing a c-string to the OLED devices i've used. doesn't matter what is used to construct/format the string.

Thanks for the responses.

The code @noiasca's recommended works fine on my 16 x 32 generic OLED. And I am embarrassed I didn't read further on the print function reference page. I only remembered the 2nd parameter as specifying the base :frowning:

For future reference:
The OLED driver is from Bill Greiman.

// ARDUINO - AHT20 - OLED
// Target processor: Pro Mini 3v3
//
#include <Wire.h>

//OLED driver from Bill Greiman.
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

#define OLED_ADDRESS 0x3C
// Define proper RST_PIN if required.
#define RST_PIN -1

#include "AHT20.h"

AHT20 AHT;
SSD1306AsciiWire oled;

void setup()
{
    Serial.begin(9600);
    delay(500);
    Serial.println("AHT20 Sensor");

    AHT.begin();

    oled.begin(&Adafruit128x32, OLED_ADDRESS);
    oled.setFont(CalLite24);
    oled.displayRemap(true);          // rotate text 180°
    oled.clear();
}

void loop() (
    float humi, temp;
    int ret = AHT.getSensor(&humi, &temp);
    
    if(ret) {    // GET DATA OK
//    temp = temp *9/5+32;
       temp = 74.12345;
       oled.SSD1306Ascii::setCursor(1*8,0);
       oled.print(temp,1);
    }
    else {       // GET DATA FAIL
        Serial.println("GET DATA FROM AHT20 FAIL");
    }
    
    delay(10000);
}

// --- eof ---
2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.