pi-stomp_development

pi-Stomp Development

This is a place to spec out new features, plan rewrites/refactors, document architectural details, etc.

  • User: User of pi-Stomp
  • Admin: Project admin who has permissions to tag a release
  1. pi-Stomp software must have tagged/verified versions in the GitHub repo
    1. [BenH] Do we want to continue using “git pull” as our update model ? Or do we want to start packaging things or doing release tarballs expanded in a known location that isn't ~patch ? (/opt/pi-stomp, /usr/lib/pi=stomp, …)
  2. A user must be able to initiate a software update via SSH or the hardware (LCD/Encoder)
  3. The result of a software update to a tagged release must be a known set of python modules including versions. The same for packages should also be considered.
    1. [BenH] Since we are based on “stable” distro releases, updating packages is probably safe and will bring security update, so the jury is still out on that one
  4. Must be possible for a User to update to the Head (untagged) or a tagged release
    1. [BenH] To make things easier, we could have a 'latest' tag pointing to the latest tagged release as well
  5. A hook for running post update tasks shall be included
    1. [BenH] This hook must be part of the “new” version of course, it probably should take the current version as an argument in case we want to work around specific bad cases in the future
  6. Tagging shall follow common “Semantic Versioning” (see below) and performed by Admin
    1. [BenH] Do we want to split “release” tags and “beta” tags or that's overkill at this point ?

Let's use a form of Semantic Versioning Specifically…

Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API/contract changes,
MINOR version when you add functionality in a backwards compatible manner, and
PATCH version when you make backwards compatible bug fixes.

In the case of pi-Stomp, the contracts are those with the hardware (how the software expects peripherals to be attached to GPIO's etc.) and with other software. Currently, the software contracts include mod-ui and the handful of utilities called via subprocesses (git, patchbox, etc.)

Thus far, pi-Stomp has only been tagged twice: “v1.0.1” before going live with v1 in Sep 2020, and “v2.0.1” in Sep 2021 as a mark of Core compatible software which I deemed “functionally complete”. Technically, we could still be on v1.x.x since no non-backward compatible changes have been made. The current head is compatible with both v1 and Core hardware, but having v2 software for v2 hardware feels right while hinting that v1.x.x shouldn't be installed on Core hardware.

Because, we'd like to maintain backward compatibility with all existing hardware, we hopefully won't be updating the major version ever for hardware reasons.

Support for additional hardware might require software support and thus a minimal minor version tag that includes that support. modalipi/mod.py extracts the version from git and could be used to verify the minimal required version in such a case.

Any change to requirements.txt should result in an increment of the minor version.

Bug fixes and super minor enhancements can just result in an increment of the patch version.

  • Add requirements.txt which explicitly lists each module dependency along with the latest version which has been verified to work with pi-stomp
  • Add update script to perform the 'git pull', installations, post-installation tasks, service restarts, etc.
  • LCD/nav changes to allow calling the update script via hardware only
  • Eventually add a Continuous Integration process to GitHub commits. eg. within a RPi container, install, run and test.

Class Architecture

  • lcd.py : Abstract Base class for all LCD's. Defines the public interface to be used by mod.py, etc.
  • lcdbase.py : Base class with properties and implementations common to all LCD's (Utility functions, generic drawing routines, etc.)
  • lcdcolor.py : Base class with implementations common to all Color LCD's (color specific drawing routines, etc.)
  • lcdgfx.py : Full implementation for the pi-stomp v1 GFXHat (128×64 monochrome with its own python module for interfacing with the display: http://docs.pimoroni.com/gfxhat/). It's a subclass only of Lcd, not Lcdbase as originally intended. Because of it's limited pixels and use only in 38 or so pi-stomps, it's likely just best for it to stay as is. Because of its GPIO requirements, GFXHat can only be used with pi-Stomp v1.
  • lcdili9341.py : Implementation for a 320×240 color display with ili9341 driver.
  • Other lcd files are partial implementations which once worked for their subset of content, but I've not tested them for quite a while.

The original intent was to have each LCD type get most of it's implementation from the base classes (lcd, lcdbase and lcdcolor), then have each concrete LCD type implement only the interface to its driver (ili9341, sy7789, etc.) along with display specific attributes/methods (ie. locations of screen elements, size specific drawing methods, etc.). Since a given driver could be used by multiple displays with different screen sizes, lcdili9341.py should probably be lcd320x240ili9341.py. Or perhaps lcd320x240.py which gets passed a driver object to its constructor (as specified in and called by Pistompcore).

As it is now, there are methods spread across lcdbase.py, lcdcolor.py and lcdili9341.py which likely didn't obey the original intent for the class. lcdcolor.py specifically, includes a lot of code specific to a 320×240 display. Anything with specific coordinates probably belongs in an lcd size specific class.

Every screen element has been tweaked to take advantage of every pixel available on the 320×240 screen. Possibly smaller screens could simply have their elements scaled then rounded to the nearest pixel. Not sure if that would yield sufficient results.

Functional Overview

To avoid full screen refreshes which were found to be visibly slow on both the GFXHat and ili9341 320×240 color display, the home screen is split into horizontal zones which span the entire width of the display. The color display has 7 zones:

  • 0: Top toolbar for status messages (“loading…”, etc.) along with the wifi, bypass and system tools
  • 1: Title zone for displaying the Pedalboard/Snapshot
  • 2: Analog Assignments zone for displaying bound controls (blank if no controls are bound)
  • 3, 4, 5: Plugin zones showing the plugin boxes (each zone is a row)
  • 6: Footswitch zone for displaying, duh, the footswitches (from 1 to 5 as defined by default_config.yml)

Each zone has a corresponding PIL Image object and Draw object. The many lcd draw methods (eg. draw_footswitch, draw_tools, etc.) draw their content (Text, Rectangle, Ellipse, etc.) into the draw object of the appropriate zone. An image, like a toolbar icon, can alternatively be pasted into the zone Image. Either way, the zone-image is filled with content, then refresh_zone() is called to render the zone-image to the display.

refresh_zone() calls render_image() with the y coordinate corresponding to the zone so that the image is placed at the correct height on the display. X coordinates are left to right, Y is top to bottom making things confusing (higher Y is lower on the screen). Also, because the display was intended to be taller than wide, we then need to flip the image 270 degrees.

render_image() includes a lock to prevent simultaneous writes to the display. I never determined exactly why, but doing so causes at least the HiLetgo display to blank. Quite annoying. The only solution is to restart mod-ala-pi-stomp or reboot completely. Unfortunately, I've not found a way to determine if the display has crashed either - if so we could just restart mod-ala-pi-stomp. So the lock might seem overzealous or problematic in its own way, but I'd rather lock than crash the display.

A more Object Oriented approach might have each screen element as an object (with its own image/draw object) responsible for redrawing itself when its state has changed. One such state change is being “selected”.

  1. Code is messy, not very OO and not so easy for new contributors to change the LCD
  2. LCD classes assume a lot about their content (horizontal zones each with specific purpose)
  3. Refreshes to a single screen element could be optimized if the entire zone didn't need to be refreshed
  4. LCD code doesn't scale to smaller displays (currently only 320×240 color and 128×64 mono GFX are fully supported)
  • Must retain all current (v2.0.1) functionality or improve it

  • pi-stomp_development.txt
  • Last modified: 2024/01/26 05:45
  • by 127.0.0.1