🔺1、main.c 文件(主函数):
#include <stdio.h>
#include <string.h>
#include "equipment.h"
#include "command.h"
#include <pthread.h>
#include <unistd.h>
struct Equipment *findEquipByName(char *name,struct Equipment *phead);
struct Command *findCommandByName(char *name,struct Command *phead);
void *voiceControlThread(void *data);
void *socketControlThread(void *data);
void *socketReadThread(void *data);
void *fireAlarmThread(void *data);
struct Equipment *equiphead = NULL;
struct Command *cmdhead = NULL;
struct Command *socketHandler = NULL;
int main()
{
if(wiringPiSetup() == -1){
printf("wiringPiSetup failed!\n");
return -1;
}
equiphead = addBathroomLightToLink(equiphead);
equiphead = addSecondfloorLightToLink(equiphead);
equiphead = addLivingroomLightToLink(equiphead);
equiphead = addRestaurantLightToLink(equiphead);
equiphead = addFireDetectionToLink(equiphead);
equiphead = addBuzzerToLink(equiphead);
cmdhead = addVoiceControlToLink(cmdhead);
cmdhead = addSocketControlToLink(cmdhead);
struct Equipment *tmpequiphead = equiphead;
while(tmpequiphead != NULL){
tmpequiphead->Init(tmpequiphead->pinNum);
tmpequiphead = tmpequiphead->next;
}
pthread_t voiceControl_thread;
pthread_t socketControl_thread;
pthread_t fireAlarm_thread;
pthread_create(&voiceControl_thread,NULL,voiceControlThread,NULL);
pthread_create(&socketControl_thread,NULL,socketControlThread,NULL);
pthread_create(&fireAlarm_thread,NULL,fireAlarmThread,NULL);
pthread_join(voiceControl_thread, NULL);
pthread_join(socketControl_thread, NULL);
pthread_join(fireAlarm_thread, NULL);
return 0;
}
void *voiceControlThread(void *data)
{
int nread;
char *temName = NULL;
struct Command *voiceHandler = NULL;
struct Equipment *linkHandler;
voiceHandler = findCommandByName("voiceControl",cmdhead);
if(voiceHandler == NULL){
printf("find voiceHandler error\n");
pthread_exit(NULL);
}
if(voiceHandler->Init(voiceHandler) < 0){
printf("voiceControl init error\n");
pthread_exit(NULL);
}
while(1){
nread = voiceHandler->getCommand(voiceHandler);
if(nread == 0){
printf("No command received\n");
}else{
printf("Get voice command:%s\n",voiceHandler->command);
if(strcmp("OpBaLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("bathroomLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClBaLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("bathroomLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
if(strcmp("OpSeLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("secondfloorLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClSeLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("secondfloorLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
if(strcmp("OpLiLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("livingroomLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClLiLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("livingroomLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
if(strcmp("OpReLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("restaurantLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClReLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("restaurantLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
if(strcmp("OpAlLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("bathroomLight",equiphead);
linkHandler->open(linkHandler->pinNum);
linkHandler = findEquipByName("secondfloorLight",equiphead);
linkHandler->open(linkHandler->pinNum);
linkHandler = findEquipByName("livingroomLight",equiphead);
linkHandler->open(linkHandler->pinNum);
linkHandler = findEquipByName("restaurantLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClAlLi",voiceHandler->command) == 0){
linkHandler = findEquipByName("bathroomLight",equiphead);
linkHandler->close(linkHandler->pinNum);
linkHandler = findEquipByName("secondfloorLight",equiphead);
linkHandler->close(linkHandler->pinNum);
linkHandler = findEquipByName("livingroomLight",equiphead);
linkHandler->close(linkHandler->pinNum);
linkHandler = findEquipByName("restaurantLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
}
}
}
void *socketControlThread(void *data)
{
int c_fd;
struct sockaddr_in c_addr;
memset(&c_addr,0,sizeof(struct sockaddr_in));
socklen_t clen = sizeof(struct sockaddr_in);
pthread_t socketRead_thread;
socketHandler = findCommandByName("socketControl",cmdhead);
if(socketHandler == NULL){
printf("find socketHandler error\n");
pthread_exit(NULL);
}
if(socketHandler->Init(socketHandler) < 0){
printf("socketControl init error\n");
pthread_exit(NULL);
}
while(1){
c_fd = accept(socketHandler->s_fd,(struct sockaddr*)&c_addr,&clen);
socketHandler->fd = c_fd;
pthread_create(&socketRead_thread,NULL,socketReadThread,NULL);
}
}
void *socketReadThread(void *data)
{
int nread;
struct Equipment *linkHandler;
memset(socketHandler->command,'\0',sizeof(socketHandler->command));
nread = read(socketHandler->fd,socketHandler->command,sizeof(socketHandler->command));
if(nread == 0){
printf("No command received\n");
}else{
printf("Get net command:%s\n",socketHandler->command);
if(strcmp("OpBaLi",socketHandler->command) == 0){
linkHandler = findEquipByName("bathroomLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClBaLi",socketHandler->command) == 0){
linkHandler = findEquipByName("bathroomLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
if(strcmp("OpSeLi",socketHandler->command) == 0){
linkHandler = findEquipByName("secondfloorLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClSeLi",socketHandler->command) == 0){
linkHandler = findEquipByName("secondfloorLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
if(strcmp("OpLiLi",socketHandler->command) == 0){
linkHandler = findEquipByName("livingroomLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClLiLi",socketHandler->command) == 0){
linkHandler = findEquipByName("livingroomLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
if(strcmp("OpReLi",socketHandler->command) == 0){
linkHandler = findEquipByName("restaurantLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClReLi",socketHandler->command) == 0){
linkHandler = findEquipByName("restaurantLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
if(strcmp("OpAlLi",socketHandler->command) == 0){
linkHandler = findEquipByName("bathroomLight",equiphead);
linkHandler->open(linkHandler->pinNum);
linkHandler = findEquipByName("secondfloorLight",equiphead);
linkHandler->open(linkHandler->pinNum);
linkHandler = findEquipByName("livingroomLight",equiphead);
linkHandler->open(linkHandler->pinNum);
linkHandler = findEquipByName("restaurantLight",equiphead);
linkHandler->open(linkHandler->pinNum);
}
if(strcmp("ClAlLi",socketHandler->command) == 0){
linkHandler = findEquipByName("bathroomLight",equiphead);
linkHandler->close(linkHandler->pinNum);
linkHandler = findEquipByName("secondfloorLight",equiphead);
linkHandler->close(linkHandler->pinNum);
linkHandler = findEquipByName("livingroomLight",equiphead);
linkHandler->close(linkHandler->pinNum);
linkHandler = findEquipByName("restaurantLight",equiphead);
linkHandler->close(linkHandler->pinNum);
}
}
}
void *fireAlarmThread(void *data)
{
int status;
struct Equipment *firetmp = NULL;
struct Equipment *buztmp = NULL;
firetmp = findEquipByName("fireDetection",equiphead);
buztmp = findEquipByName("buzzer",equiphead);
while(1){
status = firetmp->readStatus(firetmp->pinNum);
if(status == 0){
buztmp->open(buztmp->pinNum);
delay(1000);
}
if(status == 1){
buztmp->close(buztmp->pinNum);
}
}
}
struct Equipment *findEquipByName(char *name,struct Equipment *phead)
{
struct Equipment *tmp = phead;
if(phead == NULL){
return NULL;
}
while(tmp != NULL){
if(strcmp(name,tmp->equipName) == 0){
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
struct Command *findCommandByName(char *name,struct Command *phead)
{
struct Command *tmp = phead;
if(phead == NULL){
return NULL;
}
while(tmp != NULL){
if(strcmp(name,tmp->commandName) == 0){
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
🔺2、分文件:
(1) equipment.h 文件(设备类头文件):
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
struct Equipment
{
char equipName[128];
int pinNum;
int status;
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 *addBathroomLightToLink(struct Equipment *phead);
struct Equipment *addSecondfloorLightToLink(struct Equipment *phead);
struct Equipment *addLivingroomLightToLink(struct Equipment *phead);
struct Equipment *addRestaurantLightToLink(struct Equipment *phead);
struct Equipment *addFireDetectionToLink(struct Equipment *phead);
struct Equipment *addBuzzerToLink(struct Equipment *phead);
(2) bathroomLight.c 文件(浴室灯):
#include "equipment.h"
int bathroomLightInit(int pinNum);
int bathroomLightOpen(int pinNum);
int bathroomLightClose(int pinNum);
struct Equipment *addBathroomLightToLink(struct Equipment *phead);
struct Equipment bathroomLight = {
.equipName = "bathroomLight",
.pinNum = 21,
.Init = bathroomLightInit,
.open = bathroomLightOpen,
.close = bathroomLightClose,
};
int bathroomLightInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int bathroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int bathroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
struct Equipment *addBathroomLightToLink(struct Equipment *phead)
{
if(phead == NULL){
return &bathroomLight;
}else{
bathroomLight.next = phead;
phead = &bathroomLight;
return phead;
}
}
(3) secondfloorLight.c 文件(二楼灯):
#include "equipment.h"
int secondfloorLightInit(int pinNum);
int secondfloorLightOpen(int pinNum);
int secondfloorLightClose(int pinNum);
struct Equipment *addSecondfloorLightToLink(struct Equipment *phead);
struct Equipment secondfloorLight = {
.equipName = "secondfloorLight",
.pinNum = 22,
.Init = secondfloorLightInit,
.open = secondfloorLightOpen,
.close = secondfloorLightClose,
.changeStatus = secondfloorLightChangeStatus,
};
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 *addSecondfloorLightToLink(struct Equipment *phead)
{
if(phead == NULL){
return &secondfloorLight;
}else{
secondfloorLight.next = phead;
phead = &secondfloorLight;
return phead;
}
}
(4) livingroomLight.c 文件(客厅灯):
#include "equipment.h"
int livingroomLightInit(int pinNum);
int livingroomLightOpen(int pinNum);
int livingroomLightClose(int pinNum);
struct Equipment *addLivingroomLightToLink(struct Equipment *phead);
struct Equipment livingroomLight = {
.equipName = "livingroomLight",
.pinNum = 23,
.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 *addLivingroomLightToLink(struct Equipment *phead)
{
if(phead == NULL){
return &livingroomLight;
}else{
livingroomLight.next = phead;
phead = &livingroomLight;
return phead;
}
}
(5) restaurantLight.c 文件(餐厅灯):
#include "equipment.h"
int restaurantLightInit(int pinNum);
int restaurantLightOpen(int pinNum);
int restaurantLightClose(int pinNum);
struct Equipment *addRestaurantLightToLink(struct Equipment *phead);
struct Equipment restaurantLight = {
.equipName = "restaurantLight",
.pinNum = 24,
.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 *addRestaurantLightToLink(struct Equipment *phead)
{
if(phead == NULL){
return &restaurantLight;
}else{
restaurantLight.next = phead;
phead = &restaurantLight;
return phead;
}
}
(6) fireDetection.c 文件(火焰传感器):
#include "equipment.h"
int fireDetectionInit(int pinNum);
int readFireDetectionStatus(int pinNum);
struct Equipment *addFireDetectionToLink(struct Equipment *phead);
struct Equipment fireDetection = {
.equipName = "fireDetection",
.pinNum = 25,
.Init = fireDetectionInit,
.readStatus = readFireDetectionStatus,
};
int fireDetectionInit(int pinNum)
{
pinMode(pinNum,INPUT);
digitalWrite(pinNum,HIGH);
}
int readFireDetectionStatus(int pinNum)
{
return digitalRead(pinNum);
}
struct Equipment *addFireDetectionToLink(struct Equipment *phead)
{
if(phead == NULL){
return &fireDetection;
}else{
fireDetection.next = phead;
phead = &fireDetection;
return phead;
}
}
(7) buzzer.c 文件(蜂鸣器):
#include "equipment.h"
int buzzerInit(int pinNum);
int buzzerOpen(int pinNum);
int buzzerClose(int pinNum);
struct Equipment *addBuzzerToLink(struct Equipment *phead);
struct Equipment buzzer = {
.equipName = "buzzer",
.pinNum = 29,
.Init = buzzerInit,
.open = buzzerOpen,
.close = buzzerClose,
};
int buzzerInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int buzzerOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int buzzerClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
struct Equipment *addBuzzerToLink(struct Equipment *phead)
{
if(phead == NULL){
return &buzzer;
}else{
buzzer.next = phead;
phead = &buzzer;
return phead;
}
}
(8) command.h 文件(指令控制类头文件):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct Command
{
char commandName[128];
char deviceFilesName[128];
char command[32];
int fd;
int (*Init)(struct Command *file);
int s_fd;
char ipAdress[32];
char port[12];
int (*getCommand)(struct Command *cmd);
char log[1024];
struct Command *next;
};
struct Command *addVoiceControlToLink(struct Command *phead);
struct Command *addSocketControlToLink(struct Command *phead);
(9) voiceControl.c 文件(语音控制):
#include "command.h"
#include <unistd.h>
int voiceControlInit(struct Command *file);
int voiceControlGetCommand(struct Command *cmd);
struct Command *addVoiceControlToLink(struct Command *phead);
struct Command voiceControl = {
.commandName = "voiceControl",
.deviceFilesName = "/dev/ttyAMA0",
.command = {'\0'},
.Init = voiceControlInit,
.getCommand = voiceControlGetCommand,
.log = {'\0'},
};
int voiceControlInit(struct Command *file)
{
int fd;
if((fd = serialOpen(file->deviceFilesName,9600)) == -1){
exit(-1);
}
file->fd = fd;
}
int voiceControlGetCommand(struct Command *cmd)
{
int nread = 0;
memset(cmd->command,'\0',sizeof(cmd->command));
nread = read(cmd->fd,cmd->command,sizeof(cmd->command));
return nread;
}
struct Command *addVoiceControlToLink(struct Command *phead)
{
if(phead == NULL){
return &voiceControl;
}else{
voiceControl.next = phead;
phead = &voiceControl;
return phead;
}
}
(10) socketControl.c(网络端口控制):
#include "command.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
int socketControlInit(struct Command *file);
struct Command *addSocketControlToLink(struct Command *phead);
struct Command socketControl = {
.commandName = "socketControl",
.command = {'\0'},
.Init = socketControlInit,
.ipAdress = "192.168.43.97",
.port = "8888",
.log = {'\0'},
};
int socketControlInit(struct Command *file)
{
int s_fd;
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("socketControl error");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(file->port));
inet_aton(file->ipAdress,&s_addr.sin_addr);
if(bind(s_fd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr_in)) == -1){
perror("bind error");
exit(-1);
}
if(listen(s_fd,10) == -1){
perror("listen error");
exit(-1);
}
file->s_fd = s_fd;
}
struct Command *addSocketControlToLink(struct Command *phead)
{
if(phead == NULL){
return &socketControl;
}else{
socketControl.next = phead;
phead = &socketControl;
return phead;
}
}
🔺3、往期文章讲解:
【智能家居 (1) ——工厂模式继电器控制灯】
【智能家居 (2) ——工厂模式火焰报警器】
【智能家居 (3) ——语音识别控制端线程】
【智能家居 (4) ——网络控制端线程】