Skip to main content
Arduino

Return to Answer

+ more generic method.
Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

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.

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.


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.

+ Transfer-Encoding: chunked
Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

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.

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).

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.

Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

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).

AltStyle によって変換されたページ (->オリジナル) /