尝试使用套接字从 GUI 传递值到另一个应用程序。

huangapple go评论96阅读模式
英文:

Attempting to pass values from GUI to another app with socket

问题

以下是您要的代码的翻译:

  1. 如标题所述我试图创建两个独立的应用程序一个是GUI/客户端另一个是控制器/服务器
  2. GUI使用多个滑块从用户那里获取输入并通过套接字将值传输给控制器
  3. 控制器接收数据并通过SPI连接将其传输到另一个外围设备
  4. 程序传输第一个值然后崩溃我得到的错误信息是这两个
  5. 连接被对等方重置的错误和断开的管道错误
  6. GUI代码如下
  7. def Configure(e):
  8. Command(0, 0, ch0, reg_X, group_0, ch_0, 1)
  9. def dacCommand(bus, dev, dacVar, command, dacGroup, dacChannel, multFac):
  10. Vref = 3
  11. offsetCode = 0x1555
  12. M = 65535
  13. C = 32768
  14. Iout = dacVar.get()
  15. Vout = Iout * multFac
  16. byte1 = command | dacGroup | dacChannel
  17. dacCode = math.ceil(Vout * (2**16) / (4 * Vref) + 4 * offsetCode)
  18. inputCode = math.floor((dacCode - C + (2**15)) * (2**16) / (M + 1))
  19. d = struct.pack('<H', inputCode)
  20. data = [0, 0, 0]
  21. dataCommand = [byte1, d[1], d[0]]
  22. byte1bin = f'{byte1:08b}'
  23. byte2bin = f'{d[1]:08b}'
  24. byte3bin = f'{d[0]:08b}'
  25. dataString = byte1bin + byte2bin + byte3bin
  26. client_socket.send(bytes(dataString, "utf-8"))
  27. if __name__ == "__main__":
  28. window = Tk()
  29. window.title('DACs board control')
  30. window.geometry('1920x900')
  31. tab_control = ttk.Notebook(window)
  32. tab2 = Frame(tab_control)
  33. tab_control.add(tab2, text='dev1 control')
  34. tab_control.pack(expand=1, fill="both")
  35. ch0 = DoubleVar()
  36. ttk.Label(tab2, text="ch0 (V)", font=("Calibri", 12)).grid(column=0, row=0, padx=10,
  37. pady=5)
  38. ch0Scale = Scale(tab2, from_=0, to=Vmax, resolution=0.05, state="normal", variable=
  39. ch0, command=Configure, font='Helevetica 11', length=200, width=15).grid(row=1,
  40. column=0, pady=5, padx=10, sticky='w')
  41. mainloop()

控制器代码如下:

  1. if __name__ == "__main__":
  2. spi = spidev.SpiDev()
  3. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  4. s.bind((socket.gethostname(), 1234))
  5. s.listen(5)
  6. conn, address = s.accept()
  7. print(f"Connection from {address} has been established.")
  8. while True:
  9. command = conn.recv(24)
  10. if not command:
  11. break
  12. spi.open(0, 0)
  13. spi.mode = 0b01
  14. spi.max_speed_hz = 1000000
  15. part1 = command[:8]
  16. part2 = command[8: 16]
  17. part3 = command[16:]
  18. spi.xfer2([int(part1, 2), int(part2, 2), int(part3, 2)]
  19. spi.close()
  20. conn.close()

希望这些翻译对您有所帮助。如果您有任何其他问题,请随时提问。

英文:

As i state in the title i'm trying to create a 2 seperate applications, one being a GUI/client and the other being a controller/server.

The GUI uses several sliders to take an input from the user and transfers the value to the controller through a socket.

The controller receives the data and transfers it to another peripheral device, through a SPI connection.

The program transfers the first value and then proceeds to crash. The errors i get are these two :
error connection reset by peer and error broken pipe.

The gui code is

  1. def Configure(e):
  2. Command(0, 0, ch0, reg_X, group_0, ch_0, 1)
  3. def dacCommand(bus,dev,dacVar,command,dacGroup,dacChannel,multFac):
  4. Vref = 3
  5. offsetCode = 0x1555
  6. M = 65535
  7. C= 32768
  8. Iout=dacVar.get()
  9. Vout=Iout*multFac
  10. byte1 = command|dacGroup|dacChannel
  11. dacCode=math.ceil(Vout*(2**16)/(4*Vref)+4*offsetCode)
  12. inputCode=math.floor((dacCode-C+(2**15))*(2**16)/(M+1))
  13. d = struct.pack(&#39;&lt;H&#39;, inputCode)
  14. data= [0, 0, 0 ]
  15. dataCommand = [byte1, d[1], d[0]]
  16. byte1bin=f&#39;{byte1:08b}&#39;
  17. byte2bin=f&#39;{d[1]:08b}&#39;
  18. byte3bin=f&#39;{d[0]:08b}&#39;
  19. dataString=byte1bin+byte2bin+byte3bin
  20. client_socket.send(bytes(dataString,&quot;utf-8&quot;))
  21. if __name__ == &quot;__main__&quot;:
  22. window = Tk()
  23. window.title(&#39;DACs board control&#39;)
  24. window.geometry(&#39;1920x900&#39;)
  25. tab_control = ttk.Notebook( window)
  26. tab2 = Frame( tab_control)
  27. tab_control.add(tab2, text= &#39;dev1 control&#39;)
  28. tab_control.pack(expand= 1, fill= &quot;both&quot;)
  29. ch0 = DoubleVar()
  30. ttk.Label(tab2, text= &quot;ch0 (V)&quot;, font= (&quot;Calibri&quot;, 12)).grid(column= 0, row= 0, padx= 10,
  31. pady= 5)
  32. ch0Scale = Scale(tab2, from_= 0, to = Vmax, resolution = 0.05, state = &quot;normal&quot;, variable=
  33. ch0, command= Configure, font=&#39;Helevetica 11&#39;, length = 200, width = 15).grid(row = 1,
  34. column = 0, pady = 5, padx = 10, sticky = &#39;w&#39;)
  35. mainloop()

The controller code is :

  1. if __name__ == &quot;__main__&quot;:
  2. spi=spidev.SpiDev()
  3. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  4. s.bind((socket.gethostname(), 1234))
  5. s.listen(5)
  6. conn, address = s.accept()
  7. print(f&quot;Connection from {address} has been established.&quot;)
  8. while True:
  9. command = conn.recv(24)
  10. if not command:
  11. break
  12. spi.open(0,0)
  13. spi.mode = 0b01
  14. spi.max_speed_hz = 1000000
  15. part1=command[:8]
  16. part2=command[8: 16]
  17. part3=command[16:]
  18. spi.xfer2([int(part1,2),int(part2,2),int(part3,2)])
  19. spi.close()
  20. conn.close()

答案1

得分: 1

客户端和服务器正在执行单个发送和接收操作,为了解决您的问题,您应该使客户端和服务器通过持续通信来维护连接。

首先,在服务器端,您应该修改您的代码如下:

  1. if __name__ == "__main__":
  2. # ...
  3. while True:
  4. conn, address = s.accept()
  5. print(f"Connection from {address} has been established.")
  6. while True:
  7. command = conn.recv(24)
  8. if not command:
  9. break
  10. # ...
  11. conn.close()

然后在客户端端:

  1. from tkinter import filedialog
  2. def Configure(e):
  3. # ...
  4. if __name__ == "__main__":
  5. # ...
  6. window.createfilehandler(client_socket, tkinter.READABLE, Configure)
  7. # ...
  8. mainloop()
  9. window.deletefilehandler(client_socket)

它应该可以工作,但由于 recv 可能会出现更多问题,您应该考虑异步编程或多线程。

英文:

The client and server are doing a single send and receive operation, to fix your problem you should make the client and server maintain the connection by a continuous communication.

first on the server side you should modify your code like this:

  1. if __name__ == &quot;__main__&quot;:
  2. # ...
  3. while True:
  4. conn, address = s.accept()
  5. print(f&quot;Connection from {address} has been established.&quot;)
  6. while True:
  7. command = conn.recv(24)
  8. if not command:
  9. break
  10. # ...
  11. conn.close()

then on the client side:

  1. from tkinter import filedialog
  2. def Configure(e):
  3. # ...
  4. if __name__ == &quot;__main__&quot;:
  5. # ...
  6. window.createfilehandler(client_socket, tkinter.READABLE, Configure)
  7. # ...
  8. mainloop()
  9. window.deletefilehandler(client_socket)

it should work but you might have more issues because of recv you should look into asynchronous programming or multithreading.

答案2

得分: 1

Send the bytes. It appears you need to send the input code big-endian, so use &gt; instead of &lt; in the format string and include the command byte. Use sendall to ensure all 3 bytes are sent (very likely even with send() but send() can send less under the right conditions).

  1. data = struct.pack('>BH', byte1, inputCode)
  2. client_socket.sendall(data)

On the client, read the 3 bytes. Note you should check the return value of conn.recv to make sure it actually receives 3 bytes. The value is a maximum to receive.

  1. data = conn.recv(3)
  2. if len(data) != 3:
  3. # deal with it
  4. spi.xfer2(list(data)) # list on bytes data will return the values,
  5. # e.g., b'\x01\x02\x03' returns [1, 2, 3].
  6. # May not be needed if the function accepts
  7. # byte strings...
英文:

No need to send actual ones and zeros. Send the bytes. It appears you need to send the input code big-endian, so use &gt; instead of &lt; in the format string and include the command byte. Use sendall to ensure all 3 bytes are sent (very likely even with send() but send() can send less under the right conditions.

  1. data = struct.pack(&#39;&gt;BH&#39;, byte1, inputCode)
  2. client_socket.sendall(data)

On the client, read the 3 bytes. Note you should check the return value of conn.recv to make sure it actually receives 3 bytes. The value is a maximum to receive.

  1. data = conn.recv(3)
  2. if len(data) != 3:
  3. # deal with it
  4. spi.xfer2(list(data)) # list on bytes data will return the values,
  5. # e.g., b&#39;\x01\x02\x03&#39; returns [1, 2, 3].
  6. # May not be needed if the function accepts
  7. # byte strings...

huangapple
  • 本文由 发表于 2023年4月4日 16:10:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926969.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定