基于全志H616的智能垃圾桶项目

一、功能需求

  • 靠近时,垃圾桶开启2秒,2秒后关闭
  • 垃圾桶开启带滴滴声
  • 垃圾桶开启超过10秒,滴滴声警报
  • 语音控制垃圾桶开关盖
  • 回顾二阶段的Socket编程,实现Sockect客户端发送指令远程打开/关闭垃圾桶,并显示垃圾桶状态
  • 统计当天垃圾桶开关盖次数及开关盖指令来源并记录在文件中
  • 统计当天垃圾桶开关盖次数及开关盖指令来源并记录在数据库中

二、硬件

超声波测距模块,sg90,蜂鸣器,全志H616,SU-03语音模块。

三、设计模块

简单工厂模式:分模块思想编程,使代码更易于维护;

设备工厂:控制sg90舵机,超声波测距模块和蜂鸣器;

指令工厂:控制语音和Socket客户端收发指令;

记录工厂:控制文件和数据库的读写。

四、代码

contrlDevices.h

#include 
#include struct Devices
{char deviceName[128];int status;int pinNum;char date[32];int csbOpen;int csbClose;int socketOpen;int socketClose;int voiceOpen;int voiceClose;int (*open)(int pinNum);int (*close)(int pinNum);int (*deviceInit)(int pinNum);int (*readStatus)(int pinNum);int (*changeStatus)(int pinNum);struct Devices *next;struct timeval start;struct timeval stop;
};struct Devices * addBeepToDeviceLink(struct Devices *phead);
struct Devices * addCsbToDeviceLink(struct Devices *phead);
struct Devices * addDusbinToDeviceLink(struct Devices *phead);

InputCommand.h

#include 
#include 
#include 
#include 
#include struct InputCommander
{char commandName[128];//socketServer和voicechar deviceName[128];//打开的设备名称char command[32];//获取指令char log[1024];int baud;//波特率int fd;int s_fd;int c_fd;char port[12];//端口号char ipAddress[32];//ip地址int (*Init)(struct InputCommander *pInputCommand);int (*getCommand)(struct InputCommander *pInputCommand);int (*sendStatus)(int fd,char *str);struct InputCommander *next;
};struct InputCommander * addSocketContrlToInputCommand(struct InputCommander * phead);
struct InputCommander * addVoiceContrlToInputCommand(struct InputCommander * phead);

record.h

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include struct Records{ char recordName[32];//fileRecords  dataBaseRecordschar recordPathName[32];//文件名或数据库名 sqlite3 *db;int fd;int (*Init)(struct Records *pRecord);int (*writeRecords)(struct Records *pRecord);struct Records *next;
};struct Records *addFileToRecordsLink(struct  Records *phead);
struct Records * addDataBaseToRecordsLink(struct Records *phead);

csb.c

#include "contrlDevices.h"
#include 
#include 
#include #define Trig 5int csbInit(int pinNum)
{pinMode(Trig,OUTPUT);pinMode(pinNum,INPUT);
}int getDistance(int pinNum)
{//测量距离:2-400cm;struct timeval tv1;  //timeval是time.h中的预定义结构体 其中包含两个一个是秒,一个是微秒struct timeval tv2;long start, stop;float dis;digitalWrite(Trig, LOW);delayMicroseconds(2);digitalWrite(Trig, HIGH);delayMicroseconds(10);      //发出超声波脉冲digitalWrite(Trig, LOW);while(digitalRead(pinNum) != 1);gettimeofday(&tv1, NULL);           //获取当前时间 开始接收到返回信号的时候while(digitalRead(pinNum) != 0);gettimeofday(&tv2, NULL);           //获取当前时间  最后接收到返回信号的时候start = tv1.tv_sec * 1000000 + tv1.tv_usec;   //微秒级的时间stop  = tv2.tv_sec * 1000000 + tv2.tv_usec;dis = (float)(stop - start) / 1000000 * 34000 / 2;  //计算时间差求出距离if(dis>30){return 1;}else{return 0;}}
struct Devices csb=
{.deviceName="csb",.pinNum=7,.status=1,.deviceInit=csbInit,.readStatus=getDistance//大于10cm,返回1,小于10cm 返回0;
};struct Devices * addCsbToDeviceLink(struct Devices *phead)
{if(phead == NULL){return &csb;}else{csb.next=phead;return &csb;}
}

beep.c

#include "contrlDevices.h"
#include int beepOpen(int pinNum)
{digitalWrite(pinNum,HIGH);
}
int beepClose(int pinNum)
{digitalWrite(pinNum,LOW);
}int beepInit(int pinNum){pinMode(pinNum,OUTPUT);digitalWrite(pinNum,LOW);//高电平触发;}struct Devices beep=
{.deviceName="beep",.pinNum=8,.open = beepOpen,.close =beepClose,.deviceInit=beepInit,  
};struct Devices * addBeepToDeviceLink(struct Devices *phead)
{if(phead == NULL){return &beep;}else{beep.next=phead;return &beep;}
}

dusbin.c

#include "contrlDevices.h"
#include "InputCommand.h"
#include "record.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include #define SG90Pin 2
char message[200];extern struct Devices *beepHandler;
extern struct Devices *dusbinHandler;
extern struct InputCommander *socketHandler;
extern struct InputCommander *voiceHandler;
extern struct Devices *csbHandler;
extern struct Records *fileHandler;
struct Records * sqliteHandler;static int i = 0;
extern int jd_bak;
extern int jd;void recordCount()
{time_t now;struct tm* tm_now;char datemessage[12]={'\0'};time(&now);tm_now = localtime(&now);strftime(datemessage,12,"%Y/%m/%d",tm_now);//获取当前时间if(strcmp(dusbinHandler->date,datemessage)){memset(dusbinHandler->date,'\0',32);strcpy(dusbinHandler->date,datemessage);dusbinHandler->csbOpen=0;dusbinHandler->csbClose=0;dusbinHandler->voiceOpen=0;dusbinHandler->voiceClose=0;dusbinHandler->socketOpen=0;dusbinHandler->socketClose=0;}if(! csbHandler->status){dusbinHandler->csbOpen++;}else if(!strcmp(voiceHandler->command,"open")){dusbinHandler->voiceOpen++;}else if(!strcmp(socketHandler->command,"open")){dusbinHandler->socketOpen++;}else if(!strcmp(voiceHandler->command,"close")&& csbHandler->status ){dusbinHandler->voiceClose++;}else if (!strcmp(socketHandler->command,"close")&& csbHandler->status ){dusbinHandler->socketClose++;}else if(csbHandler->status   && strcmp(voiceHandler->command,"open") && strcmp(socketHandler->command,"open" )&& strcmp(voiceHandler->command,"close")&&strcmp(socketHandler->command,"close")){dusbinHandler->csbClose++;  }   memset(voiceHandler->command,'\0',32);memset(socketHandler->command,'\0',32);}int dusbinOpen(int pinNum)
{ jd =3;gettimeofday(&(beepHandler->stop),NULL);if(jd_bak!=jd){   recordCount();//记录开关盖次数fileHandler->writeRecords(fileHandler);   //写入文件;sqliteHandler->writeRecords(sqliteHandler);//写入数据库;beepHandler->open(beepHandler->pinNum);usleep(150000);beepHandler->close(beepHandler->pinNum);sleep(2);          }jd_bak=jd; }int  dusbinClose(int pinNum)
{jd = 1;if(jd_bak!=jd){   recordCount();fileHandler->writeRecords(fileHandler);sqliteHandler->writeRecords(sqliteHandler);usleep(150000);}jd_bak=jd;gettimeofday(&(beepHandler->start),NULL);   }void signal_handler(int signum)
{if(i <= jd){digitalWrite(SG90Pin, HIGH);}else{digitalWrite(SG90Pin, LOW);}if(i == 40){//20msi = 0;} i++;
}int dusbinInit(int pinNum){struct itimerval itv;jd = 1;jd_bak=1;i=0;pinMode(pinNum,OUTPUT);digitalWrite(pinNum,LOW);//设定定时时间:500微秒,itv.it_interval.tv_sec = 0;itv.it_interval.tv_usec = 500;//设定开始生效,启动定时器的时间itv.it_value.tv_sec = 1;itv.it_value.tv_usec = 0;//设定定时方式if( -1 == setitimer(ITIMER_REAL, &itv, NULL)){printf("setitimer error\n");exit(-1);}//信号处理signal(SIGALRM,signal_handler);}struct Devices dusbin=
{.deviceName="dusbin",.pinNum=2,.deviceInit=dusbinInit,.open=dusbinOpen,.close=dusbinClose,.date={'\0'},.csbOpen=0,.csbClose=0,.socketOpen=0,.socketClose=0,.voiceOpen=0,.voiceClose=0,};struct Devices * addDusbinToDeviceLink(struct Devices *phead)
{if(phead == NULL){return &dusbin;}else{dusbin.next=phead;return &dusbin;}
}

file.c

#include "record.h"
#include 
#include 
#include 
#include "contrlDevices.h"extern struct Devices *dusbinHandler;int fileInit(struct Records *pRecord)
{int fd;if((fd=open(pRecord->recordPathName,O_RDWR|O_CREAT,0600))==-1){perror("file open error");exit(-1);}close(fd);pRecord->fd=fd;return fd;
}int writeToFile(struct Records *pRecord)
{int nwrite;char *readBuf;char message[100]={'\0'};char info[200]={'\0'};int j;sprintf(message,"date=%s;",dusbinHandler->date);sprintf(info,"date=%s;csbOpen=%d;csbClose=%d;voiceOpen=%d;voiceClose=%d;socketOpen=%d;socketClose=%d;\r\n",dusbinHandler->date,dusbinHandler->csbOpen,dusbinHandler->csbClose,dusbinHandler->voiceOpen,dusbinHandler->voiceClose,dusbinHandler->socketOpen,dusbinHandler->socketClose);pRecord->fd = open(pRecord->recordPathName,O_RDWR,0600);int fileSize=lseek(pRecord->fd,0,SEEK_END);readBuf= (char *)malloc(sizeof(char )*(fileSize+strlen(info)+12));lseek(pRecord->fd,0,SEEK_SET);memset(readBuf,'\0',sizeof(readBuf));read(pRecord->fd,readBuf,fileSize);lseek(pRecord->fd,0,SEEK_SET);char *p = strstr(readBuf,message);if(p==NULL&& strlen(dusbinHandler->date)!=0){strncat(readBuf,info,strlen(info));//在尾部追加;}else{for(j=0;jfd,readBuf,strlen(readBuf));printf("write file success:%s\n",readBuf);close(pRecord->fd);return nwrite;}struct Records file={.recordName="fileRecords",.recordPathName="file1", .Init=fileInit,.writeRecords=writeToFile,};struct Records *addFileToRecordsLink(struct  Records *phead)
{if(phead == NULL){return &file;}else{file.next=phead;return &file;}
}

lite.c

#include "record.h"
#include "contrlDevices.h"
#include 
#include 
#include extern struct Devices *dusbinHandler;
int callback1(void *arg, int column_size, char *column_value[], char
*column_name[])
{int i;printf("records of dusbin.db:\n");for(i=0;idate,dusbinHandler->csbOpen,dusbinHandler->csbClose,dusbinHandler->voiceOpen,dusbinHandler->voiceClose,dusbinHandler->socketOpen,dusbinHandler->socketClose);rc=sqlite3_exec(arg, sql, NULL, 0, &zErrMsg);if( rc != SQLITE_OK ){fprintf(stderr, "insert error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{fprintf(stdout, "insert  successfully\n");} }memset(sql,'\0',strlen(sql));sprintf(sql,"select * from dusbin where date = '%s';",dusbinHandler->date);rc=sqlite3_exec(arg, sql,callback1, arg, &zErrMsg);if( rc != SQLITE_OK ){fprintf(stderr, "SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{fprintf(stdout, " select successfully\n");} sqlite3_close(arg);return 0;     
}int writeToDB(struct Records *pRecord)
{int rc;char *zErrMsg = NULL;char sql[256]={'\0'};sprintf(sql,"update dusbin set csbOpen = %d, csbClose=%d ,voiceOpen=%d,voiceClose=%d,socketOpen=%d,socketClose=%d where date ='%s' ;select count(*) from dusbin where date='%s';",dusbinHandler->csbOpen,dusbinHandler->csbClose,dusbinHandler->voiceOpen,dusbinHandler->voiceClose,dusbinHandler->socketOpen,dusbinHandler->socketClose ,dusbinHandler->date,dusbinHandler->date);    rc = sqlite3_open(pRecord->recordPathName, &(pRecord->db));if( rc!=SQLITE_OK ){fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(pRecord->db));exit(0);}else{fprintf(stderr, "Opened database successfully\n");}rc=sqlite3_exec(pRecord->db, sql, callback, pRecord->db, &zErrMsg);if( rc != SQLITE_OK ){fprintf(stderr, "update database error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{fprintf(stdout, "update  successfully\n");}sqlite3_close(pRecord->db);
}int DBInit(struct Records *pRecord)
{int rc;char *zErrMsg = NULL;char *sql = "create table dusbin(date char,csbOpen interger, csbClose interger ,voiceOpen interger ,voiceClose interger, socketOpen interger, socketClose interger );";rc = sqlite3_open(pRecord->recordPathName, &(pRecord->db));if( rc ){fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(pRecord->db));exit(0);}else{fprintf(stderr, "Opened database successfully\n");}rc = sqlite3_exec(pRecord->db, sql, NULL, 0, &zErrMsg);if( rc != SQLITE_OK ){fprintf(stderr, "table existed: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{fprintf(stdout, "created Table successfully\n");}sqlite3_close(pRecord->db);return 0;
}struct Records dbOfRecords={.recordName="dataBaseRecords",.recordPathName="dusbin.db", .Init=DBInit,.writeRecords=writeToDB,};struct Records * addDataBaseToRecordsLink(struct Records *phead)
{if(phead == NULL){return &dbOfRecords;}else{dbOfRecords.next=phead;return &dbOfRecords;}
}

mainPro.c

#include 
#include 
#include 
#include 
#include 
#include         
#include 
#include 
#include "contrlDevices.h"
#include "InputCommand.h"
#include 
#include 
#include "record.h"struct Devices *pdeviceHead = NULL;
struct InputCommander *pCommandHead=NULL;
struct Records *pRecordsHead=NULL;struct InputCommander *socketHandler;
struct InputCommander *voiceHandler;struct Devices *dusbinHandler;
struct Devices *beepHandler;
struct Devices *csbHandler;
struct Records *fileHandler;
struct Records * sqliteHandler;long diffTime;int jd_bak=0;int jd=0;struct Devices * findDevicesByName(char *str,struct Devices * phead)
{struct Devices *tmp = phead;if(tmp == NULL){printf("find devices error\n");return NULL;}else{while(tmp!=NULL){if(!strcmp(tmp->deviceName,str)){return tmp;}tmp=tmp->next;}}
}
struct InputCommander * findInputCommanderByName(char *str,struct InputCommander * phead)
{struct InputCommander *tmp = phead;if(tmp == NULL){printf("find InputCommander error\n");return NULL;}else{while(tmp!=NULL){if(!strcmp(tmp->commandName,str)){return tmp;}tmp=tmp->next;}}
}struct Records * findRecordsByName(char *str,struct Records * phead)
{struct Records *tmp = phead;if(tmp == NULL){printf("find records error\n");return NULL;}else{while(tmp!=NULL){if(!strcmp(tmp->recordName,str)){return tmp;}tmp=tmp->next;}}
}void *read_thread(void *datas)
{int n_read;char buffer[32]={'\0'};while(1){memset(buffer,'\0',sizeof(buffer));n_read = read(socketHandler->c_fd,buffer, sizeof(buffer));if(n_read == -1){perror("read");}else if(n_read>0){ memset(socketHandler->command,'\0',sizeof(socketHandler->command));strcpy(socketHandler->command,buffer);printf("socket get cmd:%s\n",socketHandler->command);}else{printf("client quit\n");break;}} 
}void *socket_thread(void *datas)
{pthread_t readThread;struct sockaddr_in c_addr;int n_read = 0;int clen = sizeof(struct sockaddr_in);memset(&c_addr,0,clen);socketHandler=findInputCommanderByName("socketServer",pCommandHead);if(socketHandler==NULL){printf("find socketHandler error\n");pthread_exit(NULL);}else{socketHandler->Init(socketHandler);printf("%s init success\n",socketHandler->commandName);while(1){//不断接收新的客户端的接入,接入新的客户端后创建新的读线程;socketHandler->c_fd = accept(socketHandler->s_fd,(struct sockaddr *)&c_addr,&clen);if(socketHandler->c_fd == -1){perror("accept");}printf("c_fd:%d\n",socketHandler->c_fd);pthread_create(&readThread,NULL,read_thread,NULL);}}}void *voice_thread(void *datas)
{int nread;pthread_t cmdThread;voiceHandler=findInputCommanderByName("voice",pCommandHead);if(voiceHandler==NULL){printf("find voiceHandler error\n");pthread_exit(NULL);}else{if(voiceHandler->Init(voiceHandler)<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){continue;}else{printf("voice get cmd: %s\n",voiceHandler->command);   }}}
} void *dusbin_thread(void *datas)
{dusbinHandler=findDevicesByName("dusbin",pdeviceHead );dusbinHandler->deviceInit(dusbinHandler->pinNum);fileHandler= findRecordsByName("fileRecords",pRecordsHead);fileHandler->Init(fileHandler);sqliteHandler = findRecordsByName("dataBaseRecords",pRecordsHead);sqliteHandler->Init(sqliteHandler);while(1){    //距离大于30cm,返回1;if(! csbHandler->status||!strcmp(voiceHandler->command,"open")||!strcmp(socketHandler->command,"open")){  //靠近时,垃圾桶开启2秒,2秒后关闭 dusbinHandler->open(dusbinHandler->pinNum);}else if( (!strcmp(voiceHandler->command,"close")||!strcmp(socketHandler->command,"close")) && csbHandler->status ){   dusbinHandler->close(dusbinHandler->pinNum);}else if(csbHandler->status && strcmp(voiceHandler->command,"open") && strcmp(socketHandler->command,"open")&& strcmp(voiceHandler->command,"close")&&strcmp(socketHandler->command,"close")){dusbinHandler->close(dusbinHandler->pinNum); } }
}void *csb_thread(void *datas)
{csbHandler=findDevicesByName("csb",pdeviceHead); beepHandler=findDevicesByName("beep",pdeviceHead);beepHandler->deviceInit(beepHandler->pinNum);csbHandler->deviceInit(csbHandler->pinNum);gettimeofday(&(beepHandler->start),NULL);while(1){csbHandler->status=csbHandler->readStatus(csbHandler->pinNum);diffTime=beepHandler->stop.tv_sec-beepHandler->start.tv_sec;if(diffTime>10){  beepHandler->open(beepHandler->pinNum);}else{beepHandler->close(beepHandler->pinNum);}usleep(500000);}
}int main()
{pthread_t voiceThread;pthread_t socketThread;pthread_t csbThread;pthread_t dusbinThread;if(wiringPiSetup()==-1){printf("wiringPi init error\n");exit(-1);}//1.指令工厂初始化pCommandHead= addSocketContrlToInputCommand(pCommandHead);pCommandHead=addVoiceContrlToInputCommand(pCommandHead);//2.设备控制工厂初始化pdeviceHead=addBeepToDeviceLink(pdeviceHead);pdeviceHead=addCsbToDeviceLink(pdeviceHead);pdeviceHead=addDusbinToDeviceLink(pdeviceHead);//文件工厂初始化pRecordsHead = addFileToRecordsLink(pRecordsHead);pRecordsHead=addDataBaseToRecordsLink(pRecordsHead);//3.线程池建立//超声波测距线程pthread_create(&csbThread,NULL,csb_thread,NULL);//3.2语音线程pthread_create(&voiceThread,NULL, voice_thread,NULL);//3.3socket 线程pthread_create(&socketThread,NULL, socket_thread,NULL);//dusbin线程pthread_create(&dusbinThread,NULL, dusbin_thread,NULL);//等待线程退出:pthread_join(csbThread,NULL);pthread_join(voiceThread,NULL);pthread_join(socketThread,NULL);pthread_join(dusbinThread,NULL);return 0;
}

编译:

gcc  file.c lite.c beep.c dusbin.c mainPro.c socketContrl.c csb.c voiceContrl.c -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt -lsqlite3

执行:

sudo ./a.out

五、功能展示

智能垃圾桶


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部