• 基于Linux的智能家居(工厂模式)


    目录

    1.项目概述

    2.程序框架

    3.函数准备

    3.1需要函数知识点

    3.2编码提醒

    4.代码

    5.注意事项


    1.项目概述

    控制端有两个,语音串口UART和Tcp通讯。

    执行端有IO输出和IO输入。

    2.程序框架

    程序分为3部分-------------1.输入控制  2.输出设备  3.主函数-多线程

    输入控制的模块----实现指令的收集,并将数据放在一个定义的头文件种。

    输出设备模块----实现设备初始化、设备启动、设备关闭的函数封装放在种。

    主函数-----实现UART和Tcp两个接收线程,不断接收指令并解析指令调用不同的设备函数封装

    亮点,在<.h>封装了一个类,调用<.h>可以编码一个对象,然后用链表将一类对象串起来。

    将对象的功能实现都封装成了函数,放在对象的结构体中,使用时直接调用。

    3.函数准备

    3.1需要函数知识点

    main中

    • 线程创建、线程退出、线程等待、wiringPi库、链表增加、链表查找

    • 链表创建、函数指针

    设备控制、输入控制中

    • wiringPi库、结构体赋值、链表增加

    3.2编码提醒

    出现不能用NULL指针,包含头文件

    香橙派编译wiringpi库时用gcc  buzzer.c -o test -lwiringPi -lwiringPiDev -lpthread -Im -Icrypt -Irt

    C语言函数没有return语句时,会返回最后一次赋值的变量的值

    函数指针是定义一个指针指向函数,调用时直接用P()或者(*p)()都行,函数名和函数地址一样

    指针有点神奇,指针是一个地址,但是同时也可以直接用指针使用地址里的值

    没办法:这里的代码在结构体实现里用了函数的递归。错错错。第575课,添加声音识别模块,形参和实参不一样的。形参只是形式,需要函数调用时赋予实参。

    炫技:这里的代码用了链表串联设备

    堆栈的存储:在函数体前面的变量,后面的函数可以直接用

    Orangepi的引脚图

    4.代码

    main中

    1. #include
    2. #include
    3. #include "contrldevice.h"
    4. #include "inputcmd.h"
    5. #include
    6. #include
    7. #include
    8. #include
    9. struct OutputDevice * pdevicehead=NULL; /*device head */
    10. struct InputDevice * pInputhead=NULL; /*Input head */
    11. struct InputDevice * tmp=NULL;
    12. struct OutputDevice *find_cmd_device(char *name,struct OutputDevice * pdevicehead)
    13. {
    14. struct OutputDevice *tmp=pdevicehead;
    15. if(tmp==NULL ){ /* compare is correct*/
    16. return NULL;
    17. }else{
    18. while(tmp!=NULL){
    19. if(0==strcmp(tmp->device_name,name)){
    20. return tmp;
    21. }
    22. tmp=tmp->next;
    23. }
    24. return NULL;
    25. }
    26. }
    27. struct InputDevice *find_input_device(char *name,struct InputDevice * pdevicehead)
    28. {
    29. struct InputDevice *tmp=pdevicehead;
    30. if(tmp==NULL ){ /* compare is correct*/
    31. return NULL;
    32. }else{
    33. while(tmp!=NULL){
    34. if(0==strcmp(tmp->cmddevice_name,name)){
    35. return tmp;
    36. }
    37. tmp=tmp->next;
    38. }
    39. return NULL;
    40. }
    41. }
    42. void * voice_thread(void *data) /* voice_thread */
    43. {
    44. int nread;
    45. struct InputDevice * tmp=find_input_device("voice",pInputhead);
    46. if(tmp==NULL){
    47. printf("no find voice phead!\r\n");
    48. pthread_exit(NULL);
    49. }else{
    50. if(tmp->init(tmp)==-1){
    51. printf("voice init faild!\r\n");
    52. pthread_exit(NULL);
    53. }
    54. }
    55. while(1){
    56. memset(tmp->cmd,0,sizeof(tmp->cmd));
    57. nread=tmp->getcmd(tmp); /* when uart no data come cmd while get uart overtime */
    58. if(nread==0){
    59. printf("voice cmd no data arival!\r\n");
    60. }else{
    61. printf("voice recive %d data:%s\r\n",nread,tmp->cmd);
    62. }
    63. }
    64. }
    65. void * sockread_thread(void *data)
    66. {
    67. int nread;
    68. while(1){
    69. memset(tmp->cmd,'\0',sizeof(tmp->cmd));
    70. nread=read(tmp->ss_fd,&tmp->cmd,sizeof(tmp->cmd));
    71. if(nread==0){ /* cannot recv cmd */
    72. printf("connect is cutdon! \r\n");
    73. pthread_exit(NULL);
    74. }else{ /*can recive cmd */
    75. printf("server receved %d cmd:%s \r\n",nread,tmp->cmd);
    76. }
    77. }
    78. }
    79. void * socket_thread(void *data)
    80. {
    81. int nread;
    82. pthread_t socketreadthread;
    83. tmp=find_input_device("socket",pInputhead);
    84. if(tmp==NULL){
    85. printf("no find socket phead!\r\n");
    86. pthread_exit(NULL);
    87. }else{
    88. if(tmp->init(tmp)==-1){
    89. printf("socket init faild!\r\n");
    90. pthread_exit(NULL);
    91. }
    92. }
    93. while(1){
    94. if(tmp->getcmd(tmp)==-1){
    95. perror("error"); /* get ss_fd error */
    96. }
    97. /*socket read线程*/
    98. pthread_create(&socketreadthread,NULL,sockread_thread,NULL);
    99. pthread_join(socketreadthread,NULL); /* 等读线程退出在进行 */
    100. }
    101. }
    102. int main(void)
    103. {
    104. char device_name[32];
    105. pthread_t voicethread;
    106. pthread_t socketthread;
    107. if(-1==wiringPiSetup()){
    108. printf("wiringpi init fail!\r\n");
    109. return 0;
    110. }
    111. /*1.指令工厂初始化 加入设备 */
    112. pInputhead=add_input_voice(pInputhead);
    113. pInputhead=add_input_socket(pInputhead);
    114. /*2.设备工厂初始化 加入设备 */
    115. pdevicehead=add_device_dingnerlight(pdevicehead);
    116. pdevicehead=add_device_restlight(pdevicehead);
    117. pdevicehead=add_device_firedetect(pdevicehead);
    118. /*2.1找设备 */
    119. /*struct OutputDevice * tmp=find_cmd_device(device_name,pdevicehead);
    120. while(1){
    121. printf("input device name:");
    122. scanf("%s",device_name);
    123. tmp=find_cmd_device(device_name,pdevicehead);
    124. printf("input cmd name 1/2:");
    125. scanf("%d",&cmd);
    126. switch(cmd){
    127. case 1:
    128. tmp->init();
    129. tmp->open();
    130. break;
    131. case 2:
    132. tmp->init();
    133. tmp->close();
    134. break;
    135. default:
    136. printf("no this cmd");
    137. break;
    138. }
    139. }*/
    140. /*3. 线程池建立*/
    141. /*3.1 语音线程*/
    142. pthread_create(&voicethread,NULL,voice_thread,NULL);
    143. /*3.2socket线程*/
    144. pthread_create(&socketthread,NULL,socket_thread,NULL);
    145. /*3.3摄像头线程*/
    146. /*3.4 火灾线程*/
    147. pthread_join(voicethread,NULL); /*线程等待不让主程序退出*/
    148. pthread_join(socketthread,NULL); /*线程等待不让主程序退出*/
    149. return 0;
    150. }

    contrldevice.h

    1. #include
    2. struct OutputDevice{
    3. char device_name[32];
    4. int status;
    5. int (*init)();
    6. int (*open)();
    7. int (*close)();
    8. int (*read)();
    9. int (*changeStatus)();
    10. struct OutputDevice *next;
    11. };
    12. struct OutputDevice * add_device_dingnerlight(struct OutputDevice *phead);
    13. struct OutputDevice * add_device_restlight(struct OutputDevice *phead);
    14. struct OutputDevice * add_device_firedetect(struct OutputDevice *phead);

    inputcmd.h

    1. #include
    2. struct InputDevice{
    3. char cmddevice_name[32];
    4. char cmd[32];
    5. int fd;
    6. int ss_fd;
    7. int (*init)();
    8. int (*getcmd)();
    9. struct InputDevice *next;
    10. };
    11. struct InputDevice * add_input_voice(struct InputDevice *phead);
    12. struct InputDevice * add_input_socket(struct InputDevice *phead);

    dingnerlight.c

    1. #include
    2. #include "contrldevice.h" //include i can use struct
    3. #include
    4. #define dingnerlightPin 2
    5. /*struct OutputDevive{
    6. char device_name[32];
    7. int status;
    8. int (*init)();
    9. int (*open)();
    10. int (*close)();
    11. int (*read)();
    12. int (*changeStatus)();
    13. sturct OutputDevive *next;
    14. } */
    15. int dingnerlight_init(void)
    16. {
    17. pinMode(dingnerlightPin,OUTPUT);
    18. digitalWrite(dingnerlightPin,HIGH);
    19. return 0;
    20. }
    21. int dingnerlight_open(void)
    22. {
    23. digitalWrite(dingnerlightPin,LOW);
    24. return 0;
    25. }
    26. int dingnerlight_close(void)
    27. {
    28. digitalWrite(dingnerlightPin,HIGH);
    29. return 0;
    30. }
    31. struct OutputDevice dingnerlight={ /*"this give valve not init"*/
    32. .device_name="dingnerlight",
    33. .init=dingnerlight_init,
    34. .open=dingnerlight_open,
    35. .close=dingnerlight_close
    36. };
    37. struct OutputDevice * add_device_dingnerlight(struct OutputDevice *phead)
    38. {
    39. if(phead==NULL){
    40. return &dingnerlight;
    41. }else{
    42. dingnerlight.next=phead;
    43. phead=&dingnerlight;
    44. return phead;
    45. }
    46. }

    firedetect.c

    1. #include
    2. #include "contrldevice.h" //include i can use struct
    3. #include
    4. #define firedetectPin 6
    5. /*struct OutputDevice{
    6. char device_name[32];
    7. int status;
    8. int (*init)();
    9. int (*open)();
    10. int (*close)();
    11. int (*read)();
    12. int (*changeStatus)();
    13. sturct OutputDevive *next;
    14. } */
    15. int firedetect_init(void)
    16. {
    17. pinMode(firedetectPin,INPUT);
    18. return 0;
    19. }
    20. int firedetect_read(void)
    21. {
    22. return digitalRead(firedetectPin);
    23. }
    24. struct OutputDevice firedetect={ /*"this give valve not init"*/
    25. .device_name="firedetect",
    26. .init=firedetect_init,
    27. .read=firedetect_read
    28. };
    29. struct OutputDevice * add_device_firedetect(struct OutputDevice *phead)
    30. {
    31. if(phead==NULL){
    32. return &firedetect;
    33. }else{
    34. firedetect.next=phead;
    35. phead=&firedetect;
    36. return phead;
    37. }
    38. }

    restlight.c

    1. #include
    2. #include "contrldevice.h" //include i can use struct
    3. #include
    4. #define restlightPin 8
    5. /*struct OutputDevice{
    6. char device_name[32];
    7. int status;
    8. int (*init)();
    9. int (*open)();
    10. int (*close)();
    11. int (*read)();
    12. int (*changeStatus)();
    13. sturct OutputDevice *next;
    14. } */
    15. int restlight_init(void)
    16. {
    17. pinMode(restlightPin,OUTPUT);
    18. digitalWrite(restlightPin,HIGH);
    19. return 0;
    20. }
    21. int restlight_open(void)
    22. {
    23. digitalWrite(restlightPin,LOW);
    24. return 0;
    25. }
    26. int restlight_close(void)
    27. {
    28. digitalWrite(restlightPin,HIGH);
    29. return 0;
    30. }
    31. struct OutputDevice restlight={ /*"this give valve not init"*/
    32. .device_name="restlight",
    33. .init=restlight_init,
    34. .open=restlight_open,
    35. .close=restlight_close
    36. };
    37. struct OutputDevice * add_device_restlight(struct OutputDevice *phead)
    38. {
    39. if(phead==NULL){
    40. return &restlight;
    41. }else{
    42. restlight.next=phead;
    43. return &restlight;
    44. }
    45. }

    socketcmd.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include "inputcmd.h"/*include i can use struct*/
    9. /*struct InputDevice{
    10. char cmddevice_name[32];
    11. char cmd[32];
    12. int fd;
    13. int ss_fd;
    14. int (*init)();
    15. int (*getcmd)();
    16. struct InputDevice *next;
    17. }; */
    18. int socket_getcmd(struct InputDevice *phead)
    19. {
    20. int len;
    21. struct sockaddr_in c_ddr; /*save clinet msg*/
    22. /*4.accept come and connect for once*/
    23. len=sizeof(c_ddr);
    24. phead->ss_fd=accept(phead->fd,(struct sockaddr *)&c_ddr,&len);
    25. if(phead->ss_fd == -1){
    26. perror("accept:");
    27. }
    28. /*5.read from connect ss_fd*/
    29. /*5.2 read*/
    30. printf("conect succese!==========\r\n");
    31. return phead->ss_fd;
    32. }
    33. int socket_init(struct InputDevice *phead)
    34. {
    35. int s_fd;
    36. struct sockaddr_in s_ddr; /*build server msg*/
    37. s_fd= socket(AF_INET, SOCK_STREAM, 0);/*1.build a soket specified*/
    38. if(s_fd==-1){
    39. perror("error is");
    40. }
    41. /*2.build all bind*/
    42. s_ddr.sin_family=AF_INET;
    43. s_ddr.sin_port=htons(8880);
    44. s_ddr.sin_addr.s_addr=htonl(INADDR_ANY);
    45. /*give the bind*/
    46. bind(s_fd,(struct sockaddr *)&s_ddr,sizeof(s_ddr));
    47. /*3.waite for client*/
    48. listen(s_fd,8);
    49. phead->fd=s_fd;
    50. return s_fd;
    51. }
    52. struct InputDevice struc_socket={
    53. .cmd={0},
    54. .cmddevice_name="socket",
    55. .init=socket_init,
    56. .getcmd=socket_getcmd
    57. };
    58. struct InputDevice * add_input_socket(struct InputDevice *phead)
    59. {
    60. if(phead==NULL){
    61. return &struc_socket;
    62. }else{
    63. struc_socket.next=phead;
    64. phead=&struc_socket;
    65. return phead;
    66. }
    67. }

    voicecmd.c

    1. //include i can use struct
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include "inputcmd.h"
    7. /*struct InputDevice{
    8. char cmddevice_name[32];
    9. char cmd[32];
    10. int fd;
    11. int (*init)();
    12. int (*getcmd)();
    13. sturct InputDevice *next;
    14. } */
    15. int voice_getcmd(struct InputDevice *phead)
    16. {
    17. int nread;
    18. nread=read(phead->fd,phead->cmd,sizeof(phead->cmd));
    19. return nread;
    20. }
    21. int voice_init(struct InputDevice *phead)
    22. {
    23. int fd1;
    24. if((fd1=serialOpen("/dev/ttyS5",115200))<0){
    25. printf("uart init fail!\r\n");
    26. exit(-1);
    27. }
    28. phead->fd=fd1;
    29. return fd1;
    30. }
    31. struct InputDevice voice={
    32. .cmd={0},
    33. .cmddevice_name="voice",
    34. .init=voice_init,
    35. .getcmd=voice_getcmd
    36. };
    37. struct InputDevice * add_input_voice(struct InputDevice *phead)
    38. {
    39. if(phead==NULL){
    40. return &voice;
    41. }else{
    42. voice.next=phead;
    43. phead=&voice;
    44. return phead;
    45. }
    46. }

    5.注意事项

  • 相关阅读:
    VScode配置 github 上传代码
    Python使用大漠插件前的准备工作
    最新接口自动化面试题
    MySQL的卸载与安装
    [题]当天是该年的第几天? #switch的小用法
    CleanMyMacX4.11.3最新版mac电脑磁盘清理工具功能
    30.【十进制和二进制的相互转化(超详解)】
    Redis 规范部署手册
    【广州华锐互动】VR模拟真实火灾场景,教你如何正确逃生和自救
    图像的高频和低频细节
  • 原文地址:https://blog.csdn.net/m0_67794575/article/details/132665056