In this tutorial, I will show you how to start a web server on an Arduino device with WiFi, for exampleArduino MKR WiFi 1010.
We will connect to an existing WiFi network and be able to interact with Arduino through the browser in the following waysHTTP.
This is very interesting for various applications. From simple sensor data checking to sensor-based actionsHTTP requestcarried out.
We will start with the procedure defined in this procedureConnect to WiFi network using ArduinoTutorial:
#include <SPI.h>
#include <WiFiNINA.h>
void setup() {
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
Serial.begin(9600);
while (!Serial);
int status = WL_IDLE_STATUS;
while (status != WL_CONNECTED) {
Serial.print("Connecting to ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(5000);
}
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
}
Before setup(), add the following line:
WiFiServer server(80);
Initialize oneTCP protocolThe server is on port 80 and at the endsetup()
call
server.begin();
Start the server.
Now, this is a TCP server, not an HTTP server. But since HTTP (TCP/IP Application Protocol) is built on top of TCP (Transport Layer), we can easily build HTTP server by ourselves.
First, we need to listen for client connections. We doloop()
:
void loop() {
WiFiClient client = server.available();
if (client) {
}
}
The available() methodserver
Listen for incoming clients.
Insideif (client) {}
Check that we are connected to an HTTP client. What we need to do is:
- call
client.connected()
Check whether the data is connected and there is data to be read - call
client.available()
Get the number of bytes that can be read (to ensure that there is data to be read) - call
client.read()
Read a byte from the incoming data (HTTP request sent by the client) - call
client.println()
orclient.print()
Send data to the client and establish an appropriate HTTP response - call
client.stop()
End connection
We start to print each character sent by the client to the serial interface, and finally close the connection:
void loop() {
WiFiClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
}
}
client.stop();
}
}
Try to upload this program to Arduino. Point your browser to the IP address. You will see something similar on the serial interface. This is what the browser sends:
GET / HTTP/1.1
Host: 192.168.1.40
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-aliveNote the ending empty line. This is the end of the HTTP request.
We need to intercept this empty line.
Each line in the HTTP request is terminated by a CR carriage return character (\r
), and a LF line feed character (\n
).
So the end of the request can be determined by 2 sets of those sequences: \r\n\r\n
.
This simple algorithm will work, we just memorize 2 characters prior to the current one, and we check if we identify the sequence \n\r\n
(the last 3 characters in that sequence are enough to determine the last line):
void loop() {
WiFiClient client = server.available();
if (client) {
<span style="color:#66d9ef">char</span> prevprev;
<span style="color:#66d9ef">char</span> prev;
<span style="color:#66d9ef">while</span> (client.connected()) {
<span style="color:#66d9ef">if</span> (client.available()) {
<span style="color:#66d9ef">char</span> c <span style="color:#f92672">=</span> client.read();
Serial.write(c);
<span style="color:#66d9ef">if</span> (prevprev <span style="color:#f92672">==</span> <span style="color:#e6db74">'\n'</span> <span style="color:#f92672">&&</span> prev <span style="color:#f92672">==</span> <span style="color:#e6db74">'\r'</span> <span style="color:#f92672">&&</span> c <span style="color:#f92672">==</span> <span style="color:#e6db74">'\n'</span>) {
<span style="color:#75715e">//we can send the response!
}
prevprev <span style="color:#f92672">=</span> prev;
prev <span style="color:#f92672">=</span> c;
}
}
client.stop();
}
}
So now we can send the response inside the if
, we can use client.println()
for this, and we add a simple response like this:
HTTP/1.1 200 OK
Content-Type: text/html
Connection: close
<!DOCTYPE HTML>
<html>
test
</html>
In this way:
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("test");
client.println("</html>");
break;
The break;
statement ends the while (client.connected()) {}
block.
Here is the full program:
#include <SPI.h>
#include <WiFiNINA.h>
WiFiServer server(80);
void setup() {
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
Serial.begin(9600);
while (!Serial);
int status = WL_IDLE_STATUS;
while (status != WL_CONNECTED) {
Serial.print("Connecting to ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(5000);
}
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
WiFiClient client = server.available();
if (client) {
<span style="color:#66d9ef">char</span> prevprev;
<span style="color:#66d9ef">char</span> prev;
<span style="color:#66d9ef">while</span> (client.connected()) {
<span style="color:#66d9ef">if</span> (client.available()) {
<span style="color:#66d9ef">char</span> c <span style="color:#f92672">=</span> client.read();
Serial.write(c);
<span style="color:#66d9ef">if</span> (prevprev <span style="color:#f92672">==</span> <span style="color:#e6db74">'\n'</span> <span style="color:#f92672">&&</span> prev <span style="color:#f92672">==</span> <span style="color:#e6db74">'\r'</span> <span style="color:#f92672">&&</span> c <span style="color:#f92672">==</span> <span style="color:#e6db74">'\n'</span>) {
client.println(<span style="color:#e6db74">"HTTP/1.1 200 OK"</span>);
client.println(<span style="color:#e6db74">"Content-Type: text/html"</span>);
client.println(<span style="color:#e6db74">"Connection: close"</span>);
client.println();
client.println(<span style="color:#e6db74">"<!DOCTYPE HTML>"</span>);
client.println(<span style="color:#e6db74">"<html>"</span>);
client.println(<span style="color:#e6db74">"test"</span>);
client.println(<span style="color:#e6db74">"</html>"</span>);
<span style="color:#66d9ef">break</span>;
}
prevprev <span style="color:#f92672">=</span> prev;
prev <span style="color:#f92672">=</span> c;
}
}
client.stop();
}
}
Try it, you should see test
showing up in the browser:

The approach works until you need to figure out how what the client asked us.
In that case you want to read each line, so this alternative approach works better:
void loop() {
WiFiClient client = server.available();
if (client) {
String line = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
<span style="color:#66d9ef">if</span> (c <span style="color:#f92672">!=</span> <span style="color:#e6db74">'\n'</span> <span style="color:#f92672">&&</span> c <span style="color:#f92672">!=</span> <span style="color:#e6db74">'\r'</span>) {
line <span style="color:#f92672">+=</span> c;
}
<span style="color:#66d9ef">if</span> (c <span style="color:#f92672">==</span> <span style="color:#e6db74">'\n'</span>) {
<span style="color:#66d9ef">if</span> (line.length() <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span>) {
client.println(<span style="color:#e6db74">"HTTP/1.1 200 OK"</span>);
client.println(<span style="color:#e6db74">"Content-Type: text/html"</span>);
client.println(<span style="color:#e6db74">"Connection: close"</span>);
client.println();
client.println(<span style="color:#e6db74">"<!DOCTYPE HTML>"</span>);
client.println(<span style="color:#e6db74">"<html>"</span>);
client.println(<span style="color:#e6db74">"test"</span>);
client.println(<span style="color:#e6db74">"</html>"</span>);
<span style="color:#66d9ef">break</span>;
} <span style="color:#66d9ef">else</span> {
line <span style="color:#f92672">=</span> <span style="color:#e6db74">""</span>;
}
}
}
}
client.stop();
}
}
In the last else
we can inspect the line because the line is terminated, and act accordingly to our needs.
More electronics tutorials:
- Arduino vs Raspberry Pi
- An introduction to Arduino
- The Arduino Uno rev 3 board
- The Arduino Uno WiFi rev 2 board
- Introduction to the Arduino Programming Language
- Milli Micro Nano Pico
- The Arduino MKR WiFi 1010
- Introduction to Electronics
- Electronics Basics: Analog vs digital
- Electronics Basics: Current
- Electronics Basics: Voltage
- Electronics Basics: Vcc, ground, ...
- Electronics Basics: Resistance
- Electronics Basics: Short Circuit
- Electronics Basics: Your first circuit
- Electronics Basics: Prototyping using breadboards
- Electronics Basics: using a multimeter
- Measuring voltage, current and resistance using a multimeter
- What to buy to get started with Arduino and Electronics
- Arduino project: blink a LED
- The Arduino built-in LED
- Breadboard Power Supply Module
- The Arduino Create Platform
- How to connect to a WiFi network using an Arduino
- How to run a Web Server on an Arduino