Saturday, 8 December 2018

PyGame on Nook Simple Touch

PyGame app launcher

Building the PyGame app launcher was the most simple part of this hack for the Nook Simple Touch. Rebuilding the Linux OS to build Python was actually a long job which I almost gave up on. I'll get into the OS later. 

I'm starting with the PyGame launcher as it's the heart of this build. Here's a video from boot up


Star field running on Nook
The launcher runs on x86 Linux and Raspberry Pi operating systems, but the code is tailored for an e-ink screen. Refresh rates are very slow compared to an LCD display and only 10 FPS really work on the Nook display. Due to the slow refresh rates all the apps are written to prevent screen blurring as much as possible. 

Although PyGame sounds like it should be just for games, it actually provides a basic graphics environment to create all kinds of apps. I've written 2 basic apps to establish a framework for future apps. One is a basic system status app with text on the screen and the other is a star field app with animated graphics and screen interaction. Both of these require different demands and the launcher framework can handle both with varied framerate support.

System status app
The 2 screen shots of the apps can be seen here. Note that the star field app takes all the CPU, but the system status (and the launcher app itself) only take up 22% or so as it only needs to update once per second. Apps can specify the framerate they require in the app config. 

Initially the code was all written in a single thread as this reduces the potential race condition bugs found in threaded apps. Polling the user input is highly demanding of the CPU so a separate thread was introduced to remove the polling and throttle back the CPU when its not required.

PyGame App Framework
Apps run one at-a-time and when they are closed they are deleted to free up memory and CPU. This keeps down overheads, but if background apps are needed in the future it should be fairly simple to change the launcher to manage these as well as a foreground app.

Getting Python on the Nook

The Nook Simple Touch from Barnes & Noble boots from an SD card. Some smart folk created rooting apps using this ability to boot up the Nook and modify the Android OS. I've used the same method to create a bootable OS which doesn't interfere with the original software installed on the Nook

Kernel source code is still available from Barnes & Nobel to download. This doesn't cross compile with new gcc cross-compilers. The only solution I could find was to track down an old compiler.
From this point a new u-boot and kernel can be built.
Soldered serial port access
With a bit of soldering the serial ports can be accessed to debug the new kernel and OS startup scripts. Modifications of u-boot startup are required to direct the console. I connected up with a ribbon header allowing easy disconnection and ability to close the case up. The XDA forums are still full of archived posts from years ago that outline the process to modify kernels and u-boot. I won't get into it here.

Building glibc, binutils and gcc on the Nook really broke the back of the OS build. Once these are in-place all the other libraries can be built on the Nook including Python.
I've opted to build Python 3.7 instead of 2.7 as hosting both shouldn't be necessary. SDL 1.2 is needed as PyGame doesn't yet support SDL 2. 
SDL 1.2 requires a minor modification to the fbcon driver because the e-ink driver doesn't support double buffer panning. Instead the display is flipped with a call to FBIOPUT_VSCREENINFO changing the yoffset. 

The USB port on the Nook is a gadget and host controller. There is limited ability to plug in a keyboard and I've had this working, but the device isn't really spec'd to be a host and it's very unreliable. There's not enough power to light up the keyboard LEDs.
As a gadget I've configured the kernel to be a serial device and a login prompt is attached to this so login access can be granted to a Nook reader if Wifi is unavailable. 

What is next?

  • Providing a downloadable image of the SD card would be great to share the OS build. It will be large so figuring out where to host it will be the problem
  • UI for wpa_configure is needed to change WiFi network access. Currently Wifi config requires editing of text files
  • Write a few more apps to demo the framework
  • Port an existing pygame e-reader app to work on the Nook, after-all this is an e-reader device


Sunday, 11 February 2018

Hyperpixel Touch Dashboard

Revisting Pimoroni Hyperpixel

This is a really nice little display that fits neatly onto any Raspberry Pi. It's sharp and responsive which is great for any interactive application. 

When I first received this I was a little disappointed that the screen took over so many of the header pins and Raspbian is pretty awful to use with a touchscreen. This got me thinking that what this screen is shouting out for is custom touchscreen applications that combine with the power of the Pi. 

Dashboarding on Raspbian

A little project of mine was focused on using the Pillow (PIL) Python library to draw custom graphs, controls and indicators for the e-ink displays. I put this aside, but reused and expanded the code to work with TK. I guess I could have gone in two other directions as well and used Pygame or Qt. I made a choice and used TK as Python seems closely associated. 

My main need was to display metrics and have limited button pressing capability. Luckily text input isn't an important requirement, although a decent on screen keyboard would be useful. 

Beer Brewing Dash

Beer brew stats are already captured in MQTT and are to hand on my phone. Why not on my desktop and on the HyperPixel. Well here's the results so far running on a Pi 3

This runs on Python 3 and 2.7 without any fuss. Linux distros will need to have some freefonts installed. The above is using FreeSans. 

Running on Windows is also possible and I've installed Python 3 to do just this. 

There's loads of configuration with the controls and the above are configured to be black on white whilst the HyperPixel is running with a black background.

The code is mostly there and should be up on GitHub soon.