logo elektroda
logo elektroda
X
logo elektroda

Arduino R4 WiFi and ArduinoHttpServer - fixes, launch, examples of use

p.kaczmarek2 
Arduino R4 WiFi board with ArduinoHTTPServer text
Here I will present the fixes, launch and development of the ArduinoHttpServer library on the Arduino R4 WiFi platform. The purpose of the topic will be to facilitate our operations related to the HTTP protocol, and more specifically, parsing HTTP requests (processing the header, resource path and GET arguments) and sending responses to these requests. By the way, I will also show a simple HTTP authorization system offered by this library.

The topic assumes that the user has a basic understanding of what HTTP is, what a GET request is, what a server is, an IP address, and so on.

Project motivation
Arduino R4 WiFi has some ready-made examples of network projects:
Screenshot of Arduino menu with the WiFi WebServer example selected.
But after opening them, to our surprise, it turns out that HTTP parsing is implemented in a very simplified way and is not packed into separate classes:
Arduino code snippet showing HTTP request handling.
So I started looking for a library that would offer it to me.
I was interested in QuickSander job:
https://github.com/QuickSander/ArduinoHttpServer
However, as it soon turned out, there are a few problems with it:
- does not compile under Arduino R4 WiFi
- the examples are quite poor
- does not support parsing GET arguments, i.e. a link like:

https://www.elektroda.pl/rtvforum/search.php?search_id=egosearch&user=1234

The link above contains two arguments: one with the key "search_id" and the value "egosearch", and the other with the key "user" and the value "1234". It would be nice to be able to get them easily from this address....
In this topic, I will try to fix all three issues.

ArduinoHttpServer installation and fixes
We download ArduinoHttpServer from Libraries Manager, by the way, you also need to install one dependency, namely Base64:
ArduinoHttpServer library with a popup window of missing dependencies
Then you can try to compile their example from Github but it will fail:
Code: C / C++
Log in, to see the code

We will get a compilation error like this:
Screenshot of Arduino R4 WiFi compilation error.
The pgmspace.h header is missing. We'll fix it right away. It is not actually needed in this case.
We open the library code, for me it is under:

C:\Users\Admin\Documents\Arduino\libraries\Base64\src\Base64.cpp

Just comment out this block (or add define for R4):
Edited source code in the Base64.cpp file with a highlighted conditional block.
Now the example should work, but if we sometimes get a message like this:
Error 400 message: Timeout occurred while waiting for data.
It's worth taking a look at:

C:\Users\Admin\Documents\Arduino\libraries\ArduinoHttpServer\src\internals\StreamHttpRequest.hpp

The problem is this piece of code:
A snippet of ArduinoHttpServer code with a loop checking for data availability in the stream.
It just detects a timeout error. Initially, I wanted to increase the value of the MAX_RETRIES_WAIT_DATA_AVAILABLE constant:
Code snippet in a text editor with a highlighted line about the constant MAX_RETRIES_WAIT_DATA_AVAILABLE.
but in the end I just commented out the whole block. From then on, the whole thing started to work a little more stable.
C++ code with a commented-out block checking for timeout.
I don't know how correct this approach is, but after this change, this library works a bit more stable for me.

Usage example from the authors of ArduinoHttpServer
Let's take a moment to test the sample ArduinoHttpServer code provided by the author of the library. This code offers a simple HTTP authorization based on a mechanism built into the browser:
Code: C / C++
Log in, to see the code

Indeed, after entering the site, we have a window asking for data:
HTTP login prompt on a local page requesting username and password.
After entering the wrong data in the log, we get:
Screenshot of console messages about client connection and authorization errors.
However, after entering the correct ones:
Console screen with logs of Arduino program operation
Authorization may be useful, but strangely enough, I don't see anything more fundamental anywhere, i.e. the ability to extract arguments from a GET request. We'll take care of it right away.

Argument parsing implementation
A short analysis of the library code shows that the HttpResource class is responsible for parsing the resource address. The author in this class only keeps one string and splits it up as needed:
Code: C / C++
Log in, to see the code

The [] operator allows you to get to specific folders in the address of the resource:
Code: C / C++
Log in, to see the code

All the magic happens in the snippet with the variable textField . The code checks if there is a GET argument with that name, and if so, it includes a message in the HTML displaying the textField value. If not, the display skips. In both cases, I continue to create an HTML form with a field named textField so that the user can easily send a GET request with the new value of this variable.
After opening the page we see:
Web page in a browser with a text input form and a Submit button.
After typing the text "ArduinoFan" and sending:
HTML page with a form field and user greeting.
My GET argument handling seems to be working.

Hint - ArduinoHttpServer building and streams
Now I would like to point out a useful feature of the discussed library resulting from object-oriented and inheritance available in the environment used.
Consider the StreamHttpReply constructor that represents the HTTP response:
Code: C / C++
Log in, to see the code

The first argument is an object of the Stream class, i.e. a stream. Various classes inherit from the Stream class, including network stream. Using StreamHttpReply then looks like this:
Code: C / C++
Log in, to see the code

It was in the example you posted. But a stream is also an object Series , which is the Arduino serial port. This allows us to construct the following:
Code: C / C++
Log in, to see the code

It may seem strange, but nothing prevents you from using the HTTP protocol on the UART stream, instead of the TCP stream. Let's consider a larger example:
Code: C / C++
Log in, to see the code

Result in the console:
Screenshot of HTML results and HTTP header in console.
That's right, this code just printed the sent HTML with the HTTP header appended. This very nicely shows the hermetic and modular structure of this library.

Summary
Quite a nice and useful library. There were no big problems with porting it to R4, which is not surprising, because its mechanisms are based on the Stream class, which can be a common interface for many streams.
A bit strange that at the moment of writing this topic, this library did not support easy access to GET arguments, but it was enough to add one function to change it.
I'll test my code a bit more and then I'll open it pull request on Github to suggest my changes and improvements, maybe the author of the library will accept them and add them to his code.
That's it for now. Has anyone of the readers already created an HTTP server on Arduino R4? Do you see any potential uses for this library?
PS: Below is the patch I sent to the author of the library: https://github.com/QuickSander/ArduinoHttpServer/pull/23

About Author
p.kaczmarek2
p.kaczmarek2 wrote 11842 posts with rating 9938 , helped 566 times. Been with us since 2014 year.

Comments

ripnetru 28 May 2024 19:42

Hello, I have R4 Uno and when compile get error Compilation error: 'const class ArduinoHttpServer::HttpResource' has no member named 'getArgument' Added after 3 [minutes]: String ssid... [Read more]

p.kaczmarek2 28 May 2024 20:17

This is because you need to use my version of the library. You can see the code here: https://github.com/QuickSander/ArduinoHttpServer/pull/23/files You can just copy and paste it. Let me know if you... [Read more]

ripnetru 28 May 2024 21:05

Good, now working, i have error 400 too and fix as you write. I setup wifi credits and it working, after reboot beginSTA with SSID pass Its ok, but i don't understand how working link return on AP... [Read more]

ripnetru 30 May 2024 17:10

Help please if it possible at all. In form we have ssid and pass, and i want if ssid and pass saved to show it on web form in input field. " <label for=\"ssid\">Enter SSID:</label><br>\n" "... [Read more]

p.kaczmarek2 30 May 2024 17:35

Can you please provide the full code you are working on currently? If you are referring to the HTML page generation, then you can do something like this: <input type="text" id="ssid" name="ssid"... [Read more]

ripnetru 30 May 2024 17:42

I no have code, working with your original code https://www.elektroda.com/rtvforum/topic4000214.html i want something like this: " <label for=\"ssid\">Enter SSID:</label><br>\n" "... [Read more]

p.kaczmarek2 30 May 2024 18:16

I see, so this is my old code snipper: reply += " <form>\n" " <label for=\"ssid\">Enter SSID:</label><br>\n" " <input... [Read more]

ripnetru 30 May 2024 18:49

I really appreciate it. I just checked, it works as I wanted. Thank you! [Read more]

p.kaczmarek2 30 May 2024 21:27

Sure, let me know if you need any futher help [Read more]

ripnetru 02 Jun 2024 23:54

Hello, Yes, i have one more question, when he working in STA mode, some times he loses connect, maybe it's interference (2,4 GHz) (00:43:00.872 -> Going to read settings... 00:43:00.872 -> Settings... [Read more]

ripnetru 03 Jun 2024 20:54

I try to make this: void loop() { int status = WL_IDLE_STATUS; while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println("Pixel"); status = WiFi.begin("Pixel",... [Read more]

ripnetru 11 Jun 2024 19:37

I figured it out, I didn’t know that variables can be taken higher than loop and setup and I made them similar to your example #include <ArduinoHttpServer.h> const char *ssidglobal; const... [Read more]