Float vs Int any advice?

Hi Guys and Gals.
I am hoping for a little advice.
I am still working on my weather station project and having difficulty using "Float" vs "Int".
I understand (I think) the difference between floating point numbers and integers, but my coding doesn't.
I pasted some code snippets below, but what I am experiencing is my code works fine if I set the variable as and "Int" but crashes when set to "Float".
I would like the variable set to two decimal point precision, but I haven't got past getting the code to work as a "Float" number, so help there is welcome as well.

I believe the problem is coming from the usage of:
"lv_label_set_text_fmt" as opposed to using something else. But I don't know what that something else is.

Thank you for the help.

// of course I set the variable early on

int DMX_Value = 0;  // init
int direction= 0;  //value read from the wind vane
int windspeed= 0;  //value read from the anamometer
int ui_Button_DMX_Transmit;
int temperature = 0;
int humidity = 0;
float pressure = 0;

here is where I print those values after some conversion calculations.

  temperature=((temp_event.temperature *1.8)+32);
  pressure = ((pressure_event.pressure / 33.8639) +.568);
  lv_label_set_text_fmt(ui_Temperature_Data, "%d", temperature);
  lv_label_set_text_fmt(ui_Temperature_Data1, "%d", temperature);
  lv_label_set_text_fmt(ui_Pressure_Data, "%d", pressure);
  lv_label_set_text_fmt(ui_Pressure_Data1, "%d", pressure);

If you don't post the entire code, people won't try to help because there is a 50% chance that the problem is in the code you didn't post.

Ok.
I am new here. I got chewed out a few days ago for posting too much code, so here is the entire script.

#include "Arduino_H7_Video.h"
#include "Arduino_GigaDisplayTouch.h"
#include "lvgl.h"
#include <ui.h>
#include <Wire.h>
#include <Adafruit_BMP280.h>
#include <AHT20.h>
AHT20 aht20;
Adafruit_BMP280 bmp; // use I2C interface
Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();

Arduino_H7_Video Display( 800, 480, GigaDisplayShield ); //( 800, 480, GigaDisplayShield );
Arduino_GigaDisplayTouch TouchDetector;

// These constants won't change. They're used to give names to the pins used:
//const int analogOutPin = A3;  // Analog output pin that the DMX data is written to

int DMX_Value = 0;  // init
int direction= 0;  //value read from the wind vane
int windspeed= 0;  //value read from the anamometer
int ui_Button_DMX_Transmit;
int temperature = 0;
int humidity = 0;
float pressure = 0;



void setup() {
  Display.begin();
  TouchDetector.begin();
  Serial.begin(9600);
  Wire.begin();
  if (aht20.begin() == false)
  {
    Serial.println("AHT20 not detected. Please check wiring. Freezing.");
    while(true);
  }

  while ( !Serial ) delay(100);   // wait for native usb
  unsigned status;
  status = bmp.begin();
  if (!status) {
    Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "
                      "try a different address!"));
                       while (1) delay(10);
  }
   /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

  bmp_temp->printSensorDetails();


  
  pinMode(A3, OUTPUT); // prepare Giga to output DMX (windspeed & direction)
  
  ui_init();
  
}


// this section is for DMX Transmit function
// ui_LBL_Transmit_DMX variable used in this section
// ui_LBL_Transmit_DMX =(the raw data read)




void loop()
{
  lv_timer_handler();
  sensors_event_t temp_event, pressure_event;
  bmp_temp->getEvent(&temp_event);
  bmp_pressure->getEvent(&pressure_event);
  float humidity = aht20.getHumidity();


  if (digitalRead(A3) == LOW) {analogWrite(A3, 0);} // look at code here for DMX Enable
  int DMX_Value = map(direction, 0, 3610, 0, 255);  // remap the analog out value for DMX:
  analogWrite(A3, DMX_Value);    // send DMX data on pin A3
  if (ui_Button_DMX_Transmit > 0) { // send DMX data on pin A3 or not
    analogWrite(A3, DMX_Value); 
  } else {analogWrite(A3, 0);
  } 
  

  // print the results to the Serial Monitor:
  Serial.print("DMX = ");
  Serial.print(DMX_Value);
  Serial.print("\t Direction = ");
  Serial.println(direction/10);
  Serial.print("\t windspeed = ");
  Serial.println(windspeed);
  Serial.println(ui_Button_DMX_Transmit);
  //if (ui_Button_DMX_Transmit1=true);
  
  // wait 2 milliseconds before the next loop for the analog-to-digital
  // converter to settle after the last reading:



// this section is for weathervane read and display
// variable used in this section
// Weather_vane =(the raw data read from the sensor)
// float voltage = (calculated wind direction corrected for scale)
// direction = (the wind direction displayed on the ui)

  int Weather_vane = analogRead(A0);
  float voltage = Weather_vane*5/600.0;
      //correct low end jitter
  if(voltage < .02){
    voltage = 0;
  }


  direction = map(Weather_vane, 0, 102.9, 0, 360); 
  lv_img_set_angle(ui_Weather_Vane_Pointer1, direction); // wind direction image screen1
  lv_img_set_angle(ui_Weather_Vane_Pointer2, direction); // wind direction image screen2
  lv_label_set_text_fmt(ui_Weather_Vane_Data, "%d", (direction/10)); // wind direction text screen1
  lv_label_set_text_fmt(ui_Weather_Vane_Data1, "%d", (direction/10)); // wind direction text screen2


// windvane section end


// this section is for anemometer read and display
// variable used in this section
// anemometer =(the raw data read from the sensor)
// float voltage = (calculated windspeed corrected for scale)
// windspeed = (the speed displayed on the ui)
{

  int anemometer = analogRead(A1); // write data to pin 1
  float voltage1 = anemometer*5/102.0; // scale data

    //correct low end jitter
  if(voltage1 < .02){
    voltage1 = 0;
  }

    windspeed = map(anemometer, 0, 636, 0, 50); // remap data
  // print out the value you read:
  // the next lines place values into the components both in both panels and both screens
  lv_bar_set_value(ui_Bar1, windspeed, LV_ANIM_ON); //windspeed bar screen 1
  lv_bar_set_value(ui_Bar2, windspeed, LV_ANIM_ON); //windspeed bar screen 2
  lv_label_set_text_fmt(ui_Anenometer_Data, "%d", windspeed); //windspeed screen 1
  lv_label_set_text_fmt(ui_Anenometer_Data1, "%d", windspeed); //windspeed screen 2
}

// thissection for temperature, pressure, humidity

{
  temperature=((temp_event.temperature *1.8)+32);
  pressure = ((pressure_event.pressure / 33.8639) +.568);
  lv_label_set_text_fmt(ui_Temperature_Data, "%d", temperature);
  lv_label_set_text_fmt(ui_Temperature_Data1, "%d", temperature);
  lv_label_set_text_fmt(ui_Pressure_Data, "%d", pressure);
  lv_label_set_text_fmt(ui_Pressure_Data1, "%d", pressure);

}

  delay(1000);
}
// anemometer section end

Not in this forum. I checked.

5 Likes

Where is ui.h? I can't check your code as it is not found.

I doubt it will ever happen in this forum.

1 Like

ui.h (3.0 KB)
ui.c (3.5 KB)

Please post both in code tags, I don;t chase unknown links

Are those two files in the same folder as the main sketch? Are there any other files there?
Post all the code in code tags is what the pinned post says.

what about ui_helpers, and ui_events? More? ALL files in the sketch folder posted in code tags.

It does, sometimes. Creating a short(er) code, that's just enough to demonstrate a problem, is often a significant effort, but can absolutely be worth it. There's a 50% chance that the coder will find and fix the problem themselves while making that shorter code. And if they don't, there's a much higher chance that someone from the forum will find it because the needle is then in a much smaller haystack.

4 Likes

Yes, that is a good approach but I have always wondered if a person who is fairly new and can't troubleshoot a larger sketch has the skills to pare it down. Isn't this a real life example of the DK effect? I am not saying it isn't a good approach, those of us with decades of experiance use it all the time but I think the skills to do that are not a lot different than the skills to solve the problem in the first place.

3 Likes

There are at least 2 more files as can be seen here.

ui_helpers.h (4.1 KB)
ui_events.h (313 Bytes)

Thanks for your patients. As you can tell, this is my first Arduino project. Hopefully some day I can help someone else.

Sorry, I have a club meeting tonight I need to get ready for so I deleted your sketch I was working on.
What I was going to do was

  1. Make all variables either global or local but NOT declared in the code. This way it is much easier to see the relationships between int and float vars.
  2. Now make sure all int vars are really int, I am sure I saw float operations being performed om int.
  3. Same thing the other way around with float.
  4. Some casting may be needed.
  5. Add Serial.println where calcs are done to show before and after.
    Good luck.

The function lv_label_set_text_fmt() uses a "printf-like" formats for output data. The %d format string that you used is not suits for floats, it is a format for an integer values.

To print a value of pressure as a float with two digits after point one should use the format below:

lv_label_set_text_fmt(ui_Pressure_Data1, "%.2f", pressure);

More detail info about printf like formats:

https://cplusplus.com/reference/cstdio/printf/

2 Likes

Hi Guys.
Well...still no help. It seams that the issue is coming from my use of LVGL to display a Float number. I am trying to display the altimeter setting which looks like this: "29.92"

In the statement: lv_label_set_text_fmt(ui_Pressure_Data1, "%.2f", pressure);

the only thing displayed on my Giga shield is the letter "f".

However when I use this statement: Serial.print(pressure ); I get the expected result.

As we all know Serial.print only displays data on the Arduino IDE workstation.
So any help someone can provide is greatly appreciated.
Thanks for looking.

Whenever you change ANYTHING in your code, post it, completely, in a new post.

Which Arduino board are you using?

Did you try to sprintf() the float to a char buffer and then print that?
EDIT:
I just looked at the library's source code. The function you're calling uses vsnprintf. So, if you're using an AVR board (which is why I asked), sprintf() won't work for a float either. In that case use dtostrf().

2 Likes

Please post all code completely and in line. Why make us download files to help you?

Well at least it is not crashing as you said in Post #1. Which version of the lvgl library do you have installed? It seems to use its own "optimized" printf. In the current v9.2.2, this is the code that checks those specifiers

        // evaluate specifier
        switch(*format) {
            case 'd' :
            case 'i' :
            case 'u' :
            case 'x' :
            case 'X' :
            case 'p' :
            case 'P' :
            case 'o' :
            case 'b' : {

What's missing? First, the one you want, further down

#if defined(PRINTF_SUPPORT_FLOAT)
            case 'f' :
            case 'F' :

enabled by a library feature flag. Digging in further, that flag is controlled by a grandparent feature flag. Overall, configuration seems a little complicated. If you want to dig in and enable it "the right way", someone may be able to offer hints if necessary. It will probably make the code a little bit bigger in several places. That might not be an issue.

Or you could, as suggested, use another function to convert the float into a C-string, which will display with %s (with code even further down). dtostrf would be the "old school" way, with manual buffer allocation; while String(pressure).c_str() is simpler, and whether it has drawbacks, "it depends"