030——从GUI->Client->Server->driver实现对红外遥控的控制

目录

[1、 解决韦东山老师irda模块中断申请失败的bug](#1、 解决韦东山老师irda模块中断申请失败的bug)

[2、 client添加处理程序](#2、 client添加处理程序)

[3、 添加服务器处理程序和驱动处理句柄](#3、 添加服务器处理程序和驱动处理句柄)

[4、 处理数据读出不准确问题](#4、 处理数据读出不准确问题)

[5、 修改后的展示](#5、 修改后的展示)


1、 解决韦东山老师irda模块中断申请失败的bug

irda需要通过中断来触发读操作,申请中断需要引脚是输入模式,但是先插入电机后引脚会变成输出模式,所以插入驱动会报错。只要在init时加上一个引脚方向调整就好了。

cpp 复制代码
/* 在入口函数 */
static int __init irda_init(void)
{
    int err;
    int i;
    int count = sizeof(gpios)/sizeof(gpios[0]);
    
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	/*设置GPIO为输入方向*/
    err = gpio_direction_input(gpios[i].gpio);
	for (i = 0; i < count; i++)
	{		
		gpios[i].irq  = gpio_to_irq(gpios[i].gpio);

		setup_timer(&gpios[i].key_timer, key_timer_expire, (unsigned long)&gpios[i]);
	 	//timer_setup(&gpios[i].key_timer, key_timer_expire, 0);
		err = request_irq(gpios[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, gpios[i].name, &gpios[i]);
	}

	/* 注册file_operations 	*/
	major = register_chrdev(0, "cebss_irda", &gpio_key_drv);  /* /dev/gpio_desc */

	gpio_class = class_create(THIS_MODULE, "cebss_irda_class");
	if (IS_ERR(gpio_class)) {
		printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
		unregister_chrdev(major, "cebss_gpio_key");
		return PTR_ERR(gpio_class);
	}

	device_create(gpio_class, NULL, MKDEV(major, 0), NULL, "CEBSS_irda"); /* /dev/irda */
	
	return err;
}

2、 client添加处理程序

3、 添加服务器处理程序和驱动处理句柄

cpp 复制代码
/* TODO 传递参数后需改为使用通信结构体 */
/* TODO 所有的魔鬼数字都要进行定义 */
int select_driver(char * cmd, int acceptfd)
{
    int opt = 0;
    int get_data = 0;
    MSG drv_msg;
    char *tx_buffer;
    char buf[32];
    char *irda_data="";
    DIRECTION direction;
    CMD drv_cmd;

    if('@' == cmd[0])
    {
#if (STD_ON == DEBUG)
        printf("cmd[0] = @\n");
#endif/*STD_ON == DEBUG*/
        drv_msg.device = extract_digit_number(cmd, 1, 3);
        printf("device is %d\n", drv_msg.device);
        /*TODO 后续需升级为多线程模式调用驱动*/
        switch(drv_msg.device)
        {
            case 0:
                /*TODO 日志打印等级控制*/
                /*TODO用设备结构体后这里要封装一下*/
                printf("LED!!!\n");
                if ('g' == cmd[4])
                {
                    direction = direction_get;
                    drv_cmd = cmd_no;
                    led_handle(direction, &drv_cmd);
                    if (cmd_close == drv_cmd)
                    {
                        tx_buffer = "@000g0";
                    }
                    else if(cmd_open == drv_cmd)
                    {
                        tx_buffer = "@000g1";
                    }
                }
                else
                {
                    if ('1' == cmd[5])
                        drv_cmd = cmd_open;
                    else if ('0' == cmd[5])
                        drv_cmd = cmd_close;
                    direction = direction_put;
                    if (NOERROR == led_handle(direction, &drv_cmd))
                    {
                        tx_buffer = "@000p1";
                    }
                    else
                    {
                        tx_buffer = "@000p0";
                    }
                }               
                if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
                {
                    perror("send failed");  
                }
                break;
            case 1:
                printf("SR501!!!\n");
                /*TODO 这里封装成带回调函数的处理函数通过传入处理函数做数据处理*/
                if ('g' == cmd[4])
                {
                    
                    sr501_handle(&get_data);
                    if (sr501_some == get_data)
                    {
                        tx_buffer = "@001g1";
                    }
                    else if(sr501_nobody == get_data)
                    {
                        tx_buffer = "@001g0";
                    }
                }              
                if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
                {
                    perror("send failed");  
                }
                break;
            case 2:
                printf("SR04!!!\n");
                if ('g' == cmd[4])
                {
                    opt = sr04_handle(&get_data);
                    if (NOERROR == opt)
                    {
                        sprintf(buf,"@002g%03d", get_data);
                        tx_buffer = buf;
                    }
                    else
                    {
                        tx_buffer = "@002e";
                    }
                }
                printf(">>>>>>%s\n",tx_buffer);         
                if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
                {
                    perror("send failed");  
                }
                break;
            case 3:
                printf("IRDA!!!\n");
                if ('g' == cmd[4])
                {
                    opt = irda_handle(irda_data);
                    if (NOERROR == opt)
                    {
                        sprintf(buf,"@003g%s", irda_data);
                        tx_buffer = buf;
                    }
                    else
                    {
                        tx_buffer = "@003e";
                    }
                }
                printf(">>>>>>%s\n",tx_buffer);         
                if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
                {
                    perror("send failed");  
                }
                break;
            case 4:
                printf("motor!!!\n");
                if ('s' == cmd[4])
                {
                    if(0 == cmd[5])
                    {
                        /*/0 /n*/
                        get_data = extract_digit_number(cmd, 6, (strlen(&cmd[5])-2));
                    }
                    else
                    {
                        get_data = -extract_digit_number(cmd, 6, (strlen(&cmd[5])-2));
                    }
                    printf("getdata == %d\n",get_data);
                    opt = motor_handle(get_data);
                    if (NOERROR == opt)
                    {
                        tx_buffer = "@004s";
                    }
                    else
                    {
                        tx_buffer = "@004e";
                    }
                }      
                if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
                {
                    perror("send failed");  
                }
                break;
            case 5:
                printf("dht11!!!\n");
                break;
            case 6:
                printf("ds18b20!!!\n");
                break;
            case 7:
                printf("IIC!!!\n");
                break;
            case 8:
                printf("SPI!!!\n");
                break;
            default:
                printf("Unknown equipment!!!\n");
        }
    }
    else
    {
        printf("cmd[0] ERROR!!!\n");
        opt = ERROR;
    }
    opt = atoi(&cmd[1]);
    return opt;
}
cpp 复制代码
/*
*author   : xintianyu
*function : Handle irda Settings
*date     : 2024-4-19
-----------------------
author date  modify

*/
int irda_handle(char *data)
{
	/*传入参数后面要做通用处理使用空指针*/
    char *device = "/dev/CEBSS_irda";
	int buf[2];
    int ret = NOERROR;
	static int fd;
    /* 打开文件 */
	fd = open(device, O_RDWR);
	if (fd == -1)
	{
		printf("can not open file %s\n", device);
		return ERROR;
	}
read:
	if (read(fd, buf, 2) == 2)
	{
		printf("get irda: deivce 0x%02x, data 0x%02x\n", buf[0], buf[1]);
		switch(buf[1])
		{
            case 0x00: goto read;
			case 0xa2: data="RED";break;
			case 0xe2: data="MENU";break;
			case 0x22: data="TEST";break;
			case 0x02: data="+";break;
			case 0xe0: data="back";break;
			default:data="";printf("no this key!!!\n");break;
		}
	}
	else
	{
		printf("get irda: -1\n");
	    ret = ERROR;
	}
	close(fd);
    return ret;
}

4、 处理数据读出不准确问题

除非一直读不然会导致读出的数据都堆积

正常应该每个都是2位的,现在都导device里了

cpp 复制代码
/*
*author   : xintianyu
*function : Handle irda Settings
*date     : 2024-4-19
-----------------------
author date  modify

*/
int irda_handle(char *data)
{
	/*传入参数后面要做通用处理使用空指针*/
    char *device = "/dev/CEBSS_irda";
	unsigned char buf[2];
    int ret = NOERROR;
	static int fd;
    /* 打开文件 */
	fd = open(device, O_RDWR);
	if (fd == -1)
	{
		printf("can not open file %s\n", device);
		return ERROR;
	}
read:
	if (read(fd, buf, 2) == 2)
	{
		printf("get irda: deivce 0x%02x, data 0x%02x\n", buf[0], buf[1]);
		switch(buf[1])
		{
            case 0x00: goto read;
			case 0xa2: data="RED";break;
			case 0xe2: data="MENU";break;
			case 0x22: data="TEST";break;
			case 0x02: data="+";break;
			case 0xe0: data="back";break;
			default:data="";printf("no this key!!!\n");break;
		}
	}
	else
	{
		printf("get irda: -1\n");
	    ret = ERROR;
	}

	close(fd);
    return ret;
}

找到问题了,我的buf是整型的因为是直接从上面copy的

驱动这面是char

现在这面可以读到了

但是拿到的是空数据

应该是作用域的问题

我不想用数组就用**好了

果然可以拿到了,我在来处理一下数据

5、 修改后的展示

client

cpp 复制代码
'''
fuction : 客户端程序
author  : 辛天宇
date    : 2024-4-13
-------------------------------
author     date      modify
辛天宇   2024-4-15   结合GUI和网络通信

'''
import show
import tcp
import tool
import socket
import global_var


def send_handle(window, client_socket, values):
    global_var.TX_BUF = values['txbuff'] 
    print(f"txbuff={global_var.TX_BUF}")
    # 清理input
    window['txbuff'].update(value='')
    data = global_var.TX_BUF
    client_socket.sendall(data.encode())

def quit_handel(client_socket):
    cmd='Q'
    client_socket.sendall(cmd.encode())
    tcp.disconnect_to_server(client_socket)

def motor_handel(window, client_socket, values):
    i = int(values['MOTOR_I'])
    global_var.MOTOR_DATA = str(abs(i)%360)
    if i >= 0:
        global_var.MOTOR_DIRECTION='0'
    else:
        global_var.MOTOR_DIRECTION='1'
    message = 's'+global_var.MOTOR_DIRECTION+global_var.MOTOR_DATA
    # 清理input
    window['MOTOR_I'].update(value='0')
    set_tx_buf('motor', message)
    send_cmd(client_socket)

# 进行一次发送
def send_cmd(client_socket):
    data = global_var.TX_BUF
    client_socket.sendall(data.encode())

# 设置发送消息
def set_tx_buf(device, message): 
    if device == 'sr04':
        global_var.TX_BUF = '@002'+message
    if device == 'led':
        global_var.TX_BUF = '@000'+message
    elif device == 'sr501':
        global_var.TX_BUF = '@001'+message
    elif device == 'irda':
        global_var.TX_BUF = '@003'+message
    elif device == 'motor':
        global_var.TX_BUF = '@004'+message
    elif device == 'dht11':
        global_var.TX_BUF = '@005'+message
        print(f"dht11={global_var.TX_BUF}")
    elif device == 'ds18b20':
        global_var.TX_BUF = '@006'
    elif device == 'iic':
        global_var.TX_BUF = '@007'
    elif device == 'spi':
        global_var.TX_BUF = '@008'
    

# 处理数据
def cmd_handle(window):
    cmd = global_var.RX_BUF
    if len(cmd) < 4:
        print("cmd ERROR")
        return -1
    if '@' == cmd[0]:
        # 目前驱动设备数量只有两位数
        if cmd[1] == '0':
            # LED: @000+1位命令位+1位数据位
            if cmd[2] == '0' and cmd[3] == '0':
                if cmd[5] == '1':
                    print("LED Status change success")
                elif cmd[5] == '0':
                    print("LED Status change failure")
                else:
                    print("message ERROR")
            # SR501:@001+1位数据位
            elif cmd[2] == '0' and cmd[3] == '1':
                if cmd[5] == '1':
                    print("有人")
                    message='有人'
                    window['SR501_O'].update(message)
                elif cmd[5] == '0':
                    print("无人")
                    message='无人'
                    window['SR501_O'].update(message)
                else:
                    print("message ERROR")
            # SR04
            elif cmd[2] == '0' and cmd[3] == '2':
                if cmd[4] == 'g':
                    global_var.SR04_DATA = cmd[5:8]
                    message = f"{global_var.SR04_DATA}cm"
                    window['SR04_O'].update(message)
                else:
                    print("SR04: message ERROR")               
            #irda
            elif cmd[2] == '0' and cmd[3] == '3':
                # message = cmd[5]
                # print(message)
                if cmd[4] == 'g':
                    if cmd[5] == 'r':
                        global_var.IRDA_DATA = "RED"
                    elif cmd[5] == 'm':
                        global_var.IRDA_DATA = "MENU"
                    elif cmd[5] == 't':
                        global_var.IRDA_DATA = "TEST"
                    elif cmd[5] == '+':
                        global_var.IRDA_DATA = "+"
                    elif cmd[5] == 'b':
                        global_var.IRDA_DATA = "BACK"
                    elif cmd[5] == 'l':
                        global_var.IRDA_DATA = "LEFT"
                    elif cmd[5] == 'p':
                        global_var.IRDA_DATA = "START"
                    elif cmd[5] == 'r':
                        global_var.IRDA_DATA = "RIGHT"
                    elif cmd[5] == '0':
                        global_var.IRDA_DATA = "0"
                    elif cmd[5] == '1':
                        global_var.IRDA_DATA = "1"
                    elif cmd[5] == '2':
                        global_var.IRDA_DATA = "2"
                    elif cmd[5] == '-':
                        global_var.IRDA_DATA = "-"
                    elif cmd[5] == 'c':
                        global_var.IRDA_DATA = "c"
                    elif cmd[5] == '3':
                        global_var.IRDA_DATA = "3"
                    elif cmd[5] == '4':
                        global_var.IRDA_DATA = "4"
                    elif cmd[5] == '5':
                        global_var.IRDA_DATA = "5"
                    elif cmd[5] == '6':
                        global_var.IRDA_DATA = "6"
                    elif cmd[5] == '7':
                        global_var.IRDA_DATA = "7"
                    elif cmd[5] == '8':
                        global_var.IRDA_DATA = "8"
                    elif cmd[5] == '9':
                        global_var.IRDA_DATA = "9"
                    window['IRDA_O'].update(global_var.IRDA_DATA)
            #motor
            elif cmd[2] == '0' and cmd[3] == '4':
                if cmd[4] == 's':
                    print("MOTOR: message SCUESS") 
                else:
                    print("MOTOR: message ERROR")  
            #dht11
            elif cmd[2] == '0' and cmd[3] == '5':
                print(cmd[4:])
                global_var.TEM=cmd[4]+cmd[5]
                global_var.HUM=cmd[6]+cmd[7]
            #ds18b20
            elif cmd[2] == '0' and cmd[3] == '6':
                print(cmd[4:])
            #iic
            elif cmd[2] == '0' and cmd[3] == '7':
                print(cmd[4:])
            #spi
            elif cmd[2] == '0' and cmd[3] == '8':
                print(cmd[4:])

# 处理事件
def event_handle(window, client_socket):
    led = 0
    # 事件循环  
    while True:  
        try:
            cmd_handle(window)
            event, values = window.read()
            if event == 'input':
                window['txbuff'].update(disabled=not values['input'])
            elif event == 'send':
                send_handle(window, client_socket, values)
            elif event == 'Clean':
                window['Output'].update(value='')
            elif event == 'dht11':
                set_tx_buf('dht11', '2525')
                send_cmd(client_socket)
                message = f"{global_var.TEM}°C   {global_var.HUM}%"
                window['Getvalue'].update(message)
            elif event == 'ds18b20':
                set_tx_buf('ds18b20')
                send_cmd(client_socket)
                message = f"{global_var.TEM}°C"
                window['Getvalue'].update(message)
            elif event == 'Quit': 
                quit_handel(client_socket) 
                print(f"See you.............")
                break
            elif event is None:
                print(f"xxxxxxxxxxxxxxxxxxxx")
                break
            elif event == 'LED':
                if led % 2 == 0:
                    set_tx_buf('led','p1')
                else:
                    set_tx_buf('led','p0')
                led+=1
                if led > 100:
                    led = 0
                send_cmd(client_socket)
            elif event == 'SR501':
                set_tx_buf('sr501','g')
                send_cmd(client_socket)
            elif event == 'SR04':
                set_tx_buf('sr04','g')
                send_cmd(client_socket)
            elif event == 'IRDA':
                set_tx_buf('irda','g')
                send_cmd(client_socket)
            elif event == 'MOTOR':
                motor_handel(window, client_socket, values)
            # 处理其他事件...
        except Exception as e:
            window.close()
            print(f"An error occurred: {e}")
            return 0
        # 接收服务器的响应
        data = client_socket.recv(512)
        # 将字节字符串转化为字符串
        global_var.RX_BUF = data.decode('utf-8')
        # print(f"rx......{global_var.RX_BUF}") 
    window.close()
    return 0  

def main():
    # 创建GUI对象
    window = show.show_window('DefaultNoMoreNagging')
    # 尝试连接到服务器  
    client_socket = tcp.connect_to_server()
    if client_socket is not None: 
        event_handle(window, client_socket)

if __name__ == '__main__':
    main()

按下IRDA会阻塞按下遥控器上的按键解析后会更新。

相关推荐
凛铄linshuo7 分钟前
爬虫简单实操2——以贴吧为例爬取“某吧”前10页的网页代码
爬虫·python·学习
蓬荜生灰8 分钟前
永磁无刷电机旋转原理
单片机·嵌入式硬件
牛客企业服务9 分钟前
2025年AI面试推荐榜单,数字化招聘转型优选
人工智能·python·算法·面试·职场和发展·金融·求职招聘
胡斌附体22 分钟前
linux测试端口是否可被外部访问
linux·运维·服务器·python·测试·端口测试·临时服务器
愚润求学30 分钟前
【Linux】自旋锁和读写锁
linux·运维
大锦终32 分钟前
【Linux】常用基本指令
linux·运维·服务器·centos
IT项目管理43 分钟前
达梦数据库DMHS介绍及安装部署
linux·数据库
知北游天1 小时前
Linux:多线程---深入互斥&&浅谈同步
linux·运维·服务器
Gappsong8741 小时前
【Linux学习】Linux安装并配置Redis
java·linux·运维·网络安全
likeGhee1 小时前
python缓存装饰器实现方案
开发语言·python·缓存