inflex / owon-b35

OWON B35 Mutltimeter data capture and display for Linux
BSD 3-Clause "New" or "Revised" License
12 stars 3 forks source link

Problems Reading from Owon B35T+ #1

Closed DeanCording closed 6 years ago

DeanCording commented 6 years ago

When I run owoncli I get no output. Using the -d flag I get:

$ ./owoncli -a 34:15:13:D1:06:28 -d
Success (gatttool -b 34:15:13:D1:06:28 --char-read --handle 0x2d --listen)
Characteristic value/descriptor: 10 2e 00 f4 ff 
Notification handle = 0x002e value: 20 f2 00 00 1d 00 

with the meter on the TEMP range and displaying 0029

Notification handle = 0x002e value: 19 f0 04 00 e9 0d 

with the meter on Volts and displaying DC355.6mv

Notification handle = 0x002e value: 63 f0 04 00 10 00

with the meter on Volts and displaying AC0.016V

Notification handle = 0x002e value: 21 f1 04 00 07 00

with the meter on Ohms and displaying 0.003 ohms

Notification handle = 0x002e value: e7 f2 00 00 00 00

with the meter on Continuity and displaying 0L

inflex commented 6 years ago

Afternoon,

Have you tried running it under 'sudo' ( though it seems you've already sorted out accessing the BLE device with user permissions ) ?

If you run it with the -t to dump to a text file, does that text file have any content ( am thinking maybe there's a shell/terminal escape sequence issue)?

DeanCording commented 6 years ago

I don't appear to need to use sudo, and it doesn't make a difference anyway.

Dumping to a text file only results in an empty file.

running the gatttool alone results in:

$ gatttool -b 34:15:13:D1:06:28 --char-read --handle 0x2d --listen
Characteristic value/descriptor: 10 2e 00 f4 ff 
Notification handle = 0x002e value: 19 f0 04 00 b2 0d 
Notification handle = 0x002e value: 19 f0 04 00 b2 0d 
Notification handle = 0x002e value: 19 f0 04 00 b2 0d 
Notification handle = 0x002e value: 19 f0 04 00 b2 0d 
Notification handle = 0x002e value: 19 f0 04 00 b2 0d 
inflex commented 6 years ago

It's like gatttool isn't giving you the full data that you should be getting, there's about another 8~10 hex values missing after the "b2 02".

inflex commented 6 years ago

There should be 14 hex values to make up the full meter data dump each time.

DeanCording commented 6 years ago

If I use Wireshark to capture the Bluetooth packets, it shows the same 6 byte packets.

hcidump -raw shows the same:

> ACL data: handle 71 flags 0x02 dlen 13
    ATT: Handle notify (0x1b)
      handle 0x002e
      value 0x19 0xf0 0x04 0x00 0xfe 0x0d
DeanCording commented 6 years ago

I'm on Ubuntu 17.10 with Bluez 5.46

inflex commented 6 years ago

Definitely missing data :( I'm using U17.10 on both laptop and desktop systems. Laptop is using internal BT device (4.0BLE) and desktop using external dongle (also supports BLE 4.0)

DeanCording commented 6 years ago

Ok, so I've done a bluetooth packet capture on my phone whilst using the Owon app, transferred log file to desktop and loaded it into Wireshark. It still shows the same 6 byte packets being sent from the meter, so it is nothing to do with the receiver, Linux Bluetooth stack or your code. Owon just must have changed the protocol.

inflex commented 6 years ago

The data is incomplete though, and I'd say they haven't changed the protocol. It's like your meter isn't generating the full block of data for what ever reason.

The start should always be 0x2B (+) or 0x2D (-)

I'm more thinking you've got a meter with a broken BLE output perhaps? What's the output of your

 sudo hcitool lescan
DeanCording commented 6 years ago

Gone even deeper now. My B35T+ uses the Semic CS7729CN-001 chip instead of the Fortune Semiconductor FS9922 chip that most images of the inside of the meter show on the Internet. The board revision is also dated 2017.03.24 v1.6.

So it looks like Owon have changed the chip which uses a different protocol.

inflex commented 6 years ago

Can you show me the output of the hcitool still?

The trouble is, 6 bytes isn't enough to convey the data on the display. Even if they used a more compact encoding method (perhaps RLE) it won't suffice. Out of the 14 bytes originally there's perhaps 2 bytes of wastage due to the BCD'ing of the 4 display digits, beyond that maybe you can squeeze out another byte, but you're not going to get it down to 6 bytes down from 14.

Does the meter work with their software in Windows or on the Android/iPhone?

DeanCording commented 6 years ago
34:15:13:D1:06:28 (unknown)
> HCI Event: LE Meta Event (0x3e) plen 15
    LE Advertising Report
      ADV_IND - Connectable undirected advertising (0)
      bdaddr 34:15:13:D1:06:28 (Public)
      Flags: 0x06
      RSSI: -73
34:15:13:D1:06:28 BDM
> HCI Event: LE Meta Event (0x3e) plen 38
    LE Advertising Report
      SCAN_RSP - Scan Response (4)
      bdaddr 34:15:13:D1:06:28 (Public)
      Complete local name: 'BDM............'
      Unknown type 0x12 with 4 bytes data
      TX power level: 0
      RSSI: -73

Yes, it works OK with the Android app

inflex commented 6 years ago

Can you sniff the data going between the meter and the android app?

I wonder if they've changed it that you have to bind to the unit now (the ones I've used there's no binding), but then the gatttool wouldn't produce any data if that was the case.

DeanCording commented 6 years ago

Yes, that is what I did earlier. It doesn't appear to need binding. When I get a bit more time I'll decode the protocol but looking at the examples above it appears that the last two bytes are the display value with LSB first. The first byte seems to encode function. I've notice changes in the second and third bytes for Min/Max/Hold.

Here is a dump of packets captured on my Android device - packets.txt

inflex commented 6 years ago
No.     Time           Source                Destination           Protocol Length Info
   1048 57.932320      TexasIns_d1:06:28 (BDM) localhost ()          ATT      18     Rcvd Handle Value Notification, Handle: 0x002e (Unknown)

Frame 1048: 18 bytes on wire (144 bits), 18 bytes captured (144 bits)

Lookin at the above, it would seem like there's 14 bytes in there somewhere; hopefully you can find out what that data is.

DeanCording commented 6 years ago
Frame 1048: 18 bytes on wire (144 bits), 18 bytes captured (144 bits)
Bluetooth
    [Source: TexasIns_d1:06:28 (34:15:13:d1:06:28)]
    [Destination: 00:00:00_00:00:00 (00:00:00:00:00:00)]
Bluetooth HCI H4
    [Direction: Rcvd (0x01)]
    HCI Packet Type: ACL Data (0x02)
Bluetooth HCI ACL Packet
    .... 0000 0000 0000 = Connection Handle: 0x000
    ..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2)
    00.. .... .... .... = BC Flag: Point-To-Point (0)
    Data Total Length: 13
    Data
    [Connect in frame: 922]
    [Disconnect in frame: 1431]
    [Source BD_ADDR: TexasIns_d1:06:28 (34:15:13:d1:06:28)]
    [Source Device Name: BDM]
    [Source Role: Unknown (0)]
    [Destination BD_ADDR: 00:00:00_00:00:00 (00:00:00:00:00:00)]
    [Destination Device Name: ]
    [Destination Role: Unknown (0)]
    [Current Mode: Unknown (-1)]
Bluetooth L2CAP Protocol
    Length: 9
    CID: Attribute Protocol (0x0004)
Bluetooth Attribute Protocol
    Opcode: Handle Value Notification (0x1b)
    Handle: 0x002e (Unknown)
    Value: 19f00400d20d

Nope, just 6 bytes of actual data

DeanCording commented 6 years ago

Ok, I've had a chance to reverse engineer the new protocol and yes, it does send all of the data in just 6 bytes.

The 6 bytes are actually 3 x 16 bit unsigned integers in LSB order.

The first integer encodes the function, scale, and decimal places.

 1 1 1 1 0 0 F F F F S S S D D D
+-------+---+-------+-----+-----+
            Function Scale Decimal

The first bits are always  111100 - possibly a start marker.

Function
    0 0 0 0 - DCV
    0 0 0 1 - ACV
    0 0 1 0 - DCA
    0 0 1 1 - ACA
    0 1 0 0 - Ohm
    0 1 0 1 - Cap
    0 1 1 0 - Hz
    0 1 1 1 - Duty
    1 0 0 0 - TempC
    1 0 0 1 - TempF
    1 0 1 0 - Diode
    1 0 1 1 - Continuity
    1 1 0 0 - hFE

Scale
    0 1 0 - micro (u)
    0 1 1 - milli (m)
    1 0 0 - Unit
    1 0 1 - kilo (k)
    1 1 0 - mega (M)

Decimal Places
    0 0 0 - 0
    0 0 1 - 1
    0 1 0 - 2
    0 1 1 - 3
    1 0 0 - 4
    1 0 1 - 5
    1 1 1 - Overload

The second integer encodes the reading type - Hold, Delta, Auto, Min, Max

Hold------------------------------------
Delta--------------------------------- |
Autorange--------------------------- | |
Min-----------------------------   | | |
Max--------------------------- |   | | |
                             | |   | | |
        0 0 0 0 0 0 0 0  X X X X X X X X
                         8 4 2 1 8 4 2 1

The third integer is the reading as a signed magnitude binary (msb is sign bit). It is converted to a floating point by using the number of decimal places as specified in the first integer.

I haven't reverse engineered the data logging functionality yet.

inflex commented 6 years ago

I'm guessing they're using BCD for the 4 digits in the last ~3 bytes?

DeanCording commented 6 years ago

Nope, just a binary signed integer hence they can get the full display in just two bytes + three bits for the decimal point place.

inflex commented 6 years ago

Pretty much needs a completely different write for the decoder. Clone the project and write a new one as B35T+v2 or something?

DeanCording commented 6 years ago

I was thinking that. I'm looking at the data logging functionality at the moment and on first look it seems pretty complex.

DeanCording commented 6 years ago

I've written a new client over at https://github.com/DeanCording/owonb35

inflex commented 6 years ago

Excellent. Is there any way to differentiate between the two meters externally?

DeanCording commented 6 years ago

On the back of mine is a serial number sticker that says "B35T+ xxxxxxxxxxxxxx BLE4.0". Other than that the only difference is the revision number on the board inside.

Just a thought, have you tested your code on the B35T or just the B35 - I don't know if they use a different chip for the true RMS capability in the B35T.