本项目使用工厂模式来编写代码,其中包括指令工厂和设备工厂,使用工厂模式的目的是为了让各模块代码更加独立,并且让C语言具有所谓的面向对象的属性; 本项目使用树莓派作为主控芯片,开发环境选择ubuntu下的Linux,通过使用交叉编译工具链,将x86架构下的代码,交叉编译成为arm架构下可执行程序,置于树莓派中; 控制方案采用socket网络控制线程和串口控制线程,其中串口控制使用的是LD3320语音模块,通过对该模块的二次开发,使其成为能够在特定语音环境下实现串口通信的功能,与树莓派通过串口进行通信,在树莓派获得LD3320发送的数据后经过相应的处理,来对设备进行控制;socket网络控制采用TCP协议,通过IP地址和端口号与树莓派建立连接,通过向树莓派发送数据,树莓派接收到相应数据之后进行处理,实现对设备的控制;
指令工程头文件:inputCommand.h
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<arpa/inet.h>
#include <netinet/in.h>
#include<string.h>
#include<pthread.h>
struct InputCommand{
char commandName[128];
char deviceName[128];
char *command[32];
int (*init)(struct InputCommand *device ,char * ipAddress,char *port);
int (*getCommand)(struct InputCommand *device);
int fd;
char port[12];
char ipAddress[32];
char log[1024];
struct InputCommand *next;
};
struct InputCommand *addVoiceIntoCommandLink(struct InputCommand *head);
struct InputCommand *addSocketIntoCommandLink(struct InputCommand *head);
设备工厂头文件 controlDevice.h
#include <stdio.h>
#include <wiringPi.h>
struct Devices{
char deviceName[128];
int status;
int pinNum;
int (*open)(int pinNum);
int (*close)(int pinNum);
int (*deviceinit)(int pinNum);
int (*readStatus)();
int (*changeStatus)(int status,int pinNum);
struct Devices* next;
};
struct Devices *addBathRoomIntoLink(struct Devices *head);
struct Devices *addBedRoomIntoLink(struct Devices *head);
struct Devices *addlockIntoLink(struct Devices *head);
struct Devices *addtoiletIntoLink(struct Devices *head);
struct Devices *addFireIntoLink(struct Devices *head);
设备1源文件 :bathroom.c
#include "controlDevice.h"
int bathRoomInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
return 0;
}
int bathRoomopen(int pinNum)
{
digitalWrite(pinNum,LOW);
return 0;
}
int bathRoomClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
return 0;
}
int bathroomchange(int status,int pinNum)
{
return 0;
}
struct Devices bathRoom = {
.pinNum = 22,
.deviceName = "bathRoomLight",
.deviceinit = bathRoomInit,
.open = bathRoomopen,
.close = bathRoomClose,
.changeStatus = bathroomchange
.next = NULL;
};
struct Devices *addBathRoomIntoLink(struct Devices *head)
{
if(head == NULL){
head = &bathRoom;
}else{
bathRoom.next = head;
head = &bathRoom;
}
return head;
}
设备2源文件:bedroom.c
#include "controlDevice.h"
int bedRoomInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
return 0;
}
int bedRoomopen(int pinNum)
{
digitalWrite(pinNum,LOW);
return 0;
}
int bedRoomClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
return 0;
}
int bedroomchange(int status,int pinNum)
{
return 0;
}
struct Devices bedRoom = {
.pinNum = 23,
.deviceName = "bedRoomLight",
.deviceinit = bedRoomInit,
.open = bedRoomopen,
.close = bedRoomClose,
.changeStatus = bedroomchange
.next = NULL;
};
struct Devices *addBedRoomIntoLink(struct Devices *head)
{
if(head == NULL){
head = &bedRoom;
}else{
bedRoom.next = head;
head = &bedRoom;
}
return head;
}
设备3源文件 fire.c
#include "controlDevice.h"
int fireInit(int pinNum)
{
pinMode(pinNum,INPUT);
digitalWrite(pinNum,HIGH);
}
int fireReadStatus(int pinNum)
{
return digitalRead(pinNum);
}
struct Devices fire = {
.pinNum = 4,
.deviceName = "fireDetect",
.deviceinit = fireInit,
.readStatus = fireReadStatus
.next = NULL;
};
struct Devices *addFireIntoLink(struct Devices *head)
{
if(head == NULL){
head = &fire;
}else{
fire.next = head;
head = &fire;
}
return head;
}
设备4源文件:lock.c
#include "controlDevice.h"
int lockInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int lockopen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int lockClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int lockchange(int status,int pinNum)
{
}
struct Devices lock = {
.pinNum = 24,
.deviceName = "lock",
.deviceinit = lockInit,
.open = lockopen,
.close = lockClose,
.changeStatus = lockchange
.next = NULL;
};
struct Devices *addlockIntoLink(struct Devices *head)
{
if(head == NULL){
head = &lock;
}else{
lock.next = head;
head = &lock;
}
return head;
}
socket网络控制源文件 socketComand.c
#include "inputCommand.h"
int socketInit(struct InputCommand* socketMsg ,char * ipAddress,char *port)
{
int s_fd;
int bind_ret;
struct sockaddr_in s_addr;
memset(&s_addr,0,sizeof(struct sockaddr_in));
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd ==-1){
perror("socket");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(socketMsg->port));
inet_aton(socketMsg->ipAddress,&s_addr.sin_addr);
bind_ret = bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
if(bind_ret == -1){
perror("bind");
exit(-1);
}
int listen_ret;
listen_ret = listen(s_fd,10);
if(listen_ret == -1){
perror("listen");
exit(-1);
}else{
printf("listening....\n");
}
socketMsg->fd = s_fd;
return s_fd;
}
int socketGetCommand(struct InputCommand* socketMsg)
{
struct sockaddr_in c_addr;
memset(&c_addr,0,sizeof(struct sockaddr_in));
int c_addr_len = sizeof(struct sockaddr_in);
int c_fd = accept(socketMsg->fd,(struct sockaddr *)&c_addr,&c_addr_len);
if(c_fd == -1){
perror("accept");
exit(-1);
}
printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));
memset(socketMsg->command,'\0',sizeof(socketMsg->command));
int nread = read(c_fd,socketMsg->command,sizeof(socketMsg->command));
if(nread ==-1){
printf("read failure\n");
}else if(nread >0){
printf("read from client %d byte,context:%s",nread,sizeof(socketMsg->command));
}else{
printf("client quit!\n");
}
return nread;
}
struct InputCommand socketControl = {
.commandName = "socketServer",
.command = {'\0'},
.ipAddress = "192.168.43.80",
.port = "8088",
.init = socketInit,
.getCommand = socketGetCommand,
.log = {'\0'},
.next = NULL
};
struct InputCommand *addSocketIntoCommandLink(struct InputCommand *head)
{
if(head == NULL){
head = &socketControl;
}else{
socketControl.next = head;
head = &socketControl;
}
}
语音指令源文件voiceControl.c
#include "inputCommand.h"
int voiceInit(struct InputCommand* voice ,char * ipAddress,char *port)
{
int fd;
if((fd = serialOpen(voice->deviceName,9600)) == -1){
exit(-1);
}
voice->fd = fd;
return fd;
}
int voiceGetCommand(struct InputCommand* voice)
{
int nread = 0;
memset(voice->command,'\0',sizeof(voice->command));
nread = read(voice->fd,voice->command,sizeof(voice->command));
return nread;
}
struct InputCommand voiceControl = {
.commandName = "voiceControl",
.command = {'\0'},
.deviceName = "/dev/ttyAMA0",
.init = voiceInit,
.getCommand = voiceGetCommand,
.log = {'\0'},
.next = NULL
};
struct InputCommand *addVoiceIntoCommandLink(struct InputCommand *head)
{
if(head == NULL){
head = &voiceControl;
}else{
voiceControl.next = head;
head = &voiceControl;
}
}
主函数main.c
#include "controlDevice.h"
#include "inputCommand.h"
#include <string.h>
struct Devices *deviceHead = NULL;
struct InputCommand *commandHead = NULL;
struct InputCommand *socketHandler = NULL;
int c_fd;
struct Devices *findDeviceInLink(char *name,struct Devices *head)
{
if(head == NULL){
printf("the link is empty\n");
return NULL;
}
while(head != NULL){
if(strcmp(head->deviceName,name)==0){
return head;
}
head = head->next;
}
return NULL;
}
struct InputCommand *findCommandDeviceInLink(char *name,struct InputCommand *head)
{
if(head == NULL){
printf("the link is empty\n");
return NULL;
}
while(head != NULL){
if(strcmp(head->commandName,name)==0){
return head;
}
head = head->next;
}
return NULL;
}
void controlDeviceDoCommand(char *command)
{
if(strstr(command,"bath") != NULL){
struct Devices *BathRoom = findDeviceInLink("bathRoomLight",deviceHead);
BathRoom->deviceinit(BathRoom->pinNum);
if(strstr(command,"open") != NULL){
BathRoom->open(BathRoom->pinNum);
}else if(strstr(command,"close") != NULL){
BathRoom->close(BathRoom->pinNum);
}
}else if(strstr(command,"bed") != NULL){
struct Devices *BedRoom = findDeviceInLink("bedRoomLight",deviceHead);
BedRoom->deviceinit(BedRoom->pinNum);
if(strstr(command,"open") != NULL){
BedRoom->open(BedRoom->pinNum);
}else if(strstr(command,"close") != NULL){
BedRoom->close(BedRoom->pinNum);
}
}else if(strstr(command,"lock") != NULL){
struct Devices *Lock = findDeviceInLink("lock",deviceHead);
Lock->deviceinit(Lock->pinNum);
if(strstr(command,"open") != NULL){
Lock->open(Lock->pinNum);
}else if(strstr(command,"close") != NULL){
Lock->close(Lock->pinNum);
}
}else{
printf("no such device\n");
}
}
void *voice_threadFunc(void *data)
{
struct InputCommand *voiceHandler = NULL;
int nread;
voiceHandler = findCommandDeviceInLink("voiceControl",commandHead);
if(voiceHandler == NULL){
printf("find voiceHandler error\n");
pthread_exit(NULL);
}else{
if(voiceHandler->init(voiceHandler,NULL,NULL)<0){
printf("voice init error\n");
pthread_exit(NULL);
}else{
printf("%s init success\n",voiceHandler->commandName);
}
while(1){
nread = voiceHandler->getCommand(voiceHandler);
if(nread == 0){
printf("no data from voice\n");
}else{
printf("get command:%s\n",voiceHandler->command);
controlDeviceDoCommand(voiceHandler->command);
}
}
}
}
void * socketReadFunc(void *data)
{
while(1){
memset(socketHandler->command,'\0',sizeof(socketHandler->command));
int nread = read(c_fd,socketHandler->command,sizeof(socketHandler->command));
if(nread == 0){
printf("no data from voice\n");
}else if(nread<0){
printf("socket read error\n");
pthread_exit(NULL);
}else{
printf("get command:%s\n",socketHandler->command);
controlDeviceDoCommand(socketHandler->command);
}
}
}
void *socket_threadFunc(void *data)
{
struct sockaddr_in c_addr;
memset(&c_addr,0,sizeof(struct sockaddr_in));
int c_addr_len = sizeof(struct sockaddr_in);
pthread_t socketRead;
socketHandler = findCommandDeviceInLink("socketServer",commandHead);
if(socketHandler == NULL){
printf("find socketHandler error\n");
pthread_exit(NULL);
}else{
printf("%s init success\n",socketHandler->commandName);
}
int s_fd = socketHandler->init(socketHandler,NULL,NULL);
while(1){
c_fd = accept(socketHandler->fd,(struct sockaddr *)&c_addr,&c_addr_len);
pthread_create(&socketRead,NULL,socketReadFunc,NULL);
}
}
int main()
{
if(wiringPiSetup() == -1){
return -1;
}
pthread_t voice_thread;
pthread_t socket_thread;
pthread_t camera_thread;
pthread_t fire_thread;
char name[128];
deviceHead = addBathRoomIntoLink(deviceHead);
deviceHead = addBedRoomIntoLink(deviceHead);
deviceHead = addtoiletIntoLink(deviceHead);
deviceHead = addlockIntoLink(deviceHead);
deviceHead = addFireIntoLink(deviceHead);
commandHead = addVoiceIntoCommandLink(commandHead);
commandHead = addSocketIntoCommandLink(commandHead);
pthread_create(&voice_thread,NULL,voice_threadFunc,NULL);
pthread_create(&socket_thread,NULL,socket_threadFunc,NULL);
pthread_join(voice_thread,NULL);
pthread_join(socket_thread,NULL);
return 0;
}
|