【智能家居】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` 的结构体,包含以下成员:
- 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
五、四盏灯控制
前面编写了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闭合通电,房间灯被点亮,可以 听见继电器“哒” 的一声