Read values from an Arduino via HTTP

By

Learn how to read sensor values from an Arduino over HTTP, expanding a WiFiNINA web server so you can open a page in your browser and see the measured data.

~~~

You can read the values measured by an Arduino by making the board serve them over HTTP. The Arduino runs a tiny web server on your WiFi network, and you open its address in the browser to see the latest sensor data.

In this tutorial I want to expand the Arduino Web Server tutorial to do exactly that. We’re going to measure the temperature using a DHT11 sensor, and print it in the page.

The starting point

This is the code from the other tutorial. It connects to WiFi using the WiFiNINA library, starts a server on port 80, and answers every request with a small HTML page:

#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) {
    String line = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);

        if (c != '\n' && c != '\r') {
          line += c;
        }

        if (c == '\n') {
          if (line.length() == 0) {
            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;
          } else {
            line = "";
          }
        }
      }
    }

    client.stop();
  }
}

The interesting part is where we print test inside the HTML. That’s where we’ll put the sensor value instead.

Adding the DHT11 sensor

Connect the DHT11 data pin to digital pin 2 on the Arduino, plus power and ground.

In the Arduino IDE, install the DHT sensor library by Adafruit from the Library Manager. Then set it up at the top of the sketch:

#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

In setup(), initialize it:

dht.begin();

Serving the temperature

Now, in the part of loop() that builds the response, read the temperature and print it instead of test:

float temperature = dht.readTemperature();

client.println("<!DOCTYPE HTML>");
client.println("<html>");
if (isnan(temperature)) {
  client.println("Failed to read from the sensor, reload the page");
} else {
  client.print("Temperature: ");
  client.print(temperature);
  client.println(" C");
}
client.println("</html>");

Notice the isnan() check. That’s the realistic failure you’ll hit with this sensor: dht.readTemperature() occasionally fails and returns nan, for example when you request readings too close together. Without the check, the page would show Temperature: nan C. With it, you tell the visitor to reload, and the next read usually works.

We read the sensor only when a request comes in. The value in the page is always the value measured at the moment you loaded it, so reloading the page gives you a new measurement.

Trying it out

Load the code on the Arduino, check the serial monitor for the IP address, and open it in the browser.

I reserved a static IP to the Arduino using my local network router, and I named it arduino.local in my /etc/hosts file, so I just open http://arduino.local/ and I see something like:

Temperature: 24.00 C

The complete program

Here’s the full sketch with the sensor integrated:

#include <SPI.h>
#include <WiFiNINA.h>
#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

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());

  dht.begin();
  server.begin();
}

void loop() {
  WiFiClient client = server.available();
  if (client) {
    String line = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);

        if (c != '\n' && c != '\r') {
          line += c;
        }

        if (c == '\n') {
          if (line.length() == 0) {
            float temperature = dht.readTemperature();

            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>");
            if (isnan(temperature)) {
              client.println("Failed to read from the sensor, reload the page");
            } else {
              client.print("Temperature: ");
              client.print(temperature);
              client.println(" C");
            }
            client.println("</html>");
            break;
          } else {
            line = "";
          }
        }
      }
    }

    client.stop();
  }
}

From here you can extend the idea to any sensor. Read the value, print it in the HTML, and anything on your network, a browser, a script, a dashboard, can fetch it over HTTP.

Tagged: Arduino · All topics
~~~

Related posts about electronics: