From f2a8d8a28e53f49c7002b13dc33b21ca8232afc8 Mon Sep 17 00:00:00 2001 From: Phil Date: Fri, 8 May 2026 16:05:53 +0300 Subject: [PATCH] sw: update console with new packet changes --- software/console.py | 74 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/software/console.py b/software/console.py index 4d55cda..074c7a3 100644 --- a/software/console.py +++ b/software/console.py @@ -1,5 +1,9 @@ import argparse import socket +import math +import matplotlib.pyplot as plt + +adc_dac_ratio = 0.52 def run_debug(args, sock): @@ -22,12 +26,16 @@ def run_debug(args, sock): def format_ctrl_data(pulse_width: int, pulse_period: int, - pulse_height: int, pulse_num: int, dac_bits: int = 16) -> bytes: + pulse_height: int, pulse_num: int, args, dac_bits: int = 16) -> bytes: """Format data packet for set_data command.""" output = bytearray() output += 0b10001000.to_bytes(1, 'little') + pulse_period_adc = (int(pulse_period * adc_dac_ratio) // + args.window_size) * args.window_size + print(pulse_period_adc) + # no negative please assert pulse_width > 0, "pulse_width should be positive" assert pulse_period > 0, "pulse_period should be positive" @@ -44,8 +52,9 @@ def format_ctrl_data(pulse_width: int, pulse_period: int, output += pulse_period.to_bytes(4, 'little') output += pulse_num.to_bytes(2, 'little') output += pulse_height.to_bytes(2, 'little') + output += pulse_period_adc.to_bytes(4, 'little') - assert len(output) == 13, "Config data should be 96 bits + 8 bit header" + assert len(output) == 17, "Config data should be 128 bits + 8 bit header" return output @@ -64,9 +73,53 @@ def verify_args(args): args.pulse_height = int(input("pulse_height: ")) +def recv_data(args, sock) -> list: + # calculate count & size + packet_count = math.ceil( + ((adc_dac_ratio * args.pulse_period) / args.window_size * args.data_width) / args.packet_size) + print(packet_count) + + recv_buf = [] + + try: + for pkt_cnt in range(packet_count): + try: + data, address = sock.recvfrom(65536) + + if len(data) % args.data_width != 0: + print("invalid packet size!") + + for i in range(0, len(data), args.data_width): + sample = int.from_bytes( + data[i:i+args.data_width], "little") + recv_buf.append(sample) + except socket.timeout: + print("socket timeout") + except KeyboardInterrupt: + print(f"recv: {pkt_cnt}") + break + except Exception as e: + print(f"err: {e}") + + expected_length = math.ceil( + adc_dac_ratio * args.pulse_period / args.window_size) + if len(recv_buf) < expected_length: + print("data underflow") + return [] + + recv_buf = recv_buf[:expected_length-1] + print(f"collected {len(recv_buf)} samples") + # print(recv_buf) + return recv_buf + + def run(args, sock): dest = (args.ip, args.send_port) + if args.pulse_period % args.window_size != 0: + print("Invalid pulse period (should be divisable by WINDOW_SIZE)") + return + # reset sock.sendto(0x0f00.to_bytes(2), dest) @@ -74,11 +127,15 @@ def run(args, sock): sock.sendto(format_ctrl_data(args.pulse_width, args.pulse_period, args.pulse_height, - args.pulse_num, + args.pulse_num, args, dac_bits=args.dac_bits), dest) sock.sendto(0xf000.to_bytes(2), dest) print("Sent start!") + data = recv_data(args, sock) + print(min(data), max(data)) + plt.plot(data) + plt.show() def main(): @@ -101,6 +158,15 @@ def main(): parser.add_argument("--dac-bits", type=int, default=12, help="Битность ЦАП (влияет на максимальный pulse_height)") + parser.add_argument("--data-width", type=int, + default=4, help="Байтность получаемых данных, по умолчанию 4 (AKA int32)") + + parser.add_argument("--window-size", type=int, + default=65, help="Размер окна для первого усреднения.") + + parser.add_argument("--packet-size", type=int, + default=1024, help="Размер отправляемых пакетов.") + # передача параметров через аргументы for arg in ("pulse_width", "pulse_period", "pulse_num", "pulse_height"): parser.add_argument(f"--{arg}", type=int, @@ -109,6 +175,8 @@ def main(): args = parser.parse_args() sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind(("0.0.0.0", args.recv_port)) if args.debug: run_debug(args, sock)