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

运行成功

网络调试助手网络功能测试
串口功能测试
相关推荐
云山工作室2 天前
智能家居环境监测系统设计(论文+源码)
单片机·嵌入式硬件·毕业设计·智能家居·毕设
Stanford_11063 天前
物联网智能项目之——智能家居项目的实现!
物联网·学习·微信小程序·智能家居·微信公众平台·twitter·微信开放平台
深圳启明云端科技3 天前
ESP32无线通信智能屏方案,设备触摸人机交互,高性能控制应用
网络·物联网·人机交互·智能家居·乐鑫
艾格北峰14 天前
STM32 物联网智能家居 (五) 设备子系统之点亮LED灯
arm开发·stm32·单片机·嵌入式硬件·物联网·架构·智能家居
智哪儿14 天前
智能家居企业如何通过设计师渠道打造第二曲线?
智能家居
深圳启明云端科技17 天前
ESP RainMaker轻量级云平台方案,产品私有云部署,物联网无线应用
网络·物联网·wifi·智能家居
不能只会打代码18 天前
32单片机综合应用案例——智能家居灯光控制系统(二)(内附详细代码讲解!!!)
单片机·嵌入式硬件·智能家居·语音识别·32单片机
艾格北峰18 天前
STM32 物联网智能家居 (二)-开发环境及工程搭建(STM32CubeMX)
arm开发·stm32·单片机·嵌入式硬件·物联网·架构·智能家居
freewzx200520 天前
VMware虚拟机安装Home Assistant智能家居平台并实现远程访问保姆级教程
智能家居
沐欣工作室_lvyiyi20 天前
基于STM32的智能家居蓝牙系统(论文+源码)
stm32·单片机·嵌入式硬件·物联网·毕业设计·智能家居