kopia lustrzana https://github.com/peterhinch/micropython-samples
Doc improvements. DS3231 portable driver added.
rodzic
a44008832f
commit
618a181fc4
|
@ -0,0 +1,91 @@
|
|||
# The DS3231 real time clock chip
|
||||
|
||||
This is a remarkably inexpensive and easily interfaced battery-backed RTC. It
|
||||
is an ideal way to rapidly calibrate the Pyboard's RTC which can then achieve
|
||||
similar levels of accuracy (+- ~2 mins/year). The chip can also provide
|
||||
accurate time to platforms lacking a good RTC (notably the ESP8266).
|
||||
|
||||
Two drivers are provided:
|
||||
1. `ds3231_port.py` A multi-platform driver.
|
||||
2. `ds3231_pb.py` A Pyboard-specific driver with RTC calibration facility.
|
||||
|
||||
Breakout boards are widely available. The interface is I2C. Pullups to 3.3V
|
||||
(typically 10KΩ) should be provided on the `SCL` and `SDA` lines if these are
|
||||
not supplied on the breakout board.
|
||||
|
||||
Both divers use edge detection to achieve millisecond-level precision from the
|
||||
DS3231. This enables relatively rapid accuracy testing of the platform's RTC,
|
||||
and fast calibration of the Pyboard's RTC.
|
||||
|
||||
###### [Main README](./README.md)
|
||||
|
||||
# 1. The multi-platform driver
|
||||
|
||||
This can use soft I2C so any pins may be used.
|
||||
|
||||
It is based on the assumption that, where a hardware RTC exists, MicroPython's
|
||||
local time (`utime.localtime()`) is based on the RTC time. Changes to local
|
||||
time don't propagate to the RTC which must explicitly be set. This holds for
|
||||
the Pyboard, ESP8266 and ESP32.
|
||||
|
||||
The official ESP32 port currently lacks support for the RTC so the Loboris port
|
||||
should be used for this purpose. The driver supports both but if the official
|
||||
port is used only the local time can be updated from the DS3231.
|
||||
|
||||
## 1.1 The DS3231 class
|
||||
|
||||
Constructor:
|
||||
This takes one mandatory argument, an initialised I2C bus.
|
||||
|
||||
Public methods:
|
||||
1. `get_time` Optional boolean arg `set_rtc=False`. If `set_rtc` is `True` it
|
||||
sets the platform's RTC from the DS3231. It returns the DS3231 time as a tuple
|
||||
in the same format as `utime.localtime()` except that yday (day of year) is 0.
|
||||
So the format is (year, month, day, hour, minute, second, wday, 0).
|
||||
Note that on ports/platforms which don't support an RTC, if `set_rtc` is
|
||||
`True`, the local time will be set from the DS3231.
|
||||
2. `save_time` No args. Sets the DS3231 time from the platform's local time.
|
||||
3. `rtc_test` Optional args: `runtime=600`, `ppm=False`. This tests the
|
||||
platform's local time against the DS3231 returning the error in parts per
|
||||
million (if `ppm` is `True`) or seconds per year. A positive value indicates
|
||||
that the DS3231 clock leads the platform local time.
|
||||
The `runtime` value in seconds defines the duration of the test. The default
|
||||
of 10 minutes provides high accuracy but shorter durations will suffice on
|
||||
devices with poor RTC's (e.g. ESP8266).
|
||||
|
||||
# 2. The Pyboard driver
|
||||
|
||||
The principal reason to use this driver is to calibrate the Pyboard's RTC.
|
||||
|
||||
This assumes that the DS3231 is connected to the hardware I2C port on the `X`
|
||||
or `Y` side of the board, and that the Pyboard's RTC is set to the correct time
|
||||
and date.
|
||||
|
||||
Usage to calibrate the Pyboard's RTC. Takes 5 minutes.
|
||||
|
||||
```python
|
||||
from ds3231_pb import DS3231
|
||||
ds3231 = DS3231('X')
|
||||
ds3231.save_time() # Set DS3231 to match Pyboard RTC
|
||||
ds3231.calibrate()
|
||||
```
|
||||
|
||||
Calibration data is stored in battery-backed memory. So if a backup cell is
|
||||
used the RTC will run accurately in the event of a power outage.
|
||||
|
||||
## 2.1 The DS3231 class
|
||||
|
||||
Constructor:
|
||||
This takes one mandatory argument, a string identifying the Pyboard side in use
|
||||
('X' or 'Y').
|
||||
|
||||
Public methods:
|
||||
1. `get_time` Optional boolean arg `set_rtc=False`. If `set_rtc` is True it
|
||||
sets the Pyboard's RTC from the DS3231. It returns the DS3231 time as a tuple
|
||||
in the same format as `utime.localtime()` except that yday (day of year) is 0.
|
||||
namely (year, month, day, hour, minute, second, wday, 0).
|
||||
2. `save_time` No args. Sets the DS3231 time from the Pyboard's RTC.
|
||||
3. `calibrate` Optional arg `minutes=5`. The time to run. This calculates the
|
||||
calibration factor and applies it to the Pyboard. It returns the calibration
|
||||
factor which may be stored in a file if the calibration needs to survive an
|
||||
outage of all power sources.
|
|
@ -0,0 +1,119 @@
|
|||
# Portable driver for DS3231 precison real time clock.
|
||||
# Adapted from WiPy driver at https://github.com/scudderfish/uDS3231
|
||||
# Includes routine to calibrate the Pyboard's RTC from the DS3231
|
||||
# delta method now operates to 1mS precision
|
||||
# precison of calibration further improved by timing Pyboard RTC transition
|
||||
# Adapted by Peter Hinch, Feb 2017
|
||||
|
||||
import utime
|
||||
import machine
|
||||
import sys
|
||||
DS3231_I2C_ADDR = 104
|
||||
|
||||
class DS3231Exception(OSError):
|
||||
pass
|
||||
|
||||
if sys.platform == 'pyboard':
|
||||
import pyb
|
||||
rtc = pyb.RTC()
|
||||
else:
|
||||
try:
|
||||
rtc = machine.RTC()
|
||||
except: # Official ESP32 port
|
||||
print('warning: machine module does not support the RTC.')
|
||||
rtc = None
|
||||
|
||||
def bcd2dec(bcd):
|
||||
return (((bcd & 0xf0) >> 4) * 10 + (bcd & 0x0f))
|
||||
|
||||
def dec2bcd(dec):
|
||||
tens, units = divmod(dec, 10)
|
||||
return (tens << 4) + units
|
||||
|
||||
def tobytes(num):
|
||||
return num.to_bytes(1, 'little')
|
||||
|
||||
class DS3231:
|
||||
def __init__(self, i2c):
|
||||
self.ds3231 = i2c
|
||||
self.timebuf = bytearray(7)
|
||||
if DS3231_I2C_ADDR not in self.ds3231.scan():
|
||||
raise DS3231Exception("DS3231 not found on I2C bus at %d" % DS3231_I2C_ADDR)
|
||||
|
||||
def get_time(self, set_rtc = False):
|
||||
if set_rtc:
|
||||
self.await_transition() # For accuracy set RTC immediately after a seconds transition
|
||||
else:
|
||||
self.ds3231.readfrom_mem_into(DS3231_I2C_ADDR, 0, self.timebuf) # don't wait
|
||||
return self.convert(set_rtc)
|
||||
|
||||
def convert(self, set_rtc=False): # Return a tuple in localtime() format (less yday)
|
||||
data = self.timebuf
|
||||
ss = bcd2dec(data[0])
|
||||
mm = bcd2dec(data[1])
|
||||
if data[2] & 0x40:
|
||||
hh = bcd2dec(data[2] & 0x1f)
|
||||
if data[2] & 0x20:
|
||||
hh += 12
|
||||
else:
|
||||
hh = bcd2dec(data[2])
|
||||
wday = data[3]
|
||||
DD = bcd2dec(data[4])
|
||||
MM = bcd2dec(data[5] & 0x1f)
|
||||
YY = bcd2dec(data[6])
|
||||
if data[5] & 0x80:
|
||||
YY += 2000
|
||||
else:
|
||||
YY += 1900
|
||||
# Time from DS3231 in time.localtime() format (less yday)
|
||||
result = YY, MM, DD, hh, mm, ss, wday -1, 0
|
||||
if set_rtc:
|
||||
if rtc is None:
|
||||
# Best we can do is to set local time
|
||||
secs = utime.mktime(result)
|
||||
utime.localtime(secs)
|
||||
else:
|
||||
if sys.platform == 'pyboard':
|
||||
rtc.datetime((YY, MM, DD, wday, hh, mm, ss, 0))
|
||||
else:
|
||||
rtc.init((YY, MM, DD, hh, mm, ss))
|
||||
return result
|
||||
|
||||
def save_time(self):
|
||||
(YY, MM, mday, hh, mm, ss, wday, yday) = utime.localtime() # Based on RTC
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 0, tobytes(dec2bcd(ss)))
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 1, tobytes(dec2bcd(mm)))
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 2, tobytes(dec2bcd(hh))) # Sets to 24hr mode
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 3, tobytes(dec2bcd(wday + 1))) # 1 == Monday, 7 == Sunday
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 4, tobytes(dec2bcd(mday))) # Day of month
|
||||
if YY >= 2000:
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 5, tobytes(dec2bcd(MM) | 0b10000000)) # Century bit
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 6, tobytes(dec2bcd(YY-2000)))
|
||||
else:
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 5, tobytes(dec2bcd(MM)))
|
||||
self.ds3231.writeto_mem(DS3231_I2C_ADDR, 6, tobytes(dec2bcd(YY-1900)))
|
||||
|
||||
# Wait until DS3231 seconds value changes before reading and returning data
|
||||
def await_transition(self):
|
||||
self.ds3231.readfrom_mem_into(DS3231_I2C_ADDR, 0, self.timebuf)
|
||||
ss = self.timebuf[0]
|
||||
while ss == self.timebuf[0]:
|
||||
self.ds3231.readfrom_mem_into(DS3231_I2C_ADDR, 0, self.timebuf)
|
||||
return self.timebuf
|
||||
|
||||
# Test hardware RTC against DS3231. Default runtime 10 min. Return amount
|
||||
# by which DS3231 clock leads RTC in PPM or seconds per year.
|
||||
# Precision is achieved by starting and ending the measurement on DS3231
|
||||
# one-seond boundaries and using ticks_ms() to time the RTC.
|
||||
# For a 10 minute measurement +-1ms corresponds to 1.7ppm or 53s/yr. Longer
|
||||
# runtimes improve this, but the DS3231 is "only" good for +-2ppm over 0-40C.
|
||||
def rtc_test(self, runtime=600, ppm=False):
|
||||
factor = 1000000 if ppm else 31557600 # seconds per year
|
||||
self.await_transition() # Start on transition
|
||||
rtc_start = utime.ticks_ms() # and get RTC time NOW
|
||||
ds3231_start = utime.mktime(self.convert())
|
||||
utime.sleep(runtime) # Wait a while (precision doesn't matter)
|
||||
self.await_transition()
|
||||
d_rtc = utime.ticks_diff(utime.ticks_ms(), rtc_start)
|
||||
d_ds3231 = 1000 * (utime.mktime(self.convert()) - ds3231_start)
|
||||
return (d_ds3231 - d_rtc) * factor / d_ds3231
|
|
@ -0,0 +1,30 @@
|
|||
# ds3231_port_test
|
||||
# Test of portable driver for DS3231 precision RTC chip
|
||||
|
||||
from machine import Pin, I2C
|
||||
import utime
|
||||
from ds3231_port import DS3231
|
||||
# Pyboard test
|
||||
#from pyb import RTC
|
||||
#rtc = RTC()
|
||||
#rtc.datetime((2018, 1, 1, 1, 12, 0, 0, 0)) # Force incorrect setting
|
||||
|
||||
# In case pullups are absent.
|
||||
#scl_pin = Pin('X2', pull=Pin.PULL_UP, mode=Pin.OPEN_DRAIN)
|
||||
#sda_pin = Pin('X1', pull=Pin.PULL_UP, mode=Pin.OPEN_DRAIN)
|
||||
scl_pin = Pin(19, pull=Pin.PULL_UP, mode=Pin.OPEN_DRAIN)
|
||||
sda_pin = Pin(18, pull=Pin.PULL_UP, mode=Pin.OPEN_DRAIN)
|
||||
i2c = I2C(-1, scl=scl_pin, sda=sda_pin)
|
||||
ds3231 = DS3231(i2c)
|
||||
|
||||
print('Initial values')
|
||||
print('DS3231 time:', ds3231.get_time())
|
||||
print('RTC time:', utime.localtime())
|
||||
|
||||
print('Setting DS3231 from RTC')
|
||||
ds3231.save_time() # Set DS3231 from RTC
|
||||
print('DS3231 time:', ds3231.get_time())
|
||||
print('RTC time:', utime.localtime())
|
||||
|
||||
print('Running RTC test for 2 mins')
|
||||
print('RTC leads DS3231 by', ds3231.rtc_test(120, True), 'ppm')
|
129
README.md
129
README.md
|
@ -2,98 +2,10 @@
|
|||
A place for assorted code ideas for MicroPython. Most are targeted at the
|
||||
Pyboard variants.
|
||||
|
||||
# fastbuild - Pull and build Pyboard firmware under Linux
|
||||
These scripts are intended to speed and simplify rebuilding firmware from
|
||||
source notably where pyboards of different types are in use, or when
|
||||
frozen bytecode necessitates repeated compilation and deployment. In
|
||||
particular ``buildpyb`` will detect the attached Pyboard type, build the
|
||||
appropriate firmware, put the board into DFU mode and deploy it, before
|
||||
launching ``rshell``. The latter step may be removed if ``rshell`` is not in
|
||||
use.
|
||||
# Fastbuild
|
||||
|
||||
The scripts should be run as your normal user and can proceed without user
|
||||
interaction.
|
||||
|
||||
Includes udev rules to avoid jumps from ``/dev/ttyACM0`` to ``/dev/ttyACM1``
|
||||
and ensuring Pyboards of all types appear as ``/dev/pyboard``. Rules are also
|
||||
offered for USB connected WiPy (V1.0) and FTDI USB/serial adaptors.
|
||||
|
||||
These scripts use Python scripts ``pyb_boot`` to put the Pyboard into DFU mode
|
||||
and ``pyb_check`` to determine the type of attached board. These use the
|
||||
``pyboard.py`` module in the source tree to execute scripts on the attached
|
||||
board.
|
||||
|
||||
### Optional Edits
|
||||
|
||||
In the ``buildpyb`` script you may wish to edit the ``-j 8`` argument to ``make``.
|
||||
This radically speeds build on a multi core PC. Empirically 8 gave the fastest
|
||||
build on my Core i7 4/8 core laptop: adjust to suit your PC. You may also want
|
||||
to remove the call to ``rshell`` if you don't plan on using it.
|
||||
|
||||
This script defaults to a frozen modules directory ``stmhal/modules``. This may
|
||||
be overridden by creating an environment variable FROZEN_DIR: a recent update
|
||||
enabled the directory for frozen to be located anywhere in the filesystem,
|
||||
allowing project specific directories.
|
||||
|
||||
In ``buildnew`` you may wish to delete the unix make commands.
|
||||
|
||||
### Dependencies and setup (on PC)
|
||||
|
||||
Python3
|
||||
The following Bash code installs pyserial, copies ``49-micropython.rules`` to
|
||||
(on most distros) ``/etc/udev/rules.d``. It installs ``rshell`` if you plan to
|
||||
use it (recommended).
|
||||
|
||||
As root:
|
||||
```
|
||||
apt-get install python3-serial
|
||||
pip install pyserial
|
||||
cp 49-micropython.rules /etc/udev/rules.d
|
||||
pip3 install rshell
|
||||
```
|
||||
|
||||
Verify that ``pyboard.py`` works. To do this, close and restart the terminal
|
||||
session. Run Python3, paste the following and check that the red LED lights:
|
||||
|
||||
```python
|
||||
import os
|
||||
mp = os.getenv('MPDIR')
|
||||
sys.path.append(''.join((mp, '/tools')))
|
||||
import pyboard
|
||||
pyb = pyboard.Pyboard('/dev/pyboard')
|
||||
pyb.enter_raw_repl()
|
||||
pyb.exec('pyb.LED(1).on()')
|
||||
pyb.exit_raw_repl()
|
||||
```
|
||||
|
||||
The build scripts expect an environment variable MPDIR holding the path to the
|
||||
MicroPython source tree. To set this up, as normal user issue (edited for your
|
||||
path to the MicroPython source tree):
|
||||
|
||||
```
|
||||
cd ~
|
||||
echo export MPDIR='/mnt/qnap2/data/Projects/MicroPython/micropython' >> .bashrc
|
||||
echo >> .bashrc
|
||||
```
|
||||
|
||||
Close and restart the terminal session before running the scripts.
|
||||
|
||||
### Build script: ``buildpyb``
|
||||
This checks the attached pyboard. If it's a V1.0, V1.1 or Lite it builds the
|
||||
correct firmware and deploys it. Otherwise it produces an error message.
|
||||
|
||||
Optional argument ``--clean`` - if supplied does a ``make clean`` to delete
|
||||
all files produced by the previous build before proceeding.
|
||||
|
||||
### Update source: ``buildnew``
|
||||
|
||||
Report state of master branch, update sources and issue ``make clean`` for
|
||||
Pyboard variants, and ESP8266. Builds cross compiler and unix port.
|
||||
|
||||
### ESP8266 Build
|
||||
|
||||
``buildesp`` A script to build and deploy ESP8266 firmware. Accepts optional
|
||||
``--clean`` argument.
|
||||
Scripts for building MicroPython for various target hardware types and for
|
||||
updating your local source. See [docs](./fastbuild/README.md)
|
||||
|
||||
# ssd1306
|
||||
|
||||
|
@ -101,31 +13,44 @@ A means of rendering multiple larger fonts to the SSD1306 OLED display. See
|
|||
[docs](./SSD1306/README.md).
|
||||
|
||||
# mutex
|
||||
A class providing mutual exclusion enabling interrupt handlers and the main program to access shared
|
||||
data in a manner which ensures data integrity.
|
||||
|
||||
A class providing mutual exclusion enabling interrupt handlers and the main
|
||||
program to access shared data in a manner which ensures data integrity.
|
||||
|
||||
# watchdog
|
||||
|
||||
Access the simpler of the Pyboard's watchdog timers.
|
||||
|
||||
# reverse
|
||||
|
||||
Fast reverse a bytearray in Arm Thumb assembler.
|
||||
Python code to bit-reverse (fast-ish) 8, 16 and 32 bit words.
|
||||
|
||||
# ds3231_pb
|
||||
Driver for the DS3231 low cost precison RTC, including a facility to calibrate the Pyboard's RTC
|
||||
# DS3231
|
||||
|
||||
This is a low cost precision battery backed real time clock (RTC) accurate to
|
||||
+-2 minutes/year. Two drivers are provided, one portable across platforms and
|
||||
one which is Pyboard specific.
|
||||
|
||||
The Pyboard-specific driver provides a facility to calibrate the Pyboard's RTC
|
||||
from the DS3231. Calibration to high precision may be achieved in five minutes.
|
||||
|
||||
The drivers are [documented here](./DS3231/README.md).
|
||||
|
||||
# Buildcheck
|
||||
|
||||
Raise an exception if a firmware build is earlier than a given date.
|
||||
|
||||
# timed_function
|
||||
|
||||
Time a function's execution using a decorator.
|
||||
|
||||
# ESP8266
|
||||
benchmark.py Tests the performance of MQTT by periodically publishing while subscribed to
|
||||
the same topic. Measures the round-trip delay. Adapt to suit your server address and desired
|
||||
QOS (quality of service, 0 and 1 are supported). After 100 messages reports maximum and
|
||||
minimum delays.
|
||||
# ESP8266 (MQTT benchmark)
|
||||
|
||||
benchmark.py Tests the performance of MQTT by periodically publishing while
|
||||
subscribed to the same topic. Measures the round-trip delay. Adapt to suit your
|
||||
server address and desired QOS (quality of service, 0 and 1 are supported).
|
||||
After 100 messages reports maximum and minimum delays.
|
||||
|
||||
conn.py Connect in station mode using saved connection details where possible.
|
||||
|
||||
|
@ -143,8 +68,8 @@ These were written for encoders producing TTL outputs. For switches, adapt the
|
|||
pull definition to provide a pull up or pull down as required.
|
||||
|
||||
The `encoder.portable.py` version should work on all MicroPython platforms.
|
||||
Tested on ESP8266. Note that interrupt latency on the ESP8266 limits performance
|
||||
(ESP32 is probably similar).
|
||||
Tested on ESP8266. Note that interrupt latency on the ESP8266 limits
|
||||
performance. ESP32 is similar.
|
||||
|
||||
# A pseudo random number generator
|
||||
|
||||
|
|
|
@ -3,16 +3,25 @@
|
|||
The official SSD1306 OLED display driver supports a single 8x8 pixel monospaced
|
||||
font. Users of the 128x64 displays in particular may wish to use larger fonts.
|
||||
This provides a means of extending the official driver to support this. Suitable
|
||||
font files may be created from standard ``ttf`` or ``otf`` files using the utility
|
||||
font files may be created from standard `ttf` or `otf` files using the utility
|
||||
presented [here](https://github.com/peterhinch/micropython-font-to-py.git).
|
||||
|
||||
Requires firmware dated 1st Dec 2017 or later.
|
||||
|
||||
A few users have pointed out limitations in the `Writer` class. While it works
|
||||
it is a rather minimal "proof of concept" for the font creator. PR's offering
|
||||
enhancements will be gratefully considered.
|
||||
|
||||
The font file format is something of a "given" as it is used elsewhere. So any
|
||||
PR requiring this to be changed is unlikely to find favour.
|
||||
|
||||

|
||||
|
||||
###### [Main README](./README.md)
|
||||
|
||||
## Release notes
|
||||
|
||||
V0.21 21st March 2017 The ``Writer`` class now uses the framebuf blit method.
|
||||
V0.21 21st March 2017 The `Writer` class now uses the framebuf blit method.
|
||||
This works for monochrome devices using 1-bit colour mapping. Example code is
|
||||
provided for rendering to colour devices: the framebuf class does not yet offer
|
||||
an effective way to handle colour mapping when blitting between buffers with
|
||||
|
@ -23,16 +32,16 @@ This is by design but see issue #2692.
|
|||
|
||||
# Files
|
||||
|
||||
1. ssd1306_test.py A simple test program.
|
||||
2. ssd1306.py A snapshot of the current official driver.
|
||||
3. writer.py A generic Writer class. Keeps track of the text insertion point
|
||||
over multiple fonts, handles newline and vertical scrolling if required.
|
||||
1. ssd1306_test.py A simple test program.
|
||||
2. ssd1306.py A snapshot of the current official driver.
|
||||
3. writer.py A generic Writer class. Keeps track of the text insertion point
|
||||
over multiple fonts, handles newline and vertical scrolling if required.
|
||||
|
||||
In addition several font files are provided as samples.
|
||||
|
||||
# Getting started
|
||||
|
||||
The file ``ssd1306_test.py`` may need editing to match your hardware notably
|
||||
The file `ssd1306_test.py` may need editing to match your hardware notably
|
||||
the values of WIDTH and HEIGHT which are set to 128x64 (w*h) pixels. Wiring
|
||||
details are included in code comments but may be changed if required as soft
|
||||
I2C and SPI interfaces are specified.
|
||||
|
@ -40,7 +49,7 @@ I2C and SPI interfaces are specified.
|
|||
Its principal testing was performed on Pyboards but I'd expect it to be
|
||||
portable to any device supporting the official driver and the `machine` module.
|
||||
|
||||
Copy files 1-3 and ``freesans20.py`` to the target and issue
|
||||
Copy files 1-3 and `freesans20.py` to the target and issue
|
||||
|
||||
```python
|
||||
import ssd1306_test
|
||||
|
@ -54,8 +63,8 @@ Font files are converted to Python modules for ease of use and also (optionally)
|
|||
to enable the modules to be frozen as bytecode to reduce RAM requirements.
|
||||
|
||||
The user program should import all fonts which are to be used and declare a
|
||||
``Writer`` instance for each one. Rendering text at the current insertion point
|
||||
is then simply a matter of issuing the appropriate writer's ``printstring``
|
||||
`Writer` instance for each one. Rendering text at the current insertion point
|
||||
is then simply a matter of issuing the appropriate writer's `printstring`
|
||||
method. After issuing all such calls required by your application the display
|
||||
should be updated by issuing
|
||||
|
||||
|
@ -69,35 +78,35 @@ The principal interaction with the driver is via this class. One instance should
|
|||
be created for each font in use. Its function is to keep track of the text
|
||||
insertion point over successive uses with multiple fonts and to handle newline
|
||||
characters and vertical scrolling. Its behaviour when text overruns the end of
|
||||
a line or the bottom of the screen may be controlled using its ``set_clip``
|
||||
a line or the bottom of the screen may be controlled using its `set_clip`
|
||||
method.
|
||||
|
||||
## Methods
|
||||
|
||||
1. ``Constructor`` This takes the ``ssd`` display instance and the font module
|
||||
as mandatory args.
|
||||
2. ``printstring`` Takes a text string as argument and renders it at the current
|
||||
insertion point. Respects newline characters.
|
||||
1. `Constructor` This takes the `ssd` display instance and the font module
|
||||
as mandatory args.
|
||||
2. `printstring` Takes a text string as argument and renders it at the current
|
||||
insertion point. Respects newline characters.
|
||||
|
||||
## Class methods
|
||||
|
||||
1. ``set_textpos`` Mandatory integer args ``row``, ``col`` defined in pixels
|
||||
relative to the top left hand corner of the display. Sets the current text
|
||||
insertion point. The coordinates of a glyph refer to its top left corner. The
|
||||
1. `set_textpos` Mandatory integer args `row`, `col` defined in pixels
|
||||
relative to the top left hand corner of the display. Sets the current text
|
||||
insertion point. The coordinates of a glyph refer to its top left corner. The
|
||||
initial default is (0,0) with text being rendered at the top left of the display.
|
||||
2. ``set_clip`` Mandatory boolean args ``row_clip``, ``col_clip``. These define
|
||||
behaviour when text overruns the physical width or height of the display. By
|
||||
default text overrunning the display width will continue on the next row. Setting
|
||||
``col_clip`` overrides this such that overrunning text is lost. Similarly, by
|
||||
default text overrunning the bottom of the display will cause text above to
|
||||
scroll up to accommodate it. Setting ``row_clip`` will override this behaviour
|
||||
causing text to be clipped.
|
||||
2. `set_clip` Mandatory boolean args `row_clip`, `col_clip`. These define
|
||||
behaviour when text overruns the physical width or height of the display. By
|
||||
default text overrunning the display width will continue on the next row. Setting
|
||||
`col_clip` overrides this such that overrunning text is lost. Similarly, by
|
||||
default text overrunning the bottom of the display will cause text above to
|
||||
scroll up to accommodate it. Setting `row_clip` will override this behaviour
|
||||
causing text to be clipped.
|
||||
|
||||
# Use of font_to_py.py
|
||||
|
||||
To convert font files to Python for use with this driver the default (vertical)
|
||||
mapping and bit order should be used. The only optional argument which may be
|
||||
needed is ``-f`` if fixed-width rendering is desired.
|
||||
needed is `-f` if fixed-width rendering is desired.
|
||||
|
||||
# License
|
||||
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# fastbuild - Pull and build Pyboard firmware under Linux
|
||||
|
||||
These scripts are intended to speed and simplify rebuilding firmware from
|
||||
source notably where pyboards of different types are in use, or when
|
||||
frozen bytecode necessitates repeated compilation and deployment. In
|
||||
particular `buildpyb` will detect the attached Pyboard type, build the
|
||||
appropriate firmware, put the board into DFU mode and deploy it, before
|
||||
launching `rshell`. The latter step may be removed if `rshell` is not in
|
||||
use.
|
||||
|
||||
The scripts should be run as your normal user and can proceed without user
|
||||
interaction.
|
||||
|
||||
Includes udev rules to avoid jumps from `/dev/ttyACM0` to `/dev/ttyACM1`
|
||||
and ensuring Pyboards of all types appear as `/dev/pyboard`. Rules are also
|
||||
offered for USB connected WiPy (V1.0) and FTDI USB/serial adaptors.
|
||||
|
||||
These scripts use Python scripts `pyb_boot` to put the Pyboard into DFU mode
|
||||
and `pyb_check` to determine the type of attached board. These use the
|
||||
`pyboard.py` module in the source tree to execute scripts on the attached
|
||||
board.
|
||||
|
||||
###### [Main README](./README.md)
|
||||
|
||||
### Optional Edits
|
||||
|
||||
In the `buildpyb` script you may wish to edit the `-j 8` argument to `make`.
|
||||
This radically speeds build on a multi core PC. Empirically 8 gave the fastest
|
||||
build on my Core i7 4/8 core laptop: adjust to suit your PC. You may also want
|
||||
to remove the call to `rshell` if you don't plan on using it.
|
||||
|
||||
This script defaults to a frozen modules directory `stmhal/modules`. This may
|
||||
be overridden by creating an environment variable FROZEN_DIR: a recent update
|
||||
enabled the directory for frozen to be located anywhere in the filesystem,
|
||||
allowing project specific directories.
|
||||
|
||||
In `buildnew` you may wish to delete the unix make commands.
|
||||
|
||||
### Dependencies and setup (on PC)
|
||||
|
||||
Python3
|
||||
The following Bash code installs pyserial, copies `49-micropython.rules` to
|
||||
(on most distros) `/etc/udev/rules.d`. It installs `rshell` if you plan to
|
||||
use it (recommended).
|
||||
|
||||
As root:
|
||||
```
|
||||
apt-get install python3-serial
|
||||
pip install pyserial
|
||||
cp 49-micropython.rules /etc/udev/rules.d
|
||||
pip3 install rshell
|
||||
```
|
||||
|
||||
Verify that `pyboard.py` works. To do this, close and restart the terminal
|
||||
session. Run Python3, paste the following and check that the red LED lights:
|
||||
|
||||
```python
|
||||
import os
|
||||
mp = os.getenv('MPDIR')
|
||||
sys.path.append(''.join((mp, '/tools')))
|
||||
import pyboard
|
||||
pyb = pyboard.Pyboard('/dev/pyboard')
|
||||
pyb.enter_raw_repl()
|
||||
pyb.exec('pyb.LED(1).on()')
|
||||
pyb.exit_raw_repl()
|
||||
```
|
||||
|
||||
The build scripts expect an environment variable MPDIR holding the path to the
|
||||
MicroPython source tree. To set this up, as normal user issue (edited for your
|
||||
path to the MicroPython source tree):
|
||||
|
||||
```
|
||||
cd ~
|
||||
echo export MPDIR='/mnt/qnap2/data/Projects/MicroPython/micropython' >> .bashrc
|
||||
echo >> .bashrc
|
||||
```
|
||||
|
||||
Close and restart the terminal session before running the scripts.
|
||||
|
||||
### Build script: `buildpyb`
|
||||
|
||||
This checks the attached pyboard. If it's a V1.0, V1.1 or Lite it builds the
|
||||
correct firmware and deploys it. Otherwise it produces an error message.
|
||||
|
||||
Optional argument `--clean` - if supplied does a `make clean` to delete
|
||||
all files produced by the previous build before proceeding.
|
||||
|
||||
### Update source: `buildnew`
|
||||
|
||||
Report state of master branch, update sources and issue `make clean` for
|
||||
Pyboard variants and ESP8266. Builds cross compiler and unix port.
|
||||
|
||||
### ESP8266 Build
|
||||
|
||||
`buildesp` A script to build and deploy ESP8266 firmware. Accepts optional
|
||||
`--clean` argument.
|
Ładowanie…
Reference in New Issue