【智能家居】5、主流程设计以及外设框架编写与测试
目录
一、主流程设计
1、工厂模式结构体定义
(1)指令工厂 inputCmd.h
(2)外设工厂 controlDevices.h
二、外设框架编写
1、创建外设工厂对象bathroomLight
2、编写相关函数框架
3、将浴室灯相关操作插入外设工厂链表等待被调用
三、外设框架测试
1、配置IO口输出状态
2、将函数加入到controlDevices.h
3、main函数编写
四、编写完成后拷贝到树莓派运行
1、创建一个文件夹用于保存上面所编写的三个代码
2、查看使用的GPIO口位于第几个引脚
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` 的结构体,包含以下成员:
- char cmdName[128]:一个长度为128的字符数组,用于存储指令名称。
- char cmd[32]:一个长度为32的字符数组,用于存储指令。
- int (*Init)(char *name, char *ipAdress, char *port):一个初始化相关指令操作的函数指针,它指向一个返回值为整型,接受三个字符指针类型的参数(名称、IP地址、端口号)的函数。
- int (*getCmd)(char *cmd):一个用于获取指令的函数指针,它指向一个返回值为整型,接受一个字符指针类型的参数(指令)的函数。
- char *log[1024]:一个长度为1024的字符指针数组,用于存储日志信息。
- 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` 的结构体,包含以下成员:
- char devicesName[128]:一个长度为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` 类型的指针,通常链表的连接。
二、外设框架编写
以浴室灯模块为例
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

相关文章:
【智能家居】5、主流程设计以及外设框架编写与测试
目录 一、主流程设计 1、工厂模式结构体定义 (1)指令工厂 inputCmd.h (2)外设工厂 controlDevices.h 二、外设框架编写 1、创建外设工厂对象bathroomLight 2、编写相关函数框架 3、将浴室灯相关操作插入外设工厂链表等待被调…...
详解ssh远程登录服务
华子目录 简介概念功能 分类文字接口图形接口 文字接口ssh连接服务器浅浅介绍一下加密技术凯撒加密加密分类对称加密非对称加密非对称加密方法(也叫公钥加密) ssh两大类认证方式:连接加密技术简介密钥解析 ssh工作过程版本协商阶段密钥和算法…...
LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄
接着前两节的Langchain,继续实现Langchain中的Agent LangChain 实现给动物取名字,LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字 代码实现 # 从langchain库中导入模块 from langchain.llms import OpenAI # 从langchain.l…...
wpf devexpress绑定grid到总计和分组统计
此主题描述了如何在gridcontrol中的视图模型和显示定义总计和分组统计 在视图模型中指定统计 1、创建 SummaryItemType 枚举你想要在GridControl中显示的统计类型: public enum SummaryItemType { Max, Count, None } 2、创建一个grid统计描述类 public class S…...
嵌入式 Linux 移植与系统启动方法
1、Linux系统启动与U-Boot 所谓移植就是把程序代码从一种运行环境转移到另一种运行环境。对于内核移植来说,主要是从一种硬件平台转移到另一种硬件平台上运行。 体系结构级别的移植是指在不同体系结构平台上Linux内核的移植,例如,在ARM、MI…...
代码随想录算法训练营|五十六天
回文子串 647. 回文子串 - 力扣(LeetCode) dp含义:表示区间内[i,j]是否有回文子串,有true,没有false。 递推公式:当s[i]和s[j]不相等,false;相等时,情况一,…...
基于django水果蔬菜生鲜销售系统
基于django水果蔬菜生鲜销售系统 摘要 基于Django的水果蔬菜生鲜销售系统是一种利用Django框架开发的电子商务平台,旨在提供高效、便捷的购物体验,同时支持水果蔬菜生鲜产品的在线销售。该系统整合了用户管理、产品管理、购物车、订单管理等核心功能&…...
【数据结构】快速排序算法你会写几种?
👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:数据结构 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有帮助…...
C#访问修饰符
C#中的访问修饰符用于控制类型成员(如字段、属性、方法等)的访问级别。以下是C#中常用的访问修饰符: public:公共访问级别,没有任何访问限制。在任何其他类或程序集中都可以访问标记为 public 的成员。 private&#…...
anaconda中安装pytorch和TensorFlow环境并在不同环境中安装kernel
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...
记一次解决Pyqt6/Pyside6添加QTreeView或QTreeWidget导致窗口卡死(未响应)的新路历程,打死我都想不到是这个原因
文章目录 💢 问题 💢🏡 环境 🏡📄 代码💯 解决方案 💯⚓️ 相关链接 ⚓️💢 问题 💢 我在窗口中添加了一个 QTreeWidget控件 ,但是程序在运行期间,只要鼠标进入到 QTreeWidget控件 内进行操作,时间超过几秒中就会出现窗口 未响应卡死的 状态 🏡 环境 �…...
用照片预测人的年龄【图像回归】
在图像分类任务中,卷积神经网络 (CNN) 是非常强大的神经网络架构。 然而,鲜为人知的是,它们同样能够执行图像回归任务。 图像分类和图像回归任务之间的基本区别在于分类任务中的目标变量(我们试图预测的东西)不是连续…...
Fork项目新分支如何同步
这里以seata项目为示例: 一、添加Fork仓库的源仓库 git remote add seata gitgithub.com:seata/seata.git二、fetch git fetch seata...
Linux 常用压缩格式
Linux 常用压缩格式简介 Linux系统用户可以根据自己的需求选择合适的压缩工具来进行文件压缩和解压操作。Linux系统中常用的压缩软件都有相应的命令行工具,并且可以通过软件包管理器进行安装。主要有gzip、bzip2、zip、tar、7z。 gzip:gzip是一个广泛使…...
高效背单词——单词APP安利
大英赛,CET四六级,以及考研英语,都在不远的未来再度来临,年复一年的考试不曾停息,想要取得好成绩,需要我们的重视并赋予相应的努力。对于应试英语,词汇量是不可忽略的硬性要求。相比于传统默写&…...
力扣 字母异位词分组 哈表 集合
👨🏫 力扣 字母异位词分组 ⭐ 思路 由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键。 🍑 AC code class Solut…...
⑩⑤【DB】详解MySQL存储过程:变量、游标、存储函数、循环,判断语句、参数传递..
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ MySQL存储过程 1. 介绍2. 使用3. 变量①系统变…...
使用SpringBoot进行游戏服务器开发
背景: 之前一直只考虑用JavaSe进行游戏服务器开发,目前项目使用了Spring,发现还是非常好的,好处如下: 好处1:依赖注入非常方便,我们只使用Spring最基本的功能即可,这样子就算是有一些模块不使用Spring管理…...
数据结构——树状数组
文章目录 前言问题引入问题分析树状数组lowbit树状数组特性初始化一个树状数组更新操作前缀和计算区间查询 总结 前言 原题的连接 最近刷leetcode的每日一题的时候,遇到了一个区间查询的问题,使用了一种特殊的数据结构树状数组,学习完之后我…...
Untiy 使用RotateAround()方法实现物体围绕某个点或者某个物体旋转
Untiy 实现物体围绕指定点或者某个物体旋转,可使用RotateAround()方法。 语法: public void RotateAround(Vector3 point, Vector3 axis, float angle); 其中,point:旋转中心点位置; axis:要围绕的轴,如x,y,z angel…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
