user15731: Im using an Arduino Uno - All code at github.com/robbrad/AirQuality
Current sketch usage:
Sketch uses 23186 bytes (71%) of program storage space. Maximum is 32256 bytes.
Global variables use 1428 bytes (69%) of dynamic memory, leaving 620 bytes for local variables. Maximum is 2048 bytes.

I wouldn't normally just spam code for a optimisation - but im looking to get about 10% memory back from this sketch
It basically checks a bunch of sensors sets the values to floats, build a string and posts that to a php page where some more processing happens.
I have tried everything to my knowledge but I just cant think of a smarter way to use less memory.
I tried an array, a function to build the data string, using one float and concatenating it to the string when it set
I even thought of reducing the Math.h include to just the math functions I was using
Maybe im just reaching the little boards limits (which are pretty good anyway :) ! )
#include <SPI.h>
#include <Ethernet.h>
#include "DHT.h"
#include <math.h>
#include <Wire.h>
#include "MutichannelGasSensor.h"
#include "HP20x_dev.h"
#include "KalmanFilter.h"

unsigned char ret = 0;

/* Instance */
KalmanFilter t_filter;    //temperature filter
KalmanFilter p_filter;    //pressure filter
KalmanFilter a_filter;    //altitude filter

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
IPAddress server(192, 168, 0, 30); // numeric IP for Google (no DNS)
//char server[] = "www.google.com";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 40);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;


#define Vc 4.95
//the number of R0 you detected just now
#define R0 35.54
#define DHTPIN A1     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

int pin = 8;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 2000;//sampe 30s&nbsp;;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
String data = "";

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  delay(150);
  HP20x.begin();
  delay(100);

  /* Determine HP20x_dev is available or not */
  ret = HP20x.isAvailable();

  pinMode(8, INPUT);
  starttime = millis();//get the current time;
  //Serial.println("power on!");


  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);

  //if (Ethernet.begin(mac) == 0) {
  //  Serial.println("Failed to configure Ethernet using DHCP");
  // try to congifure using IP address instead of DHCP:
  Ethernet.begin(mac, ip);

  // give the Ethernet shield a second to initialize:
  delay(10000);
  // Serial.println("connecting...");
  //}
  // give the Ethernet shield a second to initialize:
  //delay(1000);
  //Serial.println("connecting...");



  // Serial.println(Ethernet.localIP());


  gas.begin(0x04);//the default I2C address of the slave is 0x04
  gas.powerOn();
  //Serial.print("Firmware Version = ");
  //Serial.println(gas.getVersion());
  //Serial.println("Particles\tRS\tHCHO (PPM)\tNH3 (PPM)\tCO (PPM)\tNO2     (PPM)\tC3H8 (PPM)\tC4H10 (PPM)\tCH4 (PPM)\tH2 (PPM)\tC2H5OH (PPM)");
  dht.begin();
  delay(10000);

}

void loop() {

  if (client.available()) {
    char c = client.read();
    //  Serial.print(c);
  }

  float HATemp2;
  float HAPres2;
  float HAAlt2;
  float d;

  if (OK_HP20X_DEV == ret)
  {
    unsigned long HATemp = HP20x.ReadTemperature();
    d = HATemp / 100.0;
    HATemp2 = t_filter.Filter(d);

    unsigned long HAPres = HP20x.ReadPressure();
    d = HAPres / 100.0;
    HAPres2 = p_filter.Filter(d);

    unsigned long HAAlt = HP20x.ReadAltitude();
    d = HAAlt / 100.0;
    HAAlt2 = a_filter.Filter(d);

  }

  duration = pulseIn(pin, LOW);
  lowpulseoccupancy = lowpulseoccupancy + duration;



  if ((millis() - starttime) >= sampletime_ms) //if the sampel time = = 30s
  {
    ratio = lowpulseoccupancy / (sampletime_ms * 10.0); // Integer percentage 0=&gt;100

    d = 1.1 * pow(ratio, 3) - 3.8 * pow(ratio, 2) + 520 * ratio + 0.62; // using spec sheet curve
    //Serial.print("concentration = ");



   lowpulseoccupancy = 0;
    starttime = millis();
  }



 //Serial.print("\t");
  //HCHO

  int sensorValue = analogRead(A0);
  double Rs = (1023.0 / sensorValue) - 1;

  double ppm = pow(10.0, ((log10(Rs / R0) - 0.0827) / (-0.4807)));
  //Serial.print("HCHO ppm = ");

  //MultiChannel Gas
  float NH3 = gas.measure_NH3();
  float CO = gas.measure_CO();
  float NO2 = gas.measure_NO2();
  float C3H8 = gas.measure_C3H8();
  float C4H10 = gas.measure_C4H10();
  float CH4 = gas.measure_CH4();
  float H2 = gas.measure_H2();
  float C2H5OH = gas.measure_C2H5OH();


  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  data = String("dust=") + d + "&rs=" + Rs + "&hcho=" + ppm + "&nh3=" + NH3 + "&co=" + CO + "&no2=" + NO2 + "&c3h8=" + C3H8 + "&c4h10=" + C4H10 + "&ch4=" + CH4 + "&h2=" + H2 + "&c2h5oh=" + C2H5OH + "&temp=" + t + "&hum=" + h + "&HATemp=" + HATemp2 + "&HAPres=" + HAPres2 + "&HAAlt=" + HAAlt2;

  //Serial.println(data);


  if (client.connect(server, 80)) {
    Serial.println(F("connected"));
    client.println(F("POST /air_add.php HTTP/1.1"));
    client.println(F("Host:  192.168.0.30"));
    client.println(F("User-Agent: Arduino/1.0"));
    client.println(F("Connection: close"));
    client.println(F("Content-Type: application/x-www-form-urlencoded;"));
    client.print(F("Content-Length: "));
    client.println(data.length());
    client.println();
    client.println(data);
  }
  else
  {
    Serial.println(F("could not connect"));
  }

  Serial.println(data);

  if (client.connected()) {
    client.stop();
  }


  delay(300000);
}


user7508: I second the advice that has already been given to you about avoiding
String. Other than that, using fixed-point math could be a big win,
but given the math you do it won't be any easy.
Assuming you stick with floating point, I just found a couple of easy
optimization opportunities:

Do not use pow to evaluate a polynomial. Use the Horner's
method which is way
cheaper: d = ((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62.
The expression of ppm can be simplified:
ppm = 2500.33 * pow(Rs, -2.0803).


Edit: You could also try to implement chunked transfer
encoding. This
way you could send the data to the server on the fly, as you collet it,
instead of storing everything in memory and sending it in one go.
Example:
void send_chunk(Print &connection, const String &chunk)
{
    connection.println(chunk.length, 16);
    connection.println(chunk);
}

void loop() {
    // ...

    // last header sent to the client:
    client.println(F("Transfer-Encoding: chunked"));
    client.println();

    // Now the data:
    String chunk;
    chunk = "dust=";
    chunk += ((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62;
    send_chunk(client, chunk);
    chunk = "&rs=";
    chunk += Rs;
    send_chunk(client, chunk);
    chunk = "&hcho=";
    chunk += 2500.33 * pow(Rs, -2.0803);
    send_chunk(client, chunk);
    chunk = "&nh3=";
    chunk += gas.measure_NH3();
    send_chunk(client, chunk);
    // and so on...
    chunk = "";
    send_chunk(client, chunk);  // Empty chunk means end of message.

    // ...
}

Notice that there is no "Content-Length" header. Instead, each chunk is
preceded by its size in hex. And, most importantly, notice that this way
you can get rid of lots of variables.

Edit 2: I came out with a better (more generic) way to implement
chunked encoding, which involves sending the data through a “chunker”
filter that does the encoding and outputs to the client. Here is my
Chunker class:
/*
 * Transfer a message using the HTTP/1.1 "Chunked Transfer Coding".
 * C.f. https://tools.ietf.org/html/rfc7230#section-4.1
 */
class Chunker : public Print
{
public:
    Chunker(Print &downstream) : downstream(downstream), pos(0) {}

    virtual size_t write(uint8_t c)
    {
        buffer[pos++] = c;
        if (pos == BUFFER_SIZE)
            send();
        return 1;
    }

    void end()
    {
        if (pos) send();
        send();  // empty chunk means end of message
    }

private:
    static const uint8_t BUFFER_SIZE = 32;
    Print &downstream;
    uint8_t buffer[BUFFER_SIZE];
    uint8_t pos;

    // Send the buffer as a chunk.
    void send()
    {
        downstream.println(pos, HEX);
        if (pos) {
            downstream.write(buffer, pos);
            downstream.println();
            pos = 0;
        }
    }
};

And here is how you would use it:
Chunker message(client);  // instantiate the filter
message.print(F("dust="));
message.print(((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62);
message.print("&rs=");
message.print(Rs);
message.print(F("&hcho="));
message.print(2500.33 * pow(Rs, -2.0803));
message.print(F("&nh3="));
message.print(gas.measure_NH3());
// and so on...
message.end();  // terminate the chunked message

The main advantage of this method is that you completely avoid using the
String class, which means no dynamic memory allocation (a very
desirable thing). Also you can choose your buffer size. I've set it to
32 bytes, but you can make it smaller if needed.

user30005: Two basic approaches:
1) use fixed point math. or
1) use int16_t or int32_t in lieu of the floating types. for example, you can use x10 or x100 to designate variables with some decimal points. use x16 or x128 or even x256 for speed gains as well. you will need to make sure that it doesn't overflow.
edit: here is an example that hopefully will help you get it going.
void setup() {
    Serial.begin(9600);
    var1=100;               //var1=1.00
    var2=123;               //var2=1.23
}

void loop() {
    var1+=var2;             //increment var1
    Serial.print("var1 = "); Serial.print(var1 / 100); Serial.print("."); Serial.print(var1 - (var1 / 100) * 100); Serial.println(".");
    delay(100);
}

var1 (1.00 initially) is incremented by var2 (1.23), both are int32_t types.
here is the printout.


user-1: I counted the floats in the sketch:
Global: 2
setup: 0
loop: 14
Total: 16 floats -> 64 bytes.

If you want to reduce that, don't wait to have all your values before preparing your answer. You will use less memory if you do
  data = String("dust=") + dht.readHumidity();
  data+= "&rs=" + (1023.0 / sensorValue) - 1;
  data+= "&hch0=" + pow(10.0, ((log10(Rs / R0) - 0.0827) / (-0.4807)));
  ... and the rest ...

Your data String and concat's take way more space than the floats. Use char[] instead of string.
As last resort, you don't need to construct the complete POST before sending it to the server. Send it line by line, value by value. Use a fixed, big enough Content-Length:,  padding with spaces after you send the values and know the actual lenght.
Or you can switch your technology: MQTT need way less memory than HTTP.

15731: <p>Im using an Arduino Uno - All code at github.com/robbrad/AirQuality</p>

<p>Current sketch usage:</p>

<pre><code>Sketch uses 23186 bytes (71%) of program storage space. Maximum is 32256 bytes.
Global variables use 1428 bytes (69%) of dynamic memory, leaving 620 bytes for local variables. Maximum is 2048 bytes.
</code></pre>

<p>I wouldn't normally just spam code for a optimisation - but im looking to get about 10% memory back from this sketch</p>

<p>It basically checks a bunch of sensors sets the values to floats, build a string and posts that to a php page where some more processing happens.</p>

<p>I have tried everything to my knowledge but I just cant think of a smarter way to use less memory.</p>

<p>I tried an array, a function to build the data string, using one float and concatenating it to the string when it set</p>

<p>I even thought of reducing the Math.h include to just the math functions I was using</p>

<p>Maybe im just reaching the little boards limits (which are pretty good anyway :) ! )</p>

<pre><code>#include &lt;SPI.h&gt;
#include &lt;Ethernet.h&gt;
#include "DHT.h"
#include &lt;math.h&gt;
#include &lt;Wire.h&gt;
#include "MutichannelGasSensor.h"
#include "HP20x_dev.h"
#include "KalmanFilter.h"

unsigned char ret = 0;

/* Instance */
KalmanFilter t_filter;    //temperature filter
KalmanFilter p_filter;    //pressure filter
KalmanFilter a_filter;    //altitude filter

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
IPAddress server(192, 168, 0, 30); // numeric IP for Google (no DNS)
//char server[] = "www.google.com";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 40);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;


#define Vc 4.95
//the number of R0 you detected just now
#define R0 35.54
#define DHTPIN A1     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

int pin = 8;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 2000;//sampe 30s&amp;nbsp;;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
String data = "";

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  delay(150);
  HP20x.begin();
  delay(100);

  /* Determine HP20x_dev is available or not */
  ret = HP20x.isAvailable();

  pinMode(8, INPUT);
  starttime = millis();//get the current time;
  //Serial.println("power on!");


  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);

  //if (Ethernet.begin(mac) == 0) {
  //  Serial.println("Failed to configure Ethernet using DHCP");
  // try to congifure using IP address instead of DHCP:
  Ethernet.begin(mac, ip);

  // give the Ethernet shield a second to initialize:
  delay(10000);
  // Serial.println("connecting...");
  //}
  // give the Ethernet shield a second to initialize:
  //delay(1000);
  //Serial.println("connecting...");



  // Serial.println(Ethernet.localIP());


  gas.begin(0x04);//the default I2C address of the slave is 0x04
  gas.powerOn();
  //Serial.print("Firmware Version = ");
  //Serial.println(gas.getVersion());
  //Serial.println("Particles\tRS\tHCHO (PPM)\tNH3 (PPM)\tCO (PPM)\tNO2     (PPM)\tC3H8 (PPM)\tC4H10 (PPM)\tCH4 (PPM)\tH2 (PPM)\tC2H5OH (PPM)");
  dht.begin();
  delay(10000);

}

void loop() {

  if (client.available()) {
    char c = client.read();
    //  Serial.print(c);
  }

  float HATemp2;
  float HAPres2;
  float HAAlt2;
  float d;

  if (OK_HP20X_DEV == ret)
  {
    unsigned long HATemp = HP20x.ReadTemperature();
    d = HATemp / 100.0;
    HATemp2 = t_filter.Filter(d);

    unsigned long HAPres = HP20x.ReadPressure();
    d = HAPres / 100.0;
    HAPres2 = p_filter.Filter(d);

    unsigned long HAAlt = HP20x.ReadAltitude();
    d = HAAlt / 100.0;
    HAAlt2 = a_filter.Filter(d);

  }

  duration = pulseIn(pin, LOW);
  lowpulseoccupancy = lowpulseoccupancy + duration;



  if ((millis() - starttime) &gt;= sampletime_ms) //if the sampel time = = 30s
  {
    ratio = lowpulseoccupancy / (sampletime_ms * 10.0); // Integer percentage 0=&amp;gt;100

    d = 1.1 * pow(ratio, 3) - 3.8 * pow(ratio, 2) + 520 * ratio + 0.62; // using spec sheet curve
    //Serial.print("concentration = ");



   lowpulseoccupancy = 0;
    starttime = millis();
  }



 //Serial.print("\t");
  //HCHO

  int sensorValue = analogRead(A0);
  double Rs = (1023.0 / sensorValue) - 1;

  double ppm = pow(10.0, ((log10(Rs / R0) - 0.0827) / (-0.4807)));
  //Serial.print("HCHO ppm = ");

  //MultiChannel Gas
  float NH3 = gas.measure_NH3();
  float CO = gas.measure_CO();
  float NO2 = gas.measure_NO2();
  float C3H8 = gas.measure_C3H8();
  float C4H10 = gas.measure_C4H10();
  float CH4 = gas.measure_CH4();
  float H2 = gas.measure_H2();
  float C2H5OH = gas.measure_C2H5OH();


  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  data = String("dust=") + d + "&amp;rs=" + Rs + "&amp;hcho=" + ppm + "&amp;nh3=" + NH3 + "&amp;co=" + CO + "&amp;no2=" + NO2 + "&amp;c3h8=" + C3H8 + "&amp;c4h10=" + C4H10 + "&amp;ch4=" + CH4 + "&amp;h2=" + H2 + "&amp;c2h5oh=" + C2H5OH + "&amp;temp=" + t + "&amp;hum=" + h + "&amp;HATemp=" + HATemp2 + "&amp;HAPres=" + HAPres2 + "&amp;HAAlt=" + HAAlt2;

  //Serial.println(data);


  if (client.connect(server, 80)) {
    Serial.println(F("connected"));
    client.println(F("POST /air_add.php HTTP/1.1"));
    client.println(F("Host:  192.168.0.30"));
    client.println(F("User-Agent: Arduino/1.0"));
    client.println(F("Connection: close"));
    client.println(F("Content-Type: application/x-www-form-urlencoded;"));
    client.print(F("Content-Length: "));
    client.println(data.length());
    client.println();
    client.println(data);
  }
  else
  {
    Serial.println(F("could not connect"));
  }

  Serial.println(data);

  if (client.connected()) {
    client.stop();
  }


  delay(300000);
}
</code></pre>
 7508: <p>I second the advice that has already been given to you about avoiding
<code>String</code>. Other than that, using fixed-point math could be a big win,
but given the math you do it won't be any easy.</p>

<p>Assuming you stick with floating point, I just found a couple of easy
optimization opportunities:</p>

<ul>
<li>Do not use <code>pow</code> to evaluate a polynomial. Use the <a href="https://en.wikipedia.org/wiki/Horner%27s_method" rel="nofollow noreferrer">Horner's
method</a> which is way
cheaper: <code>d = ((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62</code>.</li>
<li>The expression of ppm can be simplified:
<code>ppm = 2500.33 * pow(Rs, -2.0803)</code>.</li>
</ul>

<hr>

<p><strong>Edit</strong>: You could also try to implement <a href="https://en.wikipedia.org/wiki/Chunked_transfer_encoding" rel="nofollow noreferrer">chunked transfer
encoding</a>. This
way you could send the data to the server on the fly, as you collet it,
instead of storing everything in memory and sending it in one go.</p>

<p>Example:</p>



<pre class="lang-c++ prettyprint-override"><code>void send_chunk(Print &amp;connection, const String &amp;chunk)
{
    connection.println(chunk.length, 16);
    connection.println(chunk);
}

void loop() {
    // ...

    // last header sent to the client:
    client.println(F("Transfer-Encoding: chunked"));
    client.println();

    // Now the data:
    String chunk;
    chunk = "dust=";
    chunk += ((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62;
    send_chunk(client, chunk);
    chunk = "&amp;rs=";
    chunk += Rs;
    send_chunk(client, chunk);
    chunk = "&amp;hcho=";
    chunk += 2500.33 * pow(Rs, -2.0803);
    send_chunk(client, chunk);
    chunk = "&amp;nh3=";
    chunk += gas.measure_NH3();
    send_chunk(client, chunk);
    // and so on...
    chunk = "";
    send_chunk(client, chunk);  // Empty chunk means end of message.

    // ...
}
</code></pre>

<p>Notice that there is no "Content-Length" header. Instead, each chunk is
preceded by its size in hex. And, most importantly, notice that this way
you can get rid of lots of variables.</p>

<hr>

<p><strong>Edit 2</strong>: I came out with a better (more generic) way to implement
chunked encoding, which involves sending the data through a “chunker”
filter that does the encoding and outputs to the client. Here is my
<code>Chunker</code> class:</p>

<pre class="lang-c++ prettyprint-override"><code>/*
 * Transfer a message using the HTTP/1.1 "Chunked Transfer Coding".
 * C.f. https://tools.ietf.org/html/rfc7230#section-4.1
 */
class Chunker : public Print
{
public:
    Chunker(Print &amp;downstream) : downstream(downstream), pos(0) {}

    virtual size_t write(uint8_t c)
    {
        buffer[pos++] = c;
        if (pos == BUFFER_SIZE)
            send();
        return 1;
    }

    void end()
    {
        if (pos) send();
        send();  // empty chunk means end of message
    }

private:
    static const uint8_t BUFFER_SIZE = 32;
    Print &amp;downstream;
    uint8_t buffer[BUFFER_SIZE];
    uint8_t pos;

    // Send the buffer as a chunk.
    void send()
    {
        downstream.println(pos, HEX);
        if (pos) {
            downstream.write(buffer, pos);
            downstream.println();
            pos = 0;
        }
    }
};
</code></pre>

<p>And here is how you would use it:</p>

<pre class="lang-c++ prettyprint-override"><code>Chunker message(client);  // instantiate the filter
message.print(F("dust="));
message.print(((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62);
message.print("&amp;rs=");
message.print(Rs);
message.print(F("&amp;hcho="));
message.print(2500.33 * pow(Rs, -2.0803));
message.print(F("&amp;nh3="));
message.print(gas.measure_NH3());
// and so on...
message.end();  // terminate the chunked message
</code></pre>

<p>The main advantage of this method is that you completely avoid using the
<code>String</code> class, which means no dynamic memory allocation (a very
desirable thing). Also you can choose your buffer size. I've set it to
32&nbsp;bytes, but you can make it smaller if needed.</p>
 30005: <p>Two basic approaches:</p>

<p>1) use fixed point math. or</p>

<p>1) use int16_t or int32_t in lieu of the floating types. for example, you can use x10 or x100 to designate variables with some decimal points. use x16 or x128 or even x256 for speed gains as well. you will need to make sure that it doesn't overflow.</p>

<p>edit: here is an example that hopefully will help you get it going.</p>

<pre><code>void setup() {
    Serial.begin(9600);
    var1=100;               //var1=1.00
    var2=123;               //var2=1.23
}

void loop() {
    var1+=var2;             //increment var1
    Serial.print("var1 = "); Serial.print(var1 / 100); Serial.print("."); Serial.print(var1 - (var1 / 100) * 100); Serial.println(".");
    delay(100);
}
</code></pre>

<p>var1 (1.00 initially) is incremented by var2 (1.23), both are int32_t types.</p>

<p>here is the printout.</p>

<p><a href="https://i.stack.imgur.com/yx7pg.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/yx7pg.png" alt="enter image description here"></a></p>
 -1: <p>I counted the floats in the sketch:</p>

<pre><code>Global: 2
setup: 0
loop: 14
Total: 16 floats -&gt; 64 bytes.
</code></pre>

<p>If you want to reduce that, don't wait to have all your values before preparing your answer. You will use less memory if you do</p>

<pre><code>  data = String("dust=") + dht.readHumidity();
  data+= "&amp;rs=" + (1023.0 / sensorValue) - 1;
  data+= "&amp;hch0=" + pow(10.0, ((log10(Rs / R0) - 0.0827) / (-0.4807)));
  ... and the rest ...
</code></pre>

<p>Your <code>data</code> String and concat's take way more space than the floats. Use char[] instead of string.</p>

<p>As last resort, you don't need to construct the complete POST before sending it to the server. Send it line by line, value by value. Use a fixed, big enough <code>Content-Length:</code>,  padding with spaces after you send the values and know the actual lenght.</p>

<p>Or you can switch your technology: MQTT need way less memory than HTTP.</p>
