目录

一、主函数

mianPro.c

二、指令工厂

voiceControl.c

socketControl.c

inputCommand.h

三、设备工厂

smokeAlarm.c

buzzer.c

livingroomLight.c

restaurantLight.c

bedroomLight.c

bathroomLight.c

controlDevice.h

四、总结

问题1:三线程同时运行,有时候无法正常进行开关灯操作。

问题2:在前几篇文章中,在open\close操作前都有Init操作

问题3: int (*changeStatus)(int status),记住设备的状态


一、主函数

mianPro.c

#include <pthread.h>
#include "controlDevice.h"
#include "inputCommand.h"struct InputCommand *pcommandHead = NULL;                             //定义指令工厂初始链表头
struct Devices      *pdeviceHead  = NULL;                            //定义设备工厂初始链表头
struct InputCommand *socketHandler = NULL;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;}
}struct InputCommand* findCommandByName(char *name, struct InputCommand *phead)
{struct InputCommand *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 Command(struct InputCommand* CmdHandler)
{struct Devices *tmp =NULL;if(strcmp("CSHALL",CmdHandler->command) == 0){tmp = findDeviceByName("smokeAlarm",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);tmp = findDeviceByName("buzzer",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);tmp = findDeviceByName("livingroomLight",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum); tmp = findDeviceByName("restaurantLight",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);tmp = findDeviceByName("bedroomLight",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);tmp = findDeviceByName("bathroomLight",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);printf("设备已全部初始化\n");}if(strcmp("OL1",CmdHandler->command) == 0){tmp = findDeviceByName("livingroomLight",pdeviceHead);if(tmp != NULL){tmp->open(tmp->pinNum);printf("已打开客厅灯\n");}}if(strcmp("CL1",CmdHandler->command) == 0){tmp = findDeviceByName("livingroomLight",pdeviceHead);if(tmp != NULL){tmp->close(tmp->pinNum);printf("已关闭客厅灯\n");}}if(strcmp("OL2",CmdHandler->command) == 0){tmp = findDeviceByName("restaurantLight",pdeviceHead);if(tmp != NULL){tmp->open(tmp->pinNum);printf("已打开餐厅灯\n");}}if(strcmp("CL2",CmdHandler->command) == 0){tmp = findDeviceByName("restaurantLight",pdeviceHead);if(tmp != NULL){tmp->close(tmp->pinNum);printf("已关闭餐厅灯\n");}}if(strcmp("OL3",CmdHandler->command) == 0){tmp = findDeviceByName("bedroomLight",pdeviceHead);if(tmp != NULL){tmp->open(tmp->pinNum);printf("已打开卧室灯\n");}}if(strcmp("CL3",CmdHandler->command) == 0){tmp = findDeviceByName("bedroomLight",pdeviceHead);if(tmp != NULL){tmp->close(tmp->pinNum);printf("已关闭卧室灯\n");}}if(strcmp("OL4",CmdHandler->command) == 0){tmp = findDeviceByName("bathroomLight",pdeviceHead);if(tmp != NULL){tmp->open(tmp->pinNum);printf("已打开浴室灯\n");}}if(strcmp("CL4",CmdHandler->command) == 0){tmp = findDeviceByName("bathroomLight",pdeviceHead);if(tmp != NULL){tmp->close(tmp->pinNum);printf("已关闭浴室灯\n");}}if(strcmp("OLALL",CmdHandler->command) == 0){tmp = findDeviceByName("livingroomLight",pdeviceHead);if(tmp != NULL)  tmp->open(tmp->pinNum);tmp = findDeviceByName("restaurantLight",pdeviceHead);if(tmp != NULL)  tmp->open(tmp->pinNum);tmp = findDeviceByName("bedroomLight",pdeviceHead);if(tmp != NULL)  tmp->open(tmp->pinNum);tmp = findDeviceByName("bathroomLight",pdeviceHead);if(tmp != NULL)  tmp->open(tmp->pinNum);printf("已打开所有灯\n");}if(strcmp("CLALL",CmdHandler->command) == 0){tmp = findDeviceByName("livingroomLight",pdeviceHead);if(tmp != NULL)  tmp->close(tmp->pinNum);tmp = findDeviceByName("restaurantLight",pdeviceHead);if(tmp != NULL)  tmp->close(tmp->pinNum);tmp = findDeviceByName("bedroomLight",pdeviceHead);if(tmp != NULL)  tmp->close(tmp->pinNum);tmp = findDeviceByName("bathroomLight",pdeviceHead);if(tmp != NULL)  tmp->close(tmp->pinNum);printf("已关闭所有灯\n");}
}void *voiceControlThread(void *data)           //“语音控制线程”执行函数
{   int nread;struct InputCommand *voiceHandler = NULL;voiceHandler =  findCommandByName("voice", pcommandHead);if(voiceHandler == NULL){printf("find voiceHandler error\n");pthread_exit(NULL);}else{if(voiceHandler->Init(voiceHandler) < 0){       //“语音控制”功能初始化printf("voiceControl init error\n");pthread_exit(NULL);}else{printf("voiceControl init success\n");}while(1){memset(voiceHandler->command,'\0',sizeof(voiceHandler->command));nread = voiceHandler->getCommand(voiceHandler);if(nread == 0){                                 //串口没有获取到指令printf("No voiceCommand received\n");}else{                                            //获取到指令printf("Get VoiceCommand -->%s\n",voiceHandler->command);Command(voiceHandler);}}   }
}void *socketReadThread(void *data)             //“读取tcp端口指令线程”执行的函数
{int n_read;printf("Connect success\n");while(1){memset(socketHandler->command,'\0',sizeof(socketHandler->command));n_read=read(socketHandler->fd,socketHandler->command,sizeof(socketHandler->command));if(n_read == -1){perror("read:");}else{printf("Get SocketCommand-->%s\n",socketHandler->command);Command(socketHandler);}}
}void *socketControlThread(void *data)           //“网络控制线程”执行的函数
{   int c_fd;                           //文件描述符struct sockaddr_in c_addr;memset(&c_addr,0,sizeof(struct sockaddr_in));int clen = sizeof(struct sockaddr_in);pthread_t socketRead_thread; //线程里面套线程,网络连接后信息通信socketHandler =  findCommandByName("socket", pcommandHead);if(socketHandler == NULL){printf("find socketHandler error\n");pthread_exit(NULL);}if(socketHandler->Init(socketHandler) < 0){   //“网络控制”功能初始化printf("socketControl init error\n");pthread_exit(NULL);}else{printf("socketControl init success\n");}while(1){//4.acceptc_fd = accept(socketHandler->s_fd,(struct sockaddr *)&c_addr,&clen); //接收连接请求,阻塞至有客户端完成三次握手socketHandler->fd = c_fd;                                              //将套接字描述符返回给“网络控制”链表节点pthread_create(&socketRead_thread,NULL,socketReadThread,NULL);            //创建新线程:用于读取TCP端口指令}
}void *smokeAlarmThread(void *data)               //“烟雾报警器线程”执行的函数
{int smokeStatus;                                               //存放“烟雾传感器”状态struct Devices *tmp = NULL;while(1){tmp = findDeviceByName("smokeAlarm", pdeviceHead);if(tmp != NULL){smokeStatus = tmp->readStatus(tmp->pinNum);delay(100);tmp = findDeviceByName("buzzer", pdeviceHead);if(tmp != NULL){if( smokeStatus == 0 ){tmp->open(tmp->pinNum);}else{tmp->close(tmp->pinNum);}           }}}
}int main()
{if (wiringPiSetup () == -1) { fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ; return 1 ; }pthread_t voiceControl_thread;pthread_t socketControl_thread;pthread_t smokeAlarm_thread;//1.指令工厂初始化pcommandHead = addVoiceControlToInputCommandLink(pcommandHead);pcommandHead = addSocketControlToInputCommandLink(pcommandHead);//2.设备控制工厂初始化pdeviceHead = addBathroomLightToDeviceLink(pdeviceHead);            //“浴室灯”加入设备链表pdeviceHead = addBedroomLightToDeviceLink(pdeviceHead);pdeviceHead = addRestaurantLightToDeviceLink(pdeviceHead);pdeviceHead = addLivingroomLightToDeviceLink(pdeviceHead);pdeviceHead = addSmokeAlarmToDeviceLink(pdeviceHead);pdeviceHead = addBuzzerToDeviceLink(pdeviceHead);//3.线程池建立  int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg); //3.1 语音线程pthread_create(&voiceControl_thread,NULL,voiceControlThread,NULL);//3.2 socket线程pthread_create(&socketControl_thread,NULL,socketControlThread,NULL);//3.3 烟雾报警线程pthread_create(&smokeAlarm_thread,NULL,smokeAlarmThread,NULL);//3.4 摄像头线程pthread_join(voiceControl_thread, NULL);       //主函数等待线程退出pthread_join(socketControl_thread, NULL);        //主函数等待线程退出pthread_join(smokeAlarm_thread, NULL);           //主函数等待线程退出return 0;
}

二、指令工厂

voiceControl.c

#include "inputCommand.h"int voiceInit(struct InputCommand *voice)
{int fd;if ((fd = serialOpen (voice->deviceName, 115200)) < 0) { fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ; return 1 ; }voice->fd = fd;return fd;
}int voiceGetCommand(struct InputCommand *voice)
{int nread = 0;nread = read(voice->fd, voice->command, sizeof(voice->command));    //读取串口return nread;            //返回读取到数据的字节数,实际读取的指令放到了command里
}struct InputCommand voiceControl = {.commandName = "voice",.deviceName = "/dev/ttyS5",.command = '\0',.Init = voiceInit,.getCommand = voiceGetCommand,.log = {'\0'},.next = NULL
};struct InputCommand* addVoiceControlToInputCommandLink(struct InputCommand *phead)    //“语音控制”(对象)加入指令方式链表函数
{if(phead == NULL){return &voiceControl;}else{voiceControl.next = phead;phead = &voiceControl;return phead;}
}

socketControl.c

#include "inputCommand.h"int socketInit(struct InputCommand *socketMsg)
{int s_fd;                                       //套接字描述符struct sockaddr_in s_addr;memset(&s_addr,0,sizeof(struct sockaddr_in));   //数据清空//1.sockets_fd=socket(AF_INET,SOCK_STREAM,0);             //创建套接字,ipv4 tcp协议if(s_fd == -1){                                 //若创建套接字失败perror("socket:");exit(-1);}s_addr.sin_family = AF_INET;                        //ipv4s_addr.sin_port = htons(atoi(socketMsg->port));     //端口号,选择5000以上。honts返回网络字节序,atoi(argv[2])防止端口被占用inet_aton(socketMsg->ipAdress,&s_addr.sin_addr);    //转换为网络能识别的格式//2.bindbind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//3.listenlisten(s_fd,10);//监听10个连接printf("socket Server listening ...\n");socketMsg->s_fd = s_fd;                         //发送套接字描述符return s_fd;
}struct InputCommand socketControl = {.commandName = "socket",.command = '\0',.port = "8080",.ipAdress = "192.168.3.77",.Init = socketInit,.log = {'\0'},.next = NULL
};struct InputCommand* addSocketControlToInputCommandLink(struct InputCommand *phead)
{if(phead == NULL){return &socketControl;}else{socketControl.next = phead;phead = &socketControl;return phead;}
}

inputCommand.h

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <wiringPi.h>
#include <wiringSerial.h>struct InputCommand
{char commandName[128];                              //“控制方式”名char deviceName[128];               char command[32];                                   //存放指令int fd;                                             //存放文件描述符(串口/网络)int s_fd;                                         //存放服务器套接字描述符char port[12];                                     //存放端口号char ipAdress[32];                                   //存放 IP地址char log[1024];                                     //日志int (*Init)(struct InputCommand *voice);            //“初始化”函数指针int (*getCommand)(struct InputCommand *voice);      //“获取指令”函数指针struct InputCommand *next;
};struct InputCommand* addVoiceControlToInputCommandLink(struct InputCommand *phead);       //“语音控制”加入指令链表函数声明
struct InputCommand* addSocketControlToInputCommandLink(struct InputCommand *phead);

三、设备工厂

smokeAlarm.c

#include "controlDevice.h"                 //自定义设备类的文件int smokeAlarmInit(int pinNum)              //C语言必须要传参,JAVA不用,可直接访问变量的值
{pinMode(pinNum,INPUT);                 //配置引脚为输入模式//digitalWrite(pinNum,HIGH);         //引脚置高电平,断开继电器
}int smokeAlarmReadStatus(int pinNum)
{return digitalRead(pinNum);
}int smokeAlarmStatus(int status)
{}struct Devices smokeAlarm = {            //定义烟雾报警器(对象).deviceName = "smokeAlarm",           //名字.pinNum = 6,                       //香橙派 6号(wPi)引脚.Init = smokeAlarmInit,             //指定初始化函数.readStatus = smokeAlarmReadStatus,.changeStatus = smokeAlarmStatus
};struct Devices* addSmokeAlarmToDeviceLink(struct Devices *phead)      //烟雾报警器(对象)加入设备链表函数
{if(phead == NULL){return &smokeAlarm;}else{smokeAlarm.next = phead;  //以前的头变成.nextphead = &smokeAlarm;      //更新头return phead;}
}

buzzer.c

#include "controlDevice.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 = 9,                               //香橙派 9号(wpi)引脚.Init = buzzerInit,                         //指定初始化函数.open = buzzerOpen,                           //指定“开启蜂鸣器”函数.close = buzzerClose,                     //指定“关闭蜂鸣器”函数
};struct Devices* addBuzzerToDeviceLink(struct Devices *phead)      //蜂鸣器(对象)加入设备链表函数
{if(phead == NULL){return &buzzer;}else{buzzer.next = phead;phead = &buzzer;return phead;}
}

livingroomLight.c

#include "controlDevice.h"         //自定义设备类的文件int livingroomLightInit(int pinNum)         //C语言必须要传参,JAVA不用,可直接访问变量的值
{pinMode(pinNum,OUTPUT);                    //配置引脚为输出模式digitalWrite(pinNum,HIGH);               //引脚置高电平,断开继电器
}int livingroomLightOpen(int pinNum)
{digitalWrite(pinNum,LOW);              //引脚置低电平,闭合继电器
}int livingroomLightClose(int pinNum)
{digitalWrite(pinNum,HIGH);             //引脚置高电平,断开继电器
}int livingroomLightStatus(int status)
{}struct Devices livingroomLight = {           //定义客厅灯(对象).deviceName = "livingroomLight",        //名字.pinNum = 16,                          //香橙派 16号(wPi)引脚.Init = livingroomLightInit,           //指定初始化函数.open = livingroomLightOpen,          //指定“打开灯”函数.close = livingroomLightClose,          //指定“关闭灯”函数.changeStatus = livingroomLightStatus
};struct Devices* addLivingroomLightToDeviceLink(struct Devices *phead)     //客厅灯(对象)加入设备链表函数
{if(phead == NULL){return &livingroomLight;}else{livingroomLight.next = phead;  //以前的头变成.nextphead = &livingroomLight;      //更新头return phead;}
}

restaurantLight.c

#include "controlDevice.h"         //自定义设备类的文件int restaurantLightInit(int pinNum)         //C语言必须要传参,JAVA不用,可直接访问变量的值
{pinMode(pinNum,OUTPUT);                    //配置引脚为输出模式digitalWrite(pinNum,HIGH);               //引脚置高电平,断开继电器
}int restaurantLightOpen(int pinNum)
{digitalWrite(pinNum,LOW);              //引脚置低电平,闭合继电器
}int restaurantLightClose(int pinNum)
{digitalWrite(pinNum,HIGH);             //引脚置高电平,断开继电器
}int restaurantLightStatus(int status)
{}struct Devices restaurantLight = {           //定义餐厅灯(对象).deviceName = "restaurantLight",        //名字.pinNum = 13,                          //香橙派 13号(wPi)引脚.Init = restaurantLightInit,           //指定初始化函数.open = restaurantLightOpen,          //指定“打开灯”函数.close = restaurantLightClose,          //指定“关闭灯”函数.changeStatus = restaurantLightStatus
};struct Devices* addRestaurantLightToDeviceLink(struct Devices *phead)     //餐厅灯(对象)加入设备链表函数
{if(phead == NULL){return &restaurantLight;}else{restaurantLight.next = phead;  //以前的头变成.nextphead = &restaurantLight;      //更新头return phead;}
}

bedroomLight.c

#include "controlDevice.h"int bedroomLightInit(int pinNum)            //C语言必须要传参,JAVA不用,可直接访问变量的值
{pinMode(pinNum,OUTPUT);                    //配置引脚为输出模式digitalWrite(pinNum,HIGH);               //引脚置高电平,断开继电器
}int bedroomLightOpen(int pinNum)
{digitalWrite(pinNum,LOW);              //引脚置低电平,闭合继电器
}int bedroomLightClose(int pinNum)
{digitalWrite(pinNum,HIGH);             //引脚置高电平,断开继电器
}int bedroomLightStatus(int status)
{}struct Devices bedroomLight = {          //定义卧室灯(对象).deviceName = "bedroomLight",       //名字.pinNum = 8,                       //香橙派 8号(wPi)引脚.Init = bedroomLightInit,           //指定初始化函数.open = bedroomLightOpen,         //指定“打开灯”函数.close = bedroomLightClose,         //指定“关闭灯”函数.changeStatus = bedroomLightStatus
};struct Devices* addBedroomLightToDeviceLink(struct Devices *phead)        //卧室灯(对象)加入设备链表函数
{if(phead == NULL){return &bedroomLight;}else{bedroomLight.next = phead;  //以前的头变成.nextphead = &bedroomLight;      //更新头return phead;}
}

bathroomLight.c

#include "controlDevice.h"         //自定义设备类的文件int bathroomLightInit(int pinNum)           //C语言必须要传参,JAVA不用,可直接访问变量的值
{pinMode(pinNum,OUTPUT);                    //配置引脚为输出模式digitalWrite(pinNum,HIGH);               //引脚置高电平,断开继电器
}int bathroomLightOpen(int pinNum)
{digitalWrite(pinNum,LOW);              //引脚置低电平,闭合继电器
}int bathroomLightClose(int pinNum)
{digitalWrite(pinNum,HIGH);             //引脚置高电平,断开继电器
}int bathroomLightStatus(int status)
{}struct Devices bathroomLight = {         //定义浴室灯(对象).deviceName = "bathroomLight",          //名字.pinNum = 2,                           //香橙派 2号(wPi)引脚.Init = bathroomLightInit,              //指定初始化函数.open = bathroomLightOpen,                //指定“打开灯”函数.close = bathroomLightClose,            //指定“关闭灯”函数.changeStatus = bathroomLightStatus
};struct Devices* addBathroomLightToDeviceLink(struct Devices *phead)       //浴室灯(对象)加入设备链表函数
{if(phead == NULL){return &bathroomLight;}else{bathroomLight.next = phead;  //以前的头变成.nextphead = &bathroomLight;      //更新头return phead;}
}

controlDevice.h

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>                 //wiringPi库struct Devices                          //设备类
{char deviceName[128];               //设备名int status;                         //状态int pinNum;                           //引脚号int (*Init)(int pinNum);           //“初始化设备”函数指针int (*open)(int pinNum);           //“打开设备”函数指针int (*close)(int pinNum);           //“关闭设备”函数指针int (*readStatus)(int pinNum);      //“读取设备状态”函数指针  为火灾报警器准备int (*changeStatus)(int status);    //“改变设备状态”函数指针struct Devices *next;
};struct Devices* addBathroomLightToDeviceLink(struct Devices *phead);      //“浴室灯”加入设备链表函数声明
struct Devices* addBedroomLightToDeviceLink(struct Devices *phead);         //“卧室灯”加入设备链表函数声明
struct Devices* addRestaurantLightToDeviceLink(struct Devices *phead);      //“餐厅灯”加入设备链表函数声明
struct Devices* addLivingroomLightToDeviceLink(struct Devices *phead);      //“客厅灯”加入设备链表函数声明
struct Devices* addSmokeAlarmToDeviceLink(struct Devices *phead);           //“烟雾报警器”加入设备链表函数声明
struct Devices* addBuzzerToDeviceLink(struct Devices *phead);               //“蜂鸣器”加入设备链表函数声明

四、总结

问题1:三线程同时运行,有时候无法正常进行开关灯操作。

初步排查:烟雾线程占用CPU100%,怀疑是死循环。

解决办法:加入延时函数。

问题2:在前几篇文章中,在open\close操作前都有Init操作

解决办法:通过指令进行初始化

if(strcmp("CSHALL",CmdHandler->command) == 0){tmp = findDeviceByName("smokeAlarm",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);tmp = findDeviceByName("buzzer",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);tmp = findDeviceByName("livingroomLight",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum); tmp = findDeviceByName("restaurantLight",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);tmp = findDeviceByName("bedroomLight",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);tmp = findDeviceByName("bathroomLight",pdeviceHead);if(tmp != NULL)  tmp->Init(tmp->pinNum);printf("设备已全部初始化\n");}

问题3: int (*changeStatus)(int status),记住设备的状态

记住设备的状态,已经执行的open、close、Init就不再执行,同时解决问题2。

待实现

智能家居项目目录

智能家居(1) —— 工厂模式引入&工厂模式实现继电器控制

智能家居(2) —— 工厂模式实现烟雾报警

智能家居(3) —— 串口通信(语音识别)线程控制

智能家居(4) —— 网络服务器线程控制

智能家居(5) —— 智能家居项目整合(语音控制线程,网络控制线程、烟雾报警线程)

网络编程知识预备(1) —— 7层OSI网络模型

网络编程知识预备(2) —— 三次握手与四次挥手、半连接状态、2MSL

网络编程知识预备(3) —— TCP流量控制(滑动窗口)、拥塞控制

网络编程知识预备(4) —— SOCKET、TCP、HTTP之间的区别与联系

网络编程知识预备(5) —— 了解应用层的HTTP协议与HTTPS协议

网络编程知识预备(6) —— libcurl库简介及其编程访问百度首页

智能家居(6) —— 香橙派摄像头安装实现监控功能

智能家居(7) —— 人脸识别 & 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)

智能家居(8) —— 香橙派摄像头加入设备工厂

智能家居 (5) ——智能家居项目整合(语音控制线程,网络控制线程、烟雾报警线程)相关推荐

  1. 智能家居(2) —— 工厂模式实现烟雾报警

    目录 工厂模式实现烟雾报警 mainPro.c(主函数) controlDevice.h(设备类) smokeAlarm.c(烟雾报警器) buzzer.c(蜂鸣器) 运行结果 线程实现 mainPr ...

  2. 智能家居(13)——智能家居控制系统

    基于树莓派制作智能家居控制系统 一.功能介绍 二.实现思路 三.源代码分析 一.功能介绍 灯光的控制:模拟客厅灯.餐厅灯.二楼灯.卫生间灯.灯光可以通过手机App.语音.控制开关. 家内发生火灾后报警 ...

  3. 智能家居系统智能联动控制

    目前,智能家居控制方式有本地控制.远程网络控制.定时控制和一键情景控制等4种方式,且每种都有自己的特色.本节笔者将为大家介绍智能家居的这4种控制方式. 本地控制 本地控制是指在智能家电附近,通过智能开 ...

  4. Homekit智能家居一智能灯泡

    一.什么是智能灯 传统的灯泡是通过手动打开和关闭开关来工作.有时,它们可以通过声控.触控.红外等方式进行控制,或者带有调光开关,让用户调暗或调亮灯光. 智能灯泡内置有芯片和通信模块,可与手机.家庭智能 ...

  5. 智能家居 (8) ——智能家居项目整合(网络控制线程、语音控制线程,火灾报警线程)

    目录 mainPro.c(主函数) 指令工厂 inputCommand.h voiceControl.c(语音控制) socketControl.c(网络线程) 控制工厂 contrlEquipmen ...

  6. 树莓派智能家居项目整合(包含语音、socket、火灾、摄像头线程)

    树莓派智能家居项目一 1.百度网盘下载代码链接 2.main.c 3.段错误 4.C语言的函数声明 4.1没声明的报错内容 5.关于报错,调试程序 坎坎坷坷,墨墨迹迹了这么久也算是完成了四个线程的同时 ...

  7. 华景机器人怎么控制_【扫地机器人选购】支持华为hilink智能家居联动/支持华为小艺语音控制的扫地机器人...

    不用找了,这里已经给你准备好了支持华为智能家居生态联动的扫地机器人,同时也支持华为小艺智能音箱联动: 什么意思呢:(我是研究智能家居的) 智能家居联动:就是可以和华为hilink其他智能设备联动,比如 ...

  8. 智能家居 (3) ——智能家居工厂模式介绍实现继电器控制灯

    目录 智能家居工厂模式整体设计框架 继电器控制灯代码 contrlEquipments.h 文件(设备类) mainPro.c 文件(主函数) bathroomLight.c 文件(浴室灯) seco ...

  9. 智能家居 (1) ——智能家居整体功能框架

    目录 智能家居整体功能框架图 硬件部分清单 往期文章 智能家居整体功能框架图 可作为大学生毕业设计内容,亦可作求职面试话术使用 使用的硬件平台:树莓派3B(型号),CortexA53(架构),博通BC ...

最新文章

  1. matlab基本运算实验报告,实验2 Matlab的基本运算实验报告
  2. Windows平台Eclipse配置Maven
  3. c语言字符密码验证码,c语言下的学生管理系统(含密码加密和验证码).docx
  4. 基于centos6.7的docker私有仓库搭建
  5. faster rcnn训练过程讲解
  6. php数组 函数,PHP array_uintersect_uassoc() 函数
  7. redis-软件安装redis5
  8. java知识总结-13
  9. 2017.10.2 计算机算法分析----0-1背包问题
  10. 大小端转换代码(宏、函数方式)(浮点、整数)
  11. 智遥工作流为SAP节省License实例
  12. form表单标签的简单使用
  13. Font Awesome文字图标的使用
  14. 处理tree 树状结构,
  15. 硬盘连接计算机后怎么使用,台式机硬盘如何接笔记本【方法步骤】
  16. VS2017 生成DLL 供python 调用
  17. QTP .net插件
  18. 博途数据类型wstring怎么用_博图V14关于自定义数据类型的疑问,大家都是怎么编程写中间标签的那。...
  19. 4G:SIM7600CE-CNSE 4G模组调试
  20. esp8266 softap 模式设置 及 注意事项

热门文章

  1. 面试君与面试官的分歧:innodb支持行锁就不锁表么?
  2. Python爬虫,私活接单记录,假日到手5500,美滋滋
  3. excel 宏 加1的计算机,巧用宏命令来为Excel工作表公式加密码 -电脑资料
  4. java json 正则_正则表达式替换json字符串
  5. 1. MGR简介 | 深入浅出MGR
  6. linux中安装百度输入法-----解决QT中使用百度输入法问题
  7. Gut代谢组学文献分享:小小肠道菌群决定肾的“生死”
  8. php 二维数组重组排序,PHP的二维数组排序
  9. 十大致癌食物黑名单公布 葵花子竟然排第一(图)
  10. 女生适不适合软件测试?从薪资、就业、学习、工作难度和加班多方面解读女生适不适合软件测试这一工作