Initial commit.
This commit is contained in:
commit
2c1f5af4c0
15 changed files with 1616 additions and 0 deletions
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
__pycache__
|
||||
_build
|
||||
*.pyc
|
||||
.env
|
||||
build*
|
||||
bundles
|
||||
*.mpy
|
||||
.DS_Store
|
||||
432
.pylintrc
Normal file
432
.pylintrc
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code
|
||||
extension-pkg-whitelist=
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
# jobs=1
|
||||
jobs=2
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once).You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
# disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
|
||||
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
enable=
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectively contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details
|
||||
#msg-template=
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio).You can also give a reporter class, eg
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=yes
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
||||
# install python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to indicated private dictionary in
|
||||
# --spelling-private-dict-file option instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,XXX,TODO
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
||||
# not used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,future.builtins
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
# expected-line-ending-format=
|
||||
expected-line-ending-format=LF
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=100
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,dict-separator
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming hint for argument names
|
||||
argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct argument names
|
||||
argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Naming hint for attribute names
|
||||
attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct attribute names
|
||||
attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,bar,baz,toto,tutu,tata
|
||||
|
||||
# Naming hint for class attribute names
|
||||
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Regular expression matching correct class attribute names
|
||||
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Naming hint for class names
|
||||
# class-name-hint=[A-Z_][a-zA-Z0-9]+$
|
||||
class-name-hint=[A-Z_][a-zA-Z0-9_]+$
|
||||
|
||||
# Regular expression matching correct class names
|
||||
# class-rgx=[A-Z_][a-zA-Z0-9]+$
|
||||
class-rgx=[A-Z_][a-zA-Z0-9_]+$
|
||||
|
||||
# Naming hint for constant names
|
||||
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Regular expression matching correct constant names
|
||||
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming hint for function names
|
||||
function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct function names
|
||||
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
# good-names=i,j,k,ex,Run,_
|
||||
good-names=r,g,b,w,i,j,k,n,x,y,z,ex,ok,Run,_
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming hint for inline iteration names
|
||||
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Regular expression matching correct inline iteration names
|
||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Naming hint for method names
|
||||
method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct method names
|
||||
method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Naming hint for module names
|
||||
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Regular expression matching correct module names
|
||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming hint for variable names
|
||||
variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct variable names
|
||||
variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=optparse,tkinter.tix
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,__new__,setUp
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,_fields,_replace,_source,_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=mcs
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
# max-attributes=7
|
||||
max-attributes=11
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=1
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "Exception"
|
||||
overgeneral-exceptions=Exception
|
||||
30
.travis.yml
Normal file
30
.travis.yml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# This is a common .travis.yml for generating library release zip files for
|
||||
# CircuitPython library releases using circuitpython-build-tools.
|
||||
# See https://github.com/adafruit/circuitpython-build-tools for detailed setup
|
||||
# instructions.
|
||||
|
||||
dist: trusty
|
||||
sudo: false
|
||||
language: python
|
||||
python:
|
||||
- "3.6"
|
||||
|
||||
cache:
|
||||
pip: true
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key: $GITHUB_TOKEN
|
||||
file_glob: true
|
||||
file: bundles/*
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
|
||||
install:
|
||||
- pip install pylint circuitpython-build-tools
|
||||
|
||||
script:
|
||||
- pylint thermal_printer.py
|
||||
- ([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name examples/*.py)
|
||||
- circuitpython-build-bundles --filename_prefix adafruit-circuitpython-thermal-printer --library_location .
|
||||
74
CODE_OF_CONDUCT.md
Normal file
74
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at support@adafruit.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Tony DiCola for Adafruit Industries
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
69
README.rst
Normal file
69
README.rst
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
|
||||
Introduction
|
||||
============
|
||||
|
||||
.. image:: https://readthedocs.org/projects/adafruit_circuitpython_thermal_printer/badge/?version=latest
|
||||
|
||||
:target: https://adafruit_circuitpython_thermal_printer.readthedocs.io/
|
||||
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image :: https://img.shields.io/discord/327254708534116352.svg
|
||||
:target: https://discord.gg/nBQh6qu
|
||||
:alt: Discord
|
||||
|
||||
TODO
|
||||
|
||||
Dependencies
|
||||
=============
|
||||
This driver depends on:
|
||||
|
||||
* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_
|
||||
|
||||
Please ensure all dependencies are available on the CircuitPython filesystem.
|
||||
This is easily achieved by downloading
|
||||
`the Adafruit library and driver bundle <https://github.com/adafruit/Adafruit_CircuitPython_Bundle>`_.
|
||||
|
||||
Usage Example
|
||||
=============
|
||||
|
||||
See examples/simpletest.py for a demo of basic printer usage.
|
||||
|
||||
API Reference
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
Contributions are welcome! Please read our `Code of Conduct
|
||||
<https://github.com/adafruit/Adafruit_CircuitPython_Thermal_Printer/blob/master/CODE_OF_CONDUCT.md>`_
|
||||
before contributing to help this project stay welcoming.
|
||||
|
||||
Building locally
|
||||
================
|
||||
|
||||
To build this library locally you'll need to install the
|
||||
`circuitpython-build-tools <https://github.com/adafruit/circuitpython-build-tools>`_ package.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python3 -m venv .env
|
||||
source .env/bin/activate
|
||||
pip install circuitpython-build-tools
|
||||
|
||||
Once installed, make sure you are in the virtual environment:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
source .env/bin/activate
|
||||
|
||||
Then run the build:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
circuitpython-build-bundles --filename_prefix adafruit_circuitpython_thermal_printer --library_location .
|
||||
0
adafruit_thermal_printer/__init__.py
Normal file
0
adafruit_thermal_printer/__init__.py
Normal file
528
adafruit_thermal_printer/thermal_printer.py
Normal file
528
adafruit_thermal_printer/thermal_printer.py
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2017 Tony DiCola
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`adafruit_thermal_printer`
|
||||
====================================================
|
||||
|
||||
Thermal printer control module built to work with small serial thermal
|
||||
receipt printers. Note that these printers have many different firmware
|
||||
versions and care must be taken to select the appropriate module inside this
|
||||
package for your firmware printer:
|
||||
- thermal_printer = The latest printers with firmware version 2.68+
|
||||
- thermal_printer_264 = Printers with firmware version 2.64 up to 2.68.
|
||||
- thermal_printer_legacy = Printers with firmware version before 2.64.
|
||||
|
||||
* Author(s): Tony DiCola
|
||||
"""
|
||||
import time
|
||||
|
||||
from micropython import const
|
||||
|
||||
|
||||
__version__ = "0.0.0-auto.0"
|
||||
__repo__ = "https://github.com/adafruit/CircuitPython_thermal_printer.git"
|
||||
|
||||
|
||||
# pylint: disable=bad-whitespace
|
||||
# Internally used constants.
|
||||
_UPDOWN_MASK = const(1 << 2)
|
||||
_BOLD_MASK = const(1 << 3)
|
||||
_DOUBLE_HEIGHT_MASK = const(1 << 4)
|
||||
_DOUBLE_WIDTH_MASK = const(1 << 5)
|
||||
_STRIKE_MASK = const(1 << 6)
|
||||
# pylint: enable=bad-whitespace
|
||||
|
||||
|
||||
# Disable too many instance members warning. This is not something pylint can
|
||||
# reasonably infer--the complexity of instance variables is required for proper
|
||||
# printer function. Disable this warning.
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
|
||||
# Disable too many public members warning. Again this is not something pylint
|
||||
# can reasonably decide. Thermal printers require lots of control functions.
|
||||
# Disable this warning.
|
||||
# pylint: disable=too-many-public-methods
|
||||
|
||||
# Thermal printer class for printers with firmware version 2.68 and higher.
|
||||
# Do not modify this class without fully understanding its coupling to the
|
||||
# legacy and 2.64+ version printer which inherit from it. These legacy printer
|
||||
# classes override specific functions which have different requirements of
|
||||
# behavior between different versions of printer firmware. Firmware printers
|
||||
# vary _greatly_ in their command set--there is not a clean abstraction. The
|
||||
# assumption here is that this class is the master with logic for the most
|
||||
# recent (2.68+) firmware printers. Older firmware versions inherit and
|
||||
# override behavior where necessary. It is highly, HIGHLY recommended you
|
||||
# carefully study the Arduino thermal printer library code and fully
|
||||
# understand all the firmware differences (notice where the library changes
|
||||
# behavior with the firmware version define):
|
||||
# https://github.com/adafruit/Adafruit-Thermal-Printer-Library
|
||||
# Bottom line: don't touch this code without understanding the big picture or
|
||||
# else it will be very easy to break or introduce subtle incompatibilities with
|
||||
# older firmware printers.
|
||||
class ThermalPrinter:
|
||||
"""Thermal printer for printers with firmware version 2.68 or higher."""
|
||||
|
||||
# pylint: disable=bad-whitespace
|
||||
# Barcode types. These vary based on the firmware version so are made
|
||||
# as class-level variables that users can reference (i.e.
|
||||
# ThermalPrinter.UPC_A, etc) and write code that is independent of the
|
||||
# printer firmware version.
|
||||
UPC_A = 65
|
||||
UPC_E = 66
|
||||
EAN13 = 67
|
||||
EAN8 = 68
|
||||
CODE39 = 69
|
||||
ITF = 70
|
||||
CODABAR = 71
|
||||
CODE93 = 72
|
||||
CODE128 = 73
|
||||
# pylint: enable=bad-whitespace
|
||||
|
||||
class _PrintModeBit:
|
||||
# Internal descriptor class to simplify printer mode change properties.
|
||||
# This is tightly coupled to the ThermalPrinter implementation--do not
|
||||
# change it without fully understanding these dependencies on the
|
||||
# internal _set_print_mode and other methods!
|
||||
|
||||
# pylint doesn't have the context to realize this internal class is
|
||||
# explicitly tightly coupled to the parent class implementation.
|
||||
# Therefore disable its warnings about protected access--this access
|
||||
# is required and by design.
|
||||
# pylint: disable=protected-access
|
||||
|
||||
# Another odd pylint case, it seems to not realize this is a descriptor
|
||||
# which by design only implements get, set, init. As a result workaround
|
||||
# this pyline issue by disabling the warning.
|
||||
# pylint: disable=too-few-public-methods
|
||||
def __init__(self, mask):
|
||||
self._mask = mask
|
||||
|
||||
def __get__(self, obj, objtype):
|
||||
return obj._print_mode & self._mask > 0
|
||||
|
||||
def __set__(self, obj, val):
|
||||
if val:
|
||||
obj._set_print_mode(self._mask)
|
||||
else:
|
||||
obj._unset_print_mode(self._mask)
|
||||
# pylint: enable=protected-access
|
||||
# pylint: enable=too-few-public-methods
|
||||
|
||||
def __init__(self, uart, byte_delay_s=0.00057346, dot_feed_s=0.0021,
|
||||
dot_print_s=0.03):
|
||||
"""Thermal printer class. Requires a serial UART connection with at
|
||||
least the TX pin connected. Take care connecting RX as the printer
|
||||
will output a 5V signal which can damage boards! If RX is unconnected
|
||||
the only loss in functionality is the has_paper function, all other
|
||||
printer functions will continue to work. The byte_delay_s, dot_feed_s,
|
||||
and dot_print_s values are delays which are used to prevent overloading
|
||||
the printer with data. Use the default delays unless you fully
|
||||
understand the workings of the printer and how delays, baud rate,
|
||||
number of dots, heat time, etc. relate to each other.
|
||||
"""
|
||||
self.max_chunk_height = 255
|
||||
self._resume = 0
|
||||
self._uart = uart
|
||||
self._print_mode = 0
|
||||
self._column = 0
|
||||
self._max_column = 32
|
||||
self._char_height = 24
|
||||
self._line_spacing = 6
|
||||
self._barcode_height = 50
|
||||
# pylint: disable=line-too-long
|
||||
# Byte delay calculated based on assumption of 19200 baud.
|
||||
# From Arduino library code, see formula here:
|
||||
# https://github.com/adafruit/Adafruit-Thermal-Printer-Library/blob/master/Adafruit_Thermal.cpp#L50-L53
|
||||
# pylint: enable=line-too-long
|
||||
self._byte_delay_s = byte_delay_s
|
||||
self._dot_feed_s = dot_feed_s
|
||||
self._dot_print_s = dot_print_s
|
||||
self.reset()
|
||||
|
||||
def _set_timeout(self, period_s):
|
||||
# Set a timeout before future commands can be sent.
|
||||
self._resume = time.monotonic() + period_s
|
||||
|
||||
def _wait_timeout(self):
|
||||
# Ensure the timeout that was previously set has passed (will busy wait).
|
||||
while time.monotonic() < self._resume:
|
||||
pass
|
||||
|
||||
def _write_char(self, char):
|
||||
# Write a single character to the printer.
|
||||
if char == '\r':
|
||||
return # Strip carriage returns by skipping them.
|
||||
self._wait_timeout()
|
||||
self._uart.write(char)
|
||||
delay = self._byte_delay_s
|
||||
# Add extra delay for newlines or moving past the last column.
|
||||
if char == '\n' or self._column == self._max_column:
|
||||
if self._column == 0:
|
||||
# Feed line delay
|
||||
delay += ((self._char_height + self._line_spacing) * \
|
||||
self._dot_feed_s)
|
||||
else:
|
||||
# Text line delay
|
||||
delay += ((self._char_height * self._dot_print_s) + \
|
||||
(self._line_spacing * self._dot_feed_s))
|
||||
self._column = 0
|
||||
else:
|
||||
self._column += 1
|
||||
self._set_timeout(delay)
|
||||
|
||||
def _write_print_mode(self):
|
||||
# Write the printer mode to the printer.
|
||||
self.send_command('\x1B!{0}'.format(chr(self._print_mode))) # ESC + '!' + print mode byte
|
||||
# Adjust character height and column count based on print mode.
|
||||
self._char_height = 48 if self._print_mode & _DOUBLE_HEIGHT_MASK else 24
|
||||
self._max_column = 16 if self._print_mode & _DOUBLE_WIDTH_MASK else 32
|
||||
|
||||
def _set_print_mode(self, mask):
|
||||
# Enable the specified bits of the print mode.
|
||||
self._print_mode |= (mask & 0xFF)
|
||||
self._write_print_mode()
|
||||
|
||||
def _unset_print_mode(self, mask):
|
||||
# Disable the specified bits of the print mode.
|
||||
self._print_mode &= ~(mask & 0xFF)
|
||||
self._write_print_mode()
|
||||
|
||||
def send_command(self, command):
|
||||
"""Send a command string to the printer."""
|
||||
for char in command:
|
||||
self._write_char(char)
|
||||
|
||||
# Do initialization in begin instead of the initializer because this
|
||||
# initialization takes a long time (5 seconds) and shouldn't happen during
|
||||
# object creation (users need explicit control of when to start it).
|
||||
def begin(self, heat_time=120):
|
||||
"""Initialize the printer. Can specify an optional heat_time keyword
|
||||
to override the default heating timing of 1.2 ms. See the datasheet
|
||||
for details on the heating time value (duration in 10uS increments).
|
||||
Note that calling this function will take about half a second for the
|
||||
printer to intialize and warm up.
|
||||
"""
|
||||
assert 0 <= heat_time <= 255
|
||||
self._set_timeout(0.5) # Half second delay for printer to initialize.
|
||||
self.wake()
|
||||
self.reset()
|
||||
# ESC 7 n1 n2 n3 Setting Control Parameter Command
|
||||
# n1 = "max heating dots" 0-255 -- max number of thermal print head
|
||||
# elements that will fire simultaneously. Units = 8 dots (minus 1).
|
||||
# Printer default is 7 (64 dots, or 1/6 of 384-dot width), this code
|
||||
# sets it to 11 (96 dots, or 1/4 of width).
|
||||
# n2 = "heating time" 3-255 -- duration that heating dots are fired.
|
||||
# Units = 10 us. Printer default is 80 (800 us), this code sets it
|
||||
# to value passed (default 120, or 1.2 ms -- a little longer than
|
||||
# the default because we've increased the max heating dots).
|
||||
# n3 = "heating interval" 0-255 -- recovery time between groups of
|
||||
# heating dots on line; possibly a function of power supply.
|
||||
# Units = 10 us. Printer default is 2 (20 us), this code sets it
|
||||
# to 40 (throttled back due to 2A supply).
|
||||
# More heating dots = more peak current, but faster printing speed.
|
||||
# More heating time = darker print, but slower printing speed and
|
||||
# possibly paper 'stiction'. More heating interval = clearer print,
|
||||
# but slower printing speed.
|
||||
self.send_command('\x1B7') # ESC + '7' (print settings)
|
||||
# Send heating dots, heat time, heat interval.
|
||||
self.send_command('\x0B{0}\x28'.format(chr(heat_time)))
|
||||
# Print density description from manual:
|
||||
# DC2 # n Set printing density
|
||||
# D4..D0 of n is used to set the printing density. Density is
|
||||
# 50% + 5% * n(D4-D0) printing density.
|
||||
# D7..D5 of n is used to set the printing break time. Break time
|
||||
# is n(D7-D5)*250us.
|
||||
print_density = 10 # 100% (? can go higher, text is darker but fuzzy)
|
||||
print_break_time = 2 # 500 uS
|
||||
dc2_value = (print_break_time << 5) | print_density
|
||||
self.send_command('\x12#{0}'.format(chr(dc2_value))) # DC2 + '#' + value
|
||||
|
||||
def reset(self):
|
||||
"""Reset the printer."""
|
||||
# Issue a reset command to the printer. (ESC + @)
|
||||
self.send_command('\x1B@')
|
||||
# Reset internal state:
|
||||
self._column = 0
|
||||
self._max_column = 32
|
||||
self._char_height = 24
|
||||
self._line_spacing = 6
|
||||
|
||||
def print(self, text, end='\n'):
|
||||
"""Print a line of text. Optionally specify the end keyword to
|
||||
override the new line printed after the text (set to None to disable
|
||||
the new line entirely).
|
||||
"""
|
||||
self.send_command(text)
|
||||
if end is not None:
|
||||
self.send_command(end)
|
||||
|
||||
def print_barcode(self, text, barcode_type):
|
||||
"""Print a barcode with the specified text/number (the meaning
|
||||
varies based on the type of barcode) and type. Type is a value from
|
||||
the datasheet or class-level variables like UPC_A, etc. for
|
||||
convenience. Note the type value changes depending on the firmware
|
||||
version so use class-level values where possible!
|
||||
"""
|
||||
assert 0 <= barcode_type <= 255
|
||||
assert 0 <= len(text) <= 255
|
||||
self.feed(1) # Recent firmware can't print barcode w/o feed first???
|
||||
self.send_command('\x1DH\x02') # Print label below barcode
|
||||
self.send_command('\x1Dw\x03') # Barcode width 3 (0.375/1.0mm thin/thick)
|
||||
self.send_command('\x1Dk{0}'.format(chr(barcode_type))) # Barcode type
|
||||
# Write length and then string (note this only works with 2.64+).
|
||||
self.send_command(chr(len(text)))
|
||||
self.send_command(text)
|
||||
self._set_timeout((self._barcode_height + 40) * self._dot_print_s)
|
||||
self._column = 0
|
||||
|
||||
def print_bitmap(self, width, height, data):
|
||||
"""Print a bitmap image of the specified width, height and data bytes.
|
||||
Data bytes must be in 1-bit per pixel format, i.e. each byte represents
|
||||
8 pixels of image data along a row of the image. You will want to
|
||||
pre-process your images with a script, you CANNOT send .jpg/.bmp/etc.
|
||||
image formats. See this Processing sketch for preprocessing:
|
||||
https://github.com/adafruit/Adafruit-Thermal-Printer-Library/blob/master/processing/bitmapImageConvert/bitmapImageConvert.pde
|
||||
"""
|
||||
assert len(data) >= ((width * height) // 8)
|
||||
row_bytes = (width + 7) // 8 # Round up to next byte boundary.
|
||||
row_bytes_clipped = min(row_bytes, 48) # 384 pixels max width.
|
||||
chunk_height_limit = 256 // row_bytes_clipped
|
||||
# Clip chunk height within the 1 to max range.
|
||||
chunk_height_limit = max(1, min(self.max_chunk_height, chunk_height_limit))
|
||||
i = 0
|
||||
for row_start in range(0, height, chunk_height_limit):
|
||||
# Issue up to chunkHeightLimit rows at a time.
|
||||
chunk_height = min(height - row_start, chunk_height_limit)
|
||||
self.send_command('\x12*{0}{1}'.format(chr(chunk_height),
|
||||
chr(row_bytes_clipped)))
|
||||
for _ in range(chunk_height):
|
||||
for _ in range(row_bytes_clipped):
|
||||
# Drop down to low level UART access to avoid newline and
|
||||
# other bitmap values being misinterpreted.
|
||||
self._wait_timeout()
|
||||
self._uart.write(chr(data[i]))
|
||||
i += 1
|
||||
i += row_bytes - row_bytes_clipped
|
||||
self._set_timeout(chunk_height * self._dot_print_s)
|
||||
self._column = 0
|
||||
|
||||
def test_page(self):
|
||||
"""Print a test page."""
|
||||
self.send_command('\x12T') # DC2 + 'T' for test page
|
||||
# Delay for 26 lines w/text (ea. 24 dots high) +
|
||||
# 26 text lines (feed 6 dots) + blank line
|
||||
self._set_timeout(self._dot_print_s * 24 * 26 + \
|
||||
self._dot_feed_s * (6 * 26 + 30))
|
||||
|
||||
def set_defaults(self):
|
||||
"""Set default printing and text options. This is useful to reset back
|
||||
to a good state after printing different size, weight, etc. text.
|
||||
"""
|
||||
self.online()
|
||||
self.justify_left()
|
||||
self.set_size_small()
|
||||
self.underline_off()
|
||||
self.inverse = False
|
||||
self.upside_down = False
|
||||
self.double_height = False
|
||||
self.double_width = False
|
||||
self.strike = False
|
||||
self.bold = False
|
||||
self.set_line_height(30)
|
||||
self.set_barcode_height(50)
|
||||
self.set_charset()
|
||||
self.set_code_page()
|
||||
|
||||
def justify_left(self):
|
||||
"""Set left justification of text."""
|
||||
self.send_command('\x1Ba\x00') # ESC + 'a' + 0
|
||||
|
||||
def justify_center(self):
|
||||
"""Set center justification of text."""
|
||||
self.send_command('\x1Ba\x01') # ESC + 'a' + 1
|
||||
|
||||
def justify_right(self):
|
||||
"""Set right justification of text."""
|
||||
self.send_command('\x1Ba\x02') # ESC + 'a' + 2
|
||||
|
||||
def set_size_small(self):
|
||||
"""Set small text size."""
|
||||
self._char_height = 24
|
||||
self._max_column = 32
|
||||
self.send_command('\x1D!\x00') # ASCII GS + '!' + 0x00
|
||||
self._column = 0
|
||||
|
||||
def set_size_medium(self):
|
||||
"""Set medium (double height) text size."""
|
||||
self._char_height = 48
|
||||
self._max_column = 32
|
||||
self.send_command('\x1D!\x01') # ASCII GS + '!' + 0x01
|
||||
self._column = 0
|
||||
|
||||
def set_size_large(self):
|
||||
"""Set large (double height & width) text size."""
|
||||
self._char_height = 48
|
||||
self._max_column = 16
|
||||
self.send_command('\x1D!\x11') # ASCII GS + '!' + 0x11
|
||||
self._column = 0
|
||||
|
||||
def underline_off(self):
|
||||
"""Turn off underline printing."""
|
||||
self.send_command('\x1B-\x00') # ESC + '-' + 0
|
||||
|
||||
def underline_thin(self):
|
||||
"""Turn on normal/thin underline printing."""
|
||||
self.send_command('\x1B-\x01') # ESC + '-' + 1
|
||||
|
||||
def underline_thick(self):
|
||||
"""Turn on thick underline printing."""
|
||||
self.send_command('\x1B-\x02') # ESC + '-' + 2
|
||||
|
||||
def _set_inverse(self, inverse):
|
||||
# Set the inverse printing state to enabled disabled with the specified
|
||||
# boolean value. This requires printer firmare 2.68+
|
||||
if inverse:
|
||||
self.send_command('\x1DB\x01') # ESC + 'B' + 1
|
||||
else:
|
||||
self.send_command('\x1DB\x00') # ESC + 'B' + 0
|
||||
|
||||
# pylint: disable=line-too-long
|
||||
# Write-only property, can't assume we can read inverse state from the
|
||||
# printer since there is no command for it and hooking up RX is discouraged
|
||||
# (5V will damage many boards).
|
||||
inverse = property(None, _set_inverse, None, "Set the inverse printing mode boolean to enable or disable inverse printing.")
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
upside_down = _PrintModeBit(_UPDOWN_MASK)
|
||||
|
||||
double_height = _PrintModeBit(_DOUBLE_HEIGHT_MASK)
|
||||
|
||||
double_width = _PrintModeBit(_DOUBLE_WIDTH_MASK)
|
||||
|
||||
strike = _PrintModeBit(_STRIKE_MASK)
|
||||
|
||||
bold = _PrintModeBit(_BOLD_MASK)
|
||||
|
||||
def feed(self, lines):
|
||||
"""Advance paper by specified number of blank lines."""
|
||||
assert 0 <= lines <= 255
|
||||
self.send_command('\x1Bd{0}'.format(chr(lines)))
|
||||
self._set_timeout(self._dot_feed_s * self._char_height)
|
||||
self._column = 0
|
||||
|
||||
def feed_rows(self, rows):
|
||||
"""Advance paper by specified number of pixel rows."""
|
||||
assert 0 <= rows <= 255
|
||||
self.send_command('\x1BJ{0}'.format(chr(rows)))
|
||||
self._set_timeout(rows * self._dot_feed_s)
|
||||
self._column = 0
|
||||
|
||||
def flush(self):
|
||||
"""Flush data pending in the printer."""
|
||||
self.send_command('\f')
|
||||
|
||||
def offline(self):
|
||||
"""Put the printer into an offline state. No other commands can be
|
||||
sent until an online call is made.
|
||||
"""
|
||||
self.send_command('\x1B=\x00') # ESC + '=' + 0
|
||||
|
||||
def online(self):
|
||||
"""Put the printer into an online state after previously put offline.
|
||||
"""
|
||||
self.send_command('\x1B=\x01') # ESC + '=' + 1
|
||||
|
||||
def sleep_after(self, seconds):
|
||||
"""Put the printer into sleep mode after the specified number of
|
||||
seconds (0-65535). Must call wake to wake up and send commands
|
||||
afterwards!
|
||||
"""
|
||||
assert 0 <= seconds <= 65535
|
||||
low_byte = seconds & 0xFF
|
||||
high_byte = (seconds >> 8) & 0xFF
|
||||
self.send_command('\x1B8{0}{1}'.format(chr(low_byte), chr(high_byte)))
|
||||
|
||||
def wake(self):
|
||||
"""Wake the thermal printer into an online state ready to receive
|
||||
commands.
|
||||
"""
|
||||
self.send_command('\xFF') # Wake command.
|
||||
time.sleep(0.050)
|
||||
self.send_command('\x1B8\x00\x00') # Sleep off
|
||||
|
||||
def has_paper(self):
|
||||
"""Return a boolean indicating if the printer has paper. You MUST have
|
||||
the serial RX line hooked up for this to work. NOTE: be VERY CAREFUL
|
||||
to ensure your board can handle a 5V serial input before hooking up
|
||||
the RX line!
|
||||
"""
|
||||
# This only works with firmware 2.64+:
|
||||
self.send_command('\x1Bv\x00') # ESC + 'v' + 0
|
||||
status = self._uart.read(1)
|
||||
if status is None:
|
||||
return False
|
||||
return not status[0] & 0b00000100
|
||||
|
||||
def set_line_height(self, height):
|
||||
"""Set the line height in pixels. This is the total amount of space
|
||||
between lines, including the height of text. The smallest value is 24
|
||||
and the largest is 255.
|
||||
"""
|
||||
assert 24 <= height <= 255
|
||||
self._line_spacing = height - 24
|
||||
self.send_command('\x1B3{0}'.format(chr(height))) # ESC + '3' + height
|
||||
|
||||
def set_barcode_height(self, height):
|
||||
"""Set the barcode height in pixels. Must be a value 1 - 255."""
|
||||
assert 1 <= height <= 255
|
||||
self._barcode_height = height
|
||||
self.send_command('\x1Dh{0}'.format(chr(height))) # ASCII GS + 'h' + height
|
||||
|
||||
def set_charset(self, charset=0):
|
||||
"""Alters the character set for ASCII characters 0x23-0x7E. See
|
||||
datasheet for details on character set values (0-15). Note this is only
|
||||
supported on more recent firmware printers!
|
||||
"""
|
||||
assert 0 <= charset <= 15
|
||||
self.send_command('\x1BR{0}'.format(chr(charset))) # ESC + 'R' + charset
|
||||
|
||||
def set_code_page(self, code_page=0):
|
||||
"""Select alternate code page for upper ASCII symbols 0x80-0xFF. See
|
||||
datasheet for code page values (0 - 47). Note this is only supported
|
||||
on more recent firmware printers!
|
||||
"""
|
||||
assert 0 <= code_page <= 47
|
||||
self.send_command('\x1Bt{0}'.format(chr(code_page))) # ESC + 't' + code page
|
||||
|
||||
def set_char_spacing(self, spacing=0):
|
||||
"""Set the character spacing (in pixels). Note this is only supported
|
||||
on more recent firmware printers!"""
|
||||
assert 0 <= spacing <= 255
|
||||
self.send_command('\x1B {0}'.format(chr(spacing))) # ESC + ' ' + spacing
|
||||
|
||||
def tab(self):
|
||||
"""Print a tab (i.e. move to next 4 character block). Note this is
|
||||
only supported on more recent firmware printers!"""
|
||||
self.send_command('\t')
|
||||
# Increment to the next position that's every 4 spaces.
|
||||
# I.e. increment by 4 and go to the floor/first position of the block.
|
||||
self._column = (self._column + 4) & 0b11111100
|
||||
89
adafruit_thermal_printer/thermal_printer_264.py
Normal file
89
adafruit_thermal_printer/thermal_printer_264.py
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2017 Tony DiCola
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`adafruit_thermal_printer_264`
|
||||
====================================================
|
||||
|
||||
Thermal printer control module built to work with small serial thermal
|
||||
receipt printers. Note that these printers have many different firmware
|
||||
versions and care must be taken to select the appropriate module inside this
|
||||
package for your firmware printer:
|
||||
- thermal_printer = The latest printers with firmware version 2.68+
|
||||
- thermal_printer_264 = Printers with firmware version 2.64 up to 2.68.
|
||||
- thermal_printer_legacy = Printers with firmware version before 2.64.
|
||||
|
||||
* Author(s): Tony DiCola
|
||||
"""
|
||||
from micropython import const
|
||||
|
||||
import adafruit_thermal_printer.thermal_printer as thermal_printer
|
||||
|
||||
|
||||
# pylint: disable=bad-whitespace
|
||||
# Internally used constants.
|
||||
_INVERSE_MASK = const(1 << 1) # Not in 2.6.8 firmware
|
||||
# pylint: enable=bad-whitespace
|
||||
|
||||
|
||||
# Legacy behavior class for printers with firmware 2.64 up to 2.68.
|
||||
# See the comments in thermal_printer.py to understand how this class overrides
|
||||
# methods which change for older firmware printers!
|
||||
class ThermalPrinter(thermal_printer.ThermalPrinter):
|
||||
"""Thermal printer for printers with firmware version 2.64 up to (but
|
||||
NOT including) 2.68.
|
||||
"""
|
||||
|
||||
# pylint: disable=bad-whitespace
|
||||
# Barcode types. These vary based on the firmware version so are made
|
||||
# as class-level variables that users can reference (i.e.
|
||||
# ThermalPrinter.UPC_A, etc) and write code that is independent of the
|
||||
# printer firmware version.
|
||||
UPC_A = 65
|
||||
UPC_E = 66
|
||||
EAN13 = 67
|
||||
EAN8 = 68
|
||||
CODE39 = 69
|
||||
ITF = 70
|
||||
CODABAR = 71
|
||||
CODE93 = 72
|
||||
CODE128 = 73
|
||||
# pylint: enable=bad-whitespace
|
||||
|
||||
|
||||
def __init__(self, uart, byte_delay_s=0.00057346, dot_feed_s=0.0021,
|
||||
dot_print_s=0.03):
|
||||
"""Thermal printer class. Requires a serial UART connection with at
|
||||
least the TX pin connected. Take care connecting RX as the printer
|
||||
will output a 5V signal which can damage boards! If RX is unconnected
|
||||
the only loss in functionality is the has_paper function, all other
|
||||
printer functions will continue to work. The byte_delay_s, dot_feed_s,
|
||||
and dot_print_s values are delays which are used to prevent overloading
|
||||
the printer with data. Use the default delays unless you fully
|
||||
understand the workings of the printer and how delays, baud rate,
|
||||
number of dots, heat time, etc. relate to each other.
|
||||
"""
|
||||
super().__init__(uart, byte_delay_s=byte_delay_s, dot_feed_s=dot_feed_s,
|
||||
dot_print_s=dot_print_s)
|
||||
|
||||
# Inverse on older printers (pre 2.68) uses a print mode bit instead of
|
||||
# specific commands.
|
||||
inverse = thermal_printer.ThermalPrinter._PrintModeBit(_INVERSE_MASK)
|
||||
161
adafruit_thermal_printer/thermal_printer_legacy.py
Normal file
161
adafruit_thermal_printer/thermal_printer_legacy.py
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2017 Tony DiCola
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`adafruit_thermal_printer_legacy`
|
||||
====================================================
|
||||
|
||||
Thermal printer control module built to work with small serial thermal
|
||||
receipt printers. Note that these printers have many different firmware
|
||||
versions and care must be taken to select the appropriate module inside this
|
||||
package for your firmware printer:
|
||||
- thermal_printer = The latest printers with firmware version 2.68+
|
||||
- thermal_printer_264 = Printers with firmware version 2.64 up to 2.68.
|
||||
- thermal_printer_legacy = Printers with firmware version before 2.64.
|
||||
|
||||
* Author(s): Tony DiCola
|
||||
"""
|
||||
from micropython import const
|
||||
|
||||
import adafruit_thermal_printer.thermal_printer as thermal_printer
|
||||
|
||||
|
||||
# pylint: disable=bad-whitespace
|
||||
# Internally used constants.
|
||||
_INVERSE_MASK = const(1 << 1) # Not in 2.6.8 firmware
|
||||
# pylint: enable=bad-whitespace
|
||||
|
||||
|
||||
# Legacy behavior class for printers with firmware before 2.64.
|
||||
# See the comments in thermal_printer.py to understand how this class overrides
|
||||
# methods which change for older firmware printers!
|
||||
class ThermalPrinter(thermal_printer.ThermalPrinter):
|
||||
"""Thermal printer for printers with firmware version before 2.64."""
|
||||
|
||||
# pylint: disable=bad-whitespace
|
||||
# Barcode types. These vary based on the firmware version so are made
|
||||
# as class-level variables that users can reference (i.e.
|
||||
# ThermalPrinter.UPC_A, etc) and write code that is independent of the
|
||||
# printer firmware version.
|
||||
UPC_A = 0
|
||||
UPC_E = 1
|
||||
EAN13 = 2
|
||||
EAN8 = 3
|
||||
CODE39 = 4
|
||||
I25 = 5
|
||||
CODEBAR = 6
|
||||
CODE93 = 7
|
||||
CODE128 = 8
|
||||
CODE11 = 9
|
||||
MSI = 10
|
||||
# pylint: enable=bad-whitespace
|
||||
|
||||
def __init__(self, uart, byte_delay_s=0.00057346, dot_feed_s=0.0021,
|
||||
dot_print_s=0.03):
|
||||
"""Thermal printer class. Requires a serial UART connection with at
|
||||
least the TX pin connected. Take care connecting RX as the printer
|
||||
will output a 5V signal which can damage boards! If RX is unconnected
|
||||
the only loss in functionality is the has_paper function, all other
|
||||
printer functions will continue to work. The byte_delay_s, dot_feed_s,
|
||||
and dot_print_s values are delays which are used to prevent overloading
|
||||
the printer with data. Use the default delays unless you fully
|
||||
understand the workings of the printer and how delays, baud rate,
|
||||
number of dots, heat time, etc. relate to each other.
|
||||
"""
|
||||
super().__init__(uart, byte_delay_s=byte_delay_s, dot_feed_s=dot_feed_s,
|
||||
dot_print_s=dot_print_s)
|
||||
|
||||
|
||||
def print_barcode(self, text, barcode_type):
|
||||
"""Print a barcode with the specified text/number (the meaning
|
||||
varies based on the type of barcode) and type. Type is a value from
|
||||
the datasheet or class-level variables like UPC_A, etc. for
|
||||
convenience. Note the type value changes depending on the firmware
|
||||
version so use class-level values where possible!
|
||||
"""
|
||||
assert 0 <= barcode_type <= 255
|
||||
assert 0 <= len(text) <= 255
|
||||
self.feed(1) # Recent firmware can't print barcode w/o feed first???
|
||||
self.send_command('\x1DH\x02') # Print label below barcode
|
||||
self.send_command('\x1Dw\x03') # Barcode width 3 (0.375/1.0mm thin/thick)
|
||||
self.send_command('\x1Dk{0}'.format(chr(barcode_type))) # Barcode type
|
||||
# Pre-2.64 firmware prints the text and then a null character to end.
|
||||
# Instead of the length of text as a prefix.
|
||||
self.send_command(text)
|
||||
self.send_command('\x00')
|
||||
self._set_timeout((self._barcode_height + 40) * self._dot_print_s)
|
||||
self._column = 0
|
||||
|
||||
def wake(self):
|
||||
"""Wake the thermal printer into an online state ready to receive
|
||||
commands.
|
||||
"""
|
||||
self.send_command('\xFF') # Wake command.
|
||||
# Datasheet recommends a 50 mS delay before issuing further commands,
|
||||
# but in practice this alone isn't sufficient (e.g. text size/style
|
||||
# commands may still be misinterpreted on wake). A slightly longer
|
||||
# delay, interspersed with NUL chars (no-ops) seems to help.
|
||||
for _ in range(10):
|
||||
self.send_command('\x00')
|
||||
self._set_timeout(0.01)
|
||||
|
||||
def sleep_after(self, seconds):
|
||||
"""Put the printer into sleep mode after the specified number of
|
||||
seconds (0-255). Must call wake to wake up and send commands
|
||||
afterwards!
|
||||
"""
|
||||
# Firmware before 2.64 uses an 8-bit number of seconds instead of 16-bit.
|
||||
assert 0 <= seconds <= 255
|
||||
self.send_command('\x1B8{0}'.format(chr(seconds)))
|
||||
|
||||
def reset(self):
|
||||
"""Reset the printer."""
|
||||
# Issue a reset command to the printer. (ESC + @)
|
||||
self.send_command('\x1B@')
|
||||
# Reset internal state:
|
||||
self._column = 0
|
||||
self._max_column = 32
|
||||
self._char_height = 24
|
||||
self._line_spacing = 6
|
||||
# Skip tab configuration on older printers.
|
||||
|
||||
def feed(self, lines):
|
||||
"""Advance paper by specified number of blank lines."""
|
||||
# Just send line feeds for older printers.
|
||||
for _ in range(lines):
|
||||
self._write_char('\n')
|
||||
|
||||
def has_paper(self):
|
||||
"""Return a boolean indicating if the printer has paper. You MUST have
|
||||
the serial RX line hooked up for this to work. NOTE: be VERY CAREFUL
|
||||
to ensure your board can handle a 5V serial input before hooking up
|
||||
the RX line!
|
||||
"""
|
||||
# The paper check command is different for older firmware:
|
||||
self.send_command('\x1Br\x00') # ESC + 'r' + 0
|
||||
status = self._uart.read(1)
|
||||
if status is None:
|
||||
return False
|
||||
return not status[0] & 0b00000100
|
||||
|
||||
# Inverse on older printers (pre 2.68) uses a print mode bit instead of
|
||||
# specific commands.
|
||||
inverse = thermal_printer.ThermalPrinter._PrintModeBit(_INVERSE_MASK)
|
||||
5
api.rst
Normal file
5
api.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
.. If you created a package, create one automodule per module in the package.
|
||||
|
||||
.. automodule:: adafruit_thermal_printer
|
||||
:members:
|
||||
147
conf.py
Normal file
147
conf.py
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
|
||||
# Uncomment the below if you use native CircuitPython modules such as
|
||||
# digitalio, micropython and busio. List the modules you use. Without it, the
|
||||
# autodoc module docs will fail to generate with a warning.
|
||||
# autodoc_mock_imports = ["digitalio", "busio"]
|
||||
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)}
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'README'
|
||||
|
||||
# General information about the project.
|
||||
project = u'adafruit_thermal_printer Library'
|
||||
copyright = u'2017 Tony DiCola'
|
||||
author = u'Tony DiCola'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = u'1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'1.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#
|
||||
default_role = "any"
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#
|
||||
add_function_parentheses = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
try:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
||||
except:
|
||||
html_theme = 'default'
|
||||
html_theme_path = ['.']
|
||||
else:
|
||||
html_theme_path = ['.']
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Adafruit_thermal_printerLibrarydoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'adafruit_thermal_printerLibrary.tex', u'adafruit_thermal_printer Library Documentation',
|
||||
author, 'manual'),
|
||||
]
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'adafruit_thermal_printerlibrary', u'adafruit_thermal_printer Library Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'adafruit_thermal_printerLibrary', u' adafruit_thermal_printer Library Documentation',
|
||||
author, 'adafruit_thermal_printerLibrary', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
48
examples/simpletest.py
Normal file
48
examples/simpletest.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Simple demo of printer functionality.
|
||||
# Author: Tony DiCola
|
||||
import board
|
||||
import busio
|
||||
|
||||
# Pick which version thermal printer to import. Only ONE of these lines should
|
||||
# be uncommented depending on the version of your printer. Hold the button on
|
||||
# the printer as it's powered on and it will print a test page that displays
|
||||
# the firmware version, like 2.64, 2.68, etc.
|
||||
# Use this line for printers with version 2.68 or higher:
|
||||
import adafruit_thermal_printer.thermal_printer as thermal_printer
|
||||
# Use this line for printers with version 2.64 up to (but not including) 2.68:
|
||||
#import adafruit_thermal_printer.thermal_printer_264 as thermal_printer
|
||||
# Use this line for printers with version up to (but not including) 2.64:
|
||||
#import adafruit_thermal_printer.thermal_printer_legacy as thermal_printer
|
||||
|
||||
# Define RX and TX pins for the board's serial port connected to the printer.
|
||||
# Only the TX pin needs to be configued, and note to take care NOT to connect
|
||||
# the RX pin if your board doesn't support 5V inputs. If RX is left unconnected
|
||||
# the only loss in functionality is checking if the printer has paper--all other
|
||||
# functions of the printer will work.
|
||||
RX = board.RX
|
||||
TX = board.TX
|
||||
|
||||
# Create a serial connection for the printer. You must use the same baud rate
|
||||
# as your printer is configured (print a test page by holding the button
|
||||
# during power-up and it will show the baud rate). Most printers use 119200.
|
||||
uart = busio.UART(TX, RX, baudrate=119200)
|
||||
|
||||
# Create the printer instance.
|
||||
printer = thermal_printer.ThermalPrinter(uart)
|
||||
|
||||
# Initialize the printer. Note this will take a few seconds for the printer
|
||||
# to warm up and be ready to accept commands (hence calling it explicitly vs.
|
||||
# automatically in the initializer above).
|
||||
printer.begin()
|
||||
|
||||
# Print a test page:
|
||||
printer.test_page()
|
||||
|
||||
# Move the paper forward two lines:
|
||||
printer.feed(2)
|
||||
|
||||
# Print a line of text:
|
||||
printer.print('Hello world!')
|
||||
|
||||
# Move the paper forward two lines:
|
||||
printer.feed(2)
|
||||
3
readthedocs.yml
Normal file
3
readthedocs.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
python:
|
||||
version: 3
|
||||
requirements_file: requirements.txt
|
||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
Loading…
Reference in a new issue