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

运行成功

网络调试助手网络功能测试
串口功能测试
相关推荐
Chery11401 小时前
nRF54LC10A芯片详解:超小尺寸低功耗多协议SoC,适用于蓝牙追踪器与Matter智能家居
智能家居
智鸟科技GemeOpen开发者智能设备18 小时前
智能插座二次开发如何接入Home Assistant,从零开始完整工程实现(Python+React)
开发语言·python·物联网·react.js·智能家居
似夜晓星辰20 小时前
用 Laya 决策模型(JEV 的开源实现)做一个智能家居决策 Demo
开源·智能家居
吴建旭 智宅焕21 小时前
智能家居全国交付平台的架构设计与实现:销服分离下的交付确定性系统
智能家居
乐橙开放平台9 天前
从「多套客户端」到一套开放能力:乐橙视频监控能力复盘
笔记·物联网·自动化·音视频·智能家居
2601_9685020610 天前
无主灯灯具怎么选?
智能家居·武汉装修·武汉无主灯·武汉灯光设计
远翔调光芯片^1382879887211 天前
ECP5702能芯科技PD取电芯片在市场上的优势有哪些?
开发语言·人工智能·单片机·嵌入式硬件·智能家居
Zentceh11 天前
海洋牧场夜间监测:AI全彩夜视+水下成像集成方案
图像处理·人工智能·科技·计算机视觉·车载系统·无人机·智能家居
远翔调光芯片^1382879887213 天前
Type-C接口统一了,但充电协议没统一,终端设备如何解决取电难题?
人工智能·科技·物联网·智能家居·能源
senyushejiaz13 天前
海珠局部改造怎么做?不用全屋重装,这些居住问题可以针对性解决
智能家居·装修