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

2023-11-21 20:30

本文主要是介绍【智能家居】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;}
}

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;}
}

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;}
}

3、测试

 

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

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

 

这篇关于【智能家居】5、主流程设计以及外设框架编写与测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/404894

相关文章

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python GUI框架中的PyQt详解

《PythonGUI框架中的PyQt详解》PyQt是Python语言中最强大且广泛应用的GUI框架之一,基于Qt库的Python绑定实现,本文将深入解析PyQt的核心模块,并通过代码示例展示其应用场... 目录一、PyQt核心模块概览二、核心模块详解与示例1. QtCore - 核心基础模块2. QtWid

最新Spring Security实战教程之Spring Security安全框架指南

《最新SpringSecurity实战教程之SpringSecurity安全框架指南》SpringSecurity是Spring生态系统中的核心组件,提供认证、授权和防护机制,以保护应用免受各种安... 目录前言什么是Spring Security?同类框架对比Spring Security典型应用场景传统

Python结合Flask框架构建一个简易的远程控制系统

《Python结合Flask框架构建一个简易的远程控制系统》这篇文章主要为大家详细介绍了如何使用Python与Flask框架构建一个简易的远程控制系统,能够远程执行操作命令(如关机、重启、锁屏等),还... 目录1.概述2.功能使用系统命令执行实时屏幕监控3. BUG修复过程1. Authorization

基于.NET编写工具类解决JSON乱码问题

《基于.NET编写工具类解决JSON乱码问题》在开发过程中,我们经常会遇到JSON数据处理的问题,尤其是在数据传输和解析过程中,很容易出现编码错误导致的乱码问题,下面我们就来编写一个.NET工具类来解... 目录问题背景核心原理工具类实现使用示例总结在开发过程中,我们经常会遇到jsON数据处理的问题,尤其是

SpringBoot集成图片验证码框架easy-captcha的详细过程

《SpringBoot集成图片验证码框架easy-captcha的详细过程》本文介绍了如何将Easy-Captcha框架集成到SpringBoot项目中,实现图片验证码功能,Easy-Captcha是... 目录SpringBoot集成图片验证码框架easy-captcha一、引言二、依赖三、代码1. Ea

Gin框架中的GET和POST表单处理的实现

《Gin框架中的GET和POST表单处理的实现》Gin框架提供了简单而强大的机制来处理GET和POST表单提交的数据,通过c.Query、c.PostForm、c.Bind和c.Request.For... 目录一、GET表单处理二、POST表单处理1. 使用c.PostForm获取表单字段:2. 绑定到结

SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程

《SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程》本文详细介绍了如何在虚拟机和宝塔面板中安装RabbitMQ,并使用Java代码实现消息的发送和接收,通过异步通讯,可以优化... 目录一、RabbitMQ安装二、启动RabbitMQ三、javascript编写Java代码1、引入

Nginx设置连接超时并进行测试的方法步骤

《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接