【智能家居】5、主流程设计以及外设框架编写与测试

目录

 一、主流程设计

1、工厂模式结构体定义

 (1)指令工厂 inputCmd.h

(2)外设工厂 controlDevices.h

二、外设框架编写

1、创建外设工厂对象bathroomLight

2、编写相关函数框架

3、将浴室灯相关操作插入外设工厂链表等待被调用

三、外设框架测试

1、配置IO口输出状态

2、将函数加入到controlDevices.h

3、main函数编写

四、编写完成后拷贝到树莓派运行

1、创建一个文件夹用于保存上面所编写的三个代码

2、查看使用的GPIO口位于第几个引脚

3、编译运行

五、四盏灯控制

1、main函数增加读取用户输入并点灯代码

2、四盏灯相关代码

3、测试


 一、主流程设计

#include <stdio.h>

int main(){

	//指令工厂初始化

	//控制外设工厂初始化

	//线程池
	
	return 0;
}

1、工厂模式结构体定义

 (1)指令工厂 inputCmd.h

struct InputCmd{
	char cmdName[128];//指令名称
	char cmd[32];//指令

	int (*Init)(char *name,char *ipAdresschar *port);//初始化函数
	int (*getCmd)(char *cmd);//获取指令函数
	char *log[1024];//日志

	struct InputCmd *next;
};

定义一个名为 `InputCmd` 的结构体,包含以下成员:

  1. char cmdName[128]:一个长度为128的字符数组,用于存储指令名称。
  2. char cmd[32]:一个长度为32的字符数组,用于存储指令。
  3. int (*Init)(char *name, char *ipAdress, char *port):一个初始化相关指令操作的函数指针,它指向一个返回值为整型,接受三个字符指针类型的参数(名称、IP地址、端口号)的函数。
  4. int (*getCmd)(char *cmd):一个用于获取指令的函数指针,它指向一个返回值为整型,接受一个字符指针类型的参数(指令)的函数。
  5. char *log[1024]:一个长度为1024的字符指针数组,用于存储日志信息。
  6. struct InputCmd *next:一个指向 `struct InputCmd` 类型的指针,用于链表的连接。

(2)外设工厂 controlDevices.h

struct Devices{
	char devicesName[128];//设备名称
	int status;//状态:开&关
    int pinNum;//引脚号
	
	int (*open)(int pinNum);//打开设备
	int (*close)(int pinNum);//关闭设备
	int (*devicesInit)(int pinNum);//设备初始化
	int (*readStatus)();//读取设备状态
	int (*changeStatus)(int status);//改变设备状态

	struct Devices *next;
};

定义一个名为 `Devices` 的结构体,包含以下成员:

  1. char devicesName[128]:一个长度为128的字符数组,用于存储设备名称。
  2. int status:一个整型变量,用于存储设备的状态(如开/关等)。
  3. int pinNum:一个整型变量,用于存储设备的引脚号。
  4. int (*open)(int pinNum):一个用于打开相关设备的函数指针,它指向一个返回值为整型、接受一个整型的参数(引脚号)的函数。
  5. int (*close)(int pinNum):一个用于关闭相关设备的函数指针,它指向一个返回值为整型、接受一个整型的参数(引脚号)的函数。
  6. int (*devicesInit)(int pinNum):一个用于初始化相关设备的函数指针,它指向一个返回值为整型、接受一个整型的参数(引脚号)的函数。
  7. int (*readStatus)():一个用于读取设备当前状态的函数指针,它指向一个返回值为整型、无参数的函数。
  8. int (*changeStatus)(int status):一个用于更改设备状态的函数指针,它指向一个返回值为整型,接受一个字符指针类型的参数(设备状态)的函数。
  9. struct Devices *next:一个指向 `struct Devices` 类型的指针,通常链表的连接。

二、外设框架编写

以浴室灯模块为例

bathroomLight.c

1、创建外设工厂对象bathroomLight

struct Devices bathroomLight={
	.name="bathroomLight",
    .pinNum=你选择的引脚号,
	.open=bathroomLight_open,
	.close=bathroomLight_close,
	.devicesInit=bathroomLight_init,
	.changeStatus=bathroomLight_status
};

2、编写相关函数框架


int bathroomLight_open(int pinNum){
	

}

int bathroomLight_close(int pinNum){

	
}

int bathroomLight_init(int pinNum){
	
}

int bathroomLight_status(int status){

}

3、将浴室灯相关操作插入外设工厂链表等待被调用

sturct  Devices *addbathroomLightToDevicesLink(struct Devices *phead){
	if(phead==NULL){
		ruturn &bathroomLight;
	}else{
		bathroomLight.next=phead;
		phead=&bathroomLight;
		}
}

三、外设框架测试

1、配置IO口输出状态

pinMode()和digitalWrite()都是WiringPi库的函数,要包含wiringPi.h头文件(我在controlDevices.h里面包含了)

bathroomLight.c

#include "controlDevices.h"

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

int bathroomLight_close(int pinNum){

	digitalWrite(pinNum,HIGH);
}

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

int bathroomLight_status(int status){

}

struct Devices bathroomLight={
	.devicesName="bathroomLight",
	.pinNum=1,
	.open=bathroomLight_open,
	.close=bathroomLight_close,
	.devicesInit=bathroomLight_init,
	.changeStatus=bathroomLight_status
};

struct  Devices* addbathroomLightToDevicesLink(struct Devices *phead){
	if(phead== NULL){
		return &bathroomLight;
	}else{
		bathroomLight.next=phead;
		phead=&bathroomLight;
	}
}

2、将函数加入到controlDevices.h

controlDevices.h

#include <wiringPi.h>
#include <stdio.h>

struct Devices{
	char devicesName[128];
	int status;
	int pinNum;
	
	int (*open)(int pinNum);
	int (*close)(int pinNum);
	int (*devicesInit)(int pinNum);
	int (*readStatus)();
	int (*changeStatus)(int status);

	struct Devices *next;
};

struct Devices *addbathroomLightToDevicesLink(struct Devices *phead);

3、main函数编写

(1)判断树莓派接口是否初始化成功

(2)将浴室灯模块加入到工厂模式的链表中等待被调用

 (3)判断+实现

mainPro.c

#include <stdio.h>
#include <string.h>

#include "controlDevices.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;
	pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);


	char *name="bathroomLight";
	struct Devices *tmp=findDevicesName(name,pdevicesHead);
	if(tmp!=NULL){
		tmp->devicesInit(tmp->pinNum);
		tmp->open(tmp->pinNum);	
	}

	return 0;
}

四、编写完成后拷贝到树莓派运行

1、创建一个文件夹用于保存上面所编写的三个代码

2、查看使用的GPIO口位于第几个引脚

我是用继电器进行测试

3、编译运行

小插曲

 编译

运行后可以听见继电器“哒” 的一声

输入gpio readall后查看发现GPIO1已经变为OUT

五、四盏灯控制

前面编写了bathroomLight的代码,对于upstairLight、reastaurantLight、livingroomLight的实现代码我们复制粘贴修改名字和对应GPIO口即可,主要是在main函数里面增加读取用户输入从而控制指定灯的代码

我使用的是GPIO1~4控制四盏灯:

GPIO1-bathroomLight   GPIO2-upstairLight   GPIO3-livingLight  GPIO4-restaurantLiht

1、main函数增加读取用户输入并点灯代码

将四个模块加入到工厂模式链表中

 获取用户输入并打开对应的灯

 mainPro.c

#include <stdio.h>
#include <string.h>

#include "controlDevices.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;
	pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);
	pdevicesHead=addupstairLightToDevicesLink(pdevicesHead);
	pdevicesHead=addlivingroomLightToDevicesLink(pdevicesHead);
	pdevicesHead=addrestaurantLightToDevicesLink(pdevicesHead);

	char name[128];
	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();
	}
	}
	return 0;
}

2、四盏灯相关代码

bathroomLight.c

#include "controlDevices.h"

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

int bathroomLight_close(int pinNum){

	digitalWrite(pinNum,HIGH);
}

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

int bathroomLight_status(int status){
	printf("bathroomLight-OPEN\n");
}


struct Devices bathroomLight={
	.devicesName="bathroomLight",
	.pinNum=1,
	.open=bathroomLight_open,
	.close=bathroomLight_close,
	.devicesInit=bathroomLight_init,
	.readStatus=bathroomLight_status
};

struct  Devices* addbathroomLightToDevicesLink(struct Devices *phead){
	if(phead== NULL){
		return &bathroomLight;
	}else{
		bathroomLight.next=phead;
		phead=&bathroomLight;
	}
}

livingroomLight.c

#include "controlDevices.h"

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

int livingroomLight_close(int pinNum){

	digitalWrite(pinNum,HIGH);
}

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

int livingroomLight_status(int status){
	printf("livingroomLight-OPEN\n");
}


struct Devices livingroomLight={
	.devicesName="livingroomLight",
	.pinNum=3,
	.open=livingroomLight_open,
	.close=livingroomLight_close,
	.devicesInit=livingroomLight_init,
	.readStatus=livingroomLight_status
};

struct  Devices* addlivingroomLightToDevicesLink(struct Devices *phead){
	if(phead== NULL){
		return &livingroomLight;
	}else{
		livingroomLight.next=phead;
		phead=&livingroomLight;
	}
}

restaurantLight.c

#include "controlDevices.h"

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

int restaurantLight_close(int pinNum){

	digitalWrite(pinNum,HIGH);
}

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

int restaurantLight_status(int status){
	printf("restaurantLight-OPEN\n");
}


struct Devices restaurantLight={
	.devicesName="restaurantLight",
	.pinNum=4,
	.open=restaurantLight_open,
	.close=restaurantLight_close,
	.devicesInit=restaurantLight_init,
	.readStatus=restaurantLight_status
};

struct  Devices* addrestaurantLightToDevicesLink(struct Devices *phead){
	if(phead== NULL){
		return &restaurantLight;
	}else{
		restaurantLight.next=phead;
		phead=&restaurantLight;
	}
}

upstairLight.c

#include "controlDevices.h"

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

int upstairLight_close(int pinNum){

	digitalWrite(pinNum,HIGH);
}

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

int upstairLight_status(int status){
	printf("upstairLight-OPEN\n");
}

struct Devices upstairLight={
	.devicesName="upstairLight",
	.pinNum=2,
	.open=upstairLight_open,
	.close=upstairLight_close,
	.devicesInit=upstairLight_init,
	.readStatus=upstairLight_status
};

struct  Devices* addupstairLightToDevicesLink(struct Devices *phead){
	if(phead== NULL){
		return &upstairLight;
	}else{
		upstairLight.next=phead;
		phead=&upstairLight;
	}
}

3、测试

 

继电器1闭合通电,浴室灯被点亮,可以 听见继电器“哒” 的一声

继电器3闭合通电,房间灯被点亮,可以 听见继电器“哒” 的一声 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Activiti7工作流

文章目录 一、工作流介绍1.1 概念1.2 适用行业1.3 应用领域1.4 传统实现方式1.5 什么是工作流引擎 二、什么是Activiti7&#xff1f;2.1 概述2.2 Activiti7内部核心机制2.3 BPMN2.4 Activiti如何使用2.4.1 整合Activiti2.4.2 业务流程建模2.4.3 部署业务流程2.4.4 启动流程实例…

大反转!OpenAI董事会辞职,求奥特曼重返OpenAI?「奥特曼24小时流放」大揭秘...

大家好&#xff0c;我是二狗。 想必大家昨天都被Sam Altman被董事会解雇的事情刷屏了。 然而才仅仅过去一天&#xff0c;OpenAI 董事会就反悔了&#xff01;正和Sam Altman 商量让他重返CEO职位。 这一反转和Altman被炒鱿鱼一样突然&#xff0c;凄凄惨惨真真假假真真&#x…

340条样本就能让GPT-4崩溃,输出有害内容高达95%?OpenAI的安全防护措施再次失效

仅需340个示例微调GPT-4&#xff0c;即可绕过安全限制&#xff0c;让模型说出“枪支改装方法”、“生化武器制作过程”等有害内容&#xff1f; OpenAI的安全防护措施再次失效&#xff0c;攻击的成功率高达95%&#xff01; 近日&#xff0c;美国顶尖大学UIUC与斯坦福联合对GPT…

python 的 import 机制

引言 对于初学 python&#xff0c;或多或少在 import 一个 module 时遇到过 ImportError: attempted relative import with no known parent package 这样的错误信息。对于初学 python&#xff0c;遇到这样的问题是因为在执行 python xxx.py 程序时&#xff0c;xxx.py 程序中 …

【心得】基于flask的SSTI个人笔记

目录 计算PIN码 例题1 SSTI的引用链 例题2 SSTI利用条件&#xff1a; 渲染字符串可控&#xff0c;也就说模板的内容可控 我们通过模板 语法 {{ xxx }}相当于变相的执行了服务器上的python代码 利用render_template_string函数参数可控&#xff0c;或者部分可控 render_…

分库分表

分库&#xff0c;分表&#xff0c;分库分表 “只分库“&#xff0c;“只分表“&#xff0c;“既分库又分表" 何时分库 在面对高并发的情况下&#xff0c;数据库连接成为性能瓶颈。当数据QPS过高导致数据库连接数不足时&#xff0c;考虑分库。在读多写少的场景下&#x…

基于Vue+SpringBoot的超市账单管理系统 开源项目

项目编号&#xff1a; S 032 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S032&#xff0c;文末获取源码。} 项目编号&#xff1a;S032&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统设计3.1 总体设计3.2 前端设计3…

SQL零基础入门教程,贼拉详细!贼拉简单! 速通数据库期末考!(十)

SQL 函数 SQL 拥有很多可用于计数和计算的内建函数。 比如&#xff1a; AVG() - 返回平均值 COUNT() - 返回行数 MAX() - 返回最大值 MIN() - 返回最小值 SUM() - 返回总和 FIRST() - 返回第一个记录的值 LAST() - 返回最后一个记录的值 GROUP BY 学习SQL函数前&#xff0c…

基于卡尔曼滤波实现行人目标跟踪

目录 1. 作者介绍2. 目标跟踪算法介绍2.1 目标跟踪背景2.2 目标跟踪任务分类2.3 目标跟踪遇到的问题2.4 目标跟踪方法 3. 卡尔曼滤波的目标跟踪算法介绍3.1 所用数据视频说明3.2 卡尔曼滤波3.3 单目标跟踪算法3.3.1 IOU匹配算法3.3.2 卡尔曼滤波的使用方法 3.4 多目标跟踪算法 …

腾讯云轻量数据库1核1G评测和租用价格表

腾讯云轻量数据库测评&#xff0c;轻量数据库100%兼容MySQL 5.7和8.0&#xff0c;腾讯云提供1C1G20GB、1C1G40GB、1C2G80GB、2C4G120GB、2C8G240GB五种规格轻量数据库&#xff0c;阿腾云atengyun.com分享腾讯云轻量数据库测评、轻量数据库详细介绍、特性、配置价格和常见问题解…

【算法】最小生成树——普利姆 (Prim) 算法

目录 1.概述2.代码实现2.1.邻接矩阵存储图2.2.邻接表存储图2.3.测试 3.应用 1.概述 &#xff08;1&#xff09;在一给定的无向图 G (V, E) 中&#xff0c;(u, v) 代表连接顶点 u 与顶点 v 的边&#xff0c;而 w(u, v) 代表此边的权重&#xff0c;若存在 T 为 E 的子集且为无循…

华为模拟器dhcp实验

实验需求&#xff0c;pc1 pc2 pc3 获取到地址且能ping通&#xff0c;pc1 pc2 为地址池模式&#xff0c;pc3为接口模式 上配置 #sysname AR1# dhcp enable # interface GigabitEthernet0/0/0ip address 10.0.47.254 255.255.255.0 dhcp select relaydhcp relay server-ip 10.0…

认识.NET Aspire:高效构建云原生应用的利器

简介 在几天前的.NET 8发布会上&#xff0c;来自微软的Glenn Condron和David Fowler为我们演示了.NET Aspire&#xff0c;在Visual Studio的帮助下&#xff0c;它展现出了惊人的开发效率。 短短的十分钟内&#xff0c;David现场演示了如何轻松创建了一个具有服务发现&#xf…

基于不确定性感知的脑肿瘤分割多维互学习

Uncertainty-Aware Multi-Dimensional Mutual Learning for Brain and Brain Tumor Segmentation 一基于不确定性感知的脑肿瘤分割多维互学习背景贡献实验方法Uncertainty-Aware Mutual Learning&#xff08;具有不确定性的相互学习&#xff09; Thinking 一基于不确定性感知的…

设计模式常见面试题

简单梳理下二十三种设计模式&#xff0c;在使用设计模式的时候&#xff0c;不仅要对其分类了然于胸&#xff0c;还要了解每个设计模式的应用场景、设计与实现&#xff0c;以及其优缺点。同时&#xff0c;还要能区分功能相近的设计模式&#xff0c;避免出现误用的情况。 什么是…

Git精讲

Git基本操作 创建Git本地仓库 git initgit clone 配置Git git config [--global] user.name "Your Name" git config [--global] user.email "emailexample.com"–global是一个可选项。如果使用了该选项&#xff0c;表示这台机器上所有的Git仓库都会使…

Network(三)动态路由与ACL配置

一 三层交换机 1 三层交换机概述 三层交换二层交换三层转发 2 虚拟接口概述 在三层交换机上配置的VLAN接口为虚拟接口&#xff0c;使用Vlanif&#xff08;VLAN虚拟接口&#xff09;实现VLAN间路由&#xff0c;VLAN接口的引入使得应用更加灵活 三层交换机VLAN间通信的转发…

Cross-View Transformers for Real-Time Map-View Semantic Segmentation 论文阅读

论文链接 Cross-View Transformers for Real-Time Map-View Semantic Segmentation 0. Abstract 提出了 Cross-View Transformers &#xff0c;一种基于注意力的高效模型&#xff0c;用于来自多个摄像机的地图视图语义分割使用相机感知的跨视图注意机制隐式学习从单个相机视…

第93步 深度学习图像分割:PSPNet建模

基于WIN10的64位系统演示 一、写在前面 本期&#xff0c;我们继续学习深度学习图像分割系列的另一个模型&#xff0c;PSPNet。 二、PSPNet简介 &#xff08;1&#xff09;金字塔池化模块 (Pyramid Pooling Module) PSPNet的核心是其金字塔池化模块&#xff0c;该模块能够捕…

4 redis的HyperLogLog入门原理

一、HyperLogLog&#xff08;字符串类型&#xff09; 需求&#xff1a;大型网站(不在大厂基本上用不到) 每个网页每天的 UV 数据(独立访客)&#xff0c;统计如何实现&#xff1f;(尽量少的占用存储空间) Redis 提供了 HyperLogLog 数据结构就是用来解决这种统计问题的。Hyper…