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

运行成功

网络调试助手网络功能测试
串口功能测试
相关推荐
sleepybear11135 天前
在Ubuntu上从零开始编译并运行Home Assistant源码并集成HACS与小米开源的Ha Xiaomi Home
python·智能家居·小米·home assistant·米家·ha xiaomi home
weixin_452600696 天前
GC393低功耗双电压比较器:精准、高效的信号处理解决方案
单片机·嵌入式硬件·智能家居·信号处理·音响·蓝牙音箱
好多渔鱼好多6 天前
【HDMI CEC】如何测试CEC协议功能
物联网·智能家居·万物互联·hdmi cec·一键控制·cec 测试
sword devil9008 天前
PYQT实战:智能家居中控
python·智能家居·pyqt
欢乐熊嵌入式编程9 天前
WIFI协议全解析01:WiFi协议的前世今生:从802.11到智能家居
esp32·智能家居·wifi协议·wifi通信
技术支持者python,php21 天前
MQTT通讯:物联网
物联网·智能家居
深圳市尚想信息技术有限公司22 天前
UL/CE双认证!光宝MOC3052-A双向可控硅输出光耦 智能家居/工业控制必备!
智能家居·工业控制·光宝·驱动光耦·输出光耦
根号三加载成功23 天前
物联网控制器:一台顶N台!路由器、PLC控制器、网关、工控机……
物联网·云计算·智能家居·工业自动化
Smartlabs24 天前
Matter协议开发者指南:使用Matter SDK构建智能家居应用
智能家居·matter·matter方案·matter协议
华普微HOPERF25 天前
让温度“说话”,数字温度传感器如何智能感知温度?
科技·单片机·嵌入式硬件·物联网·智能家居