Skip to content

Commit

Permalink
Explain Windows 0 devices issue #11 to the user. Do not crash on 0 de…
Browse files Browse the repository at this point in the history
…vices. Improve import errors. Add a test-detection script.
  • Loading branch information
Poikilos committed Feb 9, 2023
1 parent 15ac219 commit 4ebbd87
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
7 changes: 4 additions & 3 deletions pypicolcd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
import usb
except ImportError:
# NOTE: ModuleNotFoundError is only available in Python 3.
raise ImportError("pypicolcd requires pyusb (see"
" \"Install\" in README.md)")
raise ImportError(
'pypicolcd requires pyusb (see "Install" in readme.md)'
)

# TODO: remove about_msg and use pypicolcd.__doc__ (generated from
# docstring above) instead?
Expand Down Expand Up @@ -407,7 +408,7 @@ def blab(self, msg, where=None):
curframe = inspect.currentframe()
calframe = inspect.getouterframes(curframe, 2)
w_msg = " in " + calframe[1][3]
print("[ pypicolcd ] (verbose message" + w_msg + ") " + msg)
print("[ pypicolcd ] (verbose message {}) {}".format(w_msg, msg))

def get_width(self):
return self.dc["width"]
Expand Down
37 changes: 37 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# pypicolcd
<https://github.com/poikilos/pypicolcd>

If you are using Windows, special steps are necessary. See [Windows](#Windows).

Draw to picoLCD 256x64 and 20x4 using only pyusb (no driver required!) by importing the PicoLCD class.
![kitten](https://github.com/poikilos/pypicolcd/raw/master/screenshot.jpg)


## Main Features
* Easy: see <https://github.com/poikilos/pypicolcd/blob/master/example.py>
* Draw without driver
Expand All @@ -22,12 +24,14 @@ lcd-fb --localhost=`hostname -i`
```
where `\`hostname -i\`` is your IP address.


## Compare
- This module does not require a (non-Python kernel) driver unlike pyusblcd in the PyPI repository.
- This module has a persistent framebuffer server unlike other driverless modules named similarly such as [JamesTheAwesomeDude/pyPicoLCD](https://github.com/JamesTheAwesomeDude/pyPicoLCD) and [itszero/picoLCD256x64](https://github.com/itszero/picoLCD256x64).
- This module uses pyusb for driverless access and implements a lcd-cli command similarly to how [rebeccaskinner/lcddeamon](https://github.com/rebeccaskinner/lcddeamon) uses libusb for driverless access and implements a usblcd command, but that daemon is written in c.
- lcd4linux is a tool that only writes data using shell expressions in lcd4linux.conf, yet has some features such as bold text and progress bars (which are usually used as meters).


## Install
- Uninstall lcd4linux if present: pypicolcd is not designed to work while lcd4linux is installed.
- pypicolcd uses Python 3, and though has some Python 2 considerations, is not thoroughly tested on Python 2. Therefore, make sure virtualenv is Python 3 by default, otherwise follow a guide to use the Python 3 virtualenv (such as [Installing and using virtualenv with Python 3](https://help.dreamhost.com/hc/en-us/articles/115000695551-Installing-and-using-virtualenv-with-Python-3)).
Expand Down Expand Up @@ -90,6 +94,36 @@ deactivate
- You still must activate the venv, such as by running `source ~/lcd/bin/activate`, then do
`pip install --upgrade ~/git/pypicolcd && rm -rf ~/lcd/lib/python3.7/site-packages/pypicolcd/__pycache__/ && sudo systemctl daemon-reload && sudo systemctl restart lcd-fb`

### Windows

If 0 devices are listed, that is unfortunately expected on Windows
(It is not fixable without a driver installer that adds an INF
file to your system, and that will probably not happen unless someone
contributes such an INF file--See
[issue #11](https://github.com/Poikilos/pypicolcd/issues/11)). The
following manual steps are necessary.

> See [Turbo J's answer](https://stackoverflow.com/a/5767737/1619432).
> To install the USB driver `libusb` for your device I found two options:
> - Use [libusb-win32](http://www.libusb.org/wiki/libusb-win32)'s
> `inf-wizard.exe` to create the INF file and then use
> `install-filter-win.exe` to install libusb as driver for your device.
> - Use [zadig](http://zadig.akeo.ie/) (simpler)
> - if no device is shown, Options > List All Devices
> - select `libusb-win32` as driver to be installed
-[answered Oct 3, 2016 at 13:52](https://stackoverflow.com/a/39833322) by handle

Workaround:

> Libusb requires you to install a special driver for every device you
> want to use it with. That usually requires you to write an .inf file
> containing the USB IDs of the device. Only if the driver and inf file
> are installed libusb will be able to "see" your device.
-[answered Apr 23, 2011 at 23:52](https://stackoverflow.com/a/5767737) by Turbo J


## Usage
* Draw Image:
* pos is an x,y tuple
Expand All @@ -109,10 +143,12 @@ deactivate
- Otherwise, you should send the `refresh` command (such as
`lcd-cli --refresh`) to redraw the offscreen buffer.


## Known Issues
- [ ] If possible, read the state of buttons on the unit (also via pyusb).
- [ ] Add an option to disconnect from the device so it can be used by other processes.


## Troubleshooting
- Detecting resets (normally from the device being disconnected) is
only possible if you try to write while the device is disconnected.
Expand All @@ -121,6 +157,7 @@ deactivate
pixels involved in the command will not change if they would match the
existing framebuffer--this is the expected behavior).


## Authors
* resources from external sources:
* Ninepin font: by Digital Graphics Labs on <http://www.1001fonts.com/ninepin-font.html> LICENSE is "fonts/1001Fonts General Font Usage Terms.txt" except with the following specifics stated by author: Free for personal use, Free for commercial use, Modification NOT allowed, Redistribution allowed, freeware license in "fonts/ninepin/!license.txt"
Expand Down
22 changes: 22 additions & 0 deletions test-detection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
'''
If 0 devices are listed and you are using Windows, see Windows section
of readme.
'''
# <https://www.orangecoat.com/how-to/use-pyusb-to-find-vendor-and-product-
# ids-for-usb-devices>


import sys
import usb.core
# find USB devices
dev = usb.core.find(find_all=True)
# loop through devices, printing vendor and product ids in decimal and hex
count = 0
for cfg in dev:
count += 1
sys.stdout.write('Decimal VendorID=' + str(cfg.idVendor) + ' & ProductID=' + str(cfg.idProduct) + '\n')
sys.stdout.write('Hexadecimal VendorID=' + hex(cfg.idVendor) + ' & ProductID=' + hex(cfg.idProduct) + '\n\n')
print("Found {}".format(count))
if count == 0:
print(__doc__)
8 changes: 7 additions & 1 deletion testing.pyw
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
import time
import binascii
import platform
try:
from pypicolcd import PicoLCD
try:
Expand Down Expand Up @@ -60,6 +61,7 @@ except ImportError: # Python 2
import os
my_path = os.path.abspath(os.path.dirname(__file__))


def local_resource(path):
ret = None
if os.path.isfile(os.path.join(my_path, path)):
Expand Down Expand Up @@ -213,7 +215,11 @@ else:
error = p.error
if error is None:
error = "Unknown error"
error_text = tk.Text(root) # , text=error, justify=tk.LEFT)
else:
if platform.system() == "Windows":
error += (" If there are 0 devices on Windows,"
" see Windows section in readme.")
error_text = tk.Text(root) # , text=error, justify=tk.LEFT)
error_text.pack()
error_text.insert(tk.INSERT, error)

Expand Down

0 comments on commit 4ebbd87

Please sign in to comment.