Skip to main content

Sometimes there is a need to step back and do things as simply as possible. EInk / Epaper screens are amazing, they carrying on showing an image with zero power and the screens have a certain clarity that is hard to achieve with more standard LED offerings. The more difficult part is getting content onto them, especially content that is well designed and fits the screen.

 

Puppeteer can do many things but for our use it allows the Pi to open a webpage, take a screengrab, save it as an image and then close. This image can subsequently be served via Node Express and viewed on an eInk screen.

To make the most of eInk/epaper screens you generally grab some information using a microcontroller, such as a Node MCU or ESP32, send it to the screen and then power down. This means you can check for new information over a period of time, say, every 15 minutes, display it and then sleep, allowing your screen to be battery powered for weeks on end.

 

Inkplate 6 Case

At the moment we are using the amazing InkPlate 6. The InkPlate 6 is built around a recycled Kindle Screen and has a built-in ESP32 controller, a lithium battery connecter/charger and perhaps, more importantly, an easy to understand library to display an image and then sleep. In the world of eInk screens, the importance of an easy to understand library really cannot be understated, some of them are notably complex. We have published the 3D printable case to Thingiverse so all you need is the InkPlate (or any other screen you want to display an image on), a script to load a webpage and some Node JS to grab the information you want to display.

 

windy.com on an eink screen

We are using 3 variations of the same script on our ePaper display, one to grab a webpage showing environmental information, a second decoding a weather forecast from the Met Office, another showing a Rainfall radar and we cycle these every 15 minutes with the environmental information showing twice in the hour.

The information can of course be any web page you want to display, from a news site,  a social network feed, transport information or anything you want to show.

Ingredients

 

  1. You will need a device capable of running Node JS, we are using a Raspberry Pi 4. We assume here that you have a Pi up and running with the full operating system installed, if not then take a look at the main Pi site for details on how to set up. If you need any help then drop us a line in the comments and we can expand this section as needs be.
  2. Optional: An eInk screen and controller – we are using the InkPlate 6 and our code to load the image once grabbed is now available on GitHub. There are a number of eInk/epaper screens, the most popular ones being made by WaveShare. These will also work if you edit the example code from the libraries that allow the display of online images. Of course, you may simply want to have an automated screengrab of a webpage. Such things are useful in Unity3D to make Augmented Reality displays, for example.

Installing Node JS

The first part is to install Node.JS, thankfully Node is quick and easy to install – in your terminal enter:

 

$ curl -sL https://deb.nodesource.com/setup_15.10.0 | sudo -E bash -

The 15.10.0 represent the current version as of February 2021, change this number to the latest version as needs be – you can find out the current release via the main Node JS site. You have now made your Pi aware of where to find Node.

The next step is to install it:

 

sudo apt install nodejs

To check all is in place you can run:

 

node -v

This will tell you the version of Node you are running. You have installed Node, well done, now for the Puppeteer library.

Installing and Configuring Puppeteer

Puppeteer is a library for Node.js that allows for the control of the Chrome browser in headerless mode (i.e. you dont see it happening). This allows you to open a web page, do something with it – in our case take a screenshot – and then close chrome, all via a simple script.

Installing Puppeteer is all via a single line in the terminal:

 

npm i puppeteer --save

Now you have Node.js and Puppeteer installed, all you need now is to create a script to tell Node what to do:

We like to start a new script in a new directory called ‘Scripts’ (although it can be anywhere).

So firstly create a new directory via the terminal:

 

mkdir Scripts

Now create your first empty script, we are going to call ours ‘webpage.js’:

 

sudo nano webpage.js

Below is the javascript to cut and paste into your new script:

 

const puppeteer = require('puppeteer');
async function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
(async () => {
let browser = await puppeteer.launch({
          headless: true,
          executablePath: '/usr/bin/chromium-browser',
//          args: ['--no-sandbox', '--disable-setuid-sandbox']
  });
  const page = await browser.newPage();
  await page.goto('http:YourWebPageURL');
// 5 second timeout: allows the page to fully render before taking the screenshot
  await timeout(5000);
  await page.setViewport({ width: 800, height: 600});
  await page.screenshot({path: '/home/pi/Scripts/eink.jpg'});
  await browser.close();
})();

The main parts to note above are the http: where you need to add in the webpage you want to capture and the width and height of the page. This should be changed according to the resolution of your screen, the InkPlate 6 runs at 800×600 resolution. The script opens the URL, waits 5 seconds for it to fully load and then saves a screenshot as a jpg to the location of your choice.

To run your script:

node webpage.js

The script should now run, load a webpage and save the image to your Pi.

If you are running your eInk display direct from your Pi (such as using a Waveshare screen) you can stop here and point your display to the new image. If however, you are using a screen elsewhere on your network you will need to host it, this is where Node Express comes in.

Installing Node Express

As with Node and Puppeteer installing is via a simple one line command:

 

npm install express --save

To start the server and host the image, you need another script. So the same as before, create a script, we called ours server.js:

 

sudo nano server.js

Cut and paste the following:

 

var express = require('express');
var app = express();
var path = require('path');
var public = path.join(__dirname, 'public');
// viewed at http://localhost:8080
app.get('/', function(req, res) {
    res.sendFile(path.join(public, 'index.html'));
});
app.use('/', express.static(public));
app.listen(8080);

The above script runs a server at http://localhost:8080 where you can install a welcome page (index.html) if you wish but more importantly you can serve static files, in our case our screen grab eink.jpg. Note that the folder address is ‘public’ this is where you will host your files.

In our first script we now want to edit the folder where our image is saved, so we can host it as soon as it is created, so simply edit the file, (again using sudo nano webpage.js) to include the ‘public’ directory -ie /home/pi/Scripts/public/eink.jpg

If you now go to either http://localhost:8080/eink.jpg on the host machine or your http://Your IP of the PI:8080/eink.jpg you should be able to view the jpg.

All that needs to be done now is to start the server when the Pi boots and to run the webpage script every set period of time. To load different webpages simply clone the webpage.js script but with a different URL to grab and run it at a different time, as mentioned, we run 4 scripts an hour via cron jobs.

Cron Jobs

The final part is to run the server at boot and the script every 15 minutes.

Firstly go to your root directory by typing:

 

cd:

Now we want to install a new Cron Job, or edit one we have already set up:

 

sudo crontab -e

At the end of the file that opens add the following lines:

 

@reboot sudo /usr/bin/node /home/pi/Scripts/server.js
15 * * * * /usr/bin/node /home/pi/Scripts/webpage.js

Whenever the Pi reboots it will now start the server – via your server.js script and every 15 minutes run your webpage.js script to take an image of a webpage, which you can subsequently point your eInk screen to load.

It may feel like a number of hoops to jump through for a simple screengrab, but once running it opens up the wider world of Node.js and Puppeteer as well as the ability to use your eInk screen to display any webpage you want.

I hope this has been useful, do drop me a line in the comments with any thoughts or tweet me @digitalurban. It’s part of a series of new ‘how to’s’ here on digitalurban.org and over at https://connected-environments.org/


 

One Comment

  • J says:

    Hello. I’ve been waiting a year to get into this and it seems out of date.
    I managed to get to the run part of the tutorial and I get back eight, ‘syntaxerror: missing ) after argument list’ error lines.
    Is there an updated version of these instructions? I’m so excited to get it working on my inkplate 6 and 10.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Close Menu

About Salient

The Castle
Unit 345
2500 Castle Dr
Manhattan, NY

T: +216 (0)40 3629 4753
E: hello@themenectar.com