Add support for the Mooshimeter DMM

This adds support for the Mooshim Engineering BLE based Mooshimeter.
Because the meter requires raw BLE packets, the driver uses the BLE
layer directly. Since the meter has no physical way of configuring it,
the actual configuration is set entirely with sigrok device options.
This commit is contained in:
Derek Hageman 2019-02-19 16:26:27 -07:00 committed by Uwe Hermann
parent 02a8c07d89
commit ebcd1aba01
6 changed files with 2795 additions and 0 deletions

View File

@ -463,6 +463,12 @@ src_libdrivers_la_SOURCES += \
src/hardware/mic-985xx/protocol.c \
src/hardware/mic-985xx/api.c
endif
if HW_MOOSHIMETER_DMM
src_libdrivers_la_SOURCES += \
src/hardware/mooshimeter-dmm/protocol.h \
src/hardware/mooshimeter-dmm/protocol.c \
src/hardware/mooshimeter-dmm/api.c
endif
if HW_MOTECH_LPS_30X
src_libdrivers_la_SOURCES += \
src/hardware/motech-lps-30x/protocol.h \

View File

@ -107,6 +107,7 @@ The following drivers/devices do not need any firmware upload:
- maynuo-m97
- mic-985xx (including all subdrivers)
- motech-lps-30x
- mooshimeter-dmm
- norma-dmm
- openbench-logic-sniffer
- pce-322a
@ -475,3 +476,74 @@ Example:
$ sigrok-cli --driver ols:conn=/dev/ttyACM0 ...
Mooshimeter
-----------
The Mooshim Engineering Mooshimeter is controlled via Bluetooth Low Energy
(sometimes called Bluetooth 4.0), as such it requires a supported Bluetooth
interface available. The 'conn' option is required and must contain the
Bluetooth MAC address of the meter.
Example:
$ sigrok-cli --driver mooshimeter-dmm:conn=12-34-56-78-9A-BC ...
Since the Mooshimeter has no physical interface on the meter itself, the
channel configuration is set with the 'channel_config' option. The format
of this option is 'CH1,CH2' where each channel configuration has the form
'MODE:RANGE:ANALYSIS', with later parts being optional. In addition for
CLI compatibility, the ',' in the channels can also be a '/' and the ':' in
the individual configuration can be a ';'.
Available channel 1 modes:
- Current, A: Current in amps
- Temperature, T, K: Internal meter temperature in Kelvin
- Resistance, Ohm, W: Resistance in ohms
- Diode, D: Diode voltage
- Aux, LV: Auxiliary (W input) low voltage sensor (1.2V max)
Available channel 2 modes:
- Voltage, V: Voltage
- Temperature, T, K: Internal meter temperature in Kelvin
- Resistance, Ohm, W: Resistance in ohms
- Diode, D: Diode voltage
- Aux, LV: Auxiliary (W input) low voltage sensor (1.2V max)
Only one channel can use the shared inputs at a time (e.g. if CH1 is measuring
resistance, CH2 cannot measure low voltage). Temperature is excepted from
this, so the meter can measure internal temperature and low voltage at the
same time.
Additionally, the meter can calculate the real power of both channels. This
generally only makes sense when CH1 is set to current and CH2 is set to a
voltage and so it is disabled by default. It must be enabled by enabling the
'P' channel (the third channel).
The range of the channel specification sets the maximum input for that channel
and is rounded up to the next value the meter itself supports. For example,
specifying 50 for the voltage will result in the actual maximum of 60.
Specifying 61 would result in 600. If omitted, sigrok will perform
auto-ranging of the channel by selecting the next greater value than the
latest maximum.
The analysis option sets how the meter reports its internal sampling buffer
to sigrok:
- Mean, DC: The default is a simple arithmetic mean of the sample buffer
- RMS, AC: The root mean square of the sample buffer
- Buf, Buffer, Samples: Report the entire sample buffer to sigrok. This
results in packets that contain all the samples in the buffer instead
of a single output value.
The size of the sample buffer is set with the 'avg_samples' option, while
the sampling rate is set with the 'samplerate' option. So the update rate
is avg_samples/samplerate. Both are rounded up to the next supported value
by the meter.
Example:
$ sigrok-cli -c channel_config="Aux;0.1/T" --driver mooshimeter-dmm...
$ sigrok-cli -c channel_config="A;;AC/V;;AC" --driver mooshimeter-dmm...

View File

@ -136,12 +136,16 @@ SR_ARG_OPT_CHECK([libieee1284], [LIBIEEE1284],, [
AS_IF([test "x$sr_have_libieee1284" = xyes],
[SR_PREPEND([SR_EXTRA_LIBS], [-lieee1284])])
SR_ARG_OPT_PKG([libgio], [LIBGIO], , [gio-2.0 >= 2.24.0])
# See if any of the (potentially platform specific) libs are available
# which provide some means of Bluetooth communication.
AS_IF([test "x$sr_have_libbluez" = xyes],
sr_have_bluetooth=yes, sr_have_bluetooth=no)
AS_IF([test "x$sr_have_bluetooth" = xyes],
[AC_DEFINE([HAVE_BLUETOOTH], [1], [Specifies whether Bluetooth communication is supported.])])
AS_IF([test "x$sr_have_bluetooth" = xyes],
[SR_APPEND([sr_deps_avail], [bluetooth_comm])])
AS_IF([test "x$sr_have_libserialport" = xyes -o "x$sr_have_libhidapi" = xyes -o "x$sr_have_bluetooth" = xyes],
sr_have_serial_comm=yes, sr_have_serial_comm=no)
@ -290,6 +294,7 @@ SR_DRIVER([Manson HCS-3xxx], [manson-hcs-3xxx], [serial_comm])
SR_DRIVER([maynuo-m97], [maynuo-m97])
SR_DRIVER([MIC 985xx], [mic-985xx], [serial_comm])
SR_DRIVER([Microchip PICkit2], [microchip-pickit2], [libusb])
SR_DRIVER([Mooshimeter DMM], [mooshimeter-dmm], [bluetooth_comm libgio])
SR_DRIVER([Motech LPS 30x], [motech-lps-30x], [serial_comm])
SR_DRIVER([Norma DMM], [norma-dmm], [serial_comm])
SR_DRIVER([OpenBench Logic Sniffer], [openbench-logic-sniffer], [serial_comm])

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
/*
* This file is part of the libsigrok project.
*
* Copyright (C) 2019 Derek Hageman <hageman@inthat.cloud>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBSIGROK_HARDWARE_MOOSHIMETER_DMM_PROTOCOL_H
#define LIBSIGROK_HARDWARE_MOOSHIMETER_DMM_PROTOCOL_H
#include <stdint.h>
#include <glib.h>
#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"
#define LOG_PREFIX "mooshimeter-dmm"
struct packet_rx {
int sequence_number;
GSList *reorder_buffer;
GByteArray *contents;
};
struct packet_tx {
int sequence_number;
};
enum tree_node_datatype {
TREE_NODE_DATATYPE_PLAIN = 0,
TREE_NODE_DATATYPE_LINK,
TREE_NODE_DATATYPE_CHOOSER,
TREE_NODE_DATATYPE_U8,
TREE_NODE_DATATYPE_U16,
TREE_NODE_DATATYPE_U32,
TREE_NODE_DATATYPE_S8,
TREE_NODE_DATATYPE_S16,
TREE_NODE_DATATYPE_S32,
TREE_NODE_DATATYPE_STRING,
TREE_NODE_DATATYPE_BINARY,
TREE_NODE_DATATYPE_FLOAT,
};
union tree_value {
int32_t i;
float f;
GByteArray *b;
};
struct config_tree_node {
char *name;
int id;
size_t index_in_parent;
enum tree_node_datatype type;
union tree_value value;
size_t count_children;
struct config_tree_node *children;
uint32_t update_number;
void (*on_update)(struct config_tree_node *node, void *param);
void *on_update_param;
};
struct dev_context {
struct packet_rx rx;
struct packet_tx tx;
struct config_tree_node tree_root;
struct config_tree_node *tree_id_lookup[0x7F];
uint32_t buffer_bps[2];
float buffer_lsb2native[2];
void (*channel_autorange[3])(const struct sr_dev_inst *sdi, float value);
struct sr_sw_limits limits;
struct sr_analog_meaning channel_meaning[3];
gboolean enable_value_stream;
};
SR_PRIV int mooshimeter_dmm_open(const struct sr_dev_inst *sdi);
SR_PRIV int mooshimeter_dmm_close(const struct sr_dev_inst *sdi);
SR_PRIV int mooshimeter_dmm_set_chooser(const struct sr_dev_inst *sdi, const char *path, const char *choice);
SR_PRIV int mooshimeter_dmm_set_integer(const struct sr_dev_inst *sdi, const char *path, int value);
SR_PRIV int mooshimeter_dmm_set_larger_number(const struct sr_dev_inst *sdi, const char *path, const char *parent, float number);
SR_PRIV gboolean mooshimeter_dmm_set_autorange(const struct sr_dev_inst *sdi, const char *path, const char *parent, float latest);
SR_PRIV int mooshimeter_dmm_get_chosen_number(const struct sr_dev_inst *sdi, const char *path, const char *parent, float *number);
SR_PRIV int mooshimeter_dmm_get_available_number_choices(const struct sr_dev_inst *sdi, const char *path, float **numbers, size_t *count);
SR_PRIV int mooshimeter_dmm_poll(int fd, int revents, void *cb_data);
SR_PRIV int mooshimeter_dmm_heartbeat(int fd, int revents, void *cb_data);
#endif