interfaces.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. import socket
  2. import struct
  3. import subprocess
  4. import numpy as np
  5. import serial
  6. import time as tm
  7. import msgpack
  8. probe = {
  9. '10mV': np.int8(0),
  10. '20mV': np.int8(1),
  11. '50mV': np.int8(2),
  12. '100mV': np.int8(3),
  13. '200mV': np.int8(4),
  14. '500mV': np.int8(5),
  15. '1V': np.int8(6),
  16. '2V': np.int8(7),
  17. '5V': np.int8(8),
  18. '10V': np.int8(9),
  19. '20V': np.int8(10),
  20. '50V': np.int8(11),
  21. '100V': np.int8(12),
  22. '200V': np.int8(13)
  23. }
  24. class adc_default:
  25. def __init__(self, port):
  26. self.port = port
  27. self.ndata = []
  28. self.channels_data = []
  29. self.measure_code = (0x00, 0)
  30. self.connected = False
  31. self.pk = msgpack.Packer()
  32. self.proto = {
  33. 'open': 0x01,
  34. 'set_rate': 0x07,
  35. 'set_points': 0x06,
  36. 'config_channels': 0x09,
  37. 'set_premeasure': 0x28,
  38. 'set_trignum': 0x19,
  39. 'start': 0x3B,
  40. 'stop': 0x03,
  41. }
  42. def connect(self, port=0):
  43. self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  44. self.client_socket.settimeout(10.0)
  45. resp = self.client_socket.connect(('127.0.0.1', self.port))
  46. self.connected = True
  47. return resp
  48. def send_command(self, cmd_code, *args):
  49. if not self.connected:
  50. print("Not connected. Use 'connect' first.")
  51. return None
  52. try:
  53. buf = bytearray()
  54. buf.extend(self.pk.pack(0xAA))
  55. buf.extend(self.pk.pack(cmd_code))
  56. for arg in args:
  57. buf.extend(self.pk.pack(arg))
  58. self.client_socket.sendall(buf)
  59. return self.receive_response()
  60. except Exception as e:
  61. print(f"Send failed: {e}")
  62. return None
  63. def receive_response(self):
  64. try:
  65. unpacker = msgpack.Unpacker()
  66. while True:
  67. chunk = self.client_socket.recv(8192)
  68. if not chunk:
  69. break
  70. unpacker.feed(chunk)
  71. objects = []
  72. for obj in unpacker:
  73. objects.append(obj)
  74. #print(f"Code: {objects[1]}")
  75. return objects[1], objects[2:]
  76. except Exception as e:
  77. print(f"Receive failed: {e}")
  78. return None
  79. def resp_handler(self, resp, cmd):
  80. if(resp[0] != 0xAA):
  81. return (-1, 0)
  82. if(resp[1] == 0xFF):
  83. return (0xFF, resp[3])
  84. return (resp[1], 0)
  85. def open(self):
  86. resp = self.send_command(0x01)
  87. if resp:
  88. code, data = resp
  89. if code == 0xCC:
  90. return (0xCC, 0, 0)
  91. else:
  92. return (0xFF, code, data)
  93. def set_rate(self, rate):
  94. """Set sample rate. Usage: set_rate <rate>"""
  95. try:
  96. srate = int(rate)
  97. resp = self.send_command(0x07, srate)
  98. if resp:
  99. code, data = resp
  100. if code == 0xCC:
  101. return (0xCC, 0, 0)
  102. else:
  103. return (0xFF, code, data)
  104. except ValueError:
  105. return (0xFF, code, b"Invalid rate!")
  106. def set_points(self, points):
  107. """Set points vector. Usage: set_points <p1> <p2> ..."""
  108. try:
  109. resp = self.send_command(0x06, points)
  110. if resp:
  111. code, data = resp
  112. if code == 0xCC:
  113. return (0xCC, 0, 0)
  114. else:
  115. return (0xFF, code, data)
  116. except ValueError:
  117. return (0xFF, code, b"Invalid points!")
  118. def config_channels(self, nchannels, channel_ranges, trig_channel):
  119. """Configure channels. Usage: channel_configure <num_channels> <range1> <range2> ... <trig_channel>"""
  120. try:
  121. resp = self.send_command(0x09, nchannels, channel_ranges, trig_channel)
  122. if resp:
  123. code, data = resp
  124. if code == 0xCC:
  125. return (0xCC, 0, 0)
  126. else:
  127. return (0xFF, code, data)
  128. except ValueError:
  129. return (0xFF, code, b"Invalid channel data!")
  130. def trigger_configure(self, th_dir, thresh, auto_ms):
  131. """Configure trigger. Usage: trigger_configure <th_direction> <threshold> <auto_trigger_ms>"""
  132. try:
  133. resp = self.send_command(0x0A, th_dir, thresh, auto_ms) # Assuming 0x0A
  134. if resp:
  135. code, data = resp
  136. if code == 0xCC:
  137. return (0xCC, 0, 0)
  138. else:
  139. return (0xFF, code, data)
  140. except ValueError:
  141. return (0xFF, code, b"Invalid trigger data!")
  142. def set_premeasure(self, trig_premeasure):
  143. """Set premeasurement percentage. Usage: set_premeasurement <percentage>"""
  144. try:
  145. resp = self.send_command(0x0B, trig_premeasure) # Assuming 0x0B
  146. if resp:
  147. code, data = resp
  148. if code == 0xCC:
  149. return (0xCC, 0, 0)
  150. else:
  151. return (0xFF, code, data)
  152. except ValueError:
  153. return (0xFF, code, b"Invalid premeasurement!")
  154. def set_trignum(self, trig_num):
  155. pass # deprecated
  156. def start(self):
  157. """Start measurement."""
  158. resp = self.send_command(0x20)
  159. if resp:
  160. code, data = resp
  161. if code == 0xCC:
  162. return (0xCC, 0, 0)
  163. else:
  164. return (0xFF, code, data)
  165. def aqcuire_data(self):
  166. if not self.connected:
  167. print("Not connected.")
  168. return
  169. try:
  170. # Receive data packets
  171. unpacker = msgpack.Unpacker()
  172. data_collected = {}
  173. buf = bytearray()
  174. buf.extend(self.pk.pack(0xAA))
  175. buf.extend(self.pk.pack(0xBB))
  176. self.client_socket.sendall(buf)
  177. last_i = 0
  178. last_j = 0
  179. curr_data = []
  180. while True:
  181. resp_code, data = self.receive_response()
  182. #print("Chunk recieved!")
  183. #print(f'Resp: {resp_code} (need {0xCD} or {0xCE})')
  184. if resp_code == 0xCD:
  185. i, j, packet, size, packet_data = data[0], data[1], data[2], data[3], data[4]
  186. if last_j != j:
  187. print(f'Append channel {j}')
  188. self.channels_data.append(curr_data)
  189. curr_data = []
  190. if last_i != i:
  191. print(f'Append signal {i}')
  192. self.ndata.append(self.channels_data)
  193. self.channels_data = []
  194. last_i = i
  195. last_j = j
  196. curr_data.extend(packet_data)
  197. key = (i, j)
  198. #print("Received packet params.")
  199. if key not in data_collected:
  200. data_collected[key] = []
  201. #print("Key created!")
  202. data_collected[key].extend(packet_data) # Assuming packet is list of int16
  203. #print("Appended!")
  204. buf = bytearray()
  205. buf.extend(self.pk.pack(0xAA))
  206. buf.extend(self.pk.pack(0x3D))
  207. self.client_socket.sendall(buf)
  208. elif resp_code == 0xCE:
  209. self.channels_data.append(curr_data)
  210. self.ndata.append(self.channels_data)
  211. curr_data = []
  212. self.channels_data = []
  213. # Assemble data
  214. buf = bytearray()
  215. buf.extend(self.pk.pack(0xAA))
  216. buf.extend(self.pk.pack(0x3E))
  217. self.client_socket.sendall(buf)
  218. print("Data received and acknowledged.")
  219. return (0xBB, 0)
  220. else:
  221. print(f"Unexpected response: {resp_code}")
  222. return (0xFF, -1)
  223. except Exception as e:
  224. print(f"Send points failed: {e}")
  225. return (0xFF, -1)
  226. def stop(self):
  227. resp = self.send_command(0x03)
  228. if resp:
  229. code, data = resp
  230. if code == 0xCC:
  231. return (0xCC, 0, 0)
  232. else:
  233. return (0xFF, code, data)
  234. def clear_ndata(self):
  235. self.ndata = []
  236. self.channels_data = []
  237. class sync_default:
  238. def __init__(self, port):
  239. if(port != -1):
  240. self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  241. self.proto = {
  242. 'upload': 0x01,
  243. 'trig_wait': 0x02
  244. }
  245. self.serial = None
  246. def connect(self, port):
  247. self.client_socket.settimeout(5.0)
  248. resp = self.client_socket.connect(('localhost', port))
  249. return resp
  250. def resp_handler(self, resp, cmd):
  251. if(resp[0] != 0xAA):
  252. return (-1, 0)
  253. if(resp[1] == 0xFF):
  254. return (0xFF, resp[3])
  255. return (resp[1], 0)
  256. def upload(self, programPath, filePath, port):
  257. try:
  258. process = subprocess.run([programPath, filePath, '-p', str(port), '--debug'])
  259. except subprocess.CalledProcessError as e:
  260. print(f"Ошибка команды {e.cmd}!")
  261. return process.returncode
  262. def serial_open(self, port):
  263. try:
  264. self.serial = serial.Serial('COM' + str(port), 9600, timeout=1)
  265. except serial.SerialException as e:
  266. print(e)
  267. return (0xFF, -1)
  268. return(0x00, 0)
  269. def trig_wait(self, port):
  270. try:
  271. self.serial.write(b'e')
  272. except serial.SerialException as e:
  273. print(e)
  274. return (0xFF, -1)
  275. return(0x00, 0)
  276. def serial_close(self):
  277. try:
  278. self.serial.close()
  279. except:
  280. return (0xFF, -1)
  281. return (0x00, 0)
  282. class sdr_default:
  283. def __init__(self, port):
  284. if(port != -1):
  285. self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  286. self.proto = {
  287. 'transf': 0x01
  288. }
  289. def connect(self, port):
  290. self.client_socket.settimeout(5.0)
  291. resp = self.client_socket.connect(('localhost', port))
  292. return resp
  293. def transf(self, programPath, filePath, freq, rate, ampl, gain):
  294. try:
  295. process = subprocess.run([programPath, '-t', filePath, '-f', str(freq), '-s', str(rate), '-a', str(ampl), '-x', str(gain)], check=True)
  296. except subprocess.CalledProcessError as e:
  297. print(f"Ошибка команды {e.cmd}!")
  298. return (0xFF, -1)
  299. return (0x00, process.returncode)
  300. class gra_default:
  301. def __init__(self, ip, port):
  302. if(port != -1):
  303. self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  304. self.client_socket.settimeout(5.0)
  305. self.client_socket.connect((ip, port))
  306. self.proto = {
  307. 'reset': 0x0001,
  308. 'ps_on': 0x0003,
  309. 'ps_off': 0x0004,
  310. 'state': 0x0005,
  311. 'upload': 0x0006,
  312. 'send_packet': 0x0007,
  313. 'confirm': 0x0008
  314. }
  315. def connect(self, port):
  316. self.client_socket.settimeout(5.0)
  317. resp = self.client_socket.connect(('localhost', port))
  318. return resp
  319. def reset(self):
  320. msg = struct.pack('<HH', 0xAAAA, self.proto['reset'])
  321. self.client_socket.send(msg)
  322. def ps_on(self):
  323. msg = struct.pack('<HH', 0xAAAA, self.proto['ps_on'])
  324. self.client_socket.send(msg)
  325. def ps_off(self):
  326. msg = struct.pack('<HH', 0xAAAA, self.proto['ps_off'])
  327. self.client_socket.send(msg)
  328. def ps_off(self):
  329. msg = struct.pack('<HH', 0xAAAA, self.proto['ps_off'])
  330. self.client_socket.send(msg)
  331. def state(self):
  332. msg = struct.pack('<HH', 0xAAAA, self.proto['state'])
  333. self.client_socket.send(msg)
  334. resp = self.client_socket.recv(4096)
  335. if(len(resp) == 6):
  336. magic, cmd, state = struct.unpack('<HHH', resp)
  337. return (cmd, state, 0, 0)
  338. elif(len(resp) > 6):
  339. magic, cmd, state, errbits, errpoint, current_setting_amp, current_amp, first_sensor, second_sensor = struct.unpack('<HHHIIiiii', resp)
  340. return (cmd, state, errbits, errpoint)
  341. def send_packet(self, nom, nodes_num, nodes_buf):
  342. i = 0
  343. time1, time2 = struct.unpack('<HH', nodes_buf[i][0].to_bytes(4, 'little'))
  344. nom = nom | 0x8000
  345. msg = struct.pack('<HHHHHHH', 0xAAAA, self.proto['send_packet'], nom, nodes_num, time1, time2, nodes_buf[i][1].to_bytes(2, 'little'))
  346. while(i < nodes_num):
  347. i += 1
  348. time1, time2 = struct.unpack('<HH', nodes_buf[i][0].to_bytes(4, 'little'))
  349. msg += struct.pack('<HHH', time1, time2, nodes_buf[i][1].to_bytes(2, 'little'))
  350. self.client_socket.send(msg)
  351. resp = self.client_socket.recv(4096)
  352. data_resp = struct.unpack('<HHH', resp)
  353. return data_resp[3]
  354. def upload(self, points, nodes):
  355. points1, points2 = struct.unpack('<HH', points.to_bytes(4, 'little'))
  356. nodes1, nodes2 = struct.unpack('<HH', nodes[points-1][0].to_bytes(4, 'little'))
  357. msg = struct.pack('<HHHHHH', 0xAAAA, self.proto['upload'], points1, points2, nodes1, nodes2)
  358. self.client_socket.send(msg)
  359. seg_num = 0
  360. total_packets = points // 200 + 1
  361. first_idx = 0
  362. while(seg_num < total_packets):
  363. if((points - first_idx) < 200):
  364. nodes_packet = points - first_idx
  365. else:
  366. nodes_packet = 200
  367. last_idx = first_idx + nodes_packet
  368. resp = self.send_packet(seg_num, nodes_packet, nodes[first_idx:last_idx])
  369. print(resp)
  370. first_idx = last_idx
  371. seg_num += 1
  372. msg = struct.pack('<HH', 0xAAAA, 0x0008)
  373. self.client_socket.send(msg)