Yes I bought another unusual display, now how to make this one work.
Running a circular display on a Raspberry Pi
This was originally a guide page, but I think is better as a Blog post, with the guide being more hands on.
If you want to jump straight to the hands on, then it will be at Round Display page.
Yes it’s a clock.
As you can see I found this round display (from Aliexpress) and rather liked the form factor, so ordered a couple of units. These are available both as bare display, or with a mounting board. In my case as my surface mount soldering is not great I went with the mounted version.
Once they arrived (very quickly I am pleased to say) I marveled at the look and then ran into the usual issue of finding driver or sample code.
Doing a bit of digging I found a post on the Arduino forum that pointed to some sample code along with a reference to the Datasheet for the driver chip (a GC9A01A allegedly).
This post can be found at https://forum.arduino.cc/index.php?topic=690899.0 with the key software link here and the datasheet here.
Looking at the sample code it was not great, but did show the various registers being set. However when I went to cross check this with the datasheet it did indeed show that there was a lot going on that is not shown (or even mentioned) in the datasheet. I was expecting this as it was called out in the Arduino thread.
Undeterred I took the code and converted it into Python and picked a handful of pins on the Pi (initially a Pi3) and away I went connecting it up. Not surprisingly at first nothing happened but after a bit of tweaking I managed to get the screen to display something and was then able to play around with the setting to make it work for me.
For reference the wiring I used was:
|Display Connection Name||Raspberry Pi pin number||Raspberry Pi pin name|
|SCL||23||GPIO 11 / SPIO SCLK|
|SDA||19||GPIO 10 / SPIO MOSI|
|CS||24||GPIO 8 / SPIO CE0|
If you want to try this, the Python code I used for this can be found here. This code runs both on a Pi3 and Pi Zero confirmed, but will probably also run on Pi4’s and probably the 2’s.
What immediately becomes apparent however is that this is slow…VERY slow. Probably okay if you are only doing static displays, but not much use for anything real time.
I then started to look into using the hardware assisted SPI ports on the Pi (you will note the wiring above was done with this in mind). But the more I read of this the more complex this became, needing to use the Linux drivers as stream alone not being too bad, but when coupled to needing to drive a few pins directly (the D/C pin primarily) it looked to be a bit of a nightmare.
Note, for the original tests I worked with the pin headers on both the display and the Pi, but once working I de-soldered the pins from the display and wired it direct to the PiZero.
So next stage was to see where the bottleneck was, so I converted the code again into native C. Then went to find the tools for driving the low level pins. Here the issue here became which library should I use as there seemed to be a number of them available, in the end I went for the BCM2835 library, which you can get here . I picked this one as it seemed fairly simple and direct to use (and had a good few examples).
With that installed I was able to use the various samples to get a C version of the code running and indeed it was a lot faster. Using the hardware, I was able to do full screen updates in less than 100ms, compared to the Python where it was over 6 seconds per update.
Next step was to work out how to make the functions available in python from the C code. Again there seemed to be a number of ways to do this but I settled for what seems to be a simple approach of importing ctypes.
I have since added a few more functions to the C library have built a couple of Python samples using it.
The result is that the Python code can call the low level C functions and produces a fairly quick response. Not quite up to native C, but close enough that I can still develop the application in it. As you can see from the title image, I ended up making a simple clock using a bitmap image and some basic line drawing routines for the hands. This works and a very smooth second hand movement, which reminded me of my spring drive Grand Seiko hence the choice of background image.
Next steps, adding better line and graphics primitives to the C code and then tidying the code for general use.
As ever, any questions then drop me a line and I will try to help.