国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【OrangePi Zero2 智能家居】智能家居項(xiàng)目的軟件實(shí)現(xiàn)

這篇具有很好參考價(jià)值的文章主要介紹了【OrangePi Zero2 智能家居】智能家居項(xiàng)目的軟件實(shí)現(xiàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、項(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ì)

整體的軟件框架大致如下:
【OrangePi Zero2 智能家居】智能家居項(xiàng)目的軟件實(shí)現(xiàn),全志H616,智能家居,實(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)接收消息處理接口
整個(gè)項(xiàng)目開(kāi)啟4個(gè)監(jiān)聽(tīng)線(xiàn)程, 分別是:

  1. 語(yǔ)音監(jiān)聽(tīng)線(xiàn)程:用于監(jiān)聽(tīng)語(yǔ)音指令, 當(dāng)有語(yǔ)音指令過(guò)來(lái)后, 通過(guò)消息隊(duì)列的方式給消息處理線(xiàn)程發(fā)
    送指令
  2. 網(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ā)
    送指令
  3. 火災(zāi)檢測(cè)線(xiàn)程:當(dāng)存在煤氣泄漏或者火災(zāi)閑情時(shí), 發(fā)送警報(bào)指令給消息處理線(xiàn)程
  4. 消息監(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)代碼

  1. 客廳燈設(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
  1. 臥室燈設(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
  1. 實(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
  1. 蜂鳴器設(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代碼

#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)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀(guān)點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Orangepi Zero2 全志H616】驅(qū)動(dòng)串口實(shí)現(xiàn)Tik Tok—VUI(語(yǔ)音交互)

    【Orangepi Zero2 全志H616】驅(qū)動(dòng)串口實(shí)現(xiàn)Tik Tok—VUI(語(yǔ)音交互)

    一、編程實(shí)現(xiàn)語(yǔ)音和開(kāi)發(fā)板通信 wiringpi庫(kù)源碼 demo.c 二、基于前面串口的代碼修改實(shí)現(xiàn) uartTool.h uartTool.c uartTest.c 三、ADB adb控制指令 四、手機(jī)接入Linux熱拔插相關(guān) a. 把手機(jī)接入開(kāi)發(fā)板 b. 安裝adb工具,在終端輸入adb安裝指令: sudo apt-get install adb c. dmeg能查看到手機(jī)接入的信息,

    2024年02月21日
    瀏覽(30)
  • 【Orangepi Zero2 全志H616】驅(qū)動(dòng)舵機(jī)控制 / Linux定時(shí)器(signal、setitimer)

    【Orangepi Zero2 全志H616】驅(qū)動(dòng)舵機(jī)控制 / Linux定時(shí)器(signal、setitimer)

    一、SG90舵機(jī)開(kāi)發(fā) 舵機(jī)基本介紹 二、Linux定時(shí)器 signal 函數(shù) setitimer 函數(shù)原型 signal、setitimer函數(shù)API調(diào)用 三、舵機(jī) 軟件PWM實(shí)現(xiàn) 如下圖所示,最便宜的舵機(jī)sg90,常用三根或者四根接線(xiàn),黃色為PWM信號(hào)控制用處: 垃圾桶項(xiàng)目開(kāi)蓋用、智能小車(chē)的全比例轉(zhuǎn)向、攝像頭云臺(tái)、機(jī)械臂等

    2024年02月05日
    瀏覽(25)
  • 基于STM32+ESP8266+FreeRTOS+安卓App上位機(jī)+MQTT連接OneNET的智能家居項(xiàng)目(軟件開(kāi)源篇附百度網(wǎng)盤(pán)鏈接)

    ? 本篇文章主要是分享智能家居項(xiàng)目中的下位機(jī)STM32+FreeRTOS的代碼部分。以下是項(xiàng)目最終的效果 stm32 esp8266 語(yǔ)音控制智能家居_嗶哩嗶哩_bilibili ? 另外附上main函數(shù)中的部分代碼,完整代碼會(huì)在文章末尾放上百度網(wǎng)盤(pán)鏈接,可以自行下載。 鏈接:https://pan.baidu.com/s/1IS-OMLy2_pyWyM

    2024年02月08日
    瀏覽(24)
  • Linux MQTT智能家居項(xiàng)目(智能家居界面布局)

    Linux MQTT智能家居項(xiàng)目(智能家居界面布局)

    1.選擇工程名稱(chēng)和項(xiàng)目保存路徑 2.選擇QWidget 3.添加保存圖片的資源文件: 在工程目錄下添加Icon文件夾保存圖片: 將文件放入目錄中: 將圖片添加進(jìn)入資源文件中: 這里我們一共顯示4個(gè)界面:LED控制界面,溫度濕度顯示界面,光照強(qiáng)度顯示界面,攝像頭監(jiān)測(cè)界面。 所以這里

    2024年02月13日
    瀏覽(31)
  • 項(xiàng)目名稱(chēng):智能家居邊緣網(wǎng)關(guān)項(xiàng)目

    項(xiàng)目名稱(chēng):智能家居邊緣網(wǎng)關(guān)項(xiàng)目

    軟件環(huán)境: C語(yǔ)言 硬件環(huán)境: STM32G030C8TX單片機(jī)開(kāi)發(fā)板 開(kāi)發(fā)工具: Linux平臺(tái)GCC交叉編譯環(huán)境以及ukeil ? 邊緣網(wǎng)關(guān)是部署在網(wǎng)絡(luò)邊緣側(cè)的網(wǎng)關(guān),通過(guò)網(wǎng)絡(luò)聯(lián)接、協(xié)議轉(zhuǎn)換等功能聯(lián)接物理和數(shù)字世界,提供輕量化的聯(lián)接管理、實(shí)時(shí)數(shù)據(jù)分析及應(yīng)用管理功能。比較常見(jiàn)的就是智能家居中

    2024年02月16日
    瀏覽(27)
  • 人工智能在智能家居安全系統(tǒng)軟件中的人臉識(shí)別應(yīng)用

    作者:禪與計(jì)算機(jī)程序設(shè)計(jì)藝術(shù) 《人工智能在智能家居安全系統(tǒng)軟件中的人臉識(shí)別應(yīng)用》 引言 1.1. 背景介紹 隨著物聯(lián)網(wǎng)技術(shù)的發(fā)展,智能家居逐漸成為人們生活中不可或缺的一部分。智能家居系統(tǒng)通常包括智能門(mén)鎖、智能燈光、智能插座、智能窗簾、智能家電等。其中,智

    2024年02月08日
    瀏覽(125)
  • 智能家居APP軟件開(kāi)發(fā)有何優(yōu)勢(shì)?

    智能家居APP軟件開(kāi)發(fā)有何優(yōu)勢(shì)?

    ?????? 傳統(tǒng)家居行業(yè)營(yíng)銷(xiāo)模式已經(jīng)無(wú)法滿(mǎn)足現(xiàn)代人多樣化個(gè)性化的需求,也跟不上互聯(lián)網(wǎng)時(shí)代的發(fā)展步伐了,很多傳統(tǒng)家居行業(yè)都陷入了營(yíng)銷(xiāo)困境。通過(guò)智能家居APP軟件開(kāi)發(fā),可以利用互聯(lián)網(wǎng)+改造傳統(tǒng)模式,探索新的發(fā)展模式,可以說(shuō)智能家居管理系統(tǒng)的開(kāi)發(fā)為傳統(tǒng)家居

    2024年02月12日
    瀏覽(26)
  • 基于STM32智能家居控制系統(tǒng)軟件設(shè)計(jì)及實(shí)現(xiàn)

    基于STM32智能家居控制系統(tǒng)軟件設(shè)計(jì)及實(shí)現(xiàn)

    智能家居控制系統(tǒng)的軟件設(shè)計(jì)主要使用Keil uVision5進(jìn)行STM32主燒錄程序的編寫(xiě),主程序完成的功能主要為接收并判斷語(yǔ)音識(shí)別模塊傳過(guò)來(lái)的信息,然后根據(jù)滿(mǎn)足條件的不同進(jìn)行對(duì)應(yīng)的操作。例如,當(dāng)語(yǔ)音模塊傳過(guò)來(lái)的信息為“打開(kāi)電視”時(shí),STM32單片將使給8550一個(gè)低電平,這樣

    2024年02月02日
    瀏覽(102)
  • QT 項(xiàng)目 智能家居系統(tǒng) 上位機(jī)

    QT 項(xiàng)目 智能家居系統(tǒng) 上位機(jī)

    有哪些文件? : 頭文件: 1. auidio .h? 語(yǔ)音識(shí)別 模塊 2. camera.h? 人臉識(shí)別登錄模塊 3. chooselevelscene.h? 翻金幣游戲的? 4. dataconfig.h? ?翻金幣游戲的 關(guān)卡 的數(shù)據(jù)? 5.entry_mode.h 登錄方式的界面類(lèi) 6.luck_draw.h? ?開(kāi)心一天的界面類(lèi) 7.mainsence.h 翻金幣游戲的背景圖片的類(lèi)? 8.mainwindow

    2024年02月12日
    瀏覽(30)
  • Linux嵌入式項(xiàng)目-智能家居

    Linux嵌入式項(xiàng)目-智能家居

    一、資料下載 ?二、框架知識(shí) ?三、MQTT通信協(xié)議 1、上位機(jī)APP主要工作? ? ? ? 1.wait for msg? / while(1)訂閱等待消息 ? ? ? ?2.處理消息 客戶(hù)端創(chuàng)建了兩個(gè)線(xiàn)程,一個(gè)線(xiàn)程用于發(fā)布消息,一個(gè)線(xiàn)程用于監(jiān)聽(tīng)訂閱消息 (那我的仿真系統(tǒng)也可以啊,一個(gè)發(fā)送處理數(shù)據(jù)線(xiàn)程。一個(gè)監(jiān)聽(tīng)

    2024年02月16日
    瀏覽(25)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包