一 项目说明
① 设计框架
● 项目架构采用简单工厂模式来设计,将语音识别,TCP服务器设计成链表的每个节点,形成控制工厂。
● 将餐厅灯,卧室灯,二楼灯,泳池灯,蜂鸣器,火焰检测模块,也设计成链表的每个节点,形成设备端工厂。
● 基于这种架构保证项目的稳定性和功能拓展性,在添加新功能的时候,只需要添加一个链表节点文件文件就可以。
● 不管是设备端还是控制端,在实际调试过程中又涉及到临界资源的竞争,所以采用多线程来解决这个问题。
● 语音处理用的是SU-03T模块的二次开发,对串口数据进行修改并整合到树莓派的串口通信中去。
② 功能说明
● 语音模块识别语音来控制各个灯的开关,基于串口通信来配置语音命令的内容。
● 搭建TCP服务器,用socket网络通信的方式控制各个灯的开关,手机客户端发送指令到电脑服务器端来实现控制功能。
● 火灾报警,火焰检测模块结合蜂鸣器开发。接收火焰状态,检测有火源靠近时,蜂鸣器输出低电平发出警报声响,并在终端显示火灾危险提示,检测没有火源时,蜂鸣器输出高电平,停止报警声。
● 实时监控,将摄像头模块安装于树莓并配置树莓派摄像头的接口参数,打开摄像头,写入树莓ip地址及端口即可。
③ 硬件说明
树莓派开发板(3B),继电器组,房屋模型,蜂鸣器,语音模块,火焰检测模块,电池盒,摄像头,杜邦线,灯具,USB-TTL模块(串口调试)
④ 软件说明
SecureCRT8.0(树莓派终端),sourceinsight(代码编辑),filezilla(文件传输),AiThinker Serial Tool(串口调试),NetAssist(网络调试)。
二 项目代码
<1> mainPro.c 主函数
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "contrlDevices.h"//外接设备
#include "InputCommand.h"//控制
struct InputCommander *pCommandHead = NULL;
struct Devices *pdeviceHead = NULL;
struct InputCommander *socketHandler = NULL;
int c_fd;
//外设的设备查询
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 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 Command(struct InputCommander *CmdHandler)
{
struct Devices *tmp =NULL;
if(strcmp("yo",CmdHandler->command) == 0){
tmp = findDeviceByName("bathroomLight",pdeviceHead);
if(tmp != NULL){
tmp->open(tmp->pinNum);
printf("已打开泳池灯\n");
}
}
if(strcmp("yc",CmdHandler->command) == 0){
tmp = findDeviceByName("bathroomLight",pdeviceHead);
if(tmp != NULL){
tmp->close(tmp->pinNum);
printf("已关闭泳池灯\n");
}
}
if(strcmp("eo",CmdHandler->command) == 0){
tmp = findDeviceByName("upstairLight",pdeviceHead);
if(tmp != NULL){
tmp->open(tmp->pinNum);
printf("已打开二楼灯\n");
}
}
if(strcmp("ec",CmdHandler->command) == 0){
tmp = findDeviceByName("upstairLight",pdeviceHead);
if(tmp != NULL){
tmp->close(tmp->pinNum);
printf("已关闭二楼灯\n");
}
}
if(strcmp("co",CmdHandler->command) == 0){
tmp = findDeviceByName("restauranLight",pdeviceHead);
if(tmp != NULL){
tmp->open(tmp->pinNum);
printf("已打开餐厅灯\n");
}
}
if(strcmp("cc",CmdHandler->command) == 0){
tmp = findDeviceByName("restauranLight",pdeviceHead);
if(tmp != NULL){
tmp->close(tmp->pinNum);
printf("已关闭餐厅灯\n");
}
}
if(strcmp("wo",CmdHandler->command) == 0){
tmp = findDeviceByName("livingroomLight",pdeviceHead);
if(tmp != NULL){
tmp->open(tmp->pinNum);
printf("已打开卧室灯\n");
}
}
if(strcmp("wc",CmdHandler->command) == 0){
tmp = findDeviceByName("livingroomLight",pdeviceHead);
if(tmp != NULL){
tmp->close(tmp->pinNum);
printf("已关闭卧室灯\n");
}
}
if(strcmp("ao",CmdHandler->command) == 0){
tmp = findDeviceByName("bathroomLight",pdeviceHead);
if(tmp != NULL) tmp->open(tmp->pinNum);
tmp = findDeviceByName("upstairLight",pdeviceHead);
if(tmp != NULL) tmp->open(tmp->pinNum);
tmp = findDeviceByName("restauranLight",pdeviceHead);
if(tmp != NULL) tmp->open(tmp->pinNum);
tmp = findDeviceByName("livingroomLight",pdeviceHead);
if(tmp != NULL) tmp->open(tmp->pinNum);
printf("已打开所有灯\n");
}
if(strcmp("ac",CmdHandler->command) == 0){
tmp = findDeviceByName("bathroomLight",pdeviceHead);
if(tmp != NULL) tmp->close(tmp->pinNum);
tmp = findDeviceByName("upstairLight",pdeviceHead);
if(tmp != NULL) tmp->close(tmp->pinNum);
tmp = findDeviceByName("restauranLight",pdeviceHead);
if(tmp != NULL) tmp->close(tmp->pinNum);
tmp = findDeviceByName("livingroomLight",pdeviceHead);
if(tmp != NULL) tmp->close(tmp->pinNum);
printf("已关闭所有灯\n");
}
}
//语音线程
void *voice_thread(void *datas)
{
struct InputCommander *voiceHandler;
//struct Devices *tmp =NULL;
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("voice init error\n");
pthread_exit(NULL);
}else{
printf("%s init success\n",voiceHandler->commandName);
while(1){
nread = voiceHandler->getCommand(voiceHandler);
if(nread == 0){
printf("nodata form voice\n");
}else{
printf("do device contrl --> %s\n",voiceHandler->command);
Command(voiceHandler);
}
}
}
}
}
//接收客户端指令
void *read_thread(void *datas)
{
int n_read;
struct Devices *tmp =NULL;
memset(socketHandler->command,'\0',sizeof(socketHandler->command));
n_read = read(c_fd,socketHandler->command,sizeof(socketHandler->command));
if(n_read == -1){
perror("read");
}else if(n_read>0){
printf("\nget: %d,%s\n",n_read,socketHandler->command);
if(strcmp("yo",socketHandler->command) == 0){
tmp = findDeviceByName("bathroomLight",pdeviceHead);
if(tmp != NULL){
tmp->open(tmp->pinNum);
printf("已打开泳池灯\n");
}
}
if(strcmp("yc",socketHandler->command) == 0){
tmp = findDeviceByName("bathroomLight",pdeviceHead);
if(tmp != NULL){
tmp->close(tmp->pinNum);
printf("已关闭泳池灯\n");
}
}
if(strcmp("eo",socketHandler->command) == 0){
tmp = findDeviceByName("upstairLight",pdeviceHead);
if(tmp != NULL){
tmp->open(tmp->pinNum);
printf("已打开二楼灯\n");
}
}
if(strcmp("ec",socketHandler->command) == 0){
tmp = findDeviceByName("upstairLight",pdeviceHead);
if(tmp != NULL){
tmp->close(tmp->pinNum);
printf("已关闭二楼灯\n");
}
}
if(strcmp("co",socketHandler->command) == 0){
tmp = findDeviceByName("restauranLight",pdeviceHead);
if(tmp != NULL){
tmp->open(tmp->pinNum);
printf("已打开餐厅灯\n");
}
}
if(strcmp("cc",socketHandler->command) == 0){
tmp = findDeviceByName("restauranLight",pdeviceHead);
if(tmp != NULL){
tmp->close(tmp->pinNum);
printf("已关闭餐厅灯\n");
}
}
if(strcmp("wo",socketHandler->command) == 0){
tmp = findDeviceByName("livingroomLight",pdeviceHead);
if(tmp != NULL){
tmp->open(tmp->pinNum);
printf("已打开卧室灯\n");
}
}
if(strcmp("wc",socketHandler->command) == 0){
tmp = findDeviceByName("livingroomLight",pdeviceHead);
if(tmp != NULL){
tmp->close(tmp->pinNum);
printf("已关闭卧室灯\n");
}
}
if(strcmp("ao",socketHandler->command) == 0){
tmp = findDeviceByName("bathroomLight",pdeviceHead);
if(tmp != NULL) tmp->open(tmp->pinNum);
tmp = findDeviceByName("upstairLight",pdeviceHead);
if(tmp != NULL) tmp->open(tmp->pinNum);
tmp = findDeviceByName("restauranLight",pdeviceHead);
if(tmp != NULL) tmp->open(tmp->pinNum);
tmp = findDeviceByName("livingroomLight",pdeviceHead);
if(tmp != NULL) tmp->open(tmp->pinNum);
printf("已打开所有灯\n");
}
if(strcmp("ac",socketHandler->command) == 0){
tmp = findDeviceByName("bathroomLight",pdeviceHead);
if(tmp != NULL) tmp->close(tmp->pinNum);
tmp = findDeviceByName("upstairLight",pdeviceHead);
if(tmp != NULL) tmp->close(tmp->pinNum);
tmp = findDeviceByName("restauranLight",pdeviceHead);
if(tmp != NULL) tmp->close(tmp->pinNum);
tmp = findDeviceByName("livingroomLight",pdeviceHead);
if(tmp != NULL) tmp->close(tmp->pinNum);
printf("已关闭所有灯\n");
}
}else{
printf("client quit\n");
}
}
//网络线程
void *socket_thread(void *datas)
{
int n_read = 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 success\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);
}
}
//火焰线程
void *fire_thread(void *datas)
{
int status;
struct Devices *fireDeviceTmp = NULL;
struct Devices *beepDeviceTmp = NULL;
fireDeviceTmp = findDeviceByName("fireIfOrNot",pdeviceHead);
beepDeviceTmp = findDeviceByName("beep",pdeviceHead);
fireDeviceTmp->deviceInit(fireDeviceTmp->pinNum);
beepDeviceTmp->deviceInit(beepDeviceTmp->pinNum);
while(1){
status = fireDeviceTmp->changeStatus(fireDeviceTmp->pinNum); //读取“火焰传感器”状态
if(status == 0){ //检测到火焰或强光源
printf("fire danger warning!!!\n");
beepDeviceTmp->open(beepDeviceTmp->pinNum); //打开蜂鸣器
delay(1000);
}else{
beepDeviceTmp->close(beepDeviceTmp->pinNum); //关闭蜂鸣器
}
}
}
int main()
{
int status;
char name[128];
struct Devices *tmp = NULL;
pthread_t voiceThread;
pthread_t socketThread;
pthread_t fireThread;
if(-1 == wiringPiSetup()){ //初始化wiringPi库
return -1;
}
//1.指令工厂
pCommandHead = addvoiceContrlToInputCommandLink(pCommandHead);//语音
pCommandHead = addSocketContrlToInputCommandLink(pCommandHead);//网络
//2.设备控制工厂初始化
pdeviceHead = addBathroomLightToDeviceLink(pdeviceHead);//泳池灯
pdeviceHead = addUpstairLightToDeviceLink(pdeviceHead);//二楼灯
pdeviceHead = addLivingroomLightToDeviceLink(pdeviceHead);//卧室灯
pdeviceHead = addRestauranLightToDeviceLink(pdeviceHead);//餐厅灯
pdeviceHead = addFireToDeviceLink(pdeviceHead);//火灾检测
pdeviceHead = addBeepToDeviceLink(pdeviceHead);//蜂鸣器
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
//3.线程池建立
//3.1 语音线程
pthread_create(&voiceThread,NULL,voice_thread,NULL);
//3.2 socket线程
pthread_create(&socketThread,NULL,socket_thread,NULL);
//3.3 火灾线程
pthread_create(&fireThread,NULL,fire_thread,NULL);
/*while(1){ //用于四盏灯的调试
printf("input:\n");
scanf("%s",name);
tmp = findDeviceByName(name,pdeviceHead);
if(tmp != NULL){
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
}*/
pthread_join(voiceThread,NULL);
pthread_join(socketThread,NULL);
pthread_join(fireThread,NULL);
return 0;
}
<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;
char port[12];
char ipAddress[32];
int sfd;
struct InputCommander *next;
};
struct InputCommander *addvoiceContrlToInputCommandLink(struct InputCommander *phead);
struct InputCommander *addSocketContrlToInputCommandLink(struct InputCommander *phead);
<3> contrlDevices.h 外接设备头文件
#include <wiringPi.h>
#include <stdlib.h>
struct Devices{
char deviceName[128];
int status;
int pinNum;
int (*open)(int pinNum);
int (*close)(int pinNum);
int (*deviceInit)(int pinNum);
int (*changeStatus)(int status);
struct Devices *next;
};
struct Devices *addBathroomLightToDeviceLink(struct Devices *phead);
struct Devices *addUpstairLightToDeviceLink(struct Devices *phead);
struct Devices *addLivingroomLightToDeviceLink(struct Devices *phead);
struct Devices *addRestauranLightToDeviceLink(struct Devices *phead);
struct Devices *addFireToDeviceLink(struct Devices *phead);
struct Devices *addBeepToDeviceLink(struct Devices *phead);
<4> bathroomLight.c 泳池灯
#include "contrlDevices.h"
int bathroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int bathroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int bathroomLightCloseInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int bathroomLightCloseStatus(int status)
{
}
struct Devices bathroomLight = {
.deviceName = "bathroomLight",
.pinNum = 21,
.open = bathroomLightOpen,
.close = bathroomLightClose,
.deviceInit = bathroomLightCloseInit,
.changeStatus = bathroomLightCloseStatus
};
struct Devices *addBathroomLightToDeviceLink(struct Devices *phead)
{
if(phead == NULL){
return &bathroomLight;
}else{
bathroomLight.next = phead;
phead = &bathroomLight;
}
}
<5> livingroomLight.c 卧室灯
#include "contrlDevices.h"
int livingroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int livingroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int livingroomLightCloseInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int livingroomLightCloseStatus(int status)
{
}
struct Devices livingroomLight = {
.deviceName = "livingroomLight",
.pinNum = 24,
.open = livingroomLightOpen,
.close = livingroomLightClose,
.deviceInit = livingroomLightCloseInit,
.changeStatus = livingroomLightCloseStatus
};
struct Devices *addLivingroomLightToDeviceLink(struct Devices *phead)
{
if(phead == NULL){
return &livingroomLight;
}else{
livingroomLight.next = phead;
phead = &livingroomLight;
}
}
<6> restaurantLight.c 餐厅灯
#include "contrlDevices.h"
int restauranLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int restauranLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int restauranLightCloseInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int restauranLightCloseStatus(int status)
{
}
struct Devices restauranLight = {
.deviceName = "restauranLight",
.pinNum = 23,
.open = restauranLightOpen,
.close = restauranLightClose,
.deviceInit = restauranLightCloseInit,
.changeStatus = restauranLightCloseStatus
};
struct Devices *addRestauranLightToDeviceLink(struct Devices *phead)
{
if(phead == NULL){
return &restauranLight;
}else{
restauranLight.next = phead;
phead = &restauranLight;
}
}
<7> upstairLight.c 二楼灯
#include "contrlDevices.h"
int upstairLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int upstairLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int upstairLightCloseInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int upstairLightCloseStatus(int status)
{
}
struct Devices upstairLight = {
.deviceName = "upstairLight",
.pinNum = 22,
.open = upstairLightOpen,
.close = upstairLightClose,
.deviceInit = upstairLightCloseInit,
.changeStatus = upstairLightCloseStatus
};
struct Devices *addUpstairLightToDeviceLink(struct Devices *phead)
{
if(phead == NULL){
return &upstairLight;
}else{
upstairLight.next = phead;
phead = &upstairLight;
}
}
<8> fire.c 火焰传感器
#include "contrlDevices.h"
int fireIfOrNotInit(int pinNum)
{
pinMode(pinNum,INPUT);
digitalWrite(pinNum,HIGH);
}
int fireStatusRead(int pinNum)
{
return digitalRead(pinNum);
}
struct Devices fireIfOrNot = {
.deviceName = "fireIfOrNot",
.pinNum = 25,
.deviceInit = fireIfOrNotInit,
.changeStatus = fireStatusRead
};
struct Devices *addFireToDeviceLink(struct Devices *phead)
{
if(phead == NULL)
{
return &fireIfOrNot;
}else{
fireIfOrNot.next = phead;
phead = &fireIfOrNot;
//return phead;
}
}
<9> beep.c 蜂鸣器
#include "contrlDevices.h"
//struct Devices *addBeepToDeviceLink(struct Devices *phead);
int beepInit(int pinNum) //初始化函数
{
pinMode(pinNum,OUTPUT); //配置引脚为输出引脚
digitalWrite(pinNum,HIGH); //引脚输出高电平,即默认为关闭状态
}
int beepOpen(int pinNum) //打开蜂鸣器函数
{
digitalWrite(pinNum,LOW);
}
int beepClose(int pinNum) //关闭蜂鸣器函数
{
digitalWrite(pinNum,HIGH);
}
struct Devices beep = { //蜂鸣器设备链表节点
.deviceName = "beep",
.pinNum = 29,
.deviceInit = beepInit,
.open = beepOpen,
.close = beepClose,
//.next = NULL
};
struct Devices* addBeepToDeviceLink(struct Devices *phead) //头插法将设备节点加入设备工厂链表函数
{
if(phead == NULL){
return &beep;
}else{
beep.next = phead;
phead = &beep;
}
}
<10> voiceContrl.c 语音模块
#include <wiringPi.h>
#include <stdio.h>
#include <wiringSerial.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "InputCommand.h"
int voiceGetCommand(struct InputCommander *voicer)//获取指令函数
{
int nread = 0;
memset(voicer->command,'\0',sizeof(voicer->command));
nread = read(voicer->fd,voicer->command,sizeof(voicer->command));//将串口的指令读到voicer->command中
return nread;
}
int voiceInit(struct InputCommander *voicer,char *ipAdress,char *port)
{
int fd;
if((fd = serialOpen(voicer->deviceName,9600))==-1){ //初始化树莓派串口
perror("serialOpen");
return -1;
}
voicer->fd = fd; //打开串口文件成功,返回“文件描述符”到“语音控制”链表节点中
return fd;
}
struct InputCommander voiceContrl = { //语音控制链表节点
.commandName = "voice",
.deviceName = "/dev/ttyAMA0",
.command = {'\0'},
.Init = voiceInit,
.getCommand = voiceGetCommand,
.log = {'\0'},
.next = NULL
};
struct InputCommander *addvoiceContrlToInputCommandLink(struct InputCommander *phead)//头插法将“语音控制”链表节点加入指令控制工厂链表函数
{
if(phead == NULL){
return &voiceContrl;
}else{
voiceContrl.next = phead;
phead = &voiceContrl;
return phead;
}
}
<11> socketContrl.c 服务器
#include <wiringPi.h>
#include <stdio.h>
#include <wiringSerial.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "InputCommand.h"
int socketGetCommand(struct InputCommander *socketMes)
{
int c_fd;
int n_read = 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);
n_read = read(c_fd,socketMes->command,sizeof(socketMes->command));
if(n_read == -1){
perror("read");
}else if(n_read>0){
printf("\nget: %d\n",n_read);
}else{
printf("client quit\n");
}
return n_read;
}
int socketInit(struct InputCommander *socketMes,char *ipAdress,char *port) //socket初始化
{
int s_fd;
struct sockaddr_in s_addr;
memset(&s_addr,0,sizeof(struct sockaddr_in));
//1. socket创建
s_fd = socket(AF_INET, SOCK_STREAM, 0);
if(s_fd == -1){
perror("socket");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(socketMes->port));
inet_aton(socketMes->ipAddress,&s_addr.sin_addr);
//2. bind
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
//3. listen
listen(s_fd,10);
printf("socker Server listening ......\n");
socketMes->sfd = s_fd;
return s_fd; //套接字描述符返回到网络控制链表节点
}
struct InputCommander socketContrl = {
.commandName = "socketServer",
.command = {'\0'},
.port = "8080",
.ipAddress = "192.168.1.7",
.Init = socketInit,
.getCommand = socketGetCommand,
.log = {'\0'},
.next = NULL
};
struct InputCommander *addSocketContrlToInputCommandLink(struct InputCommander *phead)//头插法将设备节点加入设备工厂链表函数
{
if(phead == NULL){
return &socketContrl;
}else{
socketContrl.next = phead;
phead = &socketContrl;
}
}
三 项目演示
四 项目问题总结
通过这个项目,我对于简单工厂模式,Linux操作系统的文件,进程,线程,网络以及Linux字符设备开发都有了比较大的收获。整个项目的逻辑还算简单明了,但在实际开发调试过程中也会遇到一些问题,还好都逐一发现并解决。
问题一
语音控制不了灯
分析解决:串口测试语音能通过,串口命令测试灯也能通过,代码没有任何报错,逻辑也没有任何问题,唯独语音控制不了灯。我的语音逻辑是通过if来判断收到的控制指令从而实现对灯的控制。既然其他方面没有问题,那就是if判断不了收到的控制指令,所以把问题锁定于此。我将语音SDK重新生成配置,将判断条件修改成和语音SDK一致的内容后,继续先用串口测语音,再用串口测灯,最后实现语音控制灯,顺利实现。总结就是:语音配置的参数内容必须和判断条件的内容一致,才能准确判断并执行。之前做过语音控制刷抖音,因为太简单,中间没有任何报错,所以也就没有发现这个问题。笔记于此,当是提醒。
问题二
段错误
分析解决:做火灾检测报警这一块,因为是蜂鸣器和火焰传感器的结合,所以须将蜂鸣器整合在火焰线程中,编译后直接提示段错误,没有其他任何报错。我先检查了火焰,蜂鸣器,外接设备头文件以及火焰线程部分的代码,没有问题,至少肉眼可见的逻辑是没有问题的,然后在检查火焰传感器和蜂鸣器的IO口接线方面,也没有问题。捣鼓了很长时间无果,还好心理素质过硬,面向百度,依然无果。在最后,尝试用printf的方法将问题锁定在火焰线程中蜂鸣器的初始化部分。最后的最后才发现,在主函数int main()中设备控制工厂初始化没有添加蜂鸣器部分代码。
问题三
连接服务器超时
其实这不算什么问题,只是记录下来。通过手机客户端发送指令到服务器端实现控制灯,那么就需要连接服务器,如果出现连接超时或连接错误,首先排查是否能ping通网络,然后检查代码,ip,端口,如果都没问题,就可以考虑端口号是否被占用,修改下端口,多尝试连接几次。
问题四
线材和模块布局凌乱
前期没注意这个问题,只管接线并测试各模块的功能,到后期快完结时,走线杂乱已无力回天。后面的开发中值得注意!
五 项目相关知识点整理
该项目所涉及到的知识点,我将往期相关的博文都归纳在此:
C语言设计模式:实现简单工厂模式和工程创建
树莓派编程控制继电器及继电器组
通过Linux串口实现树莓派与电脑通信
树莓派+摄像头:mjpg-streamer实现监控功能的配置及调试
基于Linux串口实现语音控制刷抖音
C语言数据结构:链表的增删改查及动态创建
Linux网络编程:Socket服务器和客户端实现双方通信
Linux线程:创建(pthread_create),等待(pthread_join),退出(pthread_exit)
Orangepi Zero2 全志H616:蜂鸣器,链接库,shell脚本
版权归原作者 AsheHero 所有, 如有侵权,请联系我们删除。