【智能家居】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是编译后生成的可执行文件)

运行成功

网络调试助手网络功能测试
串口功能测试
相关推荐
YHPsophie17 小时前
智能家居设备
物联网·智能家居·设备
niuTaylor2 天前
瑞芯微RK3568嵌入式AI项目实战:智能家居项目(二)
人工智能·智能家居
云山工作室2 天前
基于STM32的智能家居门禁开锁控制系统(论文+源码)
stm32·嵌入式硬件·智能家居
cainiao08060510 天前
Neuralink API开发指南:用Python读取脑电信号控制智能家居
开发语言·python·智能家居
云山工作室11 天前
基于单片机的智能家居设计(论文+源码)
单片机·嵌入式硬件·毕业设计·智能家居·毕设
沐欣工作室_lvyiyi12 天前
基于单片机的智能奶茶机(论文 +源码)
stm32·单片机·嵌入式硬件·物联网·智能家居
cainiao08060512 天前
树莓派5智能家居中控:HomeAssistant全配置指南
智能家居
智享食事13 天前
智能家居赋能宠物经济:未来宠物行业的另一片蓝海
人工智能·智能家居·宠物
Smartlabs13 天前
云端陷阱:当免费午餐变成付费订阅,智能家居用户如何破局?
智能家居