• 【智能家居】7、主程序编写+实现语音、网络和串口功能


    需要毕业论文私信有偿获取

    截止目前mainPro.c代码

    1. #include
    2. #include
    3. #include "controlDevices.h"
    4. #include "inputCmd.h"
    5. struct Devices *findDevicesName(char *name,struct Devices *phead){
    6. struct Devices *tmp=phead;
    7. if(phead==NULL){
    8. return NULL;
    9. }else{
    10. while(tmp!=NULL){
    11. if(strcmp(tmp->devicesName,name)==0){
    12. return tmp;
    13. }
    14. tmp=tmp->next;
    15. }
    16. return NULL;
    17. }
    18. }
    19. int main(){
    20. if(wiringPiSetup()==-1){
    21. return -1;
    22. }
    23. struct Devices *pdevicesHead=NULL;
    24. struct InputCmd *pinputCmdHead=NULL;
    25. pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);
    26. pdevicesHead=addupstairLightToDevicesLink(pdevicesHead);
    27. pdevicesHead=addlivingroomLightToDevicesLink(pdevicesHead);
    28. pdevicesHead=addrestaurantLightToDevicesLink(pdevicesHead);
    29. pdevicesHead=addFireToDevicesLink(pdevicesHead);
    30. pinputCmdHead=addVoiceToInputCmdLink(pinputCmdHead);
    31. pinputCmdHead=addSocketToInputCmdLink(pinputCmdHead);
    32. char name[128]={'\0'};
    33. struct Devices *tmp=NULL;
    34. while(1){
    35. printf("INPUT:\n");
    36. scanf("%s",name);
    37. tmp=findDevicesName(name,pdevicesHead);
    38. if(tmp!=NULL){
    39. tmp->devicesInit(tmp->pinNum);
    40. tmp->open(tmp->pinNum);
    41. tmp->readStatus(tmp->pinNum);
    42. }
    43. }
    44. return 0;
    45. }

    一、编写流程

    1、工厂初始化

     将指令和设备结构体指针定义为全局变量

    (1)指令工厂初始化

    1. /*指令工厂初始化*/
    2. pinputCmdHead=addVoiceToInputCmdLink(pinputCmdHead);
    3. pinputCmdHead=addSocketToInputCmdLink(pinputCmdHead);

    (2)设备控制工厂初始化

    1. /*设备工厂初始化*/
    2. pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);
    3. pdevicesHead=addupstairLightToDevicesLink(pdevicesHead);
    4. pdevicesHead=addlivingroomLightToDevicesLink(pdevicesHead);
    5. pdevicesHead=addrestaurantLightToDevicesLink(pdevicesHead);
    6. pdevicesHead=addFireToDevicesLink(pdevicesHead);

    2、查找指令名称函数

    1. struct InputCmd *findCmdName(char *name,struct InputCmd *phead){
    2. struct InputCmd *tmp=phead;
    3. if(phead==NULL){
    4. return NULL;
    5. }else{
    6. while(tmp!=NULL){
    7. if(strcmp(tmp->cmdName,name)==0){
    8. return tmp;
    9. }
    10. tmp=tmp->next;
    11. }
    12. return NULL;
    13. }
    14. }

    3、线程池

    pthread_t *thread类型为指向 pthread_t 类型的指针,用于存储新创建线程的标识符。当线程成功创建后,函数会将新线程的 ID 值填入这个地址所指向的位置。

    const pthread_attr_t *attr类型为指向 pthread_attr_t 结构体的常量指针,用来指定线程属性,如线程的调度策略、优先级、栈大小等。如果不需要设置特定属性,可以传入 NULL,使用默认属性。

    void *(*start_routine)(void *)类型为指向函数的指针,该函数接收一个 void * 类型的参数,并返回 void * 类型的值。这是新线程开始执行时调用的函数,通常被称为线程入口函数或线程启动例程。

    void *arg类型为 void *,这是一个通用指针,作为传递给 start_routine 函数的唯一参数。程序员可以通过这个参数向线程传递任意类型的数据。

    函数返回值:

    • 如果成功创建线程,返回0。
    • 如果失败,则返回一个非零错误码,可以通过宏 pthread_getspecific() 来获取错误信息。

    pthread_create() 创建了一个新的线程,并安排它从指定的 start_routine 函数开始执行,同时可以传递一个自定义参数给这个线程函数

    (1)语音线程

    1. /*语音线程*/
    2. pthread_create(&voice_thread,NULL,voice_thread,NULL);
    1)线程标识符(线程ID存储位置)

    pthread_creat参数一

    2)线程入口函数

    pthread_creat参数三

    1. void *voice_thread(void *data){
    2. struct InputCmd *voiceHandler;
    3. int nread;
    4. voiceHandler=findCmdName("voice",pinputCmdHead);
    5. if(voiceHandler==NULL){
    6. printf("voiceHandler unfound!\n");
    7. pthread_exit(NULL);
    8. }else{
    9. if(voiceHandler->Init(voiceHandler,NULL,NULL)<0){
    10. printf("voice init error!\n");
    11. pthread_exit(NULL);
    12. }
    13. while(1){
    14. voiceHandler->getCmd(voiceHandler);
    15. if(nread==0){
    16. printf("voice no data was received!\n");
    17. }else{
    18. printf("voice received data:%s\n",voiceHandler->cmd);
    19. }
    20. }
    21. }
    22. }

    (2)Socket线程

    1. /*Socket线程*/
    2. pthread_create(&socket_thread,NULL,socket_thread,NULL);
    1)线程标识符(线程ID存储位置)

    pthread_creat参数一

    2)线程入口函数

    pthread_creat参数三

    1. void *socket_thread(void *data){
    2. int nread=0;
    3. pthread_t readThread;
    4. struct sockaddr_in c_addr;
    5. memset(&c_addr,0,sizeof(struct sockaddr_in));
    6. int len=sizeof(struct sockaddr_in);
    7. socketHandler=findCmdName("socket",pinputCmdHead);
    8. if(socketHandler==NULL){
    9. printf("socketHandler unfound!\n");
    10. pthread_exit(NULL);
    11. }
    12. socketHandler->Init(socketHandler,NULL,NULL);
    13. while (1){
    14. c_fd=accept(socketHandler->s_fd,(struct sockaddr *)&c_addr,&len);
    15. pthread_create(&readThread,NULL,read_thread,NULL);
    16. }
    17. }

    read线程参数三

    1. void *read_thread(void *data){
    2. int n_read;
    3. n_read=read(c_fd,socketHandler->cmd,sizeof(socketHandler->cmd));
    4. if(n_read==-1){
    5. perror("read");
    6. }else if(n_read>0){
    7. printf("\nget:%d %s\n",n_read,socketHandler->cmd);
    8. }else{
    9. printf("client quit!\n");
    10. }
    11. }

    4、mainPro.c

    1. #include
    2. #include
    3. #include "controlDevices.h"
    4. #include "inputCmd.h"
    5. #include
    6. int c_fd;
    7. struct Devices *pdevicesHead=NULL;
    8. struct InputCmd *pinputCmdHead=NULL;
    9. struct InputCmd *socketHandler=NULL;
    10. struct Devices *findDevicesName(char *name,struct Devices *phead){
    11. struct Devices *tmp=phead;
    12. if(phead==NULL){
    13. return NULL;
    14. }else{
    15. while(tmp!=NULL){
    16. if(strcmp(tmp->devicesName,name)==0){
    17. return tmp;
    18. }
    19. tmp=tmp->next;
    20. }
    21. return NULL;
    22. }
    23. }
    24. struct InputCmd *findCmdName(char *name,struct InputCmd *phead){
    25. struct InputCmd *tmp=phead;
    26. if(phead==NULL){
    27. return NULL;
    28. }else{
    29. while(tmp!=NULL){
    30. if(strcmp(tmp->cmdName,name)==0){
    31. return tmp;
    32. }
    33. tmp=tmp->next;
    34. }
    35. return NULL;
    36. }
    37. }
    38. void *voice_thread(void *data){
    39. struct InputCmd *voiceHandler;
    40. printf("voice_thread\n");
    41. int nread;//接收串口字节数
    42. voiceHandler=findCmdName("voice",pinputCmdHead);
    43. if(voiceHandler==NULL){
    44. printf("voiceHandler unfound!\n");
    45. pthread_exit(NULL);
    46. }else{
    47. if(voiceHandler->Init(voiceHandler,NULL,NULL)<0){
    48. printf("voice init error!\n");
    49. pthread_exit(NULL);
    50. }else{
    51. /*初始化语音*/
    52. printf("%s init success\n",voiceHandler->cmdName);
    53. }
    54. while(1){
    55. nread=voiceHandler->getCmd(voiceHandler);
    56. if(nread==0){
    57. printf("voice no data was received!\n");
    58. }else{
    59. printf("voice received data:%s\n",voiceHandler->cmd);
    60. }
    61. }
    62. }
    63. }
    64. void *read_thread(void *data){
    65. printf("read_thread\n");
    66. int n_read;
    67. /*清空命令接收区,方便下次检测*/
    68. memset(socketHandler->cmd,'\0',sizeof(socketHandler->cmd));
    69. n_read=read(c_fd,socketHandler->cmd,sizeof(socketHandler->cmd));
    70. if(n_read==-1){
    71. perror("read");
    72. }else if(n_read>0){
    73. printf("\nget:%d %s\n",n_read,socketHandler->cmd);
    74. }else{
    75. printf("client quit!\n");
    76. }
    77. }
    78. void *socket_thread(void *data){
    79. printf("socket_thread\n");
    80. int nread=0;
    81. pthread_t readThread;
    82. struct sockaddr_in c_addr;
    83. memset(&c_addr,0,sizeof(struct sockaddr_in));
    84. int len=sizeof(struct sockaddr_in);
    85. /*从命令工厂找到网络设备*/
    86. socketHandler=findCmdName("socket",pinputCmdHead);
    87. if(socketHandler==NULL){
    88. printf("socketHandler unfound!\n");
    89. pthread_exit(NULL);
    90. }else{
    91. printf("%s init success\n",socketHandler->cmdName);
    92. }
    93. /*初始化网络*/
    94. socketHandler->Init(socketHandler,NULL,NULL);
    95. /*不断监听客户端发送的数据,并创建线程处理*/
    96. while (1){
    97. c_fd=accept(socketHandler->s_fd,(struct sockaddr *)&c_addr,&len);
    98. pthread_create(&readThread,NULL,read_thread,NULL);
    99. }
    100. }
    101. int main(){
    102. char name[128]={'\0'};
    103. struct Devices *tmp=NULL;
    104. pthread_t voiceThread;
    105. pthread_t socketThread;
    106. if(wiringPiSetup()==-1){
    107. return -1;
    108. }
    109. printf("main\n");
    110. /*指令工厂初始化*/
    111. pinputCmdHead=addVoiceToInputCmdLink(pinputCmdHead);
    112. pinputCmdHead=addSocketToInputCmdLink(pinputCmdHead);
    113. /*设备工厂初始化*/
    114. pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);
    115. pdevicesHead=addupstairLightToDevicesLink(pdevicesHead);
    116. pdevicesHead=addlivingroomLightToDevicesLink(pdevicesHead);
    117. pdevicesHead=addrestaurantLightToDevicesLink(pdevicesHead);
    118. pdevicesHead=addFireToDevicesLink(pdevicesHead);
    119. /*线程池*/
    120. //pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(start_routine)(void *),void *arg);
    121. /*语音线程*/
    122. pthread_create(&voiceThread,NULL,voice_thread,NULL);
    123. /*Socket线程*/
    124. pthread_create(&socketThread,NULL,socket_thread,NULL);
    125. pthread_join(voiceThread,NULL);
    126. pthread_join(socketThread,NULL);
    127. // while(1){
    128. // printf("INPUT:\n");
    129. // scanf("%s",name);
    130. // tmp=findDevicesName(name,pdevicesHead);
    131. // if(tmp!=NULL){
    132. // tmp->devicesInit(tmp->pinNum);
    133. // tmp->open(tmp->pinNum);
    134. // tmp->readStatus(tmp->pinNum);
    135. // }
    136. // }
    137. return 0;
    138. }

    二、测试

    1、在树莓派上编译成功

    2、打印一些信息查看程序运行情况

    (1)mainPro.c(语音和网络线程是否创建成功)

    (2)Socket.c(网络线程是否进入监听)

    (3)编译测试

    gcc mainPro.c controlDevices.c bathroomLight.c livingroomLight.c restaurantLight.c upstairLight.c monitor.c socket.c voice.c -L ./ -lwiringPi -lpthread -o sh
    在语音初始化中开启串口报错Permission denied,权限不足

    解决办法

    1. sudo chmod 666 /dev/ttyAMA0 (修改权限)
    2. sudo ./sh (管理员方式运行,sh是编译后生成的可执行文件)

    运行成功

    网络调试助手网络功能测试

    串口功能测试

  • 相关阅读:
    python基础——基础语法
    人工神经网络理论设计及应用课后题答案韩力群
    三、Dockerfile自定义镜像
    lambdaQueryWrapper常用方法
    【word技巧】如何在word文件中方框打对勾?
    SpringCloud 之初识 GateWay
    线程中断机制和LockSupport
    23 距离判别
    Windows安装MySQL
    SQLServer连接表
  • 原文地址:https://blog.csdn.net/weixin_53062144/article/details/135889213