通俗理解的步骤就是链表通用模板定义(在头文件里定义)、链表的创建(头插尾插,在.C 文件里)、链表的初始化(init配置管脚初始电平等)、链表内容的读取(指令工厂TCP服务端读取客户端发来的指令、串口读取语音模块发来的指令)、链表的遍历查找(找到控制工厂里面需要被控制的链表节点)、链表内容的写入(写入来自指令工厂的控制指令)。
接收的指令,可以放在临时创建的变量里面,或者创建一个本地文件fd保存,或者一开始创建链表通用模板里面定义一个存放接收指令的数组,这样更方便访问。
继电器控制灯代码
contrlEquipments.h 文件(设备类)
#include <wiringPi.h> //wiringPi库
#include <stdio.h>
#include <stdlib.h>
struct Equipment //设备类
{
char equipName[128]; //设备名
int pinNum; //引脚号
int (*Init)(int pinNum); //“初始化设备”函数指针
int (*open)(int pinNum); //“打开设备”函数指针
int (*close)(int pinNum); //“关闭设备”函数指针
int (*readStatus)(int pinNum); //“读取设备状态”函数指针 为火灾报警器准备
int (*changeStatus)(int status); //“改变设备状态”函数指针
struct Equipment *next;
};
struct Equipment *addBathroomLightToEquipmentLink(struct Equipment *phead); //“浴室灯”加入设备链表函数声明
struct Equipment *addSecondfloorLightToEquipmentLink(struct Equipment *phead); //“二楼灯”加入设备链表函数声明
struct Equipment *addLivingroomLightToEquipmentLink(struct Equipment *phead); //“客厅灯”加入设备链表函数声明
struct Equipment *addRestaurantLightToEquipmentLink(struct Equipment *phead); //“餐厅灯”加入设备链表函数声明
mainPro.c 文件(主函数)
#include <stdio.h>
#include <string.h>
#include "contrlEquipments.h"
int main()
{
if(wiringPiSetup() == -1){ //使用wiringPi库,需初始化硬件
printf("wiringPiSetup failed!\n");
return -1;
}
struct Equipment *pequipHead = NULL; //定义初始链表头
pequipHead = addBathroomLightToEquipmentLink(pequipHead ); //“浴室灯”加入设备链表
pequipHead = addSecondfloorLightToEquipmentLink(pequipHead ); //“二楼灯”加入设备链表
pequipHead = addLivingroomLightToEquipmentLink(pequipHead ); //“客厅灯”加入设备链表
pequipHead = addRestaurantLightToEquipmentLink(pequipHead ); //“餐厅灯”加入设备链表
struct Equipment *tmp = pequipHead ;
while(tmp != NULL){ //继电器功能测试,打开链表上所有灯
tmp->Init(tmp->pinNum); //先初始化
tmp->open(tmp->pinNum);
tmp = tmp->next;
}
return 0;
}
bathroomLight.c 文件(浴室灯)
#include "contrlEquipments.h" //自定义设备类的文件
int bathroomLightInit(); //初始化继电器函数声明
int bathroomLightOpen(); //“打开灯”函数声明
int bathroomLightClose(); //“关闭灯”函数声明
//struct Equipment *addBathroomLightToEquipmentLink(struct Equipment *phead);
//浴室灯(对象)加入设备链表函数声明
struct Equipment bathroomLight = { //定义浴室灯(对象)
.equipName = "bathroomLight", //名字
.pinNum = 2, //树莓派 2号(wPi)引脚
.Init = bathroomLightInit, //指定初始化函数
.open = bathroomLightOpen, //指定“打开灯”函数
.close = bathroomLightClose //指定“关闭灯”函数
};
int bathroomLightInit(int pinNum) //C语言必须要传参,JAVA不用,可直接访问变量的值
{
pinMode(pinNum,OUTPUT); //配置引脚为输出模式
digitalWrite(pinNum,HIGH); //引脚置高电平,断开继电器
}
int bathroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW); //引脚置低电平,闭合继电器
}
int bathroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH); //引脚置高电平,断开继电器
}
struct Equipment *addBathroomLightToEquipmentLink(struct Equipment *phead) //浴室灯(对象)加入设备链表函数
{
if(phead == NULL){
return &bathroomLight;
}else{
bathroomLight.next = phead; //以前的头变成.next
phead = &bathroomLight; //更新头
return phead;
}
}
secondfloorLight.c 文件(二楼灯)
#include "contrlEquipments.h" //自定义设备类的文件
int secondfloorLightInit(); //初始化继电器函数声明
int secondfloorLightOpen(); //“打开灯”函数声明
int secondfloorLightClose(); //“关闭灯”函数声明
//struct Equipment *addSecondfloorLightToLink(struct Equipment *phead);
//二楼灯(对象)加入设备链表函数声明
struct Equipment secondfloorLight = { //定义二楼灯(对象)
.equipName = "secondfloorLight", //名字
.pinNum = 4, //树莓派 4号(wPi)引脚
.Init = secondfloorLightInit, //指定初始化函数
.open = secondfloorLightOpen, //指定“打开灯”函数
.close = secondfloorLightClose, //指定“关闭灯”函数
};
int secondfloorLightInit(int pinNum)
{
pinMode(pinNum,OUTPUT); //配置引脚为输出模式
digitalWrite(pinNum,HIGH); //引脚置高电平,断开继电器
}
int secondfloorLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW); //引脚置低电平,闭合继电器
}
int secondfloorLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH); //引脚置高电平,断开继电器
}
struct Equipment *addSecondfloorLightToEquipmentLink(struct Equipment *phead) //二楼灯(对象)加入设备链表函数
{
if(phead == NULL){
return &secondfloorLight;
}else{
secondfloorLight.next = phead;
phead = &secondfloorLight;
return phead;
}
}
livingroomLight.c 文件(客厅灯)
#include "contrlEquipments.h" //自定义设备类的文件
int livingroomLightInit(); //初始化继电器函数声明
int livingroomLightOpen(); //“打开灯”函数声明
int livingroomLightClose(); //“关闭灯”函数声明
//struct Equipment *addLivingroomLightToLink(struct Equipment *phead);
//客厅灯(对象)加入设备链表函数声明
struct Equipment livingroomLight = { //定义客厅灯(对象)
.equipName = "livingroomLight", //名字
.pinNum = 1, //树莓派 1号(wPi)引脚
.Init = livingroomLightInit, //指定初始化函数
.open = livingroomLightOpen, //指定“打开灯”函数
.close = livingroomLightClose, //指定“关闭灯”函数
};
int livingroomLightInit(int pinNum)
{
pinMode(pinNum,OUTPUT); //配置引脚为输出模式
digitalWrite(pinNum,HIGH); //引脚置高电平,断开继电器
}
int livingroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW); //引脚置低电平,闭合继电器
}
int livingroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH); //引脚置高电平,断开继电器
}
struct Equipment *addLivingroomLightToEquipmentLink(struct Equipment *phead) //客厅灯(对象)加入设备链表函数
{
if(phead == NULL){
return &livingroomLight;
}else{
livingroomLight.next = phead;
phead = &livingroomLight;
return phead;
}
}
restaurantLight.c 文件(餐厅灯)
#include "contrlEquipments.h" //自定义设备类的文件
int restaurantLightInit(); //初始化继电器函数声明
int restaurantLightOpen(); //“打开灯”函数声明
int restaurantLightClose(); //“关闭灯”函数声明
struct Equipment *addRestaurantLightToLink(struct Equipment *phead);
//餐厅灯(对象)加入设备链表函数声明
struct Equipment restaurantLight = { //定义餐厅灯(对象)
.equipName = "restaurantLight", //名字
.pinNum = 3, //树莓派 3号(wPi)引脚
.Init = restaurantLightInit, //指定初始化函数
.open = restaurantLightOpen, //指定“打开灯”函数
.close = restaurantLightClose, //指定“关闭灯”函数
};
int restaurantLightInit(int pinNum)
{
pinMode(pinNum,OUTPUT); //配置引脚为输出模式
digitalWrite(pinNum,HIGH); //引脚置高电平,断开继电器
}
int restaurantLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW); //引脚置低电平,闭合继电器
}
int restaurantLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH); //引脚置高电平,断开继电器
}
struct Equipment *addRestaurantLightToEquipmentLink(struct Equipment *phead) //餐厅灯(对象)加入设备链表函数
{
if(phead == NULL){
return &restaurantLight;
}else{
restaurantLight.next = phead;
phead = &restaurantLight;
return phead;
}
}
编译运行:
继电器四个灯都亮了
由于mainPro.c文件中指定继电器功能测试,打开链表上所有灯,可以发现继电器组全部亮红灯(如下图所示)。也可以将实际的家居灯接入到继电器中实现控制灯光的效果。
通过名字开关灯
其他代码和上面的代码一样,就mainPro.c修改了一下
mainPro.c代码如下:
#include <stdio.h>
#include <string.h>
#include "contrlEquipments.h"
struct Equipment* findDeviceByName(char *name, struct Equipment *pdeviceHead)
{
while(pdeviceHead != NULL)
{
if(strcmp(name, pdeviceHead->equipName) == 0)
{
printf("找到了\n");
return pdeviceHead;
}
pdeviceHead = pdeviceHead->next;
}
printf("没找到\n");
return NULL;
}
int main()
{
struct Equipment *rcv = NULL;
char name[100];
if(wiringPiSetup() == -1){ //使用wiringPi库,需初始化硬件
printf("wiringPiSetup failed!\n");
return -1;
}
struct Equipment *pequipHead = NULL; //定义初始链表头
pequipHead = addBathroomLightToEquipmentLink(pequipHead ); //“浴室灯”加入设备链表
pequipHead = addSecondfloorLightToEquipmentLink(pequipHead ); //“二楼灯”加入设备链表
pequipHead = addLivingroomLightToEquipmentLink(pequipHead ); //“客厅灯”加入设备链表
pequipHead = addRestaurantLightToEquipmentLink(pequipHead ); //“餐厅灯”加入设备链表
struct Equipment *tmp = pequipHead ;
while(tmp != NULL){ //继电器功能测试,关闭链表上所有灯
tmp->Init(tmp->pinNum); //先初始化
tmp->close(tmp->pinNum);
tmp = tmp->next;
}
printf("please input device's name\n");
scanf("%s",name);
rcv = findDeviceByName(name,pequipHead);
rcv->open(rcv->pinNum);
return 0;
}
编译运行: