一、項(xiàng)目整體設(shè)計(jì)
二、項(xiàng)目代碼的前期準(zhǔn)備
三、實(shí)現(xiàn)語(yǔ)音監(jiān)聽(tīng)接口
四、實(shí)現(xiàn)socket監(jiān)聽(tīng)接口
五、實(shí)現(xiàn)煙霧報(bào)警監(jiān)聽(tīng)接口
六、實(shí)現(xiàn)設(shè)備節(jié)點(diǎn)代碼
七、實(shí)現(xiàn)接收消息處理接口
一、項(xiàng)目整體設(shè)計(jì)
整體的軟件框架大致如下:
整個(gè)項(xiàng)目開(kāi)啟4個(gè)監(jiān)聽(tīng)線(xiàn)程, 分別是:
- 語(yǔ)音監(jiān)聽(tīng)線(xiàn)程:用于監(jiān)聽(tīng)語(yǔ)音指令, 當(dāng)有語(yǔ)音指令過(guò)來(lái)后, 通過(guò)消息隊(duì)列的方式給消息處理線(xiàn)程發(fā)
送指令 - 網(wǎng)絡(luò)監(jiān)聽(tīng)線(xiàn)程:用于監(jiān)聽(tīng)網(wǎng)絡(luò)指令,當(dāng)有網(wǎng)絡(luò)指令過(guò)來(lái)后, 通過(guò)消息隊(duì)列的方式給消息處理線(xiàn)程發(fā)
送指令 - 火災(zāi)檢測(cè)線(xiàn)程:當(dāng)存在煤氣泄漏或者火災(zāi)閑情時(shí), 發(fā)送警報(bào)指令給消息處理線(xiàn)程
- 消息監(jiān)聽(tīng)線(xiàn)程: 用于處理以上3個(gè)線(xiàn)程發(fā)過(guò)來(lái)的指令,并根據(jù)指令要求配置GPIO引腳狀態(tài),OLED
屏顯示、語(yǔ)音播報(bào),還有人臉識(shí)別開(kāi)門(mén)
上述四個(gè)線(xiàn)程采用統(tǒng)一個(gè)對(duì)外接口接口,同時(shí)添加到監(jiān)聽(tīng)鏈表中。
統(tǒng)一的監(jiān)聽(tīng)模塊接口如下:
struct control
{
char control_name[128]; //監(jiān)聽(tīng)模塊名稱(chēng)
int (*init)(void); //初始化函數(shù)
void (*final)(void);//結(jié)束釋放函數(shù)
void *(*get)(void *arg);//監(jiān)聽(tīng)函數(shù),如語(yǔ)音監(jiān)聽(tīng)
void *(*set)(void *arg); //設(shè)置函數(shù),如語(yǔ)音播報(bào)
struct control *next;
};
struct control *add_device_to_ctrl_list(struct control *phead, struct control *device);
另外,被控制的設(shè)備類(lèi)也統(tǒng)一配置接口,同時(shí)添加到設(shè)備鏈表中。
統(tǒng)一的設(shè)備類(lèi)接口如下:
struct gdevice
{
char dev_name[128]; //設(shè)備名稱(chēng)
int key; //key值,用于匹配控制指令的值
int gpio_pin; //控制的gpio引腳
int gpio_mode; //輸入輸出模式
int gpio_status; //高低電平狀態(tài)
int check_face_status; //是否進(jìn)行人臉檢測(cè)狀態(tài)
int voice_set_status; //是否語(yǔ)音語(yǔ)音播報(bào)
struct gdevice *next;
};
struct gdevice *add_device_to_gdevice_list(struct gdevice *phead, struct gdevice *device);
struct gdevice *find_gdevice_by_key(struct gdevice *pdev, unsigned char key);
int set_gpio_gdevice_status(struct gdevice *pdev);
二、項(xiàng)目代碼的前期準(zhǔn)備
之前講過(guò)智能分類(lèi)的項(xiàng)目,因?yàn)闀?huì)用到語(yǔ)音模塊、OLED顯示、網(wǎng)絡(luò)模塊、這些代碼都可以從智能分類(lèi)的項(xiàng)目中直接拷貝過(guò)來(lái)使用,另外添加之前準(zhǔn)備好的人臉識(shí)別的代碼 。 另外根據(jù)《項(xiàng)目整體設(shè)計(jì)》。再定義gdevice.h和control.h的頭文件。整個(gè)目錄結(jié)構(gòu)如下:
pg@pg-Default-string:~/smarthome$ tree -I 3rd/ #3rd目錄直接從garbage工程拷貝過(guò)來(lái), 主要是一些依賴(lài)庫(kù)和頭文件, 這里就不顯示
.
├── inc
│ ├── control.h
│ ├── face.h
│ ├── gdevice.h
│ ├── myoled.h
│ ├── socket.h
│ └── uartTool.h
├── Makefile
└── src
├── face.c
├── face.py
├── myoled.c
├── socket.c
└── uartTool.c
其中 control.h代碼如下:
#ifndef __CONTROL__H
#define __CONTROL__H
#include <stdlib.h>
struct control
{
char control_name[128];
int (*init)(void);
void (*final)(void);
void *(*get)(void *arg);
void *(*set)(void *arg);
struct control *next;
};
//頭插法,用于control類(lèi)鏈表的創(chuàng)建
struct control *add_device_to_ctrl_list(struct control *phead, struct control *device);
#endif
// /dev/ttyS5 115200 ip port buffer pin /dev/I2C-3
control.c 代碼如下:
#include "control.h"
//頭插法
struct control *add_device_to_ctrl_list(struct control *phead, struct control *device)
{
struct control *pcontrol;
if(NULL == phead){
pcontrol = device;
return pcontrol;
}else{
device->next = phead;
phead = device;
return phead;
}
}
gdevice.h 代碼如下:
#ifndef __GDEVICE_H
#define __GDEVICE_H
struct gdevice
{
char dev_name[128]; //設(shè)備名稱(chēng)
int key; //key值,用于匹配控制指令的值
int gpio_pin; //控制的gpio引腳
int gpio_mode; //輸入輸出模式
int gpio_status; //高低電平狀態(tài)
int check_face_status; //是否進(jìn)行人臉檢測(cè)狀態(tài)
int voice_set_status; //是否語(yǔ)音語(yǔ)音播報(bào)
struct gdevice *next;
};
#endif
gdevice.c 代碼如下:
#include <wiringPi.h>
#include "gdevice.h"
//根據(jù)key值(buffer[2])查找設(shè)備節(jié)點(diǎn)
struct gdevice *find_gdevice_by_key(struct gdevice *pdev, unsigned char key)
{
struct gdevice *p = NULL;
if (NULL == pdev)
{
return NULL;
}
p = pdev;
while (NULL != p)
{
if(p->key == key)
{
return p;
}
p = p->next;
}
return NULL;
}
//設(shè)置GPIO引腳狀態(tài),輸入輸出和高低電平
int set_gpio_gdevice_status(struct gdevice *pdev)
{
if (NULL == pdev)
{
return -1;
}
if (-1 != pdev->gpio_pin)
{
if (-1 != pdev->gpio_mode)
{
pinMode(pdev->gpio_pin, pdev->gpio_mode);
}
if (-1 != pdev->gpio_status)
{
digitalWrite(pdev->gpio_pin, pdev->gpio_status);
}
}
return 0;
}
//鏈表頭插法
struct gdevice *add_device_to_gdevice_list(struct gdevice *phead, struct gdevice *device)
{
struct gdevice *pgdevice;
if(NULL == phead){
pgdevice = device;
return pgdevice;
}else{
device->next = phead;
phead = device;
return phead;
}
}
Makefile 修改后內(nèi)容如下:
CC := aarch64-linux-gnu-gcc
SRC := $(shell find src -name "*.c")
INC := ./inc \
./3rd/usr/local/include \
./3rd/usr/include \
./3rd/usr/include/python3.10 \
./3rd/usr/include/aarch64-linux-gnu/python3.10 \
./3rd/usr/include/aarch64-linux-gnu
OBJ := $(subst src/,obj/,$(SRC:.c=.o))
TARGET=obj/smarthome
CFLAGS := $(foreach item, $(INC),-I$(item)) # -I./inc -I./3rd/usr/local/include
LIBS_PATH := ./3rd/usr/local/lib \
./3rd/lib/aarch64-linux-gnu \
./3rd/usr/lib/aarch64-linux-gnu \
./3rd/usr/lib/python3.10 \
#L
LDFLAGS := $(foreach item, $(LIBS_PATH),-L$(item)) # -L./3rd/usr/local/libs
LIBS := -lwiringPi -lpython3.10 -pthread -lexpat -lz -lcrypt
obj/%.o:src/%.c
mkdir -p obj
$(CC) -o $@ -c $< $(CFLAGS)
$(TARGET) :$(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
compile : $(TARGET)
clean:
rm $(TARGET) obj $(OBJ) -rf
debug:
echo $(CC)
echo $(SRC)
echo $(INC)
echo $(OBJ)
echo $(TARGET)
echo $(CFLAGS)
echo $(LDFLAGS)
echo $(LIBS)
.PHONY: clean compile debug
三、實(shí)現(xiàn)語(yǔ)音監(jiān)聽(tīng)接口
語(yǔ)音監(jiān)聽(tīng)模塊會(huì)借助消息隊(duì)列進(jìn)行消息的傳遞,因此先實(shí)現(xiàn)消息隊(duì)列的接口 msg_queque.c:
#include <stdio.h>
#include "msg_queue.h"
#define QUEQUE_NAME "/mq_queue"
mqd_t msg_queue_create(void)
{
//創(chuàng)建消息隊(duì)列
mqd_t mqd = -1;
struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 10;
attr.mq_msgsize = 256;
attr.mq_curmsgs = 0;
mqd = mq_open(QUEQUE_NAME, O_CREAT | O_RDWR, 0666, &attr);
printf("%s| %s |%d: mqd = %d\n",__FILE__, __func__, __LINE__, mqd);
return mqd;
}
void msg_queue_final(mqd_t mqd)
{
if (-1 != mqd){
mq_close(mqd);
mq_unlink(QUEQUE_NAME);
mqd = -1;
}
}
int send_message(mqd_t mqd, void *msg, int msg_len)
{
int byte_send = -1;
byte_send = mq_send(mqd, (char *)msg, msg_len, 0);
return byte_send;
}
msg_queue.h 頭文件定義:
#ifndef __MSG_QUEQUE_H
#define __MSG_QUEQUE_H
#include <mqueue.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
mqd_t msg_queue_create(void);
void msg_queue_final(mqd_t mqd);
int send_message(mqd_t mqd, void *msg, int msg_len);
#endif
根據(jù)control.h頭文件的定義,實(shí)現(xiàn)語(yǔ)音監(jiān)聽(tīng)接口
首先定義全局變量用于mqd句柄和struct control鏈表的傳遞 global.h 代碼:
#ifndef __GLOBAL__H
#define __GLOBAL__H
typedef struct {
mqd_t mqd;
struct control *ctrl_phead;
}ctrl_info_t;
#endif
緊接著語(yǔ)音監(jiān)聽(tīng)接口 voice_interface.c 代碼:
#if 0
struct control
{
char control_name[128]; //監(jiān)聽(tīng)模塊名稱(chēng)
int (*init)(void); //初始化函數(shù)
void (*final)(void);//結(jié)束釋放函數(shù)
void *(*get)(void *arg);//監(jiān)聽(tīng)函數(shù),如語(yǔ)音監(jiān)聽(tīng)
void *(*set)(void *arg); //設(shè)置函數(shù),如語(yǔ)音播報(bào)
struct control *next;
};
#endif
#include <pthread.h>
#include <stdio.h>
#include "voice_interface.h"
#include "uartTool.h"
#include "msg_queue.h"
#include "global.h"
static int serial_fd = -1;
static int voice_init(void)
{
serial_fd = myserialOpen (SERIAL_DEV, BAUD);
printf("%s|%s|%d:serial_fd=%d\n", __FILE__, __func__, __LINE__, serial_fd);
return serial_fd;
}
static void voice_final(void)
{
if (-1 != serial_fd)
{
close(serial_fd);
serial_fd = -1;
}
}
//接收語(yǔ)音指令
static void *voice_get(void *arg) // mqd應(yīng)該來(lái)自于arg傳參
{
unsigned char buffer[6] = {0x00, 0x00, 0x00, 0x00, 0X00, 0x00};
int len = 0;
mqd_t mqd = -1;
ctrl_info_t *ctrl_info= NULL;
if (NULL != arg)
ctrl_info = (ctrl_info_t *)arg;
if (-1 == serial_fd)
{
serial_fd = voice_init();
if (-1 == serial_fd)
{
pthread_exit(0);
}
}
if(NULL != ctrl_info)
{
mqd = ctrl_info->mqd;
}
if ((mqd_t)-1 == mqd)
{
pthread_exit(0);
}
pthread_detach(pthread_self());
printf("%s thread start\n", __func__);
while(1)
{
len = serialGetstring(serial_fd, buffer);
printf("%s|%s|%d:0x%x, 0x%x,0x%x, 0x%x, 0x%x,0x%x\n", __FILE__, __func__, __LINE__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4],buffer[5]);
printf("%s|%s|%d:len=%d\n", __FILE__, __func__, __LINE__, len);
if (len > 0)
{
if(buffer[0] == 0xAA && buffer[1] == 0x55
&& buffer[5] == 0xAA && buffer[4] == 0x55)
{
printf("%s|%s|%d:send 0x%x, 0x%x,0x%x, 0x%x, 0x%x,0x%x\n", __FILE__, __func__, __LINE__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4],buffer[5]);
send_message(mqd, buffer, len);//注意,不要用strlen去計(jì)算實(shí)際的長(zhǎng)度
}
memset(buffer, 0, sizeof(buffer));
}
}
pthread_exit(0);
}
//語(yǔ)音播報(bào)
static void *voice_set(void *arg)
{
pthread_detach(pthread_self());
unsigned char *buffer = (unsigned char *)arg;
if (-1 == serial_fd)
{
serial_fd = voice_init();
if (-1 == serial_fd)
{
pthread_exit(0);
}
}
if (NULL != buffer)
{
serialSendstring(serial_fd, buffer, 6);
}
pthread_exit(0);
}
struct control voice_control = {
.control_name = "voice",
.init = voice_init,
.final = voice_final,
.get = voice_get,
.set = voice_set,
.next = NULL
};
struct control *add_voice_to_ctrl_list(struct control *phead)
{//頭插法
return add_interface_to_ctrl_list(phead, &voice_control);
};
voice_interface.h代碼:
#ifndef ___VOICE_INTERFACE_H___
#define ___VOICE_INTERFACE_H___
#include "control.h"
struct control *add_voice_to_ctrl_list(struct control *phead);
#endif
四、實(shí)現(xiàn)socket監(jiān)聽(tīng)接口
參考voice接口實(shí)現(xiàn)socket 接口socket_interface.c代碼:
#include <pthread.h>
#include "socket.h"
#include "control.h"
#include "socket_interface.h"
#include "msg_queue.h"
#include "global.h"
static int s_fd = -1;
static int tcpsocket_init(void)
{
s_fd = socket_init(IPADDR, IPPORT);
return -1;
}
static void tcpsocket_final(void)
{
close(s_fd);
s_fd = -1;
}
static void* tcpsocket_get(void *arg)
{
int c_fd = -1;
int ret = -1;
struct sockaddr_in c_addr;
unsigned char buffer[BUF_SIZE];
mqd_t mqd = -1;
ctrl_info_t *ctrl_info= NULL;
int keepalive = 1; // 開(kāi)啟TCP_KEEPALIVE選項(xiàng)
int keepidle = 10; // 設(shè)置探測(cè)時(shí)間間隔為10秒
int keepinterval = 5; // 設(shè)置探測(cè)包發(fā)送間隔為5秒
int keepcount = 3; // 設(shè)置探測(cè)包發(fā)送次數(shù)為3次
pthread_detach(pthread_self());
printf("%s|%s|%d: s_fd = %d\n", __FILE__, __func__, __LINE__,s_fd);
if (-1 == s_fd)
{
s_fd = tcpsocket_init();
if (-1 == s_fd)
{
printf("tcpsocket_init failed\n");
pthread_exit(0);
}
}
if (NULL != arg)
ctrl_info = (ctrl_info_t *)arg;
if(NULL != ctrl_info)
{
mqd = ctrl_info->mqd;
}
if ((mqd_t)-1 == mqd)
{
pthread_exit(0);
}
memset(&c_addr,0,sizeof(struct sockaddr_in));
//4. accept
int clen = sizeof(struct sockaddr_in);
printf("%s thread start\n", __func__);
while (1)
{
c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);
if (-1 == c_fd)
{
continue;
}
ret = setsockopt(c_fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)); // 設(shè)置TCP_KEEPALIVE選項(xiàng)
if (ret == -1) { // 如果設(shè)置失敗,打印錯(cuò)誤信息并跳出循環(huán)
perror("setsockopt");
break;
}
ret = setsockopt(c_fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle)); // 設(shè)置探測(cè)時(shí)間間隔選項(xiàng)
if (ret == -1) { // 如果設(shè)置失敗,打印錯(cuò)誤信息并跳出循環(huán)
perror("setsockopt");
break;
}
ret = setsockopt(c_fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepinterval,
sizeof(keepinterval)); // 設(shè)置探測(cè)包發(fā)送間隔選項(xiàng)
if (ret == -1) { // 如果設(shè)置失敗,打印錯(cuò)誤信息并跳出循環(huán)
perror("setsockopt");
break;
}
ret = setsockopt(c_fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcount,
sizeof(keepcount)); // 設(shè)置探測(cè)包發(fā)送次數(shù)選項(xiàng)
if (ret == -1) { // 如果設(shè)置失敗,打印錯(cuò)誤信息并跳出循環(huán)
perror("setsockopt");
break;
}
printf("Accepted a connection from %s:%d\n", inet_ntoa(c_addr.sin_addr),
ntohs(c_addr.sin_port)); // 打印客戶(hù)端的IP地址和端口號(hào)
while (1)
{
memset(buffer, 0, BUF_SIZE);
ret = recv(c_fd, buffer, BUF_SIZE, 0);
printf("%s|%s|%d: 0x%x, 0x%x,0x%x, 0x%x, 0x%x,0x%x\n", __FILE__, __func__, __LINE__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4],buffer[5]);
if (ret > 0)
{
if(buffer[0] == 0xAA && buffer[1] == 0x55
&& buffer[5] == 0xAA && buffer[4] == 0x55)
{
printf("%s|%s|%d:send 0x%x, 0x%x,0x%x, 0x%x, 0x%x,0x%x\n", __FILE__, __func__, __LINE__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4],buffer[5]);
send_message(mqd, buffer, ret);//注意,不要用strlen去計(jì)算實(shí)際的長(zhǎng)度
}
}
else if ( -1 == ret || 0 == ret)
{
break;
}
}
}
pthread_exit(0);
}
struct control tcpsocket_control = {
.control_name = "tcpsocket",
.init = tcpsocket_init,
.final = tcpsocket_final,
.get = tcpsocket_get,
.set = NULL,
.next = NULL
};
struct control *add_tcpsocket_to_ctrl_list(struct control *phead)
{//頭插法
return add_interface_to_ctrl_list(phead, &tcpsocket_control);
};
socket.h 代碼:
#ifndef ___SOCKET_INTERFACE_H___
#define ___SOCKET_INTERFACE_H___
#include "control.h"
struct control *add_tcpsocket_to_ctrl_list(struct control *phead);
#endif
五、實(shí)現(xiàn)煙霧報(bào)警監(jiān)聽(tīng)接口
同樣參考voice接口實(shí)現(xiàn)smoke 接口smoke_interface.c代碼:
#include <pthread.h>
#include <wiringPi.h>
#include <stdio.h>
#include "control.h"
#include "smoke_interface.h"
#include "msg_queue.h"
#include "global.h"
#define SMOKE_PIN 6
#define SMOKE_MODE INPUT
static int smoke_init(void)
{
printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
pinMode(SMOKE_PIN, SMOKE_MODE);
return 0;
}
static void smoke_final(void)
{
//do nothing;
}
static void* smoke_get(void *arg)
{
int status = HIGH;
int switch_status = 0;
unsigned char buffer[6] = {0xAA, 0x55, 0x00, 0x00, 0x55, 0xAA};
ssize_t byte_send = -1;
mqd_t mqd = -1;
ctrl_info_t *ctrl_info = NULL;
if (NULL != arg)
ctrl_info = (ctrl_info_t *)arg;
if(NULL != ctrl_info)
{
mqd = ctrl_info->mqd;
}
if ((mqd_t)-1 == mqd)
{
pthread_exit(0);
}
pthread_detach(pthread_self());
printf("%s thread start\n", __func__);
while(1)
{
status = digitalRead(SMOKE_PIN);
if (LOW == status)
{
buffer[2] = 0x45;
buffer[3] = 0x00;
switch_status = 1;
printf("%s|%s|%d:send 0x%x, 0x%x,0x%x, 0x%x, 0x%x,0x%x\n", __FILE__, __func__, __LINE__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4],buffer[5]);
byte_send = mq_send(mqd, buffer, 6, 0);
if (-1 == byte_send)
{
continue;
}
}
else if (HIGH == status && 1 == switch_status)
{
buffer[2] = 0x45;
buffer[3] = 0x01;
switch_status = 0;
printf("%s|%s|%d:send 0x%x, 0x%x,0x%x, 0x%x, 0x%x,0x%x\n", __FILE__, __func__, __LINE__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4],buffer[5]);
byte_send = mq_send(mqd, buffer, 6, 0);
if (-1 == byte_send)
{
continue;
}
}
sleep(5);
}
pthread_exit(0);
}
struct control smoke_control = {
.control_name = "smoke",
.init = smoke_init,
.final = smoke_final,
.get = smoke_get,
.set = NULL,
.next = NULL
};
struct control *add_smoke_to_ctrl_list(struct control *phead)
{//頭插法
return add_interface_to_ctrl_list(phead, &smoke_control);
};
smoke_interface.h 代碼:
#ifndef ___SMOKE_INTERFACE_H___
#define ___SMOKE_INTERFACE_H___
#include "control.h"
struct control *add_smoke_to_ctrl_list(struct control *phead);
#endif
六、實(shí)現(xiàn)設(shè)備節(jié)點(diǎn)代碼
-
客廳燈設(shè)備節(jié)點(diǎn)
由于消息接收處理線(xiàn)程需要處理各設(shè)備類(lèi)外設(shè),因此先根據(jù)gdevice.h定義,實(shí)現(xiàn)客廳燈設(shè)備節(jié)點(diǎn)代碼
lrled_gdevice.c:
#include "gdevice.h"
struct gdevice lrled_gdev = {
.dev_name = "LV led",
.key = 0x41,
.gpio_pin = 2,
.gpio_mode = OUTPUT,
.gpio_status = HIGH,
.check_face_status = 0,
.voice_set_status = 0,
};
struct gdevice *add_lrled_to_gdevice_list(struct gdevice *pgdevhead)
{//頭插法
return add_device_to_gdevice_list(pgdevhead, &lrled_gdev);
};
lrled_gdevice.h 代碼如下:
#ifndef __LRLED_GDEVICE_H
#define __LRLED_GDEVICE_H
struct gdevice *add_lrled_to_gdevice_list(struct gdevice *pgdevhead);
#endif
-
臥室燈設(shè)備節(jié)點(diǎn)
臥室燈設(shè)備節(jié)點(diǎn)代碼bled_gdevice.c:
#include "gdevice.h"
struct gdevice bled_gdev = {
.dev_name = "BR led",
.key = 0x42,
.gpio_pin = 5,
.gpio_mode = OUTPUT,
.gpio_status = HIGH,
.check_face_status = 0,
.voice_set_status = 0,
};
struct gdevice *add_bled_to_gdevice_list(struct gdevice *pgdevhead)
{//頭插法
return add_device_to_gdevice_list(pgdevhead, &bled_gdev);
};
bled_gdevice.h 代碼如下:
#ifndef __BLED_GDEVICE_H
#define __BLED_GDEVICE_H
struct gdevice *add_bled_to_gdevice_list(struct gdevice *pgdevhead);
#endif
-
實(shí)現(xiàn)風(fēng)扇設(shè)備節(jié)點(diǎn)代碼
實(shí)現(xiàn)風(fēng)扇設(shè)備節(jié)點(diǎn)代碼fan_gdevice.c:
#include "gdevice.h"
struct gdevice gdevice_fan = {
.dev_name = "fan",
.key = 0x43,
.gpio_pin = 7,
.gpio_mode = OUTPUT,
.gpio_status = LOW,
.check_face_status = 0,
.voice_set_status = 0,
.next = NULL
};
struct gdevice *add_fan_to_gdevice_list(struct gdevice *phead)
{
return add_device_to_gdevice_list(phead, &gdevice_fan);
}
fan_gdevice.h 代碼如下:
#ifndef __FAN_GDEVICE_H
#define __FAN_GDEVICE_H
struct gdevice *add_fan_to_gdevice_list(struct gdevice *pgdevhead);
#endif
-
蜂鳴器設(shè)備節(jié)點(diǎn)
蜂鳴器設(shè)備節(jié)點(diǎn)代碼beep_gdevice.c:
#include "gdevice.h"
struct gdevice beep_gdev = {
.dev_name = "beep",
.key = 0x45,
.gpio_pin = 9,
.gpio_mode = OUTPUT,
.gpio_status = HIGH,
.check_face_status = 0,
.voice_set_status = 1,
};
struct gdevice *add_beep_to_gdevice_list(struct gdevice *pgdevhead)
{//頭插法
return add_device_to_gdevice_list(pgdevhead, &beep_gdev);
};
beep_gdevice.h 代碼如下:
#ifndef __BEEP_GDEVICE_H
#define __BEEP_GDEVICE_H
struct gdevice *add_beep_to_gdevice_list(struct gdevice *pgdevhead);
#endif
七、實(shí)現(xiàn)接收消息處理接口
同樣參考voice接口實(shí)現(xiàn)receive 接口receive_interface.c代碼:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-837086.html
#include "gdevice.h"
struct gdevice lock_gdev = {
.dev_name = "lock",
.key = 0x44,
.gpio_pin = 8,
.gpio_mode = OUTPUT,
.gpio_status = HIGH,
.check_face_status = 1,
.voice_set_status = 1,
};
struct gdevice *add_lock_to_gdevice_list(struct gdevice *pgdevhead)
{//頭插法
return add_device_to_gdevice_list(pgdevhead, &lock_gdev);
};
receive.h 頭文件代碼:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-837086.html
#ifndef ___RECEIVE_INTERFACE_H___
#define ___RECEIVE_INTERFACE_H___
#include "control.h"
struct control *add_receive_to_ctrl_list(struct control *phead);
#endif
到了這里,關(guān)于【OrangePi Zero2 智能家居】智能家居項(xiàng)目的軟件實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!