greiman / SSD1306Ascii

Text only Arduino Library for SSD1306 OLED displays
MIT License
490 stars 120 forks source link

Limiting display decimals, float with 1 decimal, not 2, using oled.print #116

Closed GermanAltgelt closed 7 months ago

GermanAltgelt commented 7 months ago

I want to display temperature with only one digit, rounding may be secondary. Like 27.36, I'd rather display it as 27.4 or 27.3. On an LCD, I just enter the variable let's say 'a' with lcd.print (a,1) It seems that oled.print doesn't have that capability, or I could not find it. I can think of using it as a string and chopping off the last digit or other integer methods, but I am really bad in transforming variables.

Is there any easy method to display with 1 digit?

I did humidity with no decimals by converting to integer. But with LCD I just do (b,0), being b the floating value of the humidity. Any hint would be appreciated.

I came to this library as the Adafruit for the SSD1306 classhes with Radiohead, at least in my case.

machmar commented 7 months ago

Hi, easiest way to do this is with a snprintf function turning the float variable into a string. However, processing floats on AVR chips is very inefficient so I'd advise to do a bit of procesing to extract decimal places from it as a separate number.

Here is how I'd do it:

char StringBuffer[5] = {0}; // create a place for the string to be stored in
int IntegerPart = (int)YourFloatVariable; // cast it to a int variable to remove all decimal places
int DecimalPart = (int)(YourFloatVariable * 10.f); // multiply it by ten before casting to get that one decimal place we want
DecimalPart -= IntegerPart * 10; // remove the Integer part from this variable so that we are lef with only the decimal place

snprintf(StringBuffer, 5, "%d.%d, IntegerPart, DecimalPart); // lookup how printf works if you want to understand this line
oled.print(StringBuffer); // put the created text on the display

I can't say with confidence this will work because I have not tested, but I don't think I made any mistakes. If I did, at least you get the basic idea behind formatting numbers to text.

Hope this helped 😊

GermanAltgelt commented 7 months ago

Great, thanks! Great help! I really wanted to avoid this, hoping for a simple solution, as it is for the LCD display. In reality I have the 2 strings already, coming from the radiohead message. I may work on them as strings, no rounding. I used the floats in the serial monitor while debugging. I may just get rid of them.

machmar commented 7 months ago

I'd advise that to be honest. I much prefer using two last numbers of an integer as decimal places and then formatting them accordingly when displaying. Or even better, just store them in a smaller scale - ex.: Instead of storing voltage in Volts, store it in milliVolts. Then you even have an actual reason for it being different from the base values.

But yeah, just storing it 10 times bigger in an integer variable would be a better option in my opinion. These basic AVRs don't have any hardware for processing floats, so all floating point calculations get pretty lengthy and slow.

GermanAltgelt commented 7 months ago

THANK YOU AGAIN!

greiman commented 7 months ago

I don't understand. Here is a simple example of printing a float on a Uno:

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiWire oled;
//------------------------------------------------------------------------------
void setup() {
  Wire.begin();
  Wire.setClock(400000L);

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0

  oled.setFont(Adafruit5x7);

  oled.clear();
  float f = 1.2345;
  oled.set2X();
  oled.println(f, 1);
  oled.println(f, 2);
  oled.println(f, 3); 
  oled.println(f, 4); 
}
void loop() {}

Here is the result. Excuse the poor focus.

float

See the number of digits and rounding are fine .

GermanAltgelt commented 7 months ago

I went back and tried it in my sketch and it worked... not sure what I was doing before... Thank you very much, and sorry for the noise. Your example was just great, and thank you too for all what you are doing to help us.

GermanAltgelt commented 7 months ago

close my non-existing issue. Program works fine in my cloned UNO.

machmar commented 7 months ago

I apologize for any confusion that I caused, I looked through the examples and thought this library didn't support that functionality.

GermanAltgelt commented 7 months ago

no problem at all, the one that is sorry is me... I still do not know why at first it did not work for me. Your help is very much appreciated

On Thu, Dec 7, 2023 at 1:22 PM Marek Mach @.***> wrote:

I apologize for any confusion that I caused, I looked through the examples and thought this library didn't support that functionality.

— Reply to this email directly, view it on GitHub https://github.com/greiman/SSD1306Ascii/issues/116#issuecomment-1846053291, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADH2B5UISTM6LIJ4NQ3UOLDYIIQPDAVCNFSM6AAAAABAKGWL7GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBWGA2TGMRZGE . You are receiving this because you modified the open/close state.Message ID: @.***>

-- Germán

greiman commented 7 months ago

@GermanAltgelt

no problem at all, the one that is sorry is me... I still do not know why at first it did not work for me. Your help is very much appreciated

This kind of thing happens to everyone who writes programs so I expect it and am prepared.

I have an Uno with a 64X128 display handy so I take an example replace 5 lines, run it and grab my phone. Only takes a few minutes.

@machmar

I apologize for any confusion that I caused,

I really appreciate help. So don't stop. I have way too many request for help every morning.