From da144a6269900eebb6e33cf5e1ed22c4083be8e5 Mon Sep 17 00:00:00 2001 From: Theodor Chikin Date: Wed, 4 Mar 2026 16:39:35 +0300 Subject: [PATCH] implemented --parser_16_bit_x2 key. If enabled -- receive values as 2 16-bit --- RFG_ADC_dataplotter.py | 128 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 1 deletion(-) diff --git a/RFG_ADC_dataplotter.py b/RFG_ADC_dataplotter.py index 1109aaf..d783641 100755 --- a/RFG_ADC_dataplotter.py +++ b/RFG_ADC_dataplotter.py @@ -639,6 +639,7 @@ class SweepReader(threading.Thread): fancy: bool = False, bin_mode: bool = False, logscale: bool = False, + parser_16_bit_x2: bool = False, ): super().__init__(daemon=True) self._port_path = port_path @@ -649,6 +650,7 @@ class SweepReader(threading.Thread): self._fancy = bool(fancy) self._bin_mode = bool(bin_mode) self._logscale = bool(logscale) + self._parser_16_bit_x2 = bool(parser_16_bit_x2) self._max_width: int = 0 self._sweep_idx: int = 0 self._last_sweep_ts: Optional[float] = None @@ -659,6 +661,11 @@ class SweepReader(threading.Thread): """Преобразование 32-bit слова в знаковое значение.""" return v - 0x1_0000_0000 if (v & 0x8000_0000) else v + @staticmethod + def _u16_to_i16(v: int) -> int: + """Преобразование 16-bit слова в знаковое значение.""" + return v - 0x1_0000 if (v & 0x8000) else v + def _finalize_current( self, xs, @@ -1024,6 +1031,113 @@ class SweepReader(threading.Thread): apply_inversion=False, ) + def _run_logscale_16_bit_x2_binary_stream(self, chunk_reader: SerialChunkReader): + xs: list[int] = [] + ys: list[float] = [] + avg_1_vals: list[int] = [] + avg_2_vals: list[int] = [] + cur_channel: Optional[int] = None + cur_channels: set[int] = set() + words = deque() + + buf = bytearray() + while not self._stop.is_set(): + data = chunk_reader.read_available() + if data: + buf += data + else: + time.sleep(0.0005) + continue + + usable = len(buf) & ~1 + if usable == 0: + continue + + i = 0 + while i < usable: + w = int(buf[i]) | (int(buf[i + 1]) << 8) + words.append(w) + i += 2 + + # Бинарный logscale-протокол (16-bit x2): + # старт свипа (новый): 0xFFFF, 0xFFFF, (ch<<8)|0x0A + # старт свипа (fallback): 0xFFFF, 0xFFFF, 0xFFFF, (ch<<8)|0x0A + # точка: step, avg1_lo16, avg2_lo16, 0x000A + while len(words) >= 3: + w0 = int(words[0]) + w1 = int(words[1]) + w2 = int(words[2]) + + if w0 == 0xFFFF and w1 == 0xFFFF and (w2 & 0x00FF) == 0x000A: + self._finalize_current( + xs, + ys, + cur_channels, + raw_curves=(avg_1_vals, avg_2_vals), + apply_inversion=False, + ) + xs.clear() + ys.clear() + avg_1_vals.clear() + avg_2_vals.clear() + cur_channels.clear() + cur_channel = (w2 >> 8) & 0x00FF + cur_channels.add(cur_channel) + for _ in range(3): + words.popleft() + continue + + if len(words) < 4: + break + + w3 = int(words[3]) + + if w0 == 0xFFFF and w1 == 0xFFFF and w2 == 0xFFFF and (w3 & 0x00FF) == 0x000A: + self._finalize_current( + xs, + ys, + cur_channels, + raw_curves=(avg_1_vals, avg_2_vals), + apply_inversion=False, + ) + xs.clear() + ys.clear() + avg_1_vals.clear() + avg_2_vals.clear() + cur_channels.clear() + cur_channel = (w3 >> 8) & 0x00FF + cur_channels.add(cur_channel) + for _ in range(4): + words.popleft() + continue + + if w3 == 0x000A: + if cur_channel is not None: + cur_channels.add(cur_channel) + avg_1 = self._u16_to_i16(w1) + avg_2 = self._u16_to_i16(w2) + xs.append(w0) + avg_1_vals.append(avg_1) + avg_2_vals.append(avg_2) + ys.append(_log_pair_to_sweep(avg_1, avg_2)) + for _ in range(4): + words.popleft() + continue + + words.popleft() + + del buf[:usable] + if len(buf) > 1_000_000: + del buf[:-262144] + + self._finalize_current( + xs, + ys, + cur_channels, + raw_curves=(avg_1_vals, avg_2_vals), + apply_inversion=False, + ) + def run(self): try: self._src = SerialLineSource(self._port_path, self._baud, timeout=1.0) @@ -1034,7 +1148,9 @@ class SweepReader(threading.Thread): try: chunk_reader = SerialChunkReader(self._src) - if self._logscale: + if self._parser_16_bit_x2: + self._run_logscale_16_bit_x2_binary_stream(chunk_reader) + elif self._logscale: self._run_logscale_binary_stream(chunk_reader) elif self._bin_mode: self._run_binary_stream(chunk_reader) @@ -1122,6 +1238,14 @@ def main(): "а свип считается как 10**(avg_1*0.001) - 10**(avg_2*0.001)" ), ) + parser.add_argument( + "--parser_16_bit_x2", + action="store_true", + help=( + "Бинарный logscale-протокол c парой int16 (avg_1, avg_2): " + "старт 0xFFFF,0xFFFF,(CH<<8)|0x0A; точка step,avg1_lo16,avg2_lo16,0x000A" + ), + ) parser.add_argument( "--calibrate", action="store_true", @@ -1167,6 +1291,7 @@ def main(): fancy=bool(args.fancy), bin_mode=bool(args.bin_mode), logscale=bool(args.logscale), + parser_16_bit_x2=bool(args.parser_16_bit_x2), ) reader.start() @@ -1866,6 +1991,7 @@ def run_pyqtgraph(args): fancy=bool(args.fancy), bin_mode=bool(args.bin_mode), logscale=bool(args.logscale), + parser_16_bit_x2=bool(args.parser_16_bit_x2), ) reader.start()