Skip to content

Commit

Permalink
Improved exception and error handling in LibUsbScope, doc update
Browse files Browse the repository at this point in the history
Signed-off-by: Martin <[email protected]>
  • Loading branch information
Ho-Ro committed Mar 8, 2022
1 parent 4cb4edb commit dc05698
Show file tree
Hide file tree
Showing 26 changed files with 189 additions and 81 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
2022-03-01: new sample rates 32k, 640k, doc update, tools update [4cb4edb]
2022-02-28: upversion to FW0210, new sample rate 128 kS/s (ID: 113) [f4755d2]
2022-02-08: more tool programs in examples [6c9d2d7]
2022-02-05: Merge branch 'main' of github.com:Ho-Ro/Hantek6022API fix last commit [078dffd]
Expand Down
17 changes: 13 additions & 4 deletions PyHT6022/LibUsbScope.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__author__ = 'Robert Cope', 'Jochen Hoenicke'

import os
import sys
import time
import usb1
import array
Expand Down Expand Up @@ -221,7 +222,11 @@ def open_handle(self):
self.device_handle = self.device.open()
if os.name == 'posix' and self.device_handle.kernelDriverActive(0):
self.device_handle.detachKernelDriver(0)
self.device_handle.claimInterface(0)
try:
self.device_handle.claimInterface(0)
except Exception as e:
print( e, file=sys.stderr )
return False
if self.is_device_firmware_present:
self.set_num_channels(2)
self.set_interface(0)
Expand All @@ -236,9 +241,13 @@ def close_handle(self, release_interface=True):
"""
if not self.device_handle:
return True
if release_interface:
self.device_handle.releaseInterface(0)
self.device_handle.close()
try:
if release_interface:
self.device_handle.releaseInterface(0)
self.device_handle.close()
except Exception as e:
print( e, file=sys.stderr )
return False
self.device_handle = None
return True

Expand Down
117 changes: 88 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

This repo is based on the excellent work of [Robert](https://github.com/rpcope1/Hantek6022API)
and [Jochen](https://github.com/jhoenicke/Hantek6022API)
and focusses mainly on Hantek6022BE/BL under Linux (development system: debian buster).
and focusses mainly on Hantek6022BE/BL under Linux (development system: Debian stable).

## Hantek 6022 Firmware

Expand All @@ -18,42 +18,61 @@ and focusses mainly on Hantek6022BE/BL under Linux (development system: debian b

<img alt="Scope Visualisation Example" width="100%" src="plot_from_capture.png">

This is a API for Python for the
ultra-cheap, reasonably usable (and hackable) 6022 DSO, with a libusb implementation via libusb1 for Linux.
This is a API for Python for the ultra-cheap, reasonably usable (and hackable) 6022 DSO,
with a libusb implementation via libusb1 for Linux.

The scope can be accessed by instantiating an oscilloscope object with the correct scopeid (always 0 for one scope
attached). Things like voltage divisions and sampling rates can be set by the appropriate methods.
Please check the provided example programs, the comments will give you more hints for own experiments.
Each method has some documentation as to what it does currently though, and hopefully
variable names are clear enough to give you some idea what they are for.
The scope can be accessed by instantiating an oscilloscope object.
Things like voltage divisions and sampling rates can be set by the appropriate methods.
Please check the provided [example programs](https://github.com/Ho-Ro/Hantek6022API/tree/main/examples),
the comments will give you more hints for own experiments.
Each method has documentation about what it is doing, and hopefully the variable names are clear enough
to give you an idea of what they are for.

## Developed under Linux
## Linux Install

If you're on Linux, you're in luck. Provided are bindings for libusb to operate this
little device. You may wish to first add 60-hantek-6022-usb.rules to your udev rules, via
If you're on Linux, you're in luck.
Provided are bindings for libusb to operate this little device with simple python commands.
If you are a user, you can simply download the latest Debian package from
[releases](https://github.com/Ho-Ro/Hantek6022API/releases) and use the utilities in
[examples](https://github.com/Ho-Ro/Hantek6022API/tree/main/examples),
all tools named `*_6022.py` are copied to `/usr/bin` and are thus globally available.

## Developer Info

If you are a developer, you will definitely clone the repo and work with it more intensively. So please read on...

You may wish to first add `60-hantek-6022-usb.rules` (living in [udev](https://github.com/Ho-Ro/Hantek6022API/tree/main/udev))
to your udev rules, via

sudo cp 60-hantek-6022-usb.rules /etc/udev/rules.d/

After you've done this, the scope should automatically come up with the correct permissions to be accessed
without being root user.

The following instructions are tested with Debian (*stretch* and *buster*)
and are executed also automatically under Ubuntu (*2004*) - have a look
The following instructions are tested with Debian stable versions *stretch*, *buster* and *bullseye*
and are executed also automatically by GitHub under Ubuntu (*2004*) after each push to this repo - have a look
at the [GitHub Action](https://github.com/Ho-Ro/Hantek6022API/actions/workflows/build_check.yml).
On each successful run a debian package is available under *Artifacts*.
On each successful run a Debian package is available under *Artifacts*.

### Build Preparations

To compile the custom firmware you have to install (as root) the *small devices c compiler* `sdcc` and the tool `pkgconf`:

sudo apt install sdcc pkgconf

### Submodule fx2lib
Hantek6022API uses the submodule [fx2lib](https://github.com/Ho-Ro/fx2lib) that I cloned from the [original fx2lib](https://github.com/djmuhlestein/fx2lib) to do minor maintenance updates.
Take care when the SDCC version gets updated. the step from 3.9 to 4.0 introduced a nasty regression due to [less optimal code](https://github.com/Ho-Ro/Hantek6022API/blob/4cb4edbf1e6d2d5df21dbb4dabb8f51c932a0348/PyHT6022/Firmware/DSO6022BE/scope6022.inc#L80)
from the newer version.

Hantek6022API uses the submodule [fx2lib](https://github.com/Ho-Ro/fx2lib) that I cloned from the
[original fx2lib](https://github.com/djmuhlestein/fx2lib) to do minor maintenance updates.

Pull the submodule in:
Pull the submodule in (once):

git submodule init
git submodule update --remote

### Linux Build

To build the custom firmware run `make` in the top level directory:

make
Expand All @@ -79,10 +98,44 @@ The installed programs can also be uninstalled cleanly with

sudo dpkg -P hantek6022api

With the device plugged in, run `upload_firmware_6022.py` once to bootstrap the scope for use.

You can then look at the scope traces via `capture_6022.py -t 0.01 | plot_from_capture_6022.py`,
or write your own programs - look at the programs in `examples` as a start.

If you want to make low-level experiments with the python commands you should bootstrap the scope for use:
With the device plugged in, run `upload_6022_firmware.py` once.
The *user tools* `*_6022.py` do this automatically at start.

**Don't Panik!**
The firmware is uploaded into RAM and is lost after switching off the scope or disconnecting
the USB, so the device can never be *bricked*.

This simple program sets the calibration output frequency to 400 Hz
(you can use each even divison of 2 MHz between 32 Hz and 100 kHz).

```python
#!/usr/bin/python3

# get the python package
from PyHT6022.LibUsbScope import Oscilloscope

# create an Osclloscope object
scope = Oscilloscope()

# setup the scope
scope.setup()

# attach to the scope
scope.open_handle()

# upload firmware unless already uploaded
if (not scope.is_device_firmware_present):
scope.flash_firmware()

# and now set the calibration frequency output to 400 Hz
scope.set_calibration_frequency( 400 )
```

## It even works under Windows

[@justlep](https://github.com/justlep) wrote:
Expand Down Expand Up @@ -150,10 +203,14 @@ Configure with command line arguments:
-e, --eeprom store calibration values in eeprom
-g, --measure_gain interactively measure gain (as well as offset)

### Fast Offset Calibration

Apply 0 V to both inputs (e.g. connect both probes to the GND calibration connector) and execute:

calibrate_6022.py -e

### Complete Offset and Gain Calibration

If is also possible to measure and create also gain calibration.
To calibrate gain you have to apply a well known voltage (setpoint)
and compare it with the actual value that is read by the scope:
Expand All @@ -172,24 +229,26 @@ the program measures and compares them against the expected gain settings:
6. The program option `-e` stores the calibration values in eeprom
7. The program option `-c` creates a config file `modelDSO6022.conf`

This config file can be copied into directory `~/.config/OpenHantek`.
This (optional) config file can be copied into directory `~/.config/OpenHantek`.
On every startup OpenHantek reads this file and applies the calibratipon accordingly.
The config file has higher priority than the eeprom content.
It has also the advantage not to mess with the eeprom.

The calibration voltages do not have to correspond absolutely to the given value,
but the applied voltage should not be much higher than the given value and must be determined exactly -
e.g. by measuring it with a multimeter. Type in the measured voltage at the prompt.
4 AA batteries in a battery holder are a simple and reliable voltage source:
but the applied voltage should not be much higher than the proposed value and must be determined exactly -
e.g. by measuring it with a multimeter. Type in the real measured voltage at the prompt.
4 fresh AA batteries in a battery holder are a simple and reliable voltage source:

Requested Voltage | Applied Voltage | Comment
------------------|-----------------|--------
0.4 V | 0.3 V | 2 x AA with 1/10 probe
0.8 V | 0.6 V | 4 x AA with 1/10 probe
2.0 V | 1.5 V | 1 x AA
4.0 V | 3.0 V or 4.5 V | 2 or 3 x AA
Requested Voltage | Applied Voltage | Comment
------------------|------------------|--------
0.4 V | ~0.3 V | 2 x AA with 1/10 probe
0.8 V | ~0.6 V | 4 x AA with 1/10 probe
2.0 V | ~1.5 V | 1 x AA
4.0 V | ~3.0 V or ~4.5 V | 2 or 3 x AA

[Read more about the eeprom content...](docs/README.md#eeprom)

## Use the device as a data logger ##
## Use the device as a data logger

The program `capture_6022.py` (also in `/usr/bin/`) allows to capture both channels over a long time.

Expand Down
4 changes: 3 additions & 1 deletion examples/calibrate_6022.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from PyHT6022.LibUsbScope import Oscilloscope

import sys
import time
import binascii

Expand Down Expand Up @@ -91,7 +92,8 @@ def read_avg( voltage_range, sample_rate=110, repeat = 1, samples = 12 * 1024 ):

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit( -1 )

if (not scope.is_device_firmware_present):
scope.flash_firmware()
Expand Down
3 changes: 2 additions & 1 deletion examples/capture_6022.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit( -1 )

# upload correct firmware into device's RAM
if (not scope.is_device_firmware_present):
Expand Down
4 changes: 3 additions & 1 deletion examples/continous_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from PyHT6022.LibUsbScope import Oscilloscope
import matplotlib.pyplot as plt
import sys
import time
import numpy as np
from collections import deque
Expand Down Expand Up @@ -36,7 +37,8 @@ def build_stability_array(data, threshold=1.0):

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit()
scope.flash_firmware()
scope.set_interface(1) # choose ISO
scope.set_num_channels(1)
Expand Down
6 changes: 4 additions & 2 deletions examples/get_calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

__author__ = 'Jochen Hoenicke'

import sys
from PyHT6022.LibUsbScope import Oscilloscope

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit( -1 )

calibration = scope.get_calibration_values( 48 )
scope.close_handle()

# print( calibration )
for x in calibration:
print( hex(x), end=" " )
6 changes: 3 additions & 3 deletions examples/get_firmware_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

scope = Oscilloscope()
scope.setup()
scope.open_handle()
print( hex( scope.get_fw_version() ) )
scope.close_handle()
version = scope.get_fw_version()
if version:
print( hex( version ) )
5 changes: 4 additions & 1 deletion examples/read_eeprom.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

__author__ = 'Jochen Hoenicke'

import sys
from PyHT6022.LibUsbScope import Oscilloscope

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit( -1 )

eeprom = scope.read_eeprom(0, 8)
scope.close_handle()

Expand Down
5 changes: 4 additions & 1 deletion examples/read_eeprom_256_byte.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#!/usr/bin/python3

import sys
from PyHT6022.LibUsbScope import Oscilloscope

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit( -1 )

eeprom = scope.read_eeprom( 0, 256 )
scope.close_handle()

Expand Down
4 changes: 3 additions & 1 deletion examples/read_firmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit( -1 )

firmware = scope.read_firmware(length=16*1024, chunk_len=32)
scope.close_handle()

Expand Down
3 changes: 2 additions & 1 deletion examples/record_wav.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit()
if (not scope.is_device_firmware_present):
scope.flash_firmware()
else:
Expand Down
5 changes: 4 additions & 1 deletion examples/reset_eeprom_6021.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#!/usr/bin/python3

import sys
from PyHT6022.LibUsbScope import Oscilloscope

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit( -1 )

scope.flash_firmware()
print( "FW version", hex( scope.get_fw_version() ) )

Expand Down
5 changes: 4 additions & 1 deletion examples/reset_eeprom_6022.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#!/usr/bin/python3

import sys
from PyHT6022.LibUsbScope import Oscilloscope

scope = Oscilloscope()
scope.setup()
scope.open_handle()
if not scope.open_handle():
sys.exit( -1 )

scope.flash_firmware()
print( "FW version", hex( scope.get_fw_version() ) )

Expand Down
Loading

0 comments on commit dc05698

Please sign in to comment.