Sunday, December 22, 2019

A Torrid Tail of Too Many Circles - Continued

Previously

In my earlier post, I covered how I attempted to create a Moire pattern on my pyportal screen. While the implementation was pretty simple, there were issues with excessive memory usage and dreadful refresh speed.

Moving to a faster speed


The first implementation used a lot of system memory because each rendered circle consisted of a TileGrid, Bitmap and Palette. The goal for the second implementation was to reduce the amount of memory used by using one Bitmap per group of circles. I first needed to refresh my memory on how to find the points on a circle. A quick trip down the Google results lead me to this page. I was able to quickly implement a draw_circle function to a circle to a provided Bitmap. The center and radius of the of the circle are used as the basis of the function and a SMOOTHNESS value is used to determine the size of each calculated step. The draw_circle is wrapped in two loops to generate each set of circles into a single bitmap. Parameters are provided for the number and spacing of the generated circles and how much time to wait between each set of calculations.

Journey Review


The new circle function is much faster and generates a pleasing set of circles. Memory usage is much less since only one TileGrid, Bitmap and Palette is used for the display. However, it takes quite a few seconds to generate a new set of circles in the Bitmap. However, the random placement of the circles results in display updates which can be displeasing. This issue was rectified by adding a 'wobble' to the previous generation's centers. The math still takes a long time but the updates are more pleasing.

Where to go next


Is it possible to make the updates faster?

Monday, December 16, 2019

A Torrid Tail of Too Many Circles

Where it all began....


A long time ago, I received a Adafuit pyportal from one of their mystery boxes. This device has spent most of its time collecting dust or displaying the default demonstration code. I decided to replicate some coding from the 80s and see if I could display Moire Patterns on the pyportal screen. To this end, I have started the journey of drawing too many circles on the screen.

I decided to use the CircuitPython language to code my implementations. I could use a variety of editors (vim, Mu and Atom) and run the code by simply updating the code.py file on the device. My development environment is Linux based so I eventually fell into old development habits and used vim for development, cp for deployment and minicom to monitor code execution.

And so it begins


The Adafruit maintains a list CircuitPython modules available (200!). The main modules used in this project are displayio and Display Shapes. The former is responsible for managing the display and bitmaps while the latter is used to generate shapes. Adafruit has a great information page on how to use the displayio framework. The shapes library returns a TileGrid for each shape generated.

Implementation 


For this implementation, I created a display group per set of circles and populated it with TileGrids created by Circle(). The center of the circles is randomly generated and each ring radius is incrementally larger than the previous. The code will sleep for a few seconds, delete the two display groups and regenerate a new set of circles.

Issues


There are a number of issues with this implementation

  • Memory: Each circles consists of a TileGrid, a bitmap sized to hold the new shape and a palette. This results in 60 total circles able to be drawn.
  • Display Speed: The updating of the display is dreadfully slow. It takes about 20 seconds to update the display. Maybe the Group is not flattened before being displayed. 

Moving forward


Obviously this is not an optimal solution. I continued working on this code based to make speed improvements but that is a tale for another time.