Some doc for encoder mode. Remove unwanted code/comments from demos.

pull/8/head
Peter Hinch 2021-07-04 18:21:37 +01:00
rodzic b8d8bdb0a3
commit 3a64bb5691
9 zmienionych plików z 192 dodań i 186 usunięć

Wyświetl plik

@ -19,6 +19,9 @@ to a wide range of displays. It is also portable between hosts.
![Image](./images/ttgo.JPG) TTGO T-Display. Add a joystick switch and an SIL ![Image](./images/ttgo.JPG) TTGO T-Display. Add a joystick switch and an SIL
resistor for a simple, inexpensive, WiFi capable system. resistor for a simple, inexpensive, WiFi capable system.
An alternative interface consists of two pushbuttons and an encoder such as
[this one](https://www.adafruit.com/product/377).
# Rationale # Rationale
Touch GUI's have many advantages, however they have drawbacks, principally cost Touch GUI's have many advantages, however they have drawbacks, principally cost
@ -115,7 +118,7 @@ of some display drivers.
     22.3.1 [Class Curve](./README.md#2231-class-curve)      22.3.1 [Class Curve](./README.md#2231-class-curve)
     22.3.2 [Class PolarCurve](./README.md#2232-class-polarcurve)      22.3.2 [Class PolarCurve](./README.md#2232-class-polarcurve)
22.4 [Class TSequence](./README.md#224-class-tsequence) Plotting realtime, time sequential data. 22.4 [Class TSequence](./README.md#224-class-tsequence) Plotting realtime, time sequential data.
[Appendix 1 Application design](./README.md#appendix-1-application-design) Tab order, button layout, use of graphics primitives [Appendix 1 Application design](./README.md#appendix-1-application-design) Tab order, button layout, encoder interface, use of graphics primitives
# 1. Basic concepts # 1. Basic concepts
@ -385,6 +388,8 @@ files in `gui/core` are:
The `gui/primitives` directory contains the following files: The `gui/primitives` directory contains the following files:
* `switch.py` Interface to physical pushbuttons. * `switch.py` Interface to physical pushbuttons.
* `delay_ms.py` A software triggerable timer. * `delay_ms.py` A software triggerable timer.
* `encoder.py` Driver for a quadrature encoder. This offers an alternative
interface - see [Appendix 1](./README.md#appendix-1-application-design).
The `gui/demos` directory contains a variety of demos and tests described The `gui/demos` directory contains a variety of demos and tests described
below. below.
@ -2202,6 +2207,16 @@ The apparently obvious solution of designing a vertical `Scale` is tricky owing
to the fact that the length of the internal text can be substantial and to the fact that the length of the internal text can be substantial and
variable. variable.
## Encoder interface
This alternative interface comprises just two buttons `Next` and `Prev`.
Selection and Increase/Decrease is handled by an encoder such as
[this one](https://www.adafruit.com/product/377). Selection occurs when the
knob is pressed, and movement when it is rotated. This is more intuitive,
particularly with horizontally oriented controls.
TODO wiring details.
## Screen layout ## Screen layout
Widgets are positioned using absolute `row` and `col` coordinates. These may Widgets are positioned using absolute `row` and `col` coordinates. These may

Wyświetl plik

@ -38,15 +38,15 @@ _LAST = const(3)
# Wrapper for ssd providing buttons and framebuf compatible methods # Wrapper for ssd providing buttons and framebuf compatible methods
class Display: class Display:
def __init__(self, objssd, nxt, sel, prev=None, up=None, down=None): def __init__(self, objssd, nxt, sel, prev=None, up=None, down=None, encoder=False):
global display, ssd global display, ssd
self._next = Switch(nxt) self._next = Switch(nxt)
self._sel = Switch(sel) self._sel = Switch(sel)
self._last = None # Last switch pressed. self._last = None # Last switch pressed.
# Mandatory buttons # Mandatory buttons
# Call current screen bound method # Call current screen bound method
self._next.close_func(self._closure, (self._next, Screen.next_ctrl)) self._next.close_func(self._closure, (self._next, Screen.ctrl_move, _NEXT))
self._sel.close_func(self._closure, (self._sel, Screen.sel_ctrl)) self._sel.close_func(self._closure, (self._sel, Screen.sel_ctrl, 0))
self._sel.open_func(Screen.unsel) self._sel.open_func(Screen.unsel)
self.height = objssd.height self.height = objssd.height
@ -56,26 +56,30 @@ class Display:
self._prev = None self._prev = None
if prev is not None: if prev is not None:
self._prev = Switch(prev) self._prev = Switch(prev)
self._prev.close_func(self._closure, (self._prev, Screen.prev_ctrl)) self._prev.close_func(self._closure, (self._prev, Screen.ctrl_move, _PREV))
# Up and down methods get the button as an arg. if encoder:
self._up = None if up is None or down is None:
if up is not None: raise ValueError('Must specify pins for encoder.')
self._up = Switch(up) from gui.primitives.encoder import Encoder
self._up.close_func(self._closure, (self._up, self.do_up)) self._enc = Encoder(up, down, div=encoder, callback=Screen.adjust)
self._down = None else:
if down is not None: # Up and down methods get the button as an arg.
self._down = Switch(down) if up is not None:
self._down.close_func(self._closure, (self._down, self.do_down)) sup = Switch(up)
sup.close_func(self._closure, (sup, Screen.adjust, 1))
if down is not None:
sdown = Switch(down)
sdown.close_func(self._closure, (sdown, Screen.adjust, -1))
self._is_grey = False # Not greyed-out self._is_grey = False # Not greyed-out
display = self # Populate globals display = self # Populate globals
ssd = objssd ssd = objssd
# Reject button presses where a button is already pressed. # Reject button presses where a button is already pressed.
# Execute if initialising, if same switch re-pressed or if last switch released # Execute if initialising, if same switch re-pressed or if last switch released
def _closure(self, switch, func): def _closure(self, switch, func, arg):
if (self._last is None) or (self._last == switch) or self._last(): if (self._last is None) or (self._last == switch) or self._last():
self._last = switch self._last = switch
func() func(switch, arg)
def print_centred(self, writer, x, y, text, fgcolor=None, bgcolor=None, invert=False): def print_centred(self, writer, x, y, text, fgcolor=None, bgcolor=None, invert=False):
sl = writer.stringlen(text) sl = writer.stringlen(text)
@ -94,12 +98,6 @@ class Display:
writer.printstring(txt, invert) writer.printstring(txt, invert)
writer.setcolor() # Restore defaults writer.setcolor() # Restore defaults
def do_up(self):
Screen.up_ctrl(self._up)
def do_down(self):
Screen.down_ctrl(self._down)
# Greying out has only one option given limitation of 4-bit display driver # Greying out has only one option given limitation of 4-bit display driver
# It would be possible to do better with RGB565 but would need inverse transformation # It would be possible to do better with RGB565 but would need inverse transformation
# to (r, g, b), scale and re-convert to integer. # to (r, g, b), scale and re-convert to integer.
@ -204,35 +202,27 @@ class Screen:
is_shutdown = Event() is_shutdown = Event()
@classmethod @classmethod
def next_ctrl(cls): def ctrl_move(cls, _, v):
if cls.current_screen is not None: if cls.current_screen is not None:
cls.current_screen.move(_NEXT) cls.current_screen.move(v)
@classmethod @classmethod
def prev_ctrl(cls): def sel_ctrl(cls, b, _):
if cls.current_screen is not None:
cls.current_screen.move(_PREV)
@classmethod
def sel_ctrl(cls):
if cls.current_screen is not None: if cls.current_screen is not None:
cls.current_screen.do_sel() cls.current_screen.do_sel()
@classmethod @classmethod
def unsel(cls): def unsel(cls):
if cls.current_screen is not None: if cls.current_screen is not None:
cls.current_screen.unsel_i() cls.current_screen.unsel_i()
# Adjust the value of a widget. If an encoder is used, button arg
# is an int (discarded), val is the delta. If using buttons, 1st
# arg is the button, delta is +1 or -1
@classmethod @classmethod
def up_ctrl(cls, button): def adjust(cls, button, val):
if cls.current_screen is not None: if cls.current_screen is not None:
cls.current_screen.do_up(button) cls.current_screen.do_adj(button, val)
@classmethod
def down_ctrl(cls, button):
if cls.current_screen is not None:
cls.current_screen.do_down(button)
# Move currency to a specific widget (e.g. ButtonList) # Move currency to a specific widget (e.g. ButtonList)
@classmethod @classmethod
@ -440,19 +430,12 @@ class Screen:
if co is not None: if co is not None:
co.unsel() co.unsel()
def do_up(self, button): def do_adj(self, button, val):
co = self.get_obj() co = self.get_obj()
if co is not None and hasattr(co, 'do_up'): if co is not None and hasattr(co, 'do_adj'):
co.do_up(button) # Widget handles up/down co.do_adj(button, val) # Widget can handle up/down
else: else:
Screen.current_screen.move(_FIRST) Screen.current_screen.move(_FIRST if val < 0 else _LAST)
def do_down(self, button):
co = self.get_obj()
if co is not None and hasattr(co, 'do_down'):
co.do_down(button)
else:
Screen.current_screen.move(_LAST)
# Methods optionally implemented in subclass # Methods optionally implemented in subclass
def on_open(self): def on_open(self):
@ -710,21 +693,17 @@ class LinearIO(Widget):
# but subclass can be defeat this with WHITE or another color # but subclass can be defeat this with WHITE or another color
self.prcolor = YELLOW if prcolor is None else prcolor self.prcolor = YELLOW if prcolor is None else prcolor
def do_up(self, button): # Adjust widget's value. Args: button pressed, amount of increment
asyncio.create_task(self.btnhan(button, 1)) def do_adj(self, button, val):
encoder = isinstance(button, int)
def do_down(self, button): d = self.min_delta * 0.1 if self.precision else self.min_delta
asyncio.create_task(self.btnhan(button, -1)) self.value(self.value() + val * d)
if not encoder:
asyncio.create_task(self.btnhan(button, val, d))
# Handle increase and decrease buttons. Redefined by textbox.py, scale_log.py # Handle increase and decrease buttons. Redefined by textbox.py, scale_log.py
async def btnhan(self, button, up): async def btnhan(self, button, up, d):
if self.precision: maxd = self.max_delta if self.precision else d * 4 # Why move fast in precision mode?
d = self.min_delta * 0.1
maxd = self.max_delta
else:
d = self.min_delta
maxd = d * 4 # Why move fast in precision mode?
self.value(self.value() + up * d)
t = ticks_ms() t = ticks_ms()
while not button(): while not button():
await asyncio.sleep_ms(0) # Quit fast on button release await asyncio.sleep_ms(0) # Quit fast on button release

Wyświetl plik

@ -47,13 +47,11 @@ class BaseScreen(Screen):
self.vslider = Slider(wri, 2, 2, callback=self.slider_cb, self.vslider = Slider(wri, 2, 2, callback=self.slider_cb,
bdcolor=RED, slotcolor=BLUE, bdcolor=RED, slotcolor=BLUE,
legends=('0.0', '0.5', '1.0'), value=0.5) legends=('0.0', '0.5', '1.0'), value=0.5)
#Label(wri, 2, self.vslider.mcol, 'FF')
col = 80 col = 80
row = 15 row = 15
self.hslider = HorizSlider(wri, row, col, callback=self.slider_cb, self.hslider = HorizSlider(wri, row, col, callback=self.slider_cb,
bdcolor=GREEN, slotcolor=BLUE, bdcolor=GREEN, slotcolor=BLUE,
legends=('0.0', '0.5', '1.0'), value=0.7) legends=('0.0', '0.5', '1.0'), value=0.7)
Label(wri, self.hslider.mrow, self.hslider.mcol, 'FF')
row += 30 row += 30
self.scale = Scale(wri, row, col, width = 150, tickcb = tickcb, self.scale = Scale(wri, row, col, width = 150, tickcb = tickcb,
pointercolor=RED, fontcolor=YELLOW, bdcolor=CYAN, pointercolor=RED, fontcolor=YELLOW, bdcolor=CYAN,

Wyświetl plik

@ -61,11 +61,8 @@ class FooScreen(Screen):
m0 = Meter(wri, 10, 240, divisions = 4, ptcolor=YELLOW, height=80, width=15, m0 = Meter(wri, 10, 240, divisions = 4, ptcolor=YELLOW, height=80, width=15,
label='Meter example', style=Meter.BAR, legends=('0.0', '0.5', '1.0')) label='Meter example', style=Meter.BAR, legends=('0.0', '0.5', '1.0'))
#Label(wri, 2, m0.mcol, 'FF')
# Instantiate displayable objects. bgcolor forces complete redraw. # Instantiate displayable objects. bgcolor forces complete redraw.
dial = Dial(wri, 2, 2, height = 75, ticks = 12, bgcolor=BLACK, bdcolor=None, label=120) # Border in fg color dial = Dial(wri, 2, 2, height = 75, ticks = 12, bgcolor=BLACK, bdcolor=None, label=120) # Border in fg color
#Label(wri, dial.mrow, 2, 'FF')
#Label(wri, dial.mrow, dial.mcol, 'FF')
scale = Scale(wri, 2, 100, width = 124, tickcb = tickcb, scale = Scale(wri, 2, 100, width = 124, tickcb = tickcb,
pointercolor=RED, fontcolor=YELLOW, bdcolor=CYAN) pointercolor=RED, fontcolor=YELLOW, bdcolor=CYAN)

Wyświetl plik

@ -0,0 +1,72 @@
# encoder.py Asynchronous driver for incremental quadrature encoder.
# Copyright (c) 2021 Peter Hinch
# Released under the MIT License (MIT) - see LICENSE file
# This driver is intended for encoder-based control knobs. It is
# unsuitable for NC machine applications. Please see the docs.
import uasyncio as asyncio
from machine import Pin
class Encoder:
delay = 100 # Pause (ms) for motion to stop
def __init__(self, pin_x, pin_y, v=0, vmin=None, vmax=None, div=1,
callback=lambda a, b : None, args=()):
self._pin_x = pin_x
self._pin_y = pin_y
self._v = 0 # Hardware value always starts at 0
self._cv = v # Current (divided) value
if ((vmin is not None) and v < min) or ((vmax is not None) and v > vmax):
raise ValueError('Incompatible args: must have vmin <= v <= vmax')
self._tsf = asyncio.ThreadSafeFlag()
trig = Pin.IRQ_RISING | Pin.IRQ_FALLING
try:
xirq = pin_x.irq(trigger=trig, handler=self._x_cb, hard=True)
yirq = pin_y.irq(trigger=trig, handler=self._y_cb, hard=True)
except TypeError: # hard arg is unsupported on some hosts
xirq = pin_x.irq(trigger=trig, handler=self._x_cb)
yirq = pin_y.irq(trigger=trig, handler=self._y_cb)
asyncio.create_task(self._run(vmin, vmax, div, callback, args))
# Hardware IRQ's
def _x_cb(self, pin):
fwd = pin() ^ self._pin_y()
self._v += 1 if fwd else -1
self._tsf.set()
def _y_cb(self, pin):
fwd = pin() ^ self._pin_x() ^ 1
self._v += 1 if fwd else -1
self._tsf.set()
async def _run(self, vmin, vmax, div, cb, args):
pv = self._v # Prior hardware value
cv = self._cv # Current divided value as passed to callback
pcv = cv # Prior divided value passed to callback
mod = 0
delay = self.delay
while True:
await self._tsf.wait()
await asyncio.sleep_ms(delay) # Wait for motion to stop
new = self._v # Sample hardware (atomic read)
a = new - pv # Hardware change
# Ensure symmetrical bahaviour for + and - values
q, r = divmod(abs(a), div)
if a < 0:
r = -r
q = -q
pv = new - r # Hardware value when local value was updated
cv += q
if vmax is not None:
cv = min(cv, vmax)
if vmin is not None:
cv = max(cv, vmin)
self._cv = cv # For value()
if cv != pcv:
cb(cv, cv - pcv, *args) # User CB in uasyncio context
pcv = cv
def value(self):
return self._cv

Wyświetl plik

@ -78,18 +78,17 @@ class Listbox(Widget):
self.value(v) self.value(v)
return v return v
def do_up(self, _): def do_adj(self, _, val):
if v := self._value: v = self._value
self.value(v - 1) if val > 0:
if v:
self.value(v - 1)
elif val < 0:
if v < len(self.elements) - 1:
self.value(v + 1)
if (self.also & Listbox.ON_MOVE): # Treat as if select pressed if (self.also & Listbox.ON_MOVE): # Treat as if select pressed
self.do_sel() self.do_sel()
def do_down(self, _):
if (v := self._value) < len(self.elements) - 1:
self.value(v + 1)
if (self.also & Listbox.ON_MOVE):
self.do_sel()
# Callback runs if select is pressed. Also (if ON_LEAVE) if user changes # Callback runs if select is pressed. Also (if ON_LEAVE) if user changes
# list currency and then moves off the control. Otherwise if we have a # list currency and then moves off the control. Otherwise if we have a
# callback that refreshes another control, that second control does not # callback that refreshes another control, that second control does not

Wyświetl plik

@ -23,6 +23,7 @@ dolittle = lambda *_ : None
# Start value is 1.0. User applies scaling to value and ticks callback. # Start value is 1.0. User applies scaling to value and ticks callback.
class ScaleLog(LinearIO): class ScaleLog(LinearIO):
encoder_rate = 5
def __init__(self, writer, row, col, *, def __init__(self, writer, row, col, *,
decades=5, height=0, width=160, decades=5, height=0, width=160,
bdcolor=None, fgcolor=None, bgcolor=None, bdcolor=None, fgcolor=None, bgcolor=None,
@ -141,6 +142,14 @@ class ScaleLog(LinearIO):
return self._value return self._value
# Adjust widget's value. Args: button pressed, amount of increment
def do_adj(self, button, val):
if isinstance(button, int): # Using an encoder
delta = self.delta * self.encoder_rate * 0.1 if self.precision else self.delta * self.encoder_rate
self.value(self.value() * (1 + delta)**val)
else:
asyncio.create_task(self.btnhan(button, val, d))
async def btnhan(self, button, up): async def btnhan(self, button, up):
up = up == 1 up = up == 1
if self.precision: if self.precision:

Wyświetl plik

@ -1,122 +1,54 @@
# color_setup.py Customise for your hardware config # ili9341_pico.py Customise for your hardware config
# Released under the MIT License (MIT). See LICENSE. # Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2021 Peter Hinch, Ihor Nehrutsa # Copyright (c) 2021 Peter Hinch
# Supports: # As written, supports:
# TTGO T-Display 1.14" 135*240(Pixel) based on ST7789V # ili9341 240x320 displays on Pi Pico
# http://www.lilygo.cn/claprod_view.aspx?TypeId=62&Id=1274 # Edit the driver import for other displays.
# http://www.lilygo.cn/prod_view.aspx?TypeId=50044&Id=1126
# https://github.com/Xinyuan-LilyGO/TTGO-T-Display
# https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/image/pinmap.jpg
# https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/schematic/ESP32-TFT(6-26).pdf
# WIRING (TTGO T-Display pin numbers and names).
# Pinout of TFT Driver
# ST7789 ESP32
# TFT_MISO N/A
TFT_MOSI = 19 # (SDA on schematic pdf) SPI interface output/input pin.
TFT_SCLK = 18 # This pin is used to be serial interface clock.
TFT_CS = 5 # Chip selection pin, low enable, high disable.
TFT_DC = 16 # Display data/command selection pin in 4-line serial interface.
TFT_RST = 23 # This signal will reset the device,Signal is active low.
TFT_BL = 4 # (LEDK on schematic pdf) Display backlight control pin
ADC_IN = 34 # Measuring battery or USB voltage, see comment below
ADC_EN = 14 # (PWR_EN on schematic pdf) is the ADC detection enable port
BUTTON1 = 35 # right of the USB connector
BUTTON2 = 0 # left of the USB connector
# ESP32 pins, free for use in user applications
#I2C_SDA = 21 # hardware ID 0
#I2C_SCL = 22
#UART2TXD = 17
#GPIO2 = 2
#GPIO15 = 15
#GPIO13 = 13
#GPIO12 = 12
#GPIO37 = 37
#GPIO38 = 38
#UART1TXD = 4
#UART1RXD = 5
#GPIO18 = 18
#GPIO19 = 19
#GPIO17 = 17
#DAC1 = 25
#DAC2 = 26
# Input only pins
#GPIO36 = 36 # input only
#GPIO39 = 39 # input only
# Demo of initialisation procedure designed to minimise risk of memory fail # Demo of initialisation procedure designed to minimise risk of memory fail
# when instantiating the frame buffer. The aim is to do this as early as # when instantiating the frame buffer. The aim is to do this as early as
# possible before importing other modules. # possible before importing other modules.
from machine import Pin, SPI, ADC, freq # WIRING
# Pico Display
# GPIO Pin
# 3v3 36 Vin
# IO6 9 CLK Hardware SPI0
# IO7 10 DATA (AKA SI MOSI)
# IO8 11 DC
# IO9 12 Rst
# Gnd 13 Gnd
# IO10 14 CS
# Pushbuttons are wired between the pin and Gnd
# Pico pin Meaning
# 16 Operate current control
# 17 Decrease value of current control
# 18 Select previous control
# 19 Select next control
# 20 Increase value of current control
from machine import Pin, SPI, freq
import gc import gc
from drivers.st7789.st7789_4bit import * from drivers.ili93xx.ili9341 import ILI9341 as SSD
SSD = ST7789 freq(250_000_000) # RP2 overclock
# Create and export an SSD instance
pdc = Pin(TFT_DC, Pin.OUT, value=0) # Arbitrary pins pdc = Pin(8, Pin.OUT, value=0) # Arbitrary pins
pcs = Pin(TFT_CS, Pin.OUT, value=1) prst = Pin(9, Pin.OUT, value=1)
prst = Pin(TFT_RST, Pin.OUT, value=1) pcs = Pin(10, Pin.OUT, value=1)
pbl = Pin(TFT_BL, Pin.OUT, value=1) spi = SPI(0, baudrate=30_000_000)
gc.collect() # Precaution before instantiating framebuf gc.collect() # Precaution before instantiating framebuf
# Conservative low baudrate. Can go to 62.5MHz. ssd = SSD(spi, pcs, pdc, prst, usd=True)
spi = SPI(1, 30_000_000, sck=Pin(TFT_SCLK), mosi=Pin(TFT_MOSI))
freq(160_000_000)
''' TTGO
v +----------------+
40 | | |
^ | +------+ | pin 36
| | | | |
| | | | |
240 | | | | |
| | | | |
| | | | |
v | +------+ |
40 | | | Reset button
^ +----------------+
>----<------>----<
52 135 xx
BUTTON2 BUTTON1
'''
# Right way up landscape: defined as top left adjacent to pin 36
ssd = SSD(spi, height=135, width=240, dc=pdc, cs=pcs, rst=prst, disp_mode=LANDSCAPE, display=TDISPLAY)
# Normal portrait display: consistent with TTGO logo at top
# ssd = SSD(spi, height=240, width=135, dc=pdc, cs=pcs, rst=prst, disp_mode=PORTRAIT, display=TDISPLAY)
from gui.core.ugui import Display from gui.core.ugui import Display
# Create and export a Display instance # Create and export a Display instance
# Define control buttons # Define control buttons
nxt = Pin(32, Pin.IN, Pin.PULL_UP) # Move to next control nxt = Pin(19, Pin.IN, Pin.PULL_UP) # Move to next control
sel = Pin(36, Pin.IN, Pin.PULL_UP) # Operate current control sel = Pin(16, Pin.IN, Pin.PULL_UP) # Operate current control
prev = Pin(38, Pin.IN, Pin.PULL_UP) # Move to previous control prev = Pin(18, Pin.IN, Pin.PULL_UP) # Move to previous control
increase = Pin(37, Pin.IN, Pin.PULL_UP) # Increase control's value increase = Pin(20, Pin.IN, Pin.PULL_UP) # Increase control's value
decrease = Pin(39, Pin.IN, Pin.PULL_UP) # Decrease control's value decrease = Pin(17, Pin.IN, Pin.PULL_UP) # Decrease control's value
display = Display(ssd, nxt, sel, prev, increase, decrease) display = Display(ssd, nxt, sel, prev, increase, decrease, 5) # Encoder
# optional
# b1 = Pin(BUTTON1, Pin.IN)
# b2 = Pin(BUTTON2, Pin.IN)
# adc_en = Pin(ADC_EN, Pin.OUT, value=1)
# adc_in = ADC(Pin(ADC_IN))
# adc_en.value(0)
'''
Set ADC_EN to "1" and read voltage in BAT_ADC,
if this voltage more than 4.3 V device have powered from USB.
If less then 4.3 V - device have power from battery.
To save battery you can set ADC_EN to "0" and in this case the USB converter
will be power off and do not use your battery.
When you need to measure battery voltage first set ADC_EN to "1",
measure voltage and then set ADC_EN back to "0" for save battery.
'''

Wyświetl plik

@ -101,9 +101,14 @@ from gui.core.ugui import Display
nxt = Pin(32, Pin.IN, Pin.PULL_UP) # Move to next control nxt = Pin(32, Pin.IN, Pin.PULL_UP) # Move to next control
sel = Pin(36, Pin.IN, Pin.PULL_UP) # Operate current control sel = Pin(36, Pin.IN, Pin.PULL_UP) # Operate current control
prev = Pin(38, Pin.IN, Pin.PULL_UP) # Move to previous control prev = Pin(38, Pin.IN, Pin.PULL_UP) # Move to previous control
increase = Pin(37, Pin.IN, Pin.PULL_UP) # Increase control's value encoder = 5 # Divide by 5
decrease = Pin(39, Pin.IN, Pin.PULL_UP) # Decrease control's value if encoder:
display = Display(ssd, nxt, sel, prev, increase, decrease) increase = Pin(25, Pin.IN, Pin.PULL_UP) # Encoder x and y pins
decrease = Pin(33, Pin.IN, Pin.PULL_UP)
else:
increase = Pin(37, Pin.IN, Pin.PULL_UP) # Increase control's value
decrease = Pin(39, Pin.IN, Pin.PULL_UP) # Decrease control's value
display = Display(ssd, nxt, sel, prev, increase, decrease, encoder)
# optional # optional
# b1 = Pin(BUTTON1, Pin.IN) # b1 = Pin(BUTTON1, Pin.IN)