diff --git a/README.md b/README.md index 737c086..ef58e88 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ wiring details, pin names and hardware issues. 3.4 [LED class](./README.md#34-led-class) Virtual LED of any color. 3.5 [Dial and Pointer classes](./README.md#35-dial-and-pointer-classes) Clock or compass style display of one or more pointers. + 3.6 [Scale class](./README.md#36-scale-class) Linear display with wide dynamic range. 4. [Device drivers](./README.md#4-device-drivers) Device driver compatibility requirements (these are minimal). @@ -569,6 +570,91 @@ def clock(ssd, wri): refresh(ssd) ``` +###### [Contents](./README.md#contents) + +## 5.6 Scale class + +This displays floating point data having a wide dynamic range. It is modelled +on old radios where a large scale scrolls past a small window having a fixed +pointer. This enables a scale with (say) 200 graduations (ticks) to readily be +visible on a small display, with sufficient resolution to enable the user to +interpolate between ticks. Default settings enable estimation of a value to +within +-0.1%. + +Legends for the scale are created dynamically as it scrolls past the window. +The user may control this by means of a callback. The example `lscale.py` +illustrates a variable with range 88.0 to 108.0, the callback ensuring that the +display legends match the user variable. A further callback enables the scale's +color to change over its length or in response to other circumstances. + +The scale displays floats in range -1.0 <= V <= 1.0. + +Constructor positional args: + 1. `writer` The `Writer` instance (font and screen) to use. + 2. `row` Location on screen. + 3. `col` + +Keyword only arguments (all optional): + * `ticks=200` Number of "tick" divisions on scale. Must be divisible by 2. + * `legendcb=None` Callback for populating scale legends (see below). + * `tickcb=None` Callback for setting tick colors (see below). + * `height=0` Pass 0 for a minimum height based on the font height. + * `width=200` + * `border=2` Border width in pixels. + * `fgcolor=None` Foreground color. Defaults to system color. + * `bgcolor=None` Background color defaults to system background. + * `pointercolor=None` Color of pointer. Defaults to `.fgcolor`. + * `fontcolor=None` Color of legends. Default `fgcolor`. + +Method: + * `value=None` Set or get the current value. Always returns the current value. + A passed `float` is constrained to the range -1.0 <= V <= 1.0 and becomes the + `Scale`'s current value. The `Scale` is updated. Passing `None` enables + reading the current value. + +### Callback legendcb + +The display window contains 20 ticks comprising two divisions; by default a +division covers a range of 0.1. A division has a legend at the start and end +whose text is defined by the `legendcb` callback. If no user callback is +supplied, legends will be of the form `0.3`, `0.4` etc. User code may override +these to cope with cases where a user variable is mapped onto the control's +range. The callback takes a single `float` arg which is the value of the tick +(in range -1.0 <= v <= 1.0). It must return a text string. An example from the +`lscale.py` demo shows FM radio frequencies: +```python +def legendcb(f): + return '{:2.0f}'.format(88 + ((f + 1) / 2) * (108 - 88)) +``` +The above arithmetic aims to show the logic. It can be simplified. + +### Callback tickcb + +This callback enables the tick color to be changed dynamically. For example a +scale might change from green to orange, then to red as it nears the extremes. +The callback takes two args, being the value of the tick (in range +-1.0 <= v <= 1.0) and the default color. It must return a color. This example +is taken from the `lscale.py` demo: +```python +def tickcb(f, c): + if f > 0.8: + return RED + if f < -0.8: + return BLUE + return c +``` + +### increasing the ticks value + +This increases the precision of the display. + +It does this by lengthening the scale while keeping the window the same size, +with 20 ticks displayed. If the scale becomes 10x longer, the value diference +between consecutive large ticks and legends is divided by 10. This means that +the `tickcb` callback must return a string having an additional significant +digit. If this is not done, consecutive legends will have the same value. + + # 4. Device drivers Device drivers capable of supporting `nanogui` can be extremely simple: see the diff --git a/color_setup.py b/color_setup.py index 8b57b9b..a950d22 100644 --- a/color_setup.py +++ b/color_setup.py @@ -12,7 +12,7 @@ # when instantiating the frame buffer. The aim is to do this as early as # possible before importing other modules. -# WIRING (Adafruit pin nos and names) +# WIRING (Adafruit pin nos and names). # Pyb SSD # 3v3 Vin (10) # Gnd Gnd (11)