Python GUI与C控制器Socket通信及SPI传输问题求助
问题解决方案
问题1:Python GUI Scale控件拖动过快导致数据丢失,改为松开触发发送
问题说明
原Scale控件使用command参数,拖动过程中每一次数值变化都会触发数据发送,拖动过快时会出现丢包;需要改为鼠标松开控件时才发送最终值。
解决方案
- 移除Scale的
command参数 - 给Scale控件绑定
<ButtonRelease-1>事件(鼠标左键松开事件),触发数据发送函数 - 调整
Configure函数适配事件绑定参数
修改后的关键代码
def Configure(event): dacCommand(0, 0, ch0, reg_X, group_0, ch_0, 1) if __name__ == "__main__": # ... 其余窗口初始化代码保持不变 ... # 创建Scale控件时移除command参数 ch0Scale = Scale(tab2, from_=0, to=Vmax, resolution=0.05, state="normal", variable=ch0, font='Helevetica 11', length=200, width=15) ch0Scale.grid(row=1, column=0, pady=5, padx=10, sticky='w') # 绑定鼠标左键松开事件 ch0Scale.bind("<ButtonRelease-1>", Configure) mainloop()
问题2:C控制器仅能接收GUI发送的第一个值
问题分析
accept被放在外层while(1)循环内,每次循环都会等待新连接,处理一次数据后就断开当前连接,无法在同一连接上持续接收- SPI设备在循环内被关闭,后续循环无法复用SPI资源
- 代码中使用了未定义的
tx_buffer变量,实际应为buffer - 未处理
read返回0(客户端断开连接)的异常情况
解决方案
- 将
accept留在外层循环负责等待新连接,新增内层循环在同一连接上持续接收数据 - SPI设备的打开与配置移到循环外,程序退出时再关闭
- 修正未定义变量问题
- 增加客户端断开连接的处理逻辑
修改后的关键代码
#define PORT 1234 int main(int argc, char *argv[]) { int server_fd, new_socket, valread; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[3] = {0}; int spi_fd; struct spi_ioc_transfer spi_transfer; unsigned char rx_buffer[3] = {0}; // Socket初始化、绑定、监听代码保持不变 ... // 仅初始化一次SPI设备 spi_fd = open("/dev/spidev0.0", O_RDWR); if (spi_fd < 0) { printf("Error: Failed to open SPI device.\n"); return -1; } u_int8_t mode = SPI_MODE_1; u_int8_t bits = 8; u_int32_t speed = 1000000; ioctl(spi_fd, SPI_IOC_WR_MODE, &mode); ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &bits); ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); while(1) { // 等待新客户端连接 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept"); exit(EXIT_FAILURE); } printf("Client connected\n"); // 内层循环:持续从当前连接接收数据 while(1) { memset(buffer, 0, sizeof(buffer)); valread = read(new_socket, buffer, 3); if (valread == 0) { // 客户端断开连接 printf("Client disconnected\n"); close(new_socket); break; } else if (valread < 0) { perror("read failed"); close(new_socket); break; } // 仅处理完整的3字节数据 if (valread == 3) { memset(&spi_transfer, 0, sizeof(spi_transfer)); spi_transfer.tx_buf = (unsigned long)buffer; spi_transfer.rx_buf = (unsigned long)rx_buffer; spi_transfer.len = sizeof(buffer); spi_transfer.speed_hz = speed; spi_transfer.bits_per_word = bits; spi_transfer.delay_usecs = 0; int status = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &spi_transfer); if (status < 0) { printf("Error: Failed to transfer data over SPI.\n"); } printf("Received message: %02x %02x %02x\n", buffer[0], buffer[1], buffer[2]); } } } close(spi_fd); close(server_fd); return 0; }
内容的提问来源于stack exchange,提问作者AlexandrosS
相关产品推荐
相关产品推荐

