智能家居项目(三)之框架设计及框架代码文件工程建立

news2024/9/20 20:24:22

目录

一、智能家居项目框架设计草图

二、框架代码文件工程建立

三、添加声音识别模块的串口读取功能


一、智能家居项目框架设计草图

 代码思路讲解:

1、一个指令工厂,一个控制工厂,实际上就是通过链表链起来的数据。具体怎么链接起来,就是基于简单工厂模式的类与对象的概念,上一篇文章有学习记录。
2、主函数语音指令程序和tcp指令程序各起一个线程,然后通过指令名字找到对应的控制程序,实现对应的模块的功能。

二、框架代码文件工程建立

1、在桌面新建一个项目文件夹smartHose,然后在文件夹中创建如下文件:

2、把上述的所有文件,都加载到Source lnsight工具中,如下图代表加载完毕

3、创建inputCommand.h头文件

//面向指令工厂的头文件
#include <wiringPi.h>
#include <stdlib.h>

struct InputCommander{

	char commandName[128];             //名字
	char command[32];                  //指令
	int (*Init)(char *name,char *ipAdress,char *port);  //操作函数 
	int (*getCommand)(char *cmd);      //获取数据函数

	char log[1024];                    //log日志获取
	struct InputCommander *next;
};

4、创建contrlDevices.h头文件

//设备头文件
#include <wiringPi.h>

struct Devices{

	char deviceName[128]; //名字
	int status;           //状态
	int pinNum;           //引脚
	
	int (*open)(int pinNum);        //打开
	int (*close)(int pinNum);       //关闭
	int (*deviceInit)(int pinNum);  //设备初始化

	int (*readStatus)();  //火灾
	int (*changeStatus)(int status);

	struct Devices *next;
};

struct Devices* addBathroomLightToDeviceLink(struct Devices *phead);
struct Devices* addUpstairLightToDeviceLink(struct Devices *phead);
struct Devices* addLivingRoomLightToDeviceLink(struct Devices *phead);
struct Devices* addRestaurantLightToDeviceLink(struct Devices *phead);
struct Devices* addFireToDeviceLink(struct Devices *phead);

5、创建bathroomLight.c文件

//浴室的灯
#include "contrlDevices.h"
#include<stdlib.h>

int bathroomLightOpen(int pinNum){

	digitalWrite(pinNum,LOW);
}
int bathroomLightClose(int pinNum){

	digitalWrite(pinNum,HIGH);
}
int bathroomLightCloseInit(int pinNum){

	pinMode(pinNum,OUTPUT);
	digitalWrite(pinNum,HIGH);
}
int bathroomLightCloseStatus(int status){

}
struct Devices bathroomLight={
	
	.deviceName = "bathroomLight",
	.pinNum = 26,
	.open = bathroomLightOpen,
	.close = bathroomLightClose,
	.deviceInit = bathroomLightCloseInit,
	.changeStatus = bathroomLightCloseStatus
	
};
struct Devices* addBathroomLightToDeviceLink(struct Devices *phead){

	if(phead == NULL){	
		return &bathroomLight;
	}
	else{
		bathroomLight.next = phead;
		phead = &bathroomLight;
	}
};

6、创建livingroomLight.c文件

#include "contrlDevices.h"
#include<stdlib.h>

int livingroomLightOpen(int pinNum){

	digitalWrite(pinNum,LOW);
}
int livingroomLightClose(int pinNum){

	digitalWrite(pinNum,HIGH);
}
int livingroomLightCloseInit(int pinNum){

	pinMode(pinNum,OUTPUT);
	digitalWrite(pinNum,HIGH);
}
int livingroomLightCloseStatus(int status){

}
struct Devices livingroomLight={
	
	.deviceName = "livingroomLight",
	.pinNum = 27,
	.open = livingroomLightOpen,
	.close = livingroomLightClose,
	.deviceInit = livingroomLightCloseInit,
	.changeStatus = livingroomLightCloseStatus
	
};
struct Devices* addLivingRoomLightToDeviceLink(struct Devices *phead){
	if(phead == NULL){	
		return &livingroomLight;
	}
	else{
		livingroomLight.next = phead;
		phead = &livingroomLight;
	}
};

7、创建restaurantLight.c文件

#include "contrlDevices.h"
#include<stdlib.h>

int restaurantLightOpen(int pinNum){

	digitalWrite(pinNum,LOW);
}
int restaurantLightClose(int pinNum){

	digitalWrite(pinNum,HIGH);
}
int restaurantLightCloseInit(int pinNum){

	pinMode(pinNum,OUTPUT);
	digitalWrite(pinNum,HIGH);
}
int restaurantLightCloseStatus(int status){

}
struct Devices restaurantLight={
	
	.deviceName = "restaurantLight",
	.pinNum = 28,
	.open = restaurantLightOpen,
	.close = restaurantLightClose,
	.deviceInit = restaurantLightCloseInit,
	.changeStatus = restaurantLightCloseStatus
};
struct Devices* addRestaurantLightToDeviceLink(struct Devices *phead){

	if(phead == NULL){	
		return &restaurantLight;
	}
	else{
		restaurantLight.next = phead;
		phead = &restaurantLight;
	}
};

8、创建upstairLight.c文件

//二楼灯
#include "contrlDevices.h"
#include<stdlib.h>

int upstairLightOpen(int pinNum){

	digitalWrite(pinNum,LOW);
}
int upstairLightClose(int pinNum){

	digitalWrite(pinNum,HIGH);
}
int upstairLightCloseInit(int pinNum){

	pinMode(pinNum,OUTPUT);
	digitalWrite(pinNum,HIGH);
}
int upstairLightCloseStatus(int status){

}
struct Devices upstairLight={
	
	.deviceName = "upstairLight",
	.pinNum = 29,
	.open = upstairLightOpen,
	.close = upstairLightClose,
	.deviceInit = upstairLightCloseInit,
	.changeStatus = upstairLightCloseStatus
};
struct Devices* addUpstairLightToDeviceLink(struct Devices *phead){

	if(phead == NULL){	
		return &upstairLight;
	}
	else{
		upstairLight.next = phead;
		phead = &upstairLight;
	}
};

9、创建fire.c文件

//火灾报警
#include "contrlDevices.h"
#include<stdlib.h>

int fireIfOrNotInit(int pinNum){

	pinMode(pinNum,INPUT);
	digitalWrite(pinNum,HIGH);
}
int fireStatusRead(int pinNum){

	return digitalRead(pinNum);
}
struct Devices fireIfOrNot={
	
	.deviceName = "fireIfOrNot",
	.pinNum = 25,
	.deviceInit = fireIfOrNotInit,
	.readStatus = fireStatusRead
	
};
struct Devices* addFireToDeviceLink(struct Devices *phead){

	if(phead == NULL){	
		return &fireIfOrNot;
	}
	else{
		fireIfOrNot.next = phead;
		phead = &fireIfOrNot;
	}
};

10、创建mainPro.c主函数文件

#include <stdio.h>
#include "contrlDevices.h"
#include <string.h>
#include "inputCommand.h"

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

	struct Devices *tmp = phead;
	if(phead == NULL){
		return NULL;
	}
	else{
		while(tmp != NULL){
			if(strcmp(tmp->deviceName,name) == 0){
				return tmp;
			}
			tmp = tmp->next;
		}
		return NULL;
	}
};

int main(){

	char name [128];
	struct Devices *tmp = NULL;
	if(-1 == wiringPiSetup()){
		return -1;
	}
	struct Devices *pdeviceHead = NULL;
	pdeviceHead = addBathroomLightToDeviceLink(pdeviceHead);
	pdeviceHead = addUpstairLightToDeviceLink(pdeviceHead);
	pdeviceHead = addLivingRoomLightToDeviceLink(pdeviceHead);
	pdeviceHead = addRestaurantLightToDeviceLink(pdeviceHead);
	pdeviceHead = addFireToDeviceLink(pdeviceHead);
	
	while(1){

		printf("Input:\n");
		scanf("%s",name);
		tmp = findDeviceByName(name,pdeviceHead);
		
		if(tmp != NULL){
			tmp->deviceInit(tmp->pinNum);
			tmp->open(tmp->pinNum);
		}
	}
	//1、指令工厂初始化
	//2、设备控制工厂初始化
	//3、线程池建立
	//3.1、语音线程
	//3.2、socket线程
	//3.3、摄像头线程
	//3.4、火灾线程
}

把上述的代码传到树莓派的终端,用FileZilla传即可,然后执行结果:

gcc mainPro.c upstairLight.c bathroomLight.c livingroomLight.c restaurantLight.c -lwiringPi -o test1

效果演示:(虽然没有装到实际的智能家居里,但是小灯亮了,说明程序是可以正常用的🤭)

三、添加声音识别模块的串口读取功能

这里主要通过主控芯片树莓派的串口跟语音模块连接。
树莓派的T接语音模块的R
树莓派的R接语音模块的T
然后就是供电

我们先把语音模块的代码整合到指令链表当中去:
1.语音控制设备voiceContrl.c

#include "inputCommand.h"
#include <stdlib.h>
#include <wiringPi.h>
#include <stdio.h>
#include <wiringSerial.h>
#include <unistd.h>

//串口

int voiceInit(struct InputCommander *voicer,char *ipAdress,char *port){ //声音初始化

	int fd;
	if((fd = serialOpen(voicer->deviceName,9600)) == -1){  //初始化串口,波特率9600
			exit(-1);
	}
	voicer->fd = fd;
	return fd;
} 
int voiceGetCommand(struct InputCommander *voicer){

	int nread = 0;
	nread = (voicer->fd,voicer->command,sizeof(voicer->command));
	if(nread == 0){
		printf("usart for voice read over time\n");
	}else{
		return nread;
	}
}
struct InputCommander voiceContrl = {

	.commandName = "voice", 
	.deviceName = "dev/ttyAMA0",
	.command = {'\0'},
	.Init = voiceInit,
	.getCommand = voiceGetCommand,
	.log = {'\0'},
	.next = NULL,

};
struct InputCommander* addvoiceContrlToInputCommandLink(struct InputCommander *phead){

	if(phead == NULL){
		return &voiceContrl;
	}
	else{
		voiceContrl.next = phead;
		phead = &voiceContrl;
	}
};

2.控制设备的头文件inputCommand.h

//面向指令工厂的头文件
#include <wiringPi.h>
#include <stdlib.h>

struct InputCommander{

	char commandName[128];  //声音的名字
	char command[32];       
	char deviceName[128];   //串口的名字
	int (*Init)(struct InputCommander *voicer,char *ipAdress,char *port); 
	int (*getCommand)(struct InputCommander *voicer);

	char log[1024];
	int fd;
	struct InputCommander *next;

};
struct InputCommander* addvoiceContrlToInputCommandLink(struct InputCommander *phead);

3.在mainPro.c主函数中添加语音模块的函数

#include <stdio.h>
#include "contrlDevices.h"
#include <string.h>
#include "inputCommand.h"

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

	struct Devices *tmp = phead;
	if(phead == NULL){
		return NULL;
	}
	else{
		while(tmp != NULL){
			if(strcmp(tmp->deviceName,name) == 0){
				return tmp;
			}
			tmp = tmp->next;
		}
		return NULL;
	}
};
int main(){

	char name [128];
	struct Devices *tmp = NULL;
	if(-1 == wiringPiSetup()){
		return -1;
	}
	struct Devices        *pdeviceHead = NULL;   //设备工厂
	struct InputCommander *pCommandHead = NULL;  //指令工厂
		
	pdeviceHead = addBathroomLightToDeviceLink(pdeviceHead);
	pdeviceHead = addUpstairLightToDeviceLink(pdeviceHead);
	pdeviceHead = addLivingRoomLightToDeviceLink(pdeviceHead);
	pdeviceHead = addRestaurantLightToDeviceLink(pdeviceHead);
	pdeviceHead = addFireToDeviceLink(pdeviceHead);  //火灾

	pCommandHead = addvoiceContrlToInputCommandLink(pCommandHead); //串口
	while(1){

		printf("Input:\n");
		scanf("%s",name);
		tmp = findDeviceByName(name,pdeviceHead);
		
		if(tmp != NULL){
			tmp->deviceInit(tmp->pinNum);
			tmp->open(tmp->pinNum);
		}
	}
}

4.把上述的代码传到树莓派的终端,用FileZilla传即可,然后执行结果:

gcc mainPro.c upstairLight.c bathroomLight.c fire.c livingroomLight.c restaurantLight.c voiceContrl.c -lwiringPi -o test1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/352249.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dockerfile自定义镜像安装jdk8,nginx,后端jar包和前端静态文件,并启动容器访问

dockerfile自定义镜像安装jdk8,nginx,后端jar包和前端静态文件&#xff0c;并启动容器访问简介centos7系统里面我准备的服务如下:5gsignplay-web静态文件内容如下:nginx.conf配置文件内容如下:Dockerfile内容如下:run.sh启动脚本内容如下:制作镜像并启动访问简介 通过用docker…

将SpringBoot项目部署到云服务器上面

将jar包部署到云服务器上面在项目中直接双击点击maven里面的package当控制台输出创建成功以后找到target目录下面打好的jar包然后找到jar包所在的文件目录&#xff0c;将该jar包放到服务器里面的apache-tomcat-8.5.82目录里面的webapps目录里面打开安全组开放访问端口服务器里面…

【2023进阶自动化测试第一步】什么是自动化测试基础?

01、自动化测试的定义 使用一种自动化测试工具来验证各种软件测试的需求&#xff0c;它包括测试活动的而管理与实施、测试脚本的开发与执行。 自动化测试只是策是工作的一部分&#xff0c;是对手工测试的一种补充&#xff1a;自动化测试决不能代替手工测试&#xff1b;多数情…

Word处理控件Aspose.Words功能演示:使用 Java 拆分 MS Word 文档

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c;API支持所有流行的Word处理文件…

ASE28N50-ASEMI高压N沟道MOS管ASE28N50

编辑-Z ASE28N50在TO-247封装里的静态漏极源导通电阻&#xff08;RDS(ON)&#xff09;为200mΩ&#xff0c;是一款N沟道高压MOS管。ASE28N50的最大脉冲正向电流ISM为110A&#xff0c;零栅极电压漏极电流(IDSS)为1uA&#xff0c;其工作时耐温度范围为-55~150摄氏度。ASE28N50功…

【实战场景二】如何设计一个分布式锁?

如何优雅的设计一个分布式锁&#xff1f;如何设计一个分布式锁&#xff1f;1、什么是分布式锁2、那么分布式锁&#xff0c;具备什么条件呢&#xff1f;3、设计分布式锁有哪些方式&#xff1f;3.1 利用redis实现分布式锁原理3.2 基于数据库做分布式锁3.3 基于zookeeper实现分布式…

L1-064 估值一亿的AI核心代码

以上图片来自新浪微博。 本题要求你实现一个稍微更值钱一点的 AI 英文问答程序&#xff0c;规则是&#xff1a; 无论用户说什么&#xff0c;首先把对方说的话在一行中原样打印出来&#xff1b;消除原文中多余空格&#xff1a;把相邻单词间的多个空格换成 1 个空格&#xff0c…

如何有效提升微信小程序的排名?

微信小程序排名提升的方法有很多&#xff0c;今天厦门巨神峰给大家分享几点&#xff1a; 1. 加强小程序的用户体验&#xff0c;提升用户满意度&#xff1b; 2. 加强小程序的口碑宣传&#xff0c;提升小程序的知名度&#xff1b; 3. 加强小程序的技术支持&#xff0c;提升小程…

血糖高不高,看皮肤也能知道

糖尿病是一种以高血糖为特征的代谢性疾病。长期存在的高血糖&#xff0c;导致各种组织&#xff0c;特别是眼、肾、心脏、血管、神经的慢性损害、功能障碍。很多人不知道&#xff0c;皮肤也会受到血糖影响。以下就是皮肤发出的警告&#xff1a;1.黑棘皮病&#xff1a;后脖颈、腋…

Docker安全防护与配置

author: aming email: jikcheng163.com title: Docker安全防护与配置 creation_date: 2023-02-08 12:26 Last modified date: 2023-02-08 14:09 tags: Docker安全防护与配置 File Folder with relative path: reading notes/doc remark: other: 本章背景知识 运行在容器内部的…

【C++修行之路】C/C++内存管理

文章目录程序区域内存划分C语言动态内存分配&#xff1a;new和delete&#xff1a;new、delete和malloc、free的区别:程序区域内存划分 C/C程序内存区域划分非常相似。 C语言动态内存分配&#xff1a; malloc、calloc、realloc都是C语言动态开辟内存的常用函数 其中 malloc 开…

【Mybatis源码解析】一级缓存和二级缓存源码解析

文章目录缓存使用缓存源码测试代码上一篇《【Mybatis源码解析】mapper实例化及执行流程源码分析》&#xff0c;主要讲解了Mybatis的基本原理一级执行的流程&#xff0c;这一章来讲一下Mybatis的两个缓存&#xff1a;一级缓存和二级缓存。 因为网上大部分都是使用xml配置的方式…

函数编程之Function

文章目录前言一、Function是什么&#xff1f;二、Function 怎么用?1.简单使用2.真正的强大之处总结前言 在java8之后,我已经习惯了开始用stream()方式编程,但是对于新引入的其他功能,还是不清楚,今天经历了一个编程问题后,让我对于Function() 这个函数有了新的认知; 一、Func…

渲染农场优势是什么_云渲染农场怎么用?

在回答渲染农场的优势这个问题之前&#xff0c;我先申明一下本文中提到的渲染农场/云渲染平台/云渲染农场&#xff0c;都特指CG领域内的专业3D渲染平台&#xff0c;有一些文章会强调这个叫法的区别&#xff0c;但是业内一般都不会分这么细&#xff0c;所以也就不赘述了。渲染农…

【Spark分布式内存计算框架——Spark SQL】7. 数据处理分析案例

4.3 案例&#xff1a;电影评分数据分析 使用电影评分数据进行数据分析&#xff0c;分别使用DSL编程和SQL编程&#xff0c;熟悉数据处理函数及SQL使用&#xff0c;业务需求说明&#xff1a; 对电影评分数据进行统计分析&#xff0c;获取Top10电影&#xff08;电影评分平均值最高…

4道数学题,求解极狐GitLab CI 流水线|第23题:父子流水线 + 多项目流水线

本文来自&#xff1a; 武让 极狐(GitLab) 高级解决方案架构师 &#x1f4a1; 极狐GitLab CI 依靠其一体化、轻量化、声明式、开箱即用的特性&#xff0c;在开发者群体中的使用率越来越高&#xff0c;在国内企业中仅次于 Jenkins &#xff0c;排在第二位。 极狐GitLab 流水线有…

如何解决错误“已超过了锁请求超时时段。 (Microsoft SQL Server,错误: 1222)“

解决 Microsoft SQL Server 的错误: 1222 使用存储过程 sp_who2设置 LOCK_TIMEOUT在Microsoft SQL Server Management Studio中,有时会在对象资源管理器中查看树、表或过程时收到错误。当查询等待的时间超过锁定超时设置时,通常会发生此错误。锁定超时以毫秒为单位,等待后端…

LeetCode 382. 链表随机节点

原题链接 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 给你一个单链表&#xff0c;随机选择链表的一个节点&#xff0c;并返回相应的节点值。每个节点 被选中的概率一样 。 实现 SolutionSolutionSolution 类&#xff1a; Solution(ListNodehead)Solution…

数据库(第五次作业)

1.1 Redis概述 1.1.1 什么是Redis 2008年&#xff0c;意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG&#xff0c;然而没过多久该公司的创始人 Salvatore Sanfilippo便开始对MySQL的性能感到失望&#xff0c;于是他决定亲自为LLOOGG量身定做一个数据…

Amazon S3简介

前言&#xff1a; 这段时间来到了某大数据平台&#xff0c;做平台技术底座封装和一些架构等等&#xff0c;有结构化数据也有非结构数据&#xff0c;涉及到很多技术&#xff0c;自己也私下花时间去研究了很多&#xff0c;有很多纯技术类的还是需要梳理并记录&#xff0c;巩固以及…