You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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发送的第一个值

问题分析

  1. accept被放在外层while(1)循环内,每次循环都会等待新连接,处理一次数据后就断开当前连接,无法在同一连接上持续接收
  2. SPI设备在循环内被关闭,后续循环无法复用SPI资源
  3. 代码中使用了未定义的tx_buffer变量,实际应为buffer
  4. 未处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 07:09:57