Gregor Godbersen : Mocking an ESP8266 graphics library in JavaScript
Published

Mocking an ESP8266 graphics library in JavaScript

Note that this entry was originally published 5 years ago. It may present outdated technologies or knowlege.

The tiny and cheap ESP8266 WiFi-enabled microchips allow for quick hardware prototypes. Among the libraries that have sprung up in the considerable ecosystem is the graphic library minigrafx that supports several LCD, OLED, and E-Paper displays. The API provides several graphics primitives as writing text, drawing lines and rectangles, which can be composed into complex user interfaces.

To ease the debugging of these interfaces, I have developed some small glue code in JavaScript, which renders the drawing calls onto an HTML Canvas element within the browser. This allows us to immediately preview the designs without flashing the code to the device resulting in faster iteration loops. As the JavaScript structures are reasonably close to C, drawing code can be copied directly between the mocked and real project with only minor changes. Due to small differences in the drawing engine, the result is not pixel perfect but reasonably close.

Demo

Mocked UI of weather station rendered using random data. (Live demo)

The display rendered above is from an e-paper weather station project mocked using the JavaScript library. The bitmap font used to render the forecast icons has been replaced by Unicode characters.

Library source

The library glue code and an example based on the weather station mock can be found in the GitHub repository. Use your IDEs live reload method to have instant feedback. Hint: Do not forget the commit call that applies any changes to the display.

Example conversion

The following Arduino c code is an excerpt from a weather station project that draws the forecast to an e-paper screen:

// helper for the forecast columns
void drawForecastDetail(uint16_t x, uint16_t y, uint8_t index) {
  gfx.setFont(ArialMT_Plain_10);
  gfx.setTextAlignment(TEXT_ALIGN_CENTER);
  String hour = hourlies[index].hour;
  hour.toUpperCase();
  gfx.drawString(x + 25, y - 2, hour);
  gfx.setColor(MINI_BLACK);
  gfx.drawString(x + 25, y + 12, hourlies[index].temp + "° " + hourlies[index].PoP + "%"); 
  gfx.setFont(Meteocons_Plain_21);
  String weatherIcon = getMeteoconIcon(hourlies[index].icon);
  gfx.drawString(x + 25, y + 24, weatherIcon);
  gfx.drawLine(x + 2, 12, x + 2, 65);
  gfx.drawLine(x + 2, 25, x + 43, 25);
}

When converting the code to JavaScript the function keyword must be inserted, and type information must be removed. All data that is externally generated can be mocked or replaced with a static string. The gfx object will translate all calls to the corresponding canvas drawing operations.

// helper for the forecast columns
function drawForecastDetail(x, y, index) {
  hourlies =  mock();
  getMeteoconIcon = mock();

  gfx.setFont(ArialMT_Plain_10);
  gfx.setTextAlignment(TEXT_ALIGN_CENTER);
  hour = hourlies[index].hour;
  hour.toUpperCase();
  gfx.drawString(x + 25, y - 2, hour);
  gfx.setColor(MINI_BLACK);
  gfx.drawString(x + 25, y + 12, hourlies[index].temp + "° " + hourlies[index].PoP + "%"); 
  gfx.setFont(Meteocons_Plain_21);
  weatherIcon = getMeteoconIcon(hourlies[index].icon);
  gfx.drawString(x + 25, y + 24, weatherIcon);
  gfx.drawLine(x + 2, 12, x + 2, 65);
  gfx.drawLine(x + 2, 25, x + 43, 25);
}