diff --git a/README.md b/README.md index ed36416..38b4527 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # unit_ut61eplus -Access digtal multimeter UNI-T UT61E+ from Python via CP2110 based USB connection +Access UNI-T UT61E+ Digital Multimeter from Python via CP2110 / CH9329 based USB HID Device +**NOTE:** It seems newer UNI-T UT61x DMMs come with a `CH9329` based HID->UART Adapter. +This project now detects both and automatically chooses which VID/PID to use -It should work also for other models: +This Project should work also for other models, but with adjustments for the unit conversion. +(See `from_vendor/*.json`) * UT60BT * UT61B+ * UT61D+ @@ -10,28 +13,29 @@ It should work also for other models: * UT161D * UT161E -but for this the unit conversion has to be adjusted (see `from_vendor/*.json`) - ## Status -> Working with Linux, patches/documentation for Windows are welcome (probably only docs needed to setup the HID library correctly) +> Working with Linux. Patches/Documentation for Windows is welcome +> Tested with UT61E+ and UT61B+ -## Example output (see `readDMM.py`) +## Example Output From readDMM.py ``` +Opened: VID=0x1A86, PID=0xE429 mode=DCV -range=1 -display=8.595 +range=0 +display=0.0002 +display_decimal=0.0002 +display_unit=V overload=False -decimal=8.595 +value=0.0002 unit=V -max=False -min=False -hold=False -rel=False -auto=True -battery=False -hvwarning=False -dc=True -peak_max=False -peak_min=False +isMax=False +ismin=False +isHold=False +isRel=False +isAuto=True +hasBatteryWarning=False +hashasHVWarning=False +isDC=False +isMaxPeak=False ``` diff --git a/ut61eplus/ut61eplus.py b/ut61eplus/ut61eplus.py index c706538..590ebbd 100644 --- a/ut61eplus/ut61eplus.py +++ b/ut61eplus/ut61eplus.py @@ -286,8 +286,11 @@ def __str__(self): class UT61EPLUS: - CP2110_VID = 0x10c4 - CP2110_PID = 0xEA80 + # List of Possible HID Devices to talk to + TARGETS = [ + (0x10C4, 0xEA80), # CP2110 + (0x1A86, 0xE429), # CH9329 + ] _SEQUENCE_GET_NAME = bytes.fromhex('AB CD 03 5F 01 DA') _SEQUENCE_SEND_DATA = bytes.fromhex('AB CD 03 5E 01 D9') @@ -310,14 +313,30 @@ class UT61EPLUS: def __init__(self): """open device""" self.dev = hid.device() - self.dev.open(self.CP2110_VID, self.CP2110_PID) - log.debug('device is open') + + # Find the Appropriate HID Device + device_vid_pid = self._find_device() + if not device_vid_pid: + raise RuntimeError("No Compatable HID Devices Found") + + # Open the HID Target found using path + self.dev.open_path(device_vid_pid['path']) + #self.dev.open(self.CP2110_VID, self.CP2110_PID) + print(f"Opened: VID=0x{device_vid_pid['vendor_id']:04X}, PID=0x{device_vid_pid['product_id']:04X}") + + # Send Setup Strings #self.dev.nonblocking = 1 - self.dev.send_feature_report([0x41, 0x01]) # enable uart + self.dev.send_feature_report([0x41, 0x01]) # enable uart self.dev.send_feature_report([0x50, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00]) # 9600 8N1 - from USB trace - self.dev.send_feature_report([0x43, 0x02]) # purge both fifos + self.dev.send_feature_report([0x43, 0x02]) # purge both fifos log.debug('feature requests sent') + def _find_device(self): + for dev in hid.enumerate(): + if (dev['vendor_id'], dev['product_id']) in self.TARGETS: + return dev + return None + def _write(self, b: bytes): buf = [] buf.append(len(b))