一、智能家居项目框架设计 1.代码设计思路草图: 2.代码思路讲解: a)一个指令工厂,一个控制工厂,实际上就是通过链表链起来的数据。具体怎么链接起来,就是基于简单工厂模式的类与对象的概念,上一篇文章有学习记录。 b)主函数语音指令程序和tcp指令程序各起一个线程,然后通过指令找到对应的控制程序,实现对应的模块的功能。 二、智能家居架构文件代码工程建立 有了思路之后,我们就可以来建立项目文件代码了。 1.我们先再桌面建立一个项目文件: 2.然后打开文件,逐个写好先: 3.然后打开Souce Insight,把文件都导入进去 因为用这个来写,更加的直观和方便。 三、浴室灯代码实现 1.先看主函数mainPro.c #include<stdio.h> #include"controlDevices.h" #include<string.h> struct Devices *findDeviceByName(char *name,struct Devices *phead) { struct Devices *tmp = phead; if(phead == NULL){ return NULL; }else{ while(tmp != NULL){ if(strcmp(tmp->deviceName,name) ==0){ return tmp; } tmp = tmp->next; } return NULL; } } int main() { char *name ="bathroomLight"; if(-1==wiringPiSetup()){ return-1; } struct Devices *pdeviceHead = NULL; pdeviceHead =addBathroomLightInit(pdeviceHead); struct Devices *tmp =findDeviceByName(name,pdeviceHead); if(tmp != NULL){ tmp->deviceInit(tmp->pinNum); tmp->open(tmp->pinNum); } return0; } 2.外设设备的头文件controlDevices.h #include<wiringPi.h> #include<stdlib.h> struct Devices { char deviceName[128]; int pinNum; int (*deviceInit)(int pinNum;); int (*open)(int pinNum;); int (*close)(int pinNum;); struct Devices *next; }; struct Devices *addBathroomLightInit(struct Devices *phead); 3.浴室灯bathroomLight.c #include"controlDevices.h" int bathroomLightInit(int pinNum) { pinMode(pinNum,OUTPUT); digitalWrite(pinNum,HIGH); } int bathroomLightOpen(int pinNum) { digitalWrite(pinNum,LOW); } int bathroomLightClose(int pinNum) { digitalWrite(pinNum,HIGH); } struct Devices bathroomLight = { .deviceName ="bathroomLight", .pinNum =28, .deviceInit = bathroomLightInit, .open = bathroomLightOpen, .close = bathroomLightClose }; struct Devices *addBathroomLightInit(struct Devices *phead) { if(phead == NULL){ return&bathroomLight; }else{ bathroomLight.next = phead; phead =&bathroomLight; } } 4.写完之后,利用FileZilla文件传输软件,将文件smartHouse文件传到树莓派终端: 5.进行代码编译,然后执行: 6.测试结果: 7.继电器其余四盏灯全部实现: 其余三盏灯的代码格式和上面bathroomLight.c的一样,这里就不一一展示,已经实现了。 等所有的模块都测试完,会有整个项目的实现效果和总结。 四、火焰检测和蜂鸣器模块测试 它们也是io口驱动,跟实现灯代码一样,就是要注意模块的使用说明。 1.火焰传感器fire.c #include"controlDevices.h" int fireInit(int pinNum) { pinMode(pinNum,INPUT); digitalWrite(pinNum,HIGH); } int fireStatusRead(int pinNum) { returndigitalRead(pinNum); } struct Devices fire = { .deviceName ="fire", .pinNum =0, .deviceInit = fireInit, .readStatus = fireStatusRead }; struct Devices *addFireToDevicesLink(struct Devices *phead) { if(phead == NULL){ return&fire; }else{ fire.next = phead; phead =&fire; } } 2.蜂鸣器buzzer.c #include"controlDevices.h" int buzzerInit(int pinNum) { pinMode(pinNum,OUTPUT); digitalWrite(pinNum,HIGH); } int buzzerOpen(int pinNum) { digitalWrite(pinNum,LOW); } int buzzerClose(int pinNum) { digitalWrite(pinNum,HIGH); } struct Devices buzzer = { .deviceName ="buzzer", .pinNum =7, .deviceInit = buzzerInit, .open = buzzerOpen, .close = buzzerClose }; struct Devices *addBuzzerToDevicesLink(struct Devices *phead) { if(phead == NULL){ return&buzzer; }else{ buzzer.next = phead; phead =&buzzer; } } 3.外设设备的头文件controlDevices.h #include<wiringPi.h> #include<stdlib.h> struct Devices { char deviceName[128]; int pinNum; int (*deviceInit)(int pinNum); int (*open)(int pinNum); int (*close)(int pinNum); int (*readStatus)(int pinNum); struct Devices *next; }; struct Devices *addBathroomLightToDevicesLink(struct Devices *phead); struct Devices *addLivingroomLightToDevicesLink(struct Devices *phead); struct Devices *addSwimmingpoolLightToDevicesLink(struct Devices *phead); struct Devices *addUpstairLightToDevicesLink(struct Devices *phead); struct Devices *addFireToDevicesLink(struct Devices *phead); struct Devices *addBuzzerToDevicesLink(struct Devices *phead); 4.主函数测试代码mainPro.c #include<stdio.h> #include"controlDevices.h" #include<string.h> struct Devices *findDevicesByName(char *name,struct Devices *phead) { struct Devices *tmp = phead; if(phead == NULL){ return NULL; }else{ while(tmp != NULL){ if(strcmp(tmp->deviceName,name) ==0){ return tmp; } tmp = tmp->next; } return NULL; } } int main() { int status; char name[128]; struct Devices *tmp = NULL; if(-1==wiringPiSetup()){ return-1; } struct Devices *pdeviceHead = NULL; pdeviceHead =addBathroomLightToDevicesLink(pdeviceHead); pdeviceHead =addLivingroomLightToDevicesLink(pdeviceHead); pdeviceHead =addUpstairLightToDevicesLink(pdeviceHead); pdeviceHead =addSwimmingpoolLightToDevicesLink(pdeviceHead); pdeviceHead =addFireToDevicesLink(pdeviceHead); pdeviceHead =addBuzzerToDevicesLink(pdeviceHead); struct Devices *fireDevicesTmp = NULL; struct Devices *buzzerDevicesTmp = NULL; fireDevicesTmp =findDevicesByName("fire",pdeviceHead);//在设备工厂找到火灾模块 buzzerDevicesTmp =findDevicesByName("buzzer",pdeviceHead);//在设备工厂找到蜂鸣器模块 fireDevicesTmp->deviceInit(fireDevicesTmp->pinNum);//火灾模块初始化 buzzerDevicesTmp->deviceInit(buzzerDevicesTmp->pinNum);//蜂鸣器初始化 while(1){ status = fireDevicesTmp->readStatus(fireDevicesTmp->pinNum);//不断获取火灾模块的数据 if(status ==0){ buzzerDevicesTmp->open(buzzerDevicesTmp->pinNum); }else{ buzzerDevicesTmp->close(buzzerDevicesTmp->pinNum); } } return0; } 5.测试结果: 编译运行 运行结果 五、添加语音模块的串口读取功能 语音模块之前有学过,这里主要通过主控芯片树莓派的串口跟语音模块连接。 树莓派的T接语音模块的R 树莓派的R接语音模块的T 然后就是供电 我们先把语音模块的代码整合到指令链表链表当中去: 1.语音控制设备voicevoiceContrl.c #include"inputCommand.h"#include<stdio.h> #include<wiringSerial.h> #include<unistd.h> int voiceInit(struct InputCommander *voicer,char *ipAdress,char *port) { int fd; if((fd =serialOpen(voicer->deviceName,9600)) ==-1){ exit(-1); } voicer->fd = fd; return fd; } int voiceGetCommand(struct InputCommander *voicer) { int nread =0; nread =read(voicer->fd,voicer->command,sizeof(voicer->command)); if(nread ==0){ printf("usart for voice read over time\n"); }else{ return nread; } } struct InputCommander voiceContrl = { .commandName ="voice", .deviceName ="/dev/ttyAMA0", .command = {'\0'}, .Init = voiceInit, .getCommand = voiceGetCommand }; struct InputCommander *addVoiceContrlToInputCommandLink(struct InputCommander *phead) { if(phead == NULL){ return&voiceContrl; }else{ voiceContrl.next = phead; return&voiceContrl; } } 2.控制设备的头文件inputCommand.h #include<wiringPi.h> #include<stdlib.h> struct InputCommander { char commandName[128]; char deviceName[128]; char command[32]; int (*Init)(struct InputCommander *voicer,char *ipAdress,char *port); int (*getCommand)(struct InputCommander *voicer); char log[1024]; int fd; struct InputCommander *next; }; struct InputCommander *addVoiceContrlToInputCommandLink(struct InputCommander *phead); 3.先运行测试一下: 代码没问题。 六、添加socket服务器功能 这里跟语音模块一样,我们先把socket服务器加到控制链表中去。 这里也基于语音模块代码来写。 #include"inputCommand.h" #include<stdio.h> #include<wiringSerial.h> #include<unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <fcntl.h> int socketInit(struct InputCommander *socketMes,char *ipAdress,char *port) { int s_fd; s_fd =socket(AF_INET,SOCK_STREAM,0); if(s_fd ==-1){ perror("socket"); exit(-1); } struct sockaddr_in s_addr; memset(&s_addr,0,sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; s_addr.sin_port =htons(atoi(socketMes->port)); inet_aton(socketMes->ipAdress,&s_addr.sin_addr); bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in)); listen(s_fd,10); socketMes->sfd = s_fd; return s_fd; } int socketGetCommand(struct InputCommander *socketMes) { int c_fd; int nread =0; struct sockaddr_in c_addr; memset(&c_addr,0,sizeof(struct sockaddr_in)); int clen =sizeof(struct sockaddr_in); c_fd =accept(socketMes->sfd,(struct sockaddr *)&c_addr,&clen); nread =read(c_fd,socketMes->command,sizeof(socketMes->command)); return nread; } struct InputCommander socketContrl = { .commandName ="socketServer", .command = {'\0'}, .port ="8088", .ipAdress ="192.168.31.80", .Init = socketInit, .getCommand = socketGetCommand }; struct InputCommander *addSocketContrlToInputCommandLink(struct InputCommander *phead) { if(phead == NULL){ return&socketContrl; }else{ socketContrl.next = phead; return&socketContrl; } } 2.控制设备的头文件inputCommand.h #include<wiringPi.h> #include<stdlib.h> #include<string.h> struct InputCommander { char commandName[128]; char deviceName[128]; char command[32]; int (*Init)(struct InputCommander *voicer,char *ipAdress,char *port); int (*getCommand)(struct InputCommander *voicer); char log[1024]; int fd; char port[12]; char ipAdress[32]; int sfd; struct InputCommander *next; }; struct InputCommander *addVoiceContrlToInputCommandLink(struct InputCommander *phead); struct InputCommander *addSocketContrlToInputCommandLink(struct InputCommander *phead); #include<wiringPi.h> #include<stdlib.h> #include<string.h> struct InputCommander { char commandName[128]; char deviceName[128]; char command[32]; int (*Init)(struct InputCommander *voicer,char *ipAdress,char *port); int (*getCommand)(struct InputCommander *voicer); char log[1024]; int fd; char port[12]; char ipAdress[32]; int sfd; struct InputCommander *next; }; struct InputCommander *addVoiceContrlToInputCommandLink(struct InputCommander *phead); struct InputCommander *addSocketContrlToInputCommandLink(struct InputCommander *phead); 3.编译测试一下: 七、主程序代码初步编写,实现语音和网络线程 这里还是主要测试主函数。所有控制实现功能都是在主函数里面进行。 我们来测试一下socket服务器的网络功能和树莓派连接语音的串口功能 1.主函数mainPro.c #include<stdio.h> #include"controlDevices.h" #include"inputCommand.h" #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<fcntl.h> #include<pthread.h> #include<unistd.h> #include <netinet/in.h> struct InputCommander *pcommandHead = NULL; struct Devices *pdeviceHead = NULL; struct InputCommander *socketHandler = NULL; int c_fd; struct Devices *findDevicesByName(char *name,struct Devices *phead) { struct Devices *tmp = phead; if(phead == NULL){ return NULL; }else{ while(tmp != NULL){ if(strcmp(tmp->deviceName,name) ==0){ return tmp; } tmp = tmp->next; } return NULL; } } struct InputCommander *findCommandByName(char *name,struct InputCommander *phead) { struct InputCommander *tmp = phead; if(phead == NULL){ return NULL; }else{ while(tmp != NULL){ if(strcmp(tmp->commandName,name) ==0){ return tmp; } tmp = tmp->next; } return NULL; } } void*voice_thread(void*datas) { struct InputCommander *voiceHandler; int nread; voiceHandler =findCommandByName("voice",pcommandHead); if(voiceHandler == NULL){ printf("find voiceHandler error\n"); pthread_exit(NULL); }else{ if(voiceHandler->Init(voiceHandler,NULL,NULL) <0){ printf("voiceInit error\n"); pthread_exit(NULL); }else{ printf("%s Init succcess\n",voiceHandler->commandName); } while(1){ nread = voiceHandler->getCommand(voiceHandler); if(nread ==0){ printf("nodata from voice\n"); }else{ printf("do device contrl:%s\n",voiceHandler->command); } } } } void*read_thread(void*datas) { int n_read; printf( "have user connect\n"); memset(socketHandler->command,'\0',sizeof(socketHandler->command)); n_read =read(c_fd,socketHandler->command,sizeof(socketHandler->command)); if(n_read ==-1){ perror("read"); }elseif(n_read >0){ printf("read:%s\n",socketHandler->command); }else{ printf("clien quit\n"); } } void*socket_thread(void*datas) { int nread =0; pthread_t readThread; struct sockaddr_in c_addr; memset(&c_addr,0,sizeof(struct sockaddr_in)); int clen =sizeof(struct sockaddr_in); socketHandler =findCommandByName("socketServer",pcommandHead); if(socketHandler == NULL){ printf("find socketHandler error\n"); pthread_exit(NULL); }else{ printf("%s Init succcess\n",socketHandler->commandName); } socketHandler->Init(socketHandler,NULL,NULL); while(1){ c_fd =accept(socketHandler->sfd,(struct sockaddr *)&c_addr, &clen); pthread_create(&readThread,NULL,read_thread,NULL); } } int main() { int status; char name[128]; pthread_t voiceThread; pthread_t socketThread; if(-1==wiringPiSetup()){ return-1; } //1.指令工厂的初始化 pcommandHead =addVoiceContrlToInputCommandLink(pcommandHead); pcommandHead =addSocketContrlToInputCommandLink(pcommandHead); //2.设备工厂的初始化 pdeviceHead =addBathroomLightToDevicesLink(pdeviceHead); pdeviceHead =addLivingroomLightToDevicesLink(pdeviceHead); pdeviceHead =addUpstairLightToDevicesLink(pdeviceHead); pdeviceHead =addSwimmingpoolLightToDevicesLink(pdeviceHead); pdeviceHead =addFireToDevicesLink(pdeviceHead); pdeviceHead =addBuzzerToDevicesLink(pdeviceHead); //3.线程池的建立 //3.1 语音线程 pthread_create(&voiceThread,NULL,voice_thread,NULL); //3.2 socket线程 pthread_create(&socketThread,NULL,socket_thread,NULL); //3.3 摄像头线程 //3.4 火灾线程 pthread_join(voiceThread,NULL); pthread_join(socketThread,NULL); return0; } 2.编译运行网络测试: 3.串口语音测试: 树莓派连接语音的串口功能。 测试的结果还不是特别完善,语音模块的口令那块源代码还要改下,然后收到串口的语音指令完善下。 ———————————————— |
版块:
web3.0智能硬件学院
1. 本站所有资源来源于用户上传和网络,仅作为演示数据,如有侵权请邮件联系站长!
2. 盗版,破解有损他人权益和违法作为,请各位站长支持正版!
2. 盗版,破解有损他人权益和违法作为,请各位站长支持正版!