HTTP Server using AJAX PART2
This is the 12th tutorial in the STM32 ETHERNET series, and today we will see how to use the STM32 as the webserver with AJAX (Asynchronus Javascript And XML). This tutorial will cover how to reload a specific part of the webpage to display the updated data. We will use the XMLHTTPRequest in order to achieve the same.
This tutorial is a continuation from the https://controllerstech.com/http-server-using-ajax-part1/, so all the setup is same. I am only going to make few changes in that project.
The Client
We have already used the web browser as the client. The index.html file we used in the previous tutorial will remain pretty much the same, except we will add a very few more things to it.
Since we need to display some data on the webpage, for eg- the UART output, some temperature values, or some ADC data, we need to use some kind of block to display these results in. I am going to use the textarea for this purpose.
<label for="textarea"> VALUE : </label>
<textarea id="textarea" style="vertical-align:middle" cols="20" rows="1"></textarea>
We already have the code under the <script> tag from the previous tutorial, where we used the XMLHTTPRequest to send an empty request to the server. This time we want to reload a specific part (textarea) of the webpage, so we need to use some timeout feature to reload the textarea every specific amount of time. Below is the code for the same.
function Timer1(){
xhr.onreadystatechange = function() {
document.getElementById("textarea").value = this.responseText;
}
xhr.open("GET", "getvalue", true);
xhr.send(null);
setTimeout("Timer1()", 1000);
}
- Here the Timer1() function will be called every 1 second.
- We initialize a GET request with the URL /getvalue
- Then send this request to the server
- whenever the
readyState
property of theXMLHttpRequest
changes, readystatechange will be triggered- Here we will update the value of the textarea with whatever response we get from the server.
- Since the Timer1() function is being called every 1 second, the value will be keep updating every 1 second too.
We can just call the Timer1() function once after the page has been reloaded, and then it will continue to run forever after that. To do so, we can call it inside the onload() function which is called by the onload event.
function onload(){
xhr = new XMLHttpRequest ();
Timer1();
}
OR we can create a button to call the Timer1() function once. In either case, we need to just call it once and then this function will run forever at a predefined time interval (1 second in this case).
<button type="button" onclick="Timer1()">Start</button>
The final script is shown below
<script>
var xhr;
function onload(){
xhr = new XMLHttpRequest ();
// Timer1();
}
function Timer1(){
xhr.onreadystatechange = function() {
document.getElementById("textarea").value = this.responseText;
}
xhr.open("GET", "getvalue", true);
xhr.send(null);
setTimeout("Timer1()", 1000);
}
function green (){
xhr.open ("GET", "buttoncolor=G", true);
xhr.send(null);
}
function blue (){
xhr.open ("GET", "buttoncolor=B", true);
xhr.send(null);
}
</script>
The server
FreeRTOS CMSIS V2 was having issues where the code gets stuck due to some corruption in the semaphore. So in this tutorial I have changed the to CMSIS V1.
In the httpserver.c file, we are already handling different requests for pages, images and the buttons. Among these requests, we will add 1 more to handle the data request made by the textarea.
For the simplicity, I am going to increment a variable (indx) and then send it’s value to the webpage.
if (strncmp((char const *)buf,"GET /getvalue",13)==0)
{
char *pagedata;
pagedata = pvPortMalloc(10);
int len = sprintf (pagedata, "%d", indx++);
netconn_write(conn, (const unsigned char*)pagedata, (size_t)len, NETCONN_NOCOPY);
vPortFree(pagedata);
}
- Here first we will check if the request is made to get the value from the server
- If it is, then we will first allocate the memory to the pagedata.
pvPortMalloc
must be used if you are planning to use the sprintf. I have shown it in the memory allocation of freeRTOS https://youtu.be/49Q4p4ARpng
- Then we will store the
indx
value into thepagedata
- Next we will send the data to the client using the
netconn_write
- Finally free the memory using the function
vPortFree
Other than this addition, the code is same as the previous tutorial, https://controllerstech.com/http-server-using-ajax-part1/
Result
As shown in the image above, the index value is updating and reached to 21. On the right you can see the requests made by the client, and since these are the only requests present on the wireshark, it mean that the page is not reloading while making the requests.
You can see the working more clearly in the video below.