|
|
||
|---|---|---|
| src/dt8852 | Work-around for parsing time for devices which report 12am as 00am. | |
| .gitignore | Initial commit | |
| example.py | Initial commit | |
| LICENSE.md | Initial commit | |
| pyproject.toml | Switched to suggested project layout and static setup.cfg. Bumped version. | |
| README.md | Update README and bump version. | |
| setup.cfg | Update README and bump version. | |
dt8852 overview
dt8852 is a cross-platform Python package and module for reading and controlling CEM DT-8852 and equivalent Sound Level Meter and Data Logger devices.
- Project homepage: https://codeberg.org/randysimons/dt8852
- Download: https://pypi.org/project/dt8852/
- License: GPLv3 or later
Features
- Read current SPL value as measured from device.
- Read current device configuration.
- Configure the device.
- Download recorded sessions directly to .csv.
- Can be used directly from the command line interface, and in your own application using the API.
- Single dependency: pySerial.
Compatible devices
- CEM DT-8852 (OEM)
This device is also re-branded and sold as:
- Trotec SL400
- Voltcraft SL-451
- ATP SL-8852
- ... probably various others.
The CEM DT-8851 lacks the data recording functionality, but might otherwise be supported as well. However, due to availability of only a Trotec SL400, the package is only tested on this device.
Installation and running.
Common options are to use pip to install the package, or to use pipx to install it as stand-alone command line tool, or use pipx to directly run it.
Install the package using pipx:
pipx is particularly useful if you want to install the package as a standalone command-line tool or run it directly without installing.
Option 1: Run the package directly with pipx run
If you don't want to install the package permanently, you can use pipx run to execute it directly:
$ pipx run dt8852
Note: Using pipx run will create a temporary environment, download the package, and clean up afterward.
Option 2: Install the package with pipx install
This will install the dt8852 package globally in an isolated environment, making it available as a command-line tool:
$ pipx install dt8852
Once installed, you can use the dt8852 command directly from your terminal.
Install the package using pip:
$ pip install dt8852
You can now run it as a Python module:
$ python3 -m dt8852
On Debian / Ubuntu, use pip3 instead of pip. Pip might require a virtual environment (venv).
Device driver installation
The device internally uses a USB-to-UART bridge by Silicon Labs. Your OS needs a driver for this to work, so the device can be accessed as a regular RS232 serial (COM) device.
- On Linux, the driver is already available on many distributions. No action is needed. However, a user might need permission to access serial interfaces. E.g. on Ubuntu, Debian, openSUSE, Fedora your user needs to be part of the
dialoutgroup. On Ubuntu and Debian you can add yourself to this group using$ sudo usermod -a -G dialout $USER. Others may vary. - On Windows 10, the device is automatically recognized, and Windows installs the appropriate driver. No action is needed. Alternatively, if you already have installed the provided software, no action is needed. If needed, the USB driver is available directly from Silicon Labs.
- On macOS, a USB driver is available from Silicon Labs.
Usage
After installation, the module can be run directly from the command line, and can be used as module in your own Python application (see below). In both cases, the basic setup applies:
- Connect the device to computer by USB.
- Switch on the device.
- Press button "Setup" once, to enable data communication mode.
Command line interface
The command depends on the installation method used (see above): $ pipx run dt8852, $ dt8852 or python3 -m dt8852. For brevety, the pipx install dt8852 method is assumed in the following.
Basic command: $ dt8852 MODE, where MODE is one of:
liveget live SPL measurements from device, output to stdout.set_modeconfigure device according to specified values and exits.get_moderetrieve current device configuration and exit.downloadto download recorded sessions as comma separated value (CSV) files and exit.
Use dt8852 -h for basic help, or dt8852 MODE -h for mode-specific help, for example dt8852 live -h.
Note: by default the serial interface used is COM3 on Windows, /dev/ttyUSB0 on other OSes. You can override this by using the --serial_port argument. The currently available serial interfaces can be found by running python3 -m serial.tools.list_ports on the command line.
Examples
The following examples each show a command from the command line and an example of the output. Windows users can use py instead of python3.
Basic live output
$ dt8852 live
33.3
32.4
32.9
71.8
Verbose level 1 live output
$ dt8852 live -v
2020年10月01日 22:27:02.806050,37.3
2020年10月01日 22:27:03.304626,33.0
2020年10月01日 22:27:03.802777,56.2
2020年10月01日 22:27:04.301302,53.0
Tip: if you redirect the output to a file, e.g. dt8852 live -v > output.csv, you can easily import the output in a spreadsheet.
Verbose level 5 live output
$ dt8852 live -vvvvv
('frequency_weighting', <Frequency_weighting.DBA: 'dB(A)'>, True)
('current_time', time.struct_time(tm_year=1900, tm_mon=1, tm_mday=1, tm_hour=22, tm_min=29, tm_sec=4, tm_wday=0, tm_yday=1, tm_isdst=-1), True)
('range_mode', <Range_mode.R_30_80: '30dB - 80dB'>, True)
('hold_mode', <Hold_mode.LIVE: 'Live'>, True)
('range_threshold', <Range_threshold.OK: 'Within range'>, True)
('current_spl', 41.9, True)
('output_to', <Output_to.BAR_GRAPH: 'Bar graph'>, True)
Get current configuration
$ dt8852 get_mode
current_time = 22:31:39
current_spl = 40.7dB
frequency_weighting = dB(A)
time_weighting = Fast
range_threshold = Within range
hold_mode = Live
range_mode = 30dB - 80dB
recording_mode = Not recording
memory_store = Storage available
battery_state = Battery OK
output_to = Digits
serial = /dev/ttyUSB0
Set configuration
Sets modes Range 30dB - 80dB, dB(C), slow, and starts recording to internal storage.
$ dt8852 set_mode --range R_30_80 --freqweighting DBC --timeweighting SLOW --record RECORDING
Stop recording
$ dt8852 set_mode --record NOT_RECORDING
Download recordings
Note: make sure the device is not recording anymore before downloading, otherwise memory corruption will occur. The current recording then cannot be downloaded anymore.
$ dt8852 download
Downloading 2349 bytes
Writing file: Recording 2020年10月01日 21-49-19, dB(A), sample interval 1s.csv
Number of recorded samples written to file: 7
Writing file: Recording 2020年10月01日 21-49-30, dB(A), sample interval 1s.csv
Number of recorded samples written to file: 6
Writing file: Recording 2020年10月01日 21-50-57, dB(A), sample interval 1s.csv
Number of recorded samples written to file: 1148
All done
API
The module can be used in your own applications as well. To use, instantiate an object of class dt8852.Dt8852. See below for examples.
Class methods
__init__(serial: serial.Serial) Instantiates a new Dt8852 handler on provided serial interface.
__str__() Returns string representation, with all currently known device values.
decode_next_token(changes_only=True) Generator function. Waits for and decodes the next token from the device, yields the received token type and value.
In addition, it sends commands to the device to achieve the requested modes specified by set_mode().
Return value is a tuple containing decoded token type as string, its enumeration, and its value. If changes_only is True, decode_next_token returns only if the value is different than previously received value. If changes_only is False, all updates from device are returned, which is quite spammy.
set_mode(modes) Sets the list of device configuration modes. Modes is a mutable sequence containing the requested device configuration. This list can contain any of Dt8852.Time_weighting.FAST, Dt8852.Time_weighting.SLOW, Dt8852.Frequency_weighting.DBA, Dt8852.Frequency_weighting.DBC, Dt8852.Hold_mode.LIVE, Dt8852.Hold_mode.MIN, Dt8852.Hold_mode.MAX, Dt8852.Range_mode.R_30_80, Dt8852.Range_mode.R_50_100, Dt8852.Range_mode.R_80_130, Dt8852.Range_mode.R_30_130_AUTO, Dt8852.Recording_mode.NOT_RECORDING, Dt8852.Recording_mode.RECORDING.
Requested configuration is send to the device while calling decode_next_token. The process is done, if the passed modes sequence is empty.
Currently the correct mechanism of precisely when to send the commands to the device is not well understood. More often than not, the device ignores the sent commands. The current implementation tries to mitigate this by periodically sending the command, and then waits if it has the desired effect. This method is not perfect, resulting in incorrect device configuration. Of course, you can always use the device's own buttons to set the desired mode at any time.
get_recordings() Generator function yielding all recorded sessions and data.
For example, if there are two recorded sessions, this iterator yields:
data_length [bytes to read]
recording_start [frequency weighting, start time, sample interval, bytes read so far]
[spl, timestamp, bytes read so far]
[spl, timestamp, bytes read so far]
...
recording_complete [bytes read so far]
recording_start [frequency weighting, start time, sample interval, bytes read so far]
[spl, timestamp, bytes read so far]
[spl, timestamp, bytes read so far]
...
recording_complete [bytes read so far]
dump_complete [bytes read so far]
Instance variables
The device simply outputs a stream of current values. The decode_next_token()-loop decodes this stream, and gradually fills the following instance variables. These are read-only.
current_spl Most recent SPL measurement.
current_time Current time on device.
time_weighting Dt8852.Time_weighting.FAST, Dt8852.Time_weighting.SLOW or None if not yet known.
frequency_weighting Dt8852.Frequency_weighting.DBA, Dt8852.Frequency_weighting.DBC or None if not yet known.
range_threshold Dt8852.Range_threshold.UNDER, Dt8852.Range_threshold.OK, Dt8852.Range_threshold.OVER or None if not yet known.
hold_mode Dt8852.Hold_mode.LIVE, Dt8852.Hold_mode.MIN, Dt8852.Hold_mode.MAX or None if not yet known.
range_mode Dt8852.Range_mode.R_30_80, Dt8852.Range_mode.R_50_100, Dt8852.Range_mode.R_80_130, Dt8852.Range_mode.R_30_130_AUTO or None if not yet known.
recording_mode Dt8852.Recording_mode.NOT_RECORDING, Dt8852.Recording_mode.RECORDING or None if not yet known.
memory_store Dt8852.Memory_store.AVAILABLE, Dt8852.Memory_store.FULL or None if not yet known.
battery_state Dt8852.Battery_state.OK, Dt8852.Battery_state.LOW or None if not yet known.
output_to Dt8852.Output_to.DISPLAY, Dt8852.Output_to.BAR_GRAPH or None if not yet known. This indicates whether the last reported SPL-update was shown on the digits display, or the bar graph display on device.
Examples
Minimalistic example, which decodes and prints all updates coming from the device connected on serial port /dev/ttyUSB0:
import serial, dt8852
spl_meter = dt8852.Dt8852(serial.Serial('/dev/ttyUSB0'))
for data in spl_meter.decode_next_token():
print(data)
Note: this requires the module to by installed using pip.
A more extended example of API usage is available in example.py.
The clock problem
Besides the 9V battery, these devices contain a lithium cell to keep the clock running when powered off. However, it seems that when this cell runs out after a few years, the clock stops and the time displayed is frozen at 00:00:00.
You can replace the lithium cell by opening the device. The exact type seems to vary by specific brand and/or type. The Trotec SL400 contains a CR1220 lithium cell.
After replacing the cell, the clock might still be frozen, even when setting the correct date and time. To remedy this, use the (undocumented) reset-option:
- Power on the device, while keeping the
Setupbutton pressed. - Repeatedly press
SetupuntilrStis shown. - Press
HOLD.
The device will now reset the date and time, and the clock should now work properly. You can then set the correct date and time again.
This might work without replacing the lithium cell, but the clock will reset to 00:00:00 if the device is powered off for more than a few seconds.
Attribution
The project is based on information from the Sigrok device wiki for CEM DT-8852.