user57103: I've been trying to run the following esp32 LED PWM code to change the LED's brightness, and show the current PWM duty on the webpage, but the PWM values on the webpage won't change until I hit the submit button twice.
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
WebServer ser(80);
int s=0;
String k;



String iso()
{
  k="<p style=\"text-align: center;\"><strong><font size=\"9\">LED PWM</font></strong><font size=\"3\"></font><FORM action=\"/\" method=\"post\"><input type=\"text\" name=\"duty\"><br> <input type=\"submit\" value=\"Submit\">Cureent Duty=";
  k=k+s;
  k=k+"</p>";

  return k;
}

void root()
{
  iso();
  ser.send(200, "text/html", iso());

  if (ser.hasArg("duty")) 
  {
      iso();
      s=ser.arg("duty").toInt();  
      ledcWrite(4, s);
      iso();
      ser.send(200, "text/html", iso());
  }
}





void setup() {
  Serial.begin(9600);
  ledcAttachPin(33, 4);
  ledcSetup(4, 5000, 8);
  WiFi.begin("ssid", "pass");
  Serial.print("\nConnecting To WiFi");
  while (WiFi.status()!=WL_CONNECTED)
  {

    Serial.printf("\n.");
  }
  Serial.print("\nConnected");

  ser.on("/", root);
  ser.begin(80);
}



void loop() {
  ser.handleClient();
}

Here's a GIF addressing the issue


user7508: When the client sends you a request, you should answer only once. Your
root() function attempts to answer twice whenever the request contains
the argument “duty”. The client will not handle a duplicate response to
a single request.
Here is your root() function:
void root()
{
  iso();
  ser.send(200, "text/html", iso());  // ← first response

  if (ser.hasArg("duty"))
  {
      iso();
      s=ser.arg("duty").toInt();
      ledcWrite(4, s);
      iso();
      ser.send(200, "text/html", iso());  // ← second response
  }
}

You may notice that the first response was sent before updating the
duty cycle.
The proper way to handle the request is to first handle the request
parameters, if any, then send the response:
void root()
{
  if (ser.hasArg("duty")) {
    s = ser.arg("duty").toInt();
    ledcWrite(4, s);
  }
  ser.send(200, "text/html", iso());  // ← only sent once
}

As a side note, there is absolutely no need to build the response five
times (you have five calls to iso() within root()) when you only
need it once!

57103: <p>I've been trying to run the following esp32 LED PWM code to change the LED's brightness, and show the current PWM duty on the webpage, but the PWM values on the webpage won't change until I hit the submit button twice.</p>

<pre><code>#include &lt;Arduino.h&gt;
#include &lt;WiFi.h&gt;
#include &lt;WebServer.h&gt;
WebServer ser(80);
int s=0;
String k;



String iso()
{
  k="&lt;p style=\"text-align: center;\"&gt;&lt;strong&gt;&lt;font size=\"9\"&gt;LED PWM&lt;/font&gt;&lt;/strong&gt;&lt;font size=\"3\"&gt;&lt;/font&gt;&lt;FORM action=\"/\" method=\"post\"&gt;&lt;input type=\"text\" name=\"duty\"&gt;&lt;br&gt; &lt;input type=\"submit\" value=\"Submit\"&gt;Cureent Duty=";
  k=k+s;
  k=k+"&lt;/p&gt;";

  return k;
}

void root()
{
  iso();
  ser.send(200, "text/html", iso());

  if (ser.hasArg("duty")) 
  {
      iso();
      s=ser.arg("duty").toInt();  
      ledcWrite(4, s);
      iso();
      ser.send(200, "text/html", iso());
  }
}





void setup() {
  Serial.begin(9600);
  ledcAttachPin(33, 4);
  ledcSetup(4, 5000, 8);
  WiFi.begin("ssid", "pass");
  Serial.print("\nConnecting To WiFi");
  while (WiFi.status()!=WL_CONNECTED)
  {

    Serial.printf("\n.");
  }
  Serial.print("\nConnected");

  ser.on("/", root);
  ser.begin(80);
}



void loop() {
  ser.handleClient();
}
</code></pre>

<p>Here's a GIF addressing the issue</p>

<p><a href="https://i.stack.imgur.com/Zk9vY.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Zk9vY.gif" alt="Issue"></a></p>
 7508: <p>When the client sends you a request, you should answer <em>only once</em>. Your
<code>root()</code> function attempts to answer twice whenever the request contains
the argument “duty”. The client will not handle a duplicate response to
a single request.</p>

<p>Here is your <code>root()</code> function:</p>



<pre class="lang-c++ prettyprint-override"><code>void root()
{
  iso();
  ser.send(200, "text/html", iso());  // ← first response

  if (ser.hasArg("duty"))
  {
      iso();
      s=ser.arg("duty").toInt();
      ledcWrite(4, s);
      iso();
      ser.send(200, "text/html", iso());  // ← second response
  }
}
</code></pre>

<p>You may notice that the first response was sent <em>before</em> updating the
duty cycle.</p>

<p>The proper way to handle the request is to first handle the request
parameters, if any, <em>then</em> send the response:</p>

<pre class="lang-c++ prettyprint-override"><code>void root()
{
  if (ser.hasArg("duty")) {
    s = ser.arg("duty").toInt();
    ledcWrite(4, s);
  }
  ser.send(200, "text/html", iso());  // ← only sent once
}
</code></pre>

<p>As a side note, there is absolutely no need to build the response five
times (you have five calls to <code>iso()</code> within <code>root()</code>) when you only
need it once!</p>
