Using ESPAsyncWebServer, once web server submit button, once pushed, to send query parameters to ESP32 AND THAT'S IT

I previously wrote a similar an unsolved question about simultaneously submitting three parameters to and ESP32--and moving back to the main menu. Now, I just want to submit the three parameters to the ESP32 using whatever method works (get, post, any, etc).

This is based off this tutorial: ESP32 Arduino HTTP server: Getting query parameters – techtutorialsx

GUI

File structure

sketch (folder)

  • sketch.ino
  • data (folder)
    • index.html

sketch.ino

#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <painlessMesh.h>

const char* ssid = "Wireless Controller";
const char* password = "12345678";

// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain

Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

void sendMessage() {
  taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}

AsyncWebServer server(80);

void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}
IPAddress IP(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

void setup()
{
  Serial.begin(115200);



  // Initialize SPIFFS
  if (!SPIFFS.begin(true))
  {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }



  WiFi.softAP(ssid, password);
  delay(500);
  WiFi.softAPConfig(IP, gateway, subnet);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);



  
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {

    int paramsNr = request->params();
    Serial.println(paramsNr);

    for (int i = 0; i < paramsNr; i++)
    {
      AsyncWebParameter* p = request->getParam(i);
      Serial.print("Param name: ");
      Serial.println(p->name());
      
      Serial.print("Param value: ");
      Serial.println(p->value());
      
      Serial.println("------");
    }
    
   request->send(200, "text/plain", "");

  });





  server.onNotFound(notFound);

  server.begin();
}



void loop() {}

index.html

<!DOCTYPE html>
<html>
<body>

  <h1>Main Menu</h1>
  
<form action="/" method="get"> 



	<label for="size" style="font-size: 22px">Shape Size:</label>

	<select name="size" id="size" style="font-size: 22px;">
	  <option value="1"> 1   </option>
	  <option value="2"> 1/2 </option> 
		</select>


	<p><label for="speed" style="font-size: 22px">Speed:</label>
	
	<select name="speed" id="speed" style="font-size: 24px">
	  <option value="1"> 		  Slowest </option>
	  <option value="2" selected> Regular </option>
	</select></p>




  <p><<button class="submit" name="circle" value="3">Circle</button></p>
  
  <p><button class="submit" name="square" value="4">Square</button></p>



</form>

</body>
</html>

I have changed the "get" to "post" and "any" while also changing the Arduino code to server.on("/", HTTP_POST and server.on("/", HTTP_ANY with no luck. Every time, the screen is either blank or not found.

This is a minimalistic example of a much larger program. I want to simply keep it to using one HTML file and one ino Arduino file. I realize a bunch of bells and whistles can be added with JS, and this may be better for a more advanced version, but I want to keep the first version as simple as possible. (I will not be the only one using this.)

The index.HTML file is loaded onto the ESP32 by going to Tools → ESP32 Sketch Data Upload.

In other words, the HTTP works with sending information to the ESP32 if the URL is edited. So the tutorial example works as it should. But the options (speed, size, shape) of web page itself is not visible.

Users are not going to be editing the URL themselves. They're going to be selecting from the drop down menus and using the pushbuttons.

I tried creating index.html and a selection.html the same HTML file contents. Although, I'm massively struggling with what to do in the Arduino IDE.

  request->send(SPIFFS, "/index.html", String(), false);
  });

Then what?


    int paramsNr = request->params();
    Serial.println(paramsNr);

    for (int i = 0; i < paramsNr; i++)
    {
      AsyncWebParameter* p = request->getParam(i);
      Serial.print("Param name: ");
      Serial.println(p->name());
      
      Serial.print("Param value: ");
      Serial.println(p->value());
      
      Serial.println("------");
    }
    request->send(WHAT?); // HERE is the problem?


  });

This might be useful: Input Data on HTML Form ESP32/ESP8266 Web Server Arduino IDE | Random Nerd Tutorials

I think the problem is that your form handler is root.

Try changing this

<form action="/" method="get">

to

<form action="/circle" method="get">

and copy the code in this block

server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { ... 

to

server.on("/"circle, HTTP_GET, [](AsyncWebServerRequest * request) {

One for square too?

One thing at a time...

So, did that help at all?

Kind of. I am still working on getting it all to work, but I think you've set me on the right track. I will update on progress...

  request->send(SPIFFS, "/index.html", String(), false);
  });

  server.on("/circle", HTTP_GET, [](AsyncWebServerRequest * request) {
  request->send(SPIFFS, "/circle.html", String(), false);
  });

With the corresponding HTML file change, that seemed to work. Now I don't know where to put this part for retrieving the data from the GUI:

  Serial.println(paramsNr);
  
  for (int i = 0; i < paramsNr; i++)
  {
    AsyncWebParameter* p = request->getParam(i);
    Serial.print("Param name: ");
    Serial.println(p->name());
    
    Serial.print("Param value: ");
    Serial.println(p->value());
    
    Serial.println("------");
    return F(paramsNr);    
  }

And putting request->send(200, "text/text", paramsNr); after, results in an error.

That code to retrieve the GET parameters needs to go in the handler for the "/circle" page.

For the index page? How is it going to include the other two parameters?

I need all three parameters sent at the same time: size, speed and shape. I do not understand how <form action="/circle" method="get"> can be used... unless there is a nested version of this?

index.html

<!DOCTYPE html>
<html>
<body>
<!-- -->

  <h1>Menu 1</h1>
  
<form action="/" method="get"> 



	<label for="size" style="font-size: 22px">Shape Size:</label>

	<select name="size" id="size" style="font-size: 22px;">
	  <option value="1"> 1   </option>
	  <option value="2"> 1/2 </option> 
		</select>


	<p><label for="speed" style="font-size: 22px">Speed:</label>
	
	<select name="speed" id="speed" style="font-size: 24px">
	  <option value="1"> 		  Slowest </option>
	  <option value="2" selected> Regular </option>
	</select></p>




  <p><a href="/circle.html"><button class="submit" name="circle" value="3">Circle</button></a></p>
  
  <p><a href="/square.html"><button class="submit" name="square" value="4">Square</button></a></p>



</form>

</body>
</html>

circle.html

<!DOCTYPE html>
<html>
<body> 
<!-- -->

  <h1>Menu 2</h1>

<form action="/circle" method="get"> 



	<label for="size" style="font-size: 22px">Shape Size:</label>

	<select name="size" id="size" style="font-size: 22px;">
	  <option value="1"> 1   </option>
	  <option value="2"> 1/2 </option> 
		</select>


	<p><label for="speed" style="font-size: 22px">Speed:</label>
	
	<select name="speed" id="speed" style="font-size: 24px">
	  <option value="1"> 		  Slowest </option>
	  <option value="2" selected> Regular </option>
	</select></p>




  <p><button class="submit" name="circle" value="3">Circle</button></p>
  
  <p><button class="submit" name="square" value="4">Square</button></p>



</form>

</body>
</html>

square.html

<!DOCTYPE html>
<html>
<body> 
<!-- -->

  <h1>Menu 3</h1>


<form action="/square" method="get"> 



	<label for="size" style="font-size: 22px">Shape Size:</label>

	<select name="size" id="size" style="font-size: 22px;">
	  <option value="1"> 1   </option>
	  <option value="2"> 1/2 </option> 
		</select>


	<p><label for="speed" style="font-size: 22px">Speed:</label>
	
	<select name="speed" id="speed" style="font-size: 24px">
	  <option value="1"> 		  Slowest </option>
	  <option value="2" selected> Regular </option>
	</select></p>




  <p><button class="submit" name="circle" value="3">Circle</button></p>
  
  <p><button class="submit" name="square" value="4">Square</button></p>



</form>

</body>
</html>

The circle.html and square.html do nothing. They're not accessed from the index page. So the Arduino code in each respective get handler is never accessed. This results in no information sent to the ESP32.

I think part of the problem is that you may not be familiar with http GET/POST. Refer to one of the tutorials about how variables are passed and it will help you understand the code.

I'm very familiar. I've tried every variation with both POST and GET. I believe the problem is in the Arduino code:

  {
    request->send(SPIFFS, "/index.html", String(), false);  

    int paramsNr = request->params(); // number of params (e.g., size, speed shape = 3)
    Serial.println(paramsNr);
    Serial.println();
    
    AsyncWebParameter * p = request->getParam(0); // first parameter
//    Serial.println(p->name());                   // name ^
    Serial.println(p->value());                   // value ^
  });

The web-page breaks/disconnects, and I think it is because of this line: AsyncWebParameter * p = request->getParam(0);

And also has something to do with the request->send part. But I don't know what to put.