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

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

截止目前mainPro.c代码

cpp 复制代码
#include <stdio.h>
#include <string.h>

#include "controlDevices.h"
#include "inputCmd.h"

struct Devices *findDevicesName(char *name,struct Devices *phead){

	struct Devices *tmp=phead;
	if(phead==NULL){

		return NULL;
	}else{

	while(tmp!=NULL){
		if(strcmp(tmp->devicesName,name)==0){
			return tmp;
		}
		tmp=tmp->next;
	}
	return NULL;
	}
}

int main(){
	if(wiringPiSetup()==-1){
		return -1;
	}
	
	struct Devices *pdevicesHead=NULL;
	struct InputCmd *pinputCmdHead=NULL;
	
	pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);
	pdevicesHead=addupstairLightToDevicesLink(pdevicesHead);
	pdevicesHead=addlivingroomLightToDevicesLink(pdevicesHead);
	pdevicesHead=addrestaurantLightToDevicesLink(pdevicesHead);
	pdevicesHead=addFireToDevicesLink(pdevicesHead);

	pinputCmdHead=addVoiceToInputCmdLink(pinputCmdHead);
	pinputCmdHead=addSocketToInputCmdLink(pinputCmdHead);
	
	char name[128]={'\0'};
	struct Devices *tmp=NULL;
	while(1){
	printf("INPUT:\n");
	scanf("%s",name);
	tmp=findDevicesName(name,pdevicesHead);
	
	if(tmp!=NULL){
		tmp->devicesInit(tmp->pinNum);
		tmp->open(tmp->pinNum);	
		tmp->readStatus(tmp->pinNum);
		}
	}

	
	return 0;
}

一、编写流程

1、工厂初始化

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

(1)指令工厂初始化

cpp 复制代码
	/*指令工厂初始化*/
	pinputCmdHead=addVoiceToInputCmdLink(pinputCmdHead);
	pinputCmdHead=addSocketToInputCmdLink(pinputCmdHead);

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

cpp 复制代码
/*设备工厂初始化*/
pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);
pdevicesHead=addupstairLightToDevicesLink(pdevicesHead);
pdevicesHead=addlivingroomLightToDevicesLink(pdevicesHead);
pdevicesHead=addrestaurantLightToDevicesLink(pdevicesHead);
pdevicesHead=addFireToDevicesLink(pdevicesHead);

2、查找指令名称函数

cpp 复制代码
struct InputCmd *findCmdName(char *name,struct InputCmd *phead){
	struct InputCmd *tmp=phead;
	if(phead==NULL){
		return NULL;
	}else{

	while(tmp!=NULL){
		if(strcmp(tmp->cmdName,name)==0){
			return tmp;
		}
		tmp=tmp->next;
	}
	return NULL;
	}
}

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)语音线程

cpp 复制代码
	/*语音线程*/
	pthread_create(&voice_thread,NULL,voice_thread,NULL);
1)线程标识符(线程ID存储位置)

pthread_creat参数一

2)线程入口函数

pthread_creat参数三

cpp 复制代码
void *voice_thread(void *data){
	struct InputCmd *voiceHandler;
	int nread;
	voiceHandler=findCmdName("voice",pinputCmdHead);
	if(voiceHandler==NULL){
		printf("voiceHandler unfound!\n");
		pthread_exit(NULL);
	}else{
		if(voiceHandler->Init(voiceHandler,NULL,NULL)<0){
			printf("voice init error!\n");
			pthread_exit(NULL);
		}
		while(1){
			voiceHandler->getCmd(voiceHandler);
			if(nread==0){
				printf("voice no data was received!\n");
			}else{
				printf("voice received data:%s\n",voiceHandler->cmd);
			}
		}	
	}
}

(2)Socket线程

cpp 复制代码
	/*Socket线程*/
	pthread_create(&socket_thread,NULL,socket_thread,NULL);
1)线程标识符(线程ID存储位置)

pthread_creat参数一

2)线程入口函数

pthread_creat参数三

cpp 复制代码
void *socket_thread(void *data){
	int nread=0;
	pthread_t readThread;
	struct sockaddr_in c_addr;
	memset(&c_addr,0,sizeof(struct sockaddr_in));
	int len=sizeof(struct sockaddr_in);
	socketHandler=findCmdName("socket",pinputCmdHead);
	if(socketHandler==NULL){
		printf("socketHandler unfound!\n");
		pthread_exit(NULL);
	}
	socketHandler->Init(socketHandler,NULL,NULL);
	while (1){
		c_fd=accept(socketHandler->s_fd,(struct sockaddr *)&c_addr,&len);
		pthread_create(&readThread,NULL,read_thread,NULL);
	}
}

read线程参数三

cpp 复制代码
void *read_thread(void *data){
	int n_read;
	n_read=read(c_fd,socketHandler->cmd,sizeof(socketHandler->cmd));
	if(n_read==-1){
		perror("read");
	}else if(n_read>0){
		printf("\nget:%d  %s\n",n_read,socketHandler->cmd);
	}else{
		printf("client quit!\n");
	}
}

4、mainPro.c

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include "controlDevices.h"
#include "inputCmd.h"
#include <pthread.h>

int c_fd;
struct Devices *pdevicesHead=NULL;
struct InputCmd *pinputCmdHead=NULL;
struct InputCmd *socketHandler=NULL;

struct Devices *findDevicesName(char *name,struct Devices *phead){

	struct Devices *tmp=phead;
	if(phead==NULL){

		return NULL;
	}else{

	while(tmp!=NULL){
		if(strcmp(tmp->devicesName,name)==0){
			return tmp;
		}
		tmp=tmp->next;
	}
	return NULL;
	}
}

struct InputCmd *findCmdName(char *name,struct InputCmd *phead){
	struct InputCmd *tmp=phead;
	if(phead==NULL){
		return NULL;
	}else{

	while(tmp!=NULL){
		if(strcmp(tmp->cmdName,name)==0){
			return tmp;
		}
		tmp=tmp->next;
	}
	return NULL;
	}
}

void *voice_thread(void *data){
	struct InputCmd *voiceHandler;
	printf("voice_thread\n");
	int nread;//接收串口字节数

	voiceHandler=findCmdName("voice",pinputCmdHead);
	if(voiceHandler==NULL){
		printf("voiceHandler unfound!\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->cmdName);
		}

		while(1){
			nread=voiceHandler->getCmd(voiceHandler);
			if(nread==0){
				printf("voice no data was received!\n");
			}else{
				printf("voice received data:%s\n",voiceHandler->cmd);
			}
		}	
	}
}

void *read_thread(void *data){
	printf("read_thread\n");
	int n_read;
	/*清空命令接收区,方便下次检测*/
	memset(socketHandler->cmd,'\0',sizeof(socketHandler->cmd));
	n_read=read(c_fd,socketHandler->cmd,sizeof(socketHandler->cmd));
	if(n_read==-1){
		perror("read");
	}else if(n_read>0){
		printf("\nget:%d  %s\n",n_read,socketHandler->cmd);
	}else{
		printf("client quit!\n");
	}
}

void *socket_thread(void *data){
	printf("socket_thread\n");
	int nread=0;
	pthread_t readThread;
	struct sockaddr_in c_addr;
	memset(&c_addr,0,sizeof(struct sockaddr_in));
	int len=sizeof(struct sockaddr_in);
	/*从命令工厂找到网络设备*/
	socketHandler=findCmdName("socket",pinputCmdHead);
	if(socketHandler==NULL){
		printf("socketHandler unfound!\n");
		pthread_exit(NULL);
	}else{
		printf("%s init success\n",socketHandler->cmdName);
	}
	/*初始化网络*/
	socketHandler->Init(socketHandler,NULL,NULL);
	/*不断监听客户端发送的数据,并创建线程处理*/
	while (1){
		c_fd=accept(socketHandler->s_fd,(struct sockaddr *)&c_addr,&len);
		pthread_create(&readThread,NULL,read_thread,NULL);
	}
}

int main(){
	char name[128]={'\0'};
	struct Devices *tmp=NULL;
	pthread_t voiceThread;
	pthread_t socketThread;

	if(wiringPiSetup()==-1){
		return -1;
	}
	printf("main\n");
	/*指令工厂初始化*/
	pinputCmdHead=addVoiceToInputCmdLink(pinputCmdHead);
	pinputCmdHead=addSocketToInputCmdLink(pinputCmdHead);

	/*设备工厂初始化*/
	pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);
	pdevicesHead=addupstairLightToDevicesLink(pdevicesHead);
	pdevicesHead=addlivingroomLightToDevicesLink(pdevicesHead);
	pdevicesHead=addrestaurantLightToDevicesLink(pdevicesHead);
	pdevicesHead=addFireToDevicesLink(pdevicesHead);

	/*线程池*/
	//pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(start_routine)(void *),void *arg);

	/*语音线程*/
	pthread_create(&voiceThread,NULL,voice_thread,NULL);

	/*Socket线程*/
	pthread_create(&socketThread,NULL,socket_thread,NULL);

	pthread_join(voiceThread,NULL);
	pthread_join(socketThread,NULL);

	// while(1){
	// printf("INPUT:\n");
	// scanf("%s",name);
	// tmp=findDevicesName(name,pdevicesHead);
	
	// if(tmp!=NULL){
	// 	tmp->devicesInit(tmp->pinNum);
	// 	tmp->open(tmp->pinNum);	
	// 	tmp->readStatus(tmp->pinNum);
	// 	}
	// }
	return 0;
}

二、测试

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,权限不足

解决办法

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

运行成功

网络调试助手网络功能测试
串口功能测试
相关推荐
stm32发烧友2 小时前
基于STM32的智能家居环境监测系统设计
stm32·嵌入式硬件·智能家居
lucy1530275107920 小时前
【青牛科技】GC2803:白色家电与安防领域中 ULN2803 的卓越替代者
科技·单片机·智能家居·能源·安防·开关电源·白色家电
尘浮生3 天前
Java项目实战II基于Spring Boot的智能家居系统(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·mysql·maven·智能家居
沐欣工作室_lvyiyi4 天前
基于单片机的智能家居排气扇系统设计
stm32·单片机·嵌入式硬件·物联网·智能家居
乐鑫科技 Espressif6 天前
ESP-HaloPanel:用 ESP32-C2 打造超低成本智能家居面板
esp32·智能家居·wi-fi
花伤情犹在6 天前
Docker 安装HomeAssistant智能家居系统
docker·容器·智能家居
yufei-coder8 天前
使用语音模块的开发智能家居产品(使用雷龙LSYT201B 语音模块)
嵌入式·智能家居·语音模块
唯创知音8 天前
医疗器械设备语音ic芯片方案-选型大全
人工智能·单片机·物联网·智能家居·语音识别
飞睿科技8 天前
智能家居10G雷达感应开关模块,飞睿智能uA级别低功耗、超高灵敏度,瞬间响应快
智能家居·照明·空调·雷达感应开关模块·ua级别低功耗·超高灵敏度·喂食器