kopia lustrzana https://github.com/peterhinch/micropython-nano-gui
Update README files for sharp displays.
rodzic
c5e7fbb5e0
commit
f24a1f53ea
15
README.md
15
README.md
|
@ -1,6 +1,6 @@
|
||||||
A lightweight and minimal MicroPython GUI library for display drivers based on
|
A lightweight and minimal MicroPython GUI library for display drivers based on
|
||||||
the `framebuf` class. With the exception of the Nokia 5110, such drivers are
|
the `framebuf` class. Various display technologies are supported, primarily
|
||||||
currently for color and monochrome OLED displays. This is coincidental.
|
small color OLED's.
|
||||||
|
|
||||||
These images don't do justice to the OLED displays which are visually
|
These images don't do justice to the OLED displays which are visually
|
||||||
impressive with bright colors and extreme contrast. For some reason they are
|
impressive with bright colors and extreme contrast. For some reason they are
|
||||||
|
@ -54,6 +54,9 @@ display driver is subclassed from the `framebuf` class. Examples are:
|
||||||
* A driver for [Adafruit 1.5 inch OLED](https://www.adafruit.com/product/1431)
|
* A driver for [Adafruit 1.5 inch OLED](https://www.adafruit.com/product/1431)
|
||||||
and [Adafruit 1.27 inch OLED](https://www.adafruit.com/product/1673) may be
|
and [Adafruit 1.27 inch OLED](https://www.adafruit.com/product/1673) may be
|
||||||
found [here](./drivers/ssd1351/README.md).
|
found [here](./drivers/ssd1351/README.md).
|
||||||
|
* A driver for Sharp ultra low power consumption monochrome displays such as
|
||||||
|
[2.7 inch 400x240 pixels](https://www.adafruit.com/product/4694)
|
||||||
|
is [here](./drivers/sharp/README.md).
|
||||||
|
|
||||||
Widgets are intended for the display of data from physical devices such as
|
Widgets are intended for the display of data from physical devices such as
|
||||||
sensors. The GUI is display-only: there is no provision for user input. This
|
sensors. The GUI is display-only: there is no provision for user input. This
|
||||||
|
@ -462,6 +465,10 @@ For a driver to support `nanogui` it must be subclassed from
|
||||||
the display size in pixels. This, and a `show` method, are all that is required
|
the display size in pixels. This, and a `show` method, are all that is required
|
||||||
for monochrome drivers.
|
for monochrome drivers.
|
||||||
|
|
||||||
|
Refresh must be handled by a `show` method taking no arguments; when called,
|
||||||
|
the contents of the buffer underlying the `FrameBuffer` must be copied to the
|
||||||
|
hardware.
|
||||||
|
|
||||||
For color drivers, to conserve RAM it is suggested that 8-bit color is used
|
For color drivers, to conserve RAM it is suggested that 8-bit color is used
|
||||||
for the `framebuf`. If the hardware does not support this, conversion to the
|
for the `framebuf`. If the hardware does not support this, conversion to the
|
||||||
supported color space needs to be done "on the fly" as per the SSD1351 driver.
|
supported color space needs to be done "on the fly" as per the SSD1351 driver.
|
||||||
|
@ -476,10 +483,6 @@ form acceptable to the driver. For 8-bit rrrgggbb this can be:
|
||||||
```
|
```
|
||||||
This should be amended if the hardware uses a different 8-bit format.
|
This should be amended if the hardware uses a different 8-bit format.
|
||||||
|
|
||||||
Refresh must be handled by a `show` method taking no arguments; when called,
|
|
||||||
the contents of the buffer underlying the `FrameBuffer` must be copied to the
|
|
||||||
hardware.
|
|
||||||
|
|
||||||
The `Writer` (monochrome) or `CWriter` (color) classes and the `nanogui` module
|
The `Writer` (monochrome) or `CWriter` (color) classes and the `nanogui` module
|
||||||
should then work automatically.
|
should then work automatically.
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,8 @@ The datasheet specifies a minimum refresh rate of 1Hz.
|
||||||
|
|
||||||
1. `sharptest.py` Basic functionality test.
|
1. `sharptest.py` Basic functionality test.
|
||||||
2. `clocktest.py` Digital and analog clock display.
|
2. `clocktest.py` Digital and analog clock display.
|
||||||
3. `clock_batt.py` As above but designed for low power operation.
|
3. `clock_batt.py` As above but designed for low power operation. Pyboard
|
||||||
|
specific.
|
||||||
|
|
||||||
`sharptest` should not be run for long periods as it does not regularly refresh
|
`sharptest` should not be run for long periods as it does not regularly refresh
|
||||||
the display. It tests `writer.py` and some `framebuffer` graphics primitives.
|
the display. It tests `writer.py` and some `framebuffer` graphics primitives.
|
||||||
|
@ -124,6 +125,28 @@ the 2.7 inch display this is 400*240//8 = 12000 bytes in size. This should be
|
||||||
instantiated as soon as possible in the application to ensure that sufficient
|
instantiated as soon as possible in the application to ensure that sufficient
|
||||||
contiguous RAM is available.
|
contiguous RAM is available.
|
||||||
|
|
||||||
|
## 4.1 Micropower applications
|
||||||
|
|
||||||
|
These comments largely assume a Pyboard host. The application should import
|
||||||
|
`upower` from
|
||||||
|
[micropython-micropower](https://github.com/peterhinch/micropython-micropower).
|
||||||
|
This turns the USB interface off if not in use to conserve power. It also
|
||||||
|
provides an `lpdelay` function to implement a delay using `pyb.stop()` to
|
||||||
|
conserve power.
|
||||||
|
|
||||||
|
In tests the `clock_batt` demo consumed 700μA between updates. A full refresh
|
||||||
|
every 30s consumed about 48mA for 128ms. These figures correspond to a mean
|
||||||
|
current consumption of 904μA implying about 46 days operation per AH of
|
||||||
|
battery capacity. LiPo cells of 2AH capacity are widely available offering a
|
||||||
|
theoretical runtime of 92 days between charges.
|
||||||
|
|
||||||
|
Lower currents might be achieved using standby but I have major doubts. This is
|
||||||
|
because it is necessary to toggle the VCOM bit at a minimum of 1Hz. Waking from
|
||||||
|
standby uses significan amounts of power as the modules are compiled. Even if
|
||||||
|
frozen bytecode is used, there is still significant power usage importing
|
||||||
|
modules and instantiating classes; this usage is not incurred in the loop in
|
||||||
|
the demo.
|
||||||
|
|
||||||
# 5. Resources
|
# 5. Resources
|
||||||
|
|
||||||
[Schematic for 2.7" unit](https://learn.adafruit.com/assets/94077)
|
[Schematic for 2.7" unit](https://learn.adafruit.com/assets/94077)
|
||||||
|
|
|
@ -61,26 +61,22 @@ def aclock():
|
||||||
lbldat = Label(wri, 100, 230, 100)
|
lbldat = Label(wri, 100, 230, 100)
|
||||||
hrs = Pointer(dial)
|
hrs = Pointer(dial)
|
||||||
mins = Pointer(dial)
|
mins = Pointer(dial)
|
||||||
secs = Pointer(dial)
|
|
||||||
|
|
||||||
hstart = 0 + 0.7j # Pointer lengths and position at top
|
hstart = 0 + 0.7j # Pointer lengths and position at top
|
||||||
mstart = 0 + 0.92j
|
mstart = 0 + 0.92j
|
||||||
sstart = 0 + 0.92j
|
|
||||||
while True:
|
while True:
|
||||||
t = rtc.datetime() # (year, month, day, weekday, hours, minutes, seconds, subseconds)
|
t = rtc.datetime() # (year, month, day, weekday, hours, minutes, seconds, subseconds)
|
||||||
hang = -t[4]*pi/6 - t[5]*pi/360 # Angles of hour and minute hands
|
hang = -t[4]*pi/6 - t[5]*pi/360 # Angles of hands in radians
|
||||||
mang = -t[5] * pi/30
|
mang = -t[5] * pi/30
|
||||||
sang = -t[6] * pi/30
|
if abs(hang - mang) < pi/360: # Avoid visually confusing overlap of hands
|
||||||
if abs(hang - mang) < pi/360: # Avoid overlap of hands
|
hang += pi/30 # by making hr hand lag slightly
|
||||||
hang += pi/18
|
|
||||||
hrs.value(hstart * uv(hang))
|
hrs.value(hstart * uv(hang))
|
||||||
mins.value(mstart * uv(mang))
|
mins.value(mstart * uv(mang))
|
||||||
secs.value(sstart * uv(sang))
|
lbltim.value('{:02d}.{:02d}'.format(t[4], t[5]))
|
||||||
lbltim.value('{:02d}.{:02d}.{:02d}'.format(t[4], t[5], t[6]))
|
|
||||||
lbldat.value('{} {} {} {}'.format(days[t[3] - 1], t[2], months[t[1] - 1], t[0]))
|
lbldat.value('{} {} {} {}'.format(days[t[3] - 1], t[2], months[t[1] - 1], t[0]))
|
||||||
refresh(ssd)
|
refresh(ssd)
|
||||||
# Power saving: only refresh every 10s
|
# Power saving: only refresh every 30s
|
||||||
for _ in range(10):
|
for _ in range(30):
|
||||||
upower.lpdelay(1000)
|
upower.lpdelay(1000)
|
||||||
ssd.update() # Toggle VCOM
|
ssd.update() # Toggle VCOM
|
||||||
|
|
||||||
|
|
|
@ -64,11 +64,14 @@ def aclock():
|
||||||
sstart = 0 + 0.92j
|
sstart = 0 + 0.92j
|
||||||
while True:
|
while True:
|
||||||
t = utime.localtime()
|
t = utime.localtime()
|
||||||
# Add 0.5min offset to hour hand. This avoids a confusing display by
|
hang = -t[4]*pi/6 - t[5]*pi/360 # Angles of hour and minute hands
|
||||||
# ensuring hour and minute hand never exactly overlap
|
mang = -t[5] * pi/30
|
||||||
hrs.value(hstart * uv(-t[3]*pi/6 - t[4]*pi/360) - pi/720)
|
sang = -t[6] * pi/30
|
||||||
mins.value(mstart * uv(-t[4] * pi/30))
|
if abs(hang - mang) < pi/360: # Avoid overlap of hr and min hands
|
||||||
secs.value(sstart * uv(-t[5] * pi/30))
|
hang += pi/30 # which is visually confusing. Add slight lag to hts
|
||||||
|
hrs.value(hstart * uv(hang))
|
||||||
|
mins.value(mstart * uv(mang))
|
||||||
|
secs.value(sstart * uv(sang))
|
||||||
lbltim.value('{:02d}.{:02d}.{:02d}'.format(t[3], t[4], t[5]))
|
lbltim.value('{:02d}.{:02d}.{:02d}'.format(t[3], t[4], t[5]))
|
||||||
lbldat.value('{} {} {} {}'.format(days[t[6]], t[2], months[t[1] - 1], t[0]))
|
lbldat.value('{} {} {} {}'.format(days[t[6]], t[2], months[t[1] - 1], t[0]))
|
||||||
refresh(ssd)
|
refresh(ssd)
|
||||||
|
|
Ładowanie…
Reference in New Issue