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


    目录

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

    2、 client添加处理程序

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

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

    5、 修改后的展示


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

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

     

    1. /* 在入口函数 */
    2. static int __init irda_init(void)
    3. {
    4. int err;
    5. int i;
    6. int count = sizeof(gpios)/sizeof(gpios[0]);
    7. printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    8. /*设置GPIO为输入方向*/
    9. err = gpio_direction_input(gpios[i].gpio);
    10. for (i = 0; i < count; i++)
    11. {
    12. gpios[i].irq = gpio_to_irq(gpios[i].gpio);
    13. setup_timer(&gpios[i].key_timer, key_timer_expire, (unsigned long)&gpios[i]);
    14. //timer_setup(&gpios[i].key_timer, key_timer_expire, 0);
    15. err = request_irq(gpios[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, gpios[i].name, &gpios[i]);
    16. }
    17. /* 注册file_operations */
    18. major = register_chrdev(0, "cebss_irda", &gpio_key_drv); /* /dev/gpio_desc */
    19. gpio_class = class_create(THIS_MODULE, "cebss_irda_class");
    20. if (IS_ERR(gpio_class)) {
    21. printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    22. unregister_chrdev(major, "cebss_gpio_key");
    23. return PTR_ERR(gpio_class);
    24. }
    25. device_create(gpio_class, NULL, MKDEV(major, 0), NULL, "CEBSS_irda"); /* /dev/irda */
    26. return err;
    27. }

    2、 client添加处理程序

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

    1. /* TODO 传递参数后需改为使用通信结构体 */
    2. /* TODO 所有的魔鬼数字都要进行定义 */
    3. int select_driver(char * cmd, int acceptfd)
    4. {
    5. int opt = 0;
    6. int get_data = 0;
    7. MSG drv_msg;
    8. char *tx_buffer;
    9. char buf[32];
    10. char *irda_data="";
    11. DIRECTION direction;
    12. CMD drv_cmd;
    13. if('@' == cmd[0])
    14. {
    15. #if (STD_ON == DEBUG)
    16. printf("cmd[0] = @\n");
    17. #endif/*STD_ON == DEBUG*/
    18. drv_msg.device = extract_digit_number(cmd, 1, 3);
    19. printf("device is %d\n", drv_msg.device);
    20. /*TODO 后续需升级为多线程模式调用驱动*/
    21. switch(drv_msg.device)
    22. {
    23. case 0:
    24. /*TODO 日志打印等级控制*/
    25. /*TODO用设备结构体后这里要封装一下*/
    26. printf("LED!!!\n");
    27. if ('g' == cmd[4])
    28. {
    29. direction = direction_get;
    30. drv_cmd = cmd_no;
    31. led_handle(direction, &drv_cmd);
    32. if (cmd_close == drv_cmd)
    33. {
    34. tx_buffer = "@000g0";
    35. }
    36. else if(cmd_open == drv_cmd)
    37. {
    38. tx_buffer = "@000g1";
    39. }
    40. }
    41. else
    42. {
    43. if ('1' == cmd[5])
    44. drv_cmd = cmd_open;
    45. else if ('0' == cmd[5])
    46. drv_cmd = cmd_close;
    47. direction = direction_put;
    48. if (NOERROR == led_handle(direction, &drv_cmd))
    49. {
    50. tx_buffer = "@000p1";
    51. }
    52. else
    53. {
    54. tx_buffer = "@000p0";
    55. }
    56. }
    57. if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
    58. {
    59. perror("send failed");
    60. }
    61. break;
    62. case 1:
    63. printf("SR501!!!\n");
    64. /*TODO 这里封装成带回调函数的处理函数通过传入处理函数做数据处理*/
    65. if ('g' == cmd[4])
    66. {
    67. sr501_handle(&get_data);
    68. if (sr501_some == get_data)
    69. {
    70. tx_buffer = "@001g1";
    71. }
    72. else if(sr501_nobody == get_data)
    73. {
    74. tx_buffer = "@001g0";
    75. }
    76. }
    77. if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
    78. {
    79. perror("send failed");
    80. }
    81. break;
    82. case 2:
    83. printf("SR04!!!\n");
    84. if ('g' == cmd[4])
    85. {
    86. opt = sr04_handle(&get_data);
    87. if (NOERROR == opt)
    88. {
    89. sprintf(buf,"@002g%03d", get_data);
    90. tx_buffer = buf;
    91. }
    92. else
    93. {
    94. tx_buffer = "@002e";
    95. }
    96. }
    97. printf(">>>>>>%s\n",tx_buffer);
    98. if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
    99. {
    100. perror("send failed");
    101. }
    102. break;
    103. case 3:
    104. printf("IRDA!!!\n");
    105. if ('g' == cmd[4])
    106. {
    107. opt = irda_handle(irda_data);
    108. if (NOERROR == opt)
    109. {
    110. sprintf(buf,"@003g%s", irda_data);
    111. tx_buffer = buf;
    112. }
    113. else
    114. {
    115. tx_buffer = "@003e";
    116. }
    117. }
    118. printf(">>>>>>%s\n",tx_buffer);
    119. if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
    120. {
    121. perror("send failed");
    122. }
    123. break;
    124. case 4:
    125. printf("motor!!!\n");
    126. if ('s' == cmd[4])
    127. {
    128. if(0 == cmd[5])
    129. {
    130. /*/0 /n*/
    131. get_data = extract_digit_number(cmd, 6, (strlen(&cmd[5])-2));
    132. }
    133. else
    134. {
    135. get_data = -extract_digit_number(cmd, 6, (strlen(&cmd[5])-2));
    136. }
    137. printf("getdata == %d\n",get_data);
    138. opt = motor_handle(get_data);
    139. if (NOERROR == opt)
    140. {
    141. tx_buffer = "@004s";
    142. }
    143. else
    144. {
    145. tx_buffer = "@004e";
    146. }
    147. }
    148. if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
    149. {
    150. perror("send failed");
    151. }
    152. break;
    153. case 5:
    154. printf("dht11!!!\n");
    155. break;
    156. case 6:
    157. printf("ds18b20!!!\n");
    158. break;
    159. case 7:
    160. printf("IIC!!!\n");
    161. break;
    162. case 8:
    163. printf("SPI!!!\n");
    164. break;
    165. default:
    166. printf("Unknown equipment!!!\n");
    167. }
    168. }
    169. else
    170. {
    171. printf("cmd[0] ERROR!!!\n");
    172. opt = ERROR;
    173. }
    174. opt = atoi(&cmd[1]);
    175. return opt;
    176. }
    1. /*
    2. *author : xintianyu
    3. *function : Handle irda Settings
    4. *date : 2024-4-19
    5. -----------------------
    6. author date modify
    7. */
    8. int irda_handle(char *data)
    9. {
    10. /*传入参数后面要做通用处理使用空指针*/
    11. char *device = "/dev/CEBSS_irda";
    12. int buf[2];
    13. int ret = NOERROR;
    14. static int fd;
    15. /* 打开文件 */
    16. fd = open(device, O_RDWR);
    17. if (fd == -1)
    18. {
    19. printf("can not open file %s\n", device);
    20. return ERROR;
    21. }
    22. read:
    23. if (read(fd, buf, 2) == 2)
    24. {
    25. printf("get irda: deivce 0x%02x, data 0x%02x\n", buf[0], buf[1]);
    26. switch(buf[1])
    27. {
    28. case 0x00: goto read;
    29. case 0xa2: data="RED";break;
    30. case 0xe2: data="MENU";break;
    31. case 0x22: data="TEST";break;
    32. case 0x02: data="+";break;
    33. case 0xe0: data="back";break;
    34. default:data="";printf("no this key!!!\n");break;
    35. }
    36. }
    37. else
    38. {
    39. printf("get irda: -1\n");
    40. ret = ERROR;
    41. }
    42. close(fd);
    43. return ret;
    44. }

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

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

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

    1. /*
    2. *author : xintianyu
    3. *function : Handle irda Settings
    4. *date : 2024-4-19
    5. -----------------------
    6. author date modify
    7. */
    8. int irda_handle(char *data)
    9. {
    10. /*传入参数后面要做通用处理使用空指针*/
    11. char *device = "/dev/CEBSS_irda";
    12. unsigned char buf[2];
    13. int ret = NOERROR;
    14. static int fd;
    15. /* 打开文件 */
    16. fd = open(device, O_RDWR);
    17. if (fd == -1)
    18. {
    19. printf("can not open file %s\n", device);
    20. return ERROR;
    21. }
    22. read:
    23. if (read(fd, buf, 2) == 2)
    24. {
    25. printf("get irda: deivce 0x%02x, data 0x%02x\n", buf[0], buf[1]);
    26. switch(buf[1])
    27. {
    28. case 0x00: goto read;
    29. case 0xa2: data="RED";break;
    30. case 0xe2: data="MENU";break;
    31. case 0x22: data="TEST";break;
    32. case 0x02: data="+";break;
    33. case 0xe0: data="back";break;
    34. default:data="";printf("no this key!!!\n");break;
    35. }
    36. }
    37. else
    38. {
    39. printf("get irda: -1\n");
    40. ret = ERROR;
    41. }
    42. close(fd);
    43. return ret;
    44. }

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

    驱动这面是char

    现在这面可以读到了

    但是拿到的是空数据

    应该是作用域的问题

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

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

    5、 修改后的展示

    client

    1. '''
    2. fuction : 客户端程序
    3. author : 辛天宇
    4. date : 2024-4-13
    5. -------------------------------
    6. author date modify
    7. 辛天宇 2024-4-15 结合GUI和网络通信
    8. '''
    9. import show
    10. import tcp
    11. import tool
    12. import socket
    13. import global_var
    14. def send_handle(window, client_socket, values):
    15. global_var.TX_BUF = values['txbuff']
    16. print(f"txbuff={global_var.TX_BUF}")
    17. # 清理input
    18. window['txbuff'].update(value='')
    19. data = global_var.TX_BUF
    20. client_socket.sendall(data.encode())
    21. def quit_handel(client_socket):
    22. cmd='Q'
    23. client_socket.sendall(cmd.encode())
    24. tcp.disconnect_to_server(client_socket)
    25. def motor_handel(window, client_socket, values):
    26. i = int(values['MOTOR_I'])
    27. global_var.MOTOR_DATA = str(abs(i)%360)
    28. if i >= 0:
    29. global_var.MOTOR_DIRECTION='0'
    30. else:
    31. global_var.MOTOR_DIRECTION='1'
    32. message = 's'+global_var.MOTOR_DIRECTION+global_var.MOTOR_DATA
    33. # 清理input
    34. window['MOTOR_I'].update(value='0')
    35. set_tx_buf('motor', message)
    36. send_cmd(client_socket)
    37. # 进行一次发送
    38. def send_cmd(client_socket):
    39. data = global_var.TX_BUF
    40. client_socket.sendall(data.encode())
    41. # 设置发送消息
    42. def set_tx_buf(device, message):
    43. if device == 'sr04':
    44. global_var.TX_BUF = '@002'+message
    45. if device == 'led':
    46. global_var.TX_BUF = '@000'+message
    47. elif device == 'sr501':
    48. global_var.TX_BUF = '@001'+message
    49. elif device == 'irda':
    50. global_var.TX_BUF = '@003'+message
    51. elif device == 'motor':
    52. global_var.TX_BUF = '@004'+message
    53. elif device == 'dht11':
    54. global_var.TX_BUF = '@005'+message
    55. print(f"dht11={global_var.TX_BUF}")
    56. elif device == 'ds18b20':
    57. global_var.TX_BUF = '@006'
    58. elif device == 'iic':
    59. global_var.TX_BUF = '@007'
    60. elif device == 'spi':
    61. global_var.TX_BUF = '@008'
    62. # 处理数据
    63. def cmd_handle(window):
    64. cmd = global_var.RX_BUF
    65. if len(cmd) < 4:
    66. print("cmd ERROR")
    67. return -1
    68. if '@' == cmd[0]:
    69. # 目前驱动设备数量只有两位数
    70. if cmd[1] == '0':
    71. # LED: @000+1位命令位+1位数据位
    72. if cmd[2] == '0' and cmd[3] == '0':
    73. if cmd[5] == '1':
    74. print("LED Status change success")
    75. elif cmd[5] == '0':
    76. print("LED Status change failure")
    77. else:
    78. print("message ERROR")
    79. # SR501:@001+1位数据位
    80. elif cmd[2] == '0' and cmd[3] == '1':
    81. if cmd[5] == '1':
    82. print("有人")
    83. message='有人'
    84. window['SR501_O'].update(message)
    85. elif cmd[5] == '0':
    86. print("无人")
    87. message='无人'
    88. window['SR501_O'].update(message)
    89. else:
    90. print("message ERROR")
    91. # SR04
    92. elif cmd[2] == '0' and cmd[3] == '2':
    93. if cmd[4] == 'g':
    94. global_var.SR04_DATA = cmd[5:8]
    95. message = f"{global_var.SR04_DATA}cm"
    96. window['SR04_O'].update(message)
    97. else:
    98. print("SR04: message ERROR")
    99. #irda
    100. elif cmd[2] == '0' and cmd[3] == '3':
    101. # message = cmd[5]
    102. # print(message)
    103. if cmd[4] == 'g':
    104. if cmd[5] == 'r':
    105. global_var.IRDA_DATA = "RED"
    106. elif cmd[5] == 'm':
    107. global_var.IRDA_DATA = "MENU"
    108. elif cmd[5] == 't':
    109. global_var.IRDA_DATA = "TEST"
    110. elif cmd[5] == '+':
    111. global_var.IRDA_DATA = "+"
    112. elif cmd[5] == 'b':
    113. global_var.IRDA_DATA = "BACK"
    114. elif cmd[5] == 'l':
    115. global_var.IRDA_DATA = "LEFT"
    116. elif cmd[5] == 'p':
    117. global_var.IRDA_DATA = "START"
    118. elif cmd[5] == 'r':
    119. global_var.IRDA_DATA = "RIGHT"
    120. elif cmd[5] == '0':
    121. global_var.IRDA_DATA = "0"
    122. elif cmd[5] == '1':
    123. global_var.IRDA_DATA = "1"
    124. elif cmd[5] == '2':
    125. global_var.IRDA_DATA = "2"
    126. elif cmd[5] == '-':
    127. global_var.IRDA_DATA = "-"
    128. elif cmd[5] == 'c':
    129. global_var.IRDA_DATA = "c"
    130. elif cmd[5] == '3':
    131. global_var.IRDA_DATA = "3"
    132. elif cmd[5] == '4':
    133. global_var.IRDA_DATA = "4"
    134. elif cmd[5] == '5':
    135. global_var.IRDA_DATA = "5"
    136. elif cmd[5] == '6':
    137. global_var.IRDA_DATA = "6"
    138. elif cmd[5] == '7':
    139. global_var.IRDA_DATA = "7"
    140. elif cmd[5] == '8':
    141. global_var.IRDA_DATA = "8"
    142. elif cmd[5] == '9':
    143. global_var.IRDA_DATA = "9"
    144. window['IRDA_O'].update(global_var.IRDA_DATA)
    145. #motor
    146. elif cmd[2] == '0' and cmd[3] == '4':
    147. if cmd[4] == 's':
    148. print("MOTOR: message SCUESS")
    149. else:
    150. print("MOTOR: message ERROR")
    151. #dht11
    152. elif cmd[2] == '0' and cmd[3] == '5':
    153. print(cmd[4:])
    154. global_var.TEM=cmd[4]+cmd[5]
    155. global_var.HUM=cmd[6]+cmd[7]
    156. #ds18b20
    157. elif cmd[2] == '0' and cmd[3] == '6':
    158. print(cmd[4:])
    159. #iic
    160. elif cmd[2] == '0' and cmd[3] == '7':
    161. print(cmd[4:])
    162. #spi
    163. elif cmd[2] == '0' and cmd[3] == '8':
    164. print(cmd[4:])
    165. # 处理事件
    166. def event_handle(window, client_socket):
    167. led = 0
    168. # 事件循环
    169. while True:
    170. try:
    171. cmd_handle(window)
    172. event, values = window.read()
    173. if event == 'input':
    174. window['txbuff'].update(disabled=not values['input'])
    175. elif event == 'send':
    176. send_handle(window, client_socket, values)
    177. elif event == 'Clean':
    178. window['Output'].update(value='')
    179. elif event == 'dht11':
    180. set_tx_buf('dht11', '2525')
    181. send_cmd(client_socket)
    182. message = f"{global_var.TEM}°C {global_var.HUM}%"
    183. window['Getvalue'].update(message)
    184. elif event == 'ds18b20':
    185. set_tx_buf('ds18b20')
    186. send_cmd(client_socket)
    187. message = f"{global_var.TEM}°C"
    188. window['Getvalue'].update(message)
    189. elif event == 'Quit':
    190. quit_handel(client_socket)
    191. print(f"See you.............")
    192. break
    193. elif event is None:
    194. print(f"xxxxxxxxxxxxxxxxxxxx")
    195. break
    196. elif event == 'LED':
    197. if led % 2 == 0:
    198. set_tx_buf('led','p1')
    199. else:
    200. set_tx_buf('led','p0')
    201. led+=1
    202. if led > 100:
    203. led = 0
    204. send_cmd(client_socket)
    205. elif event == 'SR501':
    206. set_tx_buf('sr501','g')
    207. send_cmd(client_socket)
    208. elif event == 'SR04':
    209. set_tx_buf('sr04','g')
    210. send_cmd(client_socket)
    211. elif event == 'IRDA':
    212. set_tx_buf('irda','g')
    213. send_cmd(client_socket)
    214. elif event == 'MOTOR':
    215. motor_handel(window, client_socket, values)
    216. # 处理其他事件...
    217. except Exception as e:
    218. window.close()
    219. print(f"An error occurred: {e}")
    220. return 0
    221. # 接收服务器的响应
    222. data = client_socket.recv(512)
    223. # 将字节字符串转化为字符串
    224. global_var.RX_BUF = data.decode('utf-8')
    225. # print(f"rx......{global_var.RX_BUF}")
    226. window.close()
    227. return 0
    228. def main():
    229. # 创建GUI对象
    230. window = show.show_window('DefaultNoMoreNagging')
    231. # 尝试连接到服务器
    232. client_socket = tcp.connect_to_server()
    233. if client_socket is not None:
    234. event_handle(window, client_socket)
    235. if __name__ == '__main__':
    236. main()

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

  • 相关阅读:
    ATF源码篇(九):docs文件夹-Components组件(8)固件升级
    初阶C语言 - 分支语句(if、switch)
    使用远程桌面软件改善工作与生活的平衡
    企业网络自动化配置
    浏览器原生JavaScript离线文字转语音TTS播放,支持Windows自带TTS语音和移动端(安卓、IOS)
    Pinia(二)了解和使用Store
    C++: 冒泡排序(Bubble Sort)
    Pytorch中实例化一个数据集的类,用于网络训练
    MATALAB绘制色图变换和Voronoi图
    redis 实现互相关注功能
  • 原文地址:https://blog.csdn.net/qq_52479948/article/details/137966306