Thursday, January 1, 2015

JavaFX on e-paper

Hi there,

Before christmas I was playing around with the following e-paper display from Embedded Artists...
E paper display
The nice thing about e-paper displays is the fact that they are very energy saving because they use an interesting approach to visualize data (wikipedia). The Embedded Artists display only needs power to change the screen content and after it has changed it will stay on the display even without power connected to the panel. 

If you hear this for the first time you think...man...that's great I wanna use it for my embedded project...BUT...keep in mind that it has two major drawbacks...
  • It is only black and white...so no colors, gradients etc.
  • The screen refresh is really slow compared to the TFT panels (this panel takes up to 2 sec to change the screen)
So an e-paper display is not useful for animated or colorful apps but if you think about a weather station or a price display in a supermarket it absolutely makes sense to use such a display. In these cases the content of the display only changes a couple of times a day (weather station) or week (price display).

For me it was only interesting to see if I would be able to use JavaFX to render something on this display. If people hear JavaFX they first of all think about animations, effects etc. but hey, it's just a simple UI toolkit which can create visual content.

So I wanted to use the e-paper display on an Odroid-W from Hardkernel (which is hardware compatible to the Raspberry Pi). Lucky me there was already a tutorial on the Embedded Artists website that describes how to hookup the e-paper panel to a Raspberry Pi. In principle it describes how to install the driver for the panel on the Pi and how to display some content on it. My idea was to visualize maybe a clock (without second pointer) and also some weather information. So I would have to change the content of the screen at least once a minute which should be ok.

The tool that was provided by Embedded Artists is able to display an image in XBM format which is a plain text binary image format to store bitmaps (wikipedia). To display the xbm image you simple clear the screen and copy the image to a special folder by using two shell commands.

Now to the idea on how to use JavaFX to visualize data on the e-paper panel...

1. Create the JavaFX scene
  • Make sure that the size of the scene is exactly the size of the e-paper display (264 x 176 px).
  • Instead of colors just use black on white (you could also use white on black).
  • Make sure that you don't use an AnimationTimer (it will lead to render on every pulse)
  • Update the scene from a scheduled task via Platform.runLater(()->{...}) once a minute
And this is how my JavaFX app looks like when connected to a standard display

Monosnap 2014 12 31 13 17 50


2. Create the XBM file
To create an xbm image file we first need to take a snapshot which is very easy in JavaFX. In fact it is just one line of code...


final WritableImage SNAPSHOT = NODE.snapshot(new SnapshotParameters(), null);

With the writable image in place we now can use a PixelReader to read out the color of every pixel in the image. This is needed to create the corresponding hex string for the xbm image. Creating the image is done by two loops that simply loop over all pixels, read out the rgb value of each pixel in the snapshot, convert it into a hex string (0x00 - 0xff) and write it into a file. To give you an idea on how the xbm file will look like, here are some lines from the file...

#define yotaclock_width 264
#define yotaclock_height 176
static unsigned char yotaclock_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xf8,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,
0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
...
}

3. Updating the e-paper display
Now we only have to update the display every time we create a xbm image file. To make it as easy as possible I simply call the shell commands via ProcessBuilder like follows...


Process p1 = new ProcessBuilder("/bin/bash", "-c""/PATH/TO/DRIVER/gratis/PlatformWithOS/driver-common/xbm2bin < /PATH/TO/IMAGE/YOUR_IMAGE.xbm > /PATH/TO/EPD/epd/display").start();
p1.waitFor(1, TimeUnit.SECONDS);

Process p2 = new ProcessBuilder("/bin/bash", "-c", "echo U > /PATH/TO/EPD/epd/command").start();
p2.waitFor(1, TimeUnit.SECONDS);

And that's all you have to do to use JavaFX with an e-paper display on a Raspberry Pi. This really more a quick hack than a really nice solution but it works :)

And here is an example image of the e-paper display...



There is definitely place for improvements like handling the whole image thing in memory and pass it directly to the driver instead of saving it to a file and calling the update via a shell command. But because I don't update the display very often this approach also works really well.

I've created a little gist that contains the code you need...

That's it for today...so keep coding... :)

No comments:

Post a Comment