Deploy Angular on an ESP8266

Motivation

Angular is a web framework. It adds additional features to TypeScript, HTML and CSS and compiles these parts into HTML, CSS and JavaScript (the stack that is required for a dynamic website). Since this framework is very powerful and developers can build UIs with great user experience one might think of empowering these UIs with the machine world. There are several possibilities to place websites on computers or micro controllers and read sensors like temperature or pressure. These websites can bring machine related data in a beautiful way to the user. For them it feels fluent and they don't need to have any clue about GPIOs or other internals.

The most common and also most powerful device is a Raspberry Pi. But this tiny computer brings features one doesn't even need and also its power consumption is way higher then a plain micro controller. The other wide spread device is the Arduino. It is a micro controller which easy to develop and has an easy to use IDE. There is very few setup compared to other micro controllers. The problem with the arduino is, that it is not powered with any Wifi or network capabilities by default. There comes the ESP8266 into play. It has several versions and we are going to discuss them in detail next.

This article covers the complete setup and getting your Angular application running on the device in your local network or via a self-contained access point. The communication via websockets will be covered in an upcoming article. Basic Angular knowledge is required in the Angular section of this article.

What you need

As mentioned before, we are going to need a ESP8266 device. Which one to choose depends on the size of our final website. For a simple Angular website 1MB might be enough, but we should plan with at least 3MB. There are ESP devices with up to 16MB, if I know correctly. For our needs, the NodeMCU seems to fit perfectly. It has a 4MB flash drive on which we can place our data, so that we have 1MB for the program itself and 3MB for the website data.

Setup

Install the Arduino IDE from the official website and add the following url to your additional board urls entry inside the Arduino IDEs settings.

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Run the board manager and install the ESP8266 boards. Then select the board NodeMCU v1 with the flash disk configuration (spiffs) of 4MB/3MB. This means that we are going to use 3MB of the onboard flash storage as a filesystem and 1MB as storage for the application that will be running on the device (our webserver serving the Angular application).

For Angular we need NodeJS and the Angular CLI installed. Download NodeJS from the official website (or via nvm) and install Angular by npm install -g @angular/cli. And that's it. Create a new Angular CLI application with ng new and start coding your frontend without any restrictions (just keep 3MB in mind).

The webserver

You should already have the proper board selected in the Arduino IDE (e.g. NodeMCU v1). Also make sure that you have selected 3MB for the SPIFFS (SPI Flash File System) size. If that is done, we can start programming the server application.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>

const String ssid  = "NetworkSSID";
const String password = "password";
ESP8266WebServer server(80);

void setup() {
  SPIFFS.begin();
  WiFi.begin(ssid, password);
  delay(100);

  server.onNotFound([]() {
    if (!handleFileRead(server.uri())) {
      server.send(404, "text/plain", "404: Not Found");
    }
  });
  server.begin();
}

void loop() {
  server.handleClient();
}

The server imports the Wifi and Spiffs related libraries. Enter your wifi credentials to which wifi the device should connect, when running. We are using the port 80 because it is the standard http port. In the setup function we initialize the SPIFFS and the wifi first. Next we are defining the servermethods with a lambda function. It should look for files in the SPIFFS and if it does not find any file, it should return 404. In the loop we are making the server listen to any actions.

bool handleFileRead(String path) {
  Serial.println("handleFileRead: " + path);
  if (path.endsWith("/")) path += "index.html";
  String contentType = getContentType(path);
  if (SPIFFS.exists(path)) {
    File file = SPIFFS.open(path, "r");
    size_t sent = server.streamFile(file, contentType);
    file.close();
    return true;
  }
  Serial.println("\tFile Not Found");
  return false;
}

As already mentioned, we are looking for files in the SPIFFS and return false if the file does not exist. If the file exists we are returning the file back to the client via server.streamFile.

String getContentType(String filename) {
  if(filename.endsWith(".htm")) return "text/html";
  else if(filename.endsWith(".html")) return "text/html";
  else if(filename.endsWith(".css")) return "text/css";
  else if(filename.endsWith(".js")) return "application/javascript";
  else if(filename.endsWith(".png")) return "image/png";
  else if(filename.endsWith(".gif")) return "image/gif";
  else if(filename.endsWith(".jpg")) return "image/jpeg";
  else if(filename.endsWith(".ico")) return "image/x-icon";
  else if(filename.endsWith(".xml")) return "text/xml";
  else if(filename.endsWith(".pdf")) return "application/x-pdf";
  else if(filename.endsWith(".zip")) return "application/x-zip";
  else if(filename.endsWith(".gz")) return "application/x-gzip";
  return "text/plain";
}

For the web it is important to also send the content type of the files. In this function it checks the ending for known signatures and returns the proper content-type. And that's already it.

Uploading the Angular UI

Since this is not an Angular tutorial I guess you are familiar with implementing Angular applications (This works also with plain web applications and other frameworks). Imagine you have got a working application and you build it by running ng build --prod. The build files will be placed in the /dist folder by default. Copy these files into a /data folder inside the folder in which your Arduino sketch is placed.

Conclusion

In this article you have learned how to setup up a webserver on ESP8266 devices and how to upload sketches and Angular apps (or web applications in general) to the device. This devices serve your website either in a connected Wifi network or in a self-hostet access point.