基于全志H616的智能垃圾桶
功能需求
1.手靠近时,垃圾桶开启,手远离,垃圾桶关闭
2.垃圾桶开启带滴滴声
3.垃圾桶开启超过10秒,滴滴声警报
4.语音控制垃圾桶开关盖
5.实现Sockect客户端发送指令远程打开/关闭垃圾桶
6.开关盖时,并显示垃圾桶状态
7.统计开关盖次数并记录在文件中;
8.统计开关盖次数并记录在数据库中;
用到的硬件:香橙派,舵机,超声波模块,语音模块,蜂鸣器,oled模块
上代码
main.c
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <signal.h>
#include <pthread.h>
#include <wiringPi.h>
#include <errno.h>
#include <time.h>
#include <stdint.h>
#include <sqlite3.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "oled.h"
#include "font.h"
#include"uartTool.h"
#define BEEP 2
#define SG90pin 8
#define open1 1
#define close1 0
#define Trag 5
#define Echo 7
double dis;
int fd;
int jd;
static int openUart = 0;
static int openSocket=0;
char deviceName[32] = {0};
char filename[32];
struct display_info disp;
static int i = 0;
static int j = 0;
static int cnt=0;
char msg[128] = {0};
int n_read;
int c_fd;
pthread_mutex_t mutex;
void openDusbin()
{
jd = 4;
digitalWrite(BEEP, LOW);
usleep(300000);
digitalWrite(BEEP, HIGH);
sleep(2);
}
void closeDusbin()
{
jd = 1;
}
int oled_show_open(struct display_info *disp)
{
oled_putstrto(disp, 45, 25, "open");
disp->font = font3;
oled_send_buffer(disp);
return 0;
}
int oled_show_close(struct display_info *disp)
{
oled_putstrto(disp, 45, 25, "close");
disp->font = font3;
oled_send_buffer(disp);
return 0;
}
void save_SQL_Open(int cnt)
{
sqlite3 *db = NULL;
char *errmsg = NULL;
char buf[128] = {0};
int ret = 0;
ret = sqlite3_open("orange.db", &db);
if (ret)
{
fprintf(stderr, "Can't open orangebase: %s\n", sqlite3_errmsg(db));
exit(0);
}
else
{
fprintf(stdout, "Opened database successfully\n");
}
sprintf(buf, "create table orangebase (ID Integer)");
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("create table error:%s,ret=%d\n", errmsg, ret);
}
memset(buf, 0, 128);
sprintf(buf, "insert into orangebase values (%d)",cnt);
sqlite3_exec(db, buf, NULL, NULL, NULL);
sqlite3_close(db);
}
void save_SQL_Close(int cnt)
{
sqlite3 *db = NULL;
char *errmsg = NULL;
char buf[128] = {0};
int ret = 0;
ret = sqlite3_open("orange1.db", &db);
if (ret)
{
fprintf(stderr, "Can't open orange1base: %s\n", sqlite3_errmsg(db));
exit(0);
}
else
{
fprintf(stdout, "Opened database successfully\n");
}
sprintf(buf, "create table orange1base (ID Integer)");
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("create table error:%s,ret=%d\n", errmsg, ret);
}
memset(buf, 0, 128);
sprintf(buf, "insert into orange1base values (%d)",cnt);
sqlite3_exec(db, buf, NULL, NULL, NULL);
sqlite3_close(db);
}
void save_File_Open(int cnt)
{
int fd;
int n_write;
fd=open("./file",O_RDWR);
if(fd==-1)
{
printf("open file failed\n");
}
n_write=write(fd,&cnt,sizeof(int));
if(n_write!=-1)
{
printf("write %d success\n",cnt);
}
close(fd);
}
void save_File_Close(int cnt)
{
int fd;
int n_write;
fd=open("./file1",O_RDWR);
if(fd==-1)
{
printf("open file failed\n");
}
n_write=write(fd,&cnt,sizeof(int));
if(n_write!=-1)
{
printf("write %d success\n",cnt);
}
close(fd);
}
int get_cmd_type(char *get_cmd)
{
if (strstr(get_cmd, "open1"))
return 1;
if (strstr(get_cmd, "close1"))
return 0;
return -1;
}
void cmdHandler(char *pdata, int c_fd)
{
int cmd;
cmd = get_cmd_type(pdata);
printf("%d\n", cmd);
switch (cmd)
{
case open1:
printf("open\n");
openSocket=1;
break;
case close1:
printf("close\n");
openSocket=0;
break;
}
}
double getDistance()
{
pthread_mutex_lock(&mutex);
double dis;
struct timeval time_start;
struct timeval time_stop;
digitalWrite(Trag, LOW);
usleep(5);
digitalWrite(Trag, HIGH);
usleep(10);
digitalWrite(Trag, LOW);
while (!digitalRead(Echo))
;
gettimeofday(&time_start, NULL);
while (digitalRead(Echo))
;
gettimeofday(&time_stop, NULL);
long longTime = 1000000 * (time_stop.tv_sec - time_start.tv_sec) + (time_stop.tv_usec - time_start.tv_usec);
// printf("longTime=%ld\n",longTime);
dis = (double)longTime / 1000000 * 34000 / 2;
pthread_mutex_unlock(&mutex);
return dis;
}
void signal_handler(int signum)
{
if (i <= jd)
{
digitalWrite(SG90pin, HIGH);
j++;
}
else
{
digitalWrite(SG90pin, LOW);
}
if (j > 20000)
{
printf("hello\n");
digitalWrite(BEEP, LOW);
sleep(5);
digitalWrite(BEEP, HIGH);
j = 0;
}
if (i == 40)
{
i = 0;
}
i++;
}
void SG90Init()
{
struct itimerval itv;
// 1.设定定时时间
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 500;
// 2.设定开始生效,启动定时器的时间
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
// 3.设定定时方式
if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
{
perror("error");
exit(-1);
}
// 4.信号处理
signal(SIGALRM, signal_handler);
}
void *socket_cmd()
{
while (1)
{
memset(msg, 0, sizeof(msg));
n_read = read(c_fd, msg, sizeof(msg));
if (n_read == 0)
{
printf("clinet out\n");
break;
}
else if (n_read > 0)
{
printf("read data\n");
cmdHandler(msg, c_fd);
}
}
}
void *revhandler()
{
char cmd;
while (1)
{
cmd = myserialGetchar(fd);
printf("cmd=%c\n", cmd);
switch (cmd)
{
case 'A':
printf("kaigai\n");
openUart = 1;
break;
case 'B':
printf("guanggai\n");
openUart = 0;
break;
}
}
}
void *SG90Fun()
{
while (1)
{
dis = getDistance();
if (dis < 10 || openUart == 1 || openSocket==1)
{
//printf("open\n");
openDusbin();
cnt++;
save_SQL_Open(cnt);
save_File_Open(cnt);
}
else if (openUart == 0 || openSocket ==0)
{
//printf("close\n");
closeDusbin();
cnt++;
save_SQL_Close(cnt);
save_File_Close(cnt);
}
usleep(50000);
}
}
void *oledhandler()
{
while (1)
{
dis = getDistance();
if (dis < 10 || openUart == 1 || openSocket==1)
{
//printf("open\n");
oled_show_open(&disp);
}
else if (openUart == 0 || openSocket ==0)
{
//printf("close\n");
oled_show_close(&disp);
}
usleep(50000);
}
}
int main(int argc, char **argv)
{
int s_fd;
pthread_t socket_t;
pthread_t rev_t;
pthread_t sg90_t;
pthread_t oled_t;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
memset(&s_addr, 0, sizeof(struct sockaddr_in));
memset(&c_addr, 0, sizeof(struct sockaddr_in));
if (argc < 4)
{
printf("params is no ok\n");
exit(-1);
}
strcpy(deviceName, argv[1]);
memset(&disp, 0, sizeof(disp));
sprintf(filename, "%s", argv[2]);
disp.address = OLED_I2C_ADDR;
disp.font = font2;
wiringPiSetup();
SG90Init();
pinMode(BEEP, OUTPUT);
pinMode(SG90pin, OUTPUT);
pinMode(Trag, OUTPUT);
pinMode(Echo, INPUT);
oled_open(&disp, filename);
oled_init(&disp);
if ((fd = myserialOpen(deviceName, 115200)) == -1)
{
printf("open %s error\n", deviceName);
return -1;
}
// 1.socket
s_fd = socket(AF_INET, SOCK_STREAM, 0);
if (s_fd == -1)
{
perror("socket");
exit(-1);
}
// 2.bind
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[4]));
inet_aton(argv[3], &s_addr.sin_addr);
bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));
// 3.listen
listen(s_fd, 10);
pthread_mutex_init(&mutex, NULL);
pthread_create(&rev_t, NULL, revhandler, NULL);
pthread_create(&sg90_t, NULL, SG90Fun, NULL);
pthread_create(&oled_t,NULL,oledhandler,NULL);
int len = sizeof(struct sockaddr_in);
while (1)
{
// 4.accept
c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &len);
if (c_fd == -1)
{
perror("accept:");
}
printf("get connect:%s\n", inet_ntoa(c_addr.sin_addr));
pthread_create(&socket_t, NULL, socket_cmd, NULL);
}
pthread_join(rev_t, NULL);
pthread_join(socket_t, NULL);
pthread_join(sg90_t, NULL);
pthread_join(oled_t,NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
uartTool.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "wiringSerial.h"
int myserialOpen (const char *device, const int baud)
{
struct termios options ;
speed_t myBaud ;
int status, fd ;
switch (baud)
{
case 9600: myBaud = B9600 ; break ;
case 115200: myBaud = B115200 ; break ;
}
if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
return -1 ;
fcntl (fd, F_SETFL, O_RDWR) ;
tcgetattr (fd, &options) ;
cfmakeraw (&options) ;
cfsetispeed (&options, myBaud) ;
cfsetospeed (&options, myBaud) ;
options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;
options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
tcsetattr (fd, TCSANOW, &options) ;
ioctl (fd, TIOCMGET, &status);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ; // 10mS
return fd ;
}
void serialSendString (const int fd, const char *s)
{
int ret;
ret = write (fd, s, strlen (s));
if (ret < 0)
printf("Serial Puts Error\n");
}
int serialGetString ( int fd,char *buffer)
{
int n_read;
n_read=read (fd, buffer,32);
return n_read;
}
char myserialGetchar (const int fd)
{
char x ;
if (read (fd, &x, 1) != 1)
return -1 ;
return x ;
}
uartTool.h
```c
int myserialOpen (const char *device, const int baud);
void serialSendString (const int fd, const char *s);
int serialGetString ( const int fd,char *buffer);
char myserialGetchar (const int fd);
client.c
#include<stdio.h>
#include<sys/types.h> /* See NOTES */
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char **argv)
{
int c_fd;
int ret;
struct sockaddr_in c_addr;
char msg[128]={0};
memset(&c_addr,0,sizeof(struct sockaddr_in));
if(argc!=3)
{
printf("params is no good\n");
exit(-1);
}
//1.socket
c_fd=socket(AF_INET,SOCK_STREAM,0);
if(c_fd==-1)
{
perror("socket");
exit(-1);
}
printf("socket\n");
//2.connect
c_addr.sin_family=AF_INET;
c_addr.sin_port=htons(atoi(argv[2]));
inet_aton(argv[1],&c_addr.sin_addr);
printf("wait\n");
if(connect(c_fd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr_in))==-1)
{
perror("connect");
exit(-1);
}
printf("connect....\n");
while(1)
{
memset(msg,0,sizeof(msg));
printf("input: \n");
fgets(msg, 128, stdin);
write(c_fd,msg,strlen(msg));
}
close(c_fd);
return 0;
}
编译指令:
服务端:
gcc socketseverdemo.c uartTool.c -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt -o server
sudo ./server /dev/ttyS5 /dev/i2c-3 127.0.0.1 8989
客户端
sudo client 127.0.0.1 8989
项目总结:这个项目能锻炼到linux的文件编程,进程,进程间通信(定时器的信号),线程,网络,数据库,还是可以学到很多东西。在做项目的过程中,可以把每一个模块的demo整合。
在这里在做一个笔记
把链表的数据写进数据库:
#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
#include <string.h>
struct Test
{
int data;
struct Test *next;
};
struct Test *insertFromhead(struct Test *head, struct Test *new)
{
struct Test *point = head;
if (head == NULL)
{
head = new;
return head;
}
while (point->next != NULL)
{
point = point->next;
}
point->next = new;
return head;
}
struct Test *creatLink(struct Test *head)
{
struct Test *new = NULL;
int i;
int num;
printf("please create link\n");
scanf("%d", &num);
for (i = 0; i < num; i++)
{
new = (struct Test *)malloc(sizeof(struct Test));
new->next = NULL;
printf("please input NO %d Link data\n", i + 1);
scanf("%d", &(new->data));
head = insertFromhead(head, new);
}
return head;
}
void printLink(struct Test *head)
{
struct Test *point = head;
while (point != NULL)
{
printf("%d ", point->data);
point = point->next;
}
putchar('\n');
}
int callback(void *arg, int column_size, char *column_value[], char *column_name[])
{
int i;
struct Test *head = NULL;
head = (struct Test *)arg;
while (head != NULL)
{
for (i = 0; i < column_size; i++)
{
printf("%s=%s\n", column_name[i], column_value[i]);
}
printf("=================================\n");
head = head->next;
}
return 0;
}
void save_SQL(struct Test *head)
{
struct Test *point = head;
sqlite3 *db = NULL;
char *errmsg = NULL;
char buf[128] = {0};
int ret = 0;
ret = sqlite3_open("link.db", &db);
if (ret)
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}
else
{
fprintf(stdout, "Opened database successfully\n");
}
sprintf(buf, "create table base (ID Integer)");
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("create table error:%s,ret=%d\n", errmsg, ret);
}
while (point != NULL)
{
memset(buf, 0, 128);
sprintf(buf, "insert into base values (%d)", point->data);
sqlite3_exec(db, buf, NULL, NULL, NULL);
point = point->next;
}
sqlite3_close(db);
}
void read_SQL(struct Test *head)
{
sqlite3 *db = NULL;
char *errmsg = NULL;
char buf[128] = {0};
int ret = 0;
ret = sqlite3_open("link.db", &db);
if (ret)
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}
else
{
fprintf(stdout, "Opened database successfully\n");
}
sprintf(buf, "select * from base");
ret = sqlite3_exec(db, buf, callback, (void *)head, &errmsg);
if (ret != SQLITE_OK)
{
printf("create table error:%s,ret=%d\n", errmsg, ret);
}
sqlite3_close(db);
}
int main()
{
struct Test *head = NULL;
head = creatLink(head);
printLink(head);
// 把链表得数据插入数据库
save_SQL(head);
// 查询数据库中得数据
read_SQL(head);
return 0;
}
把链表的数据写进文件
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
struct Test
{
int data;
struct Test *next;
};
struct Test* insertFormHead(struct Test *head,struct Test *new)
{
struct Test* point=head;
if(point==NULL)
{
head=new;
return new;
}
while(point->next!=NULL)
{
point=point->next;
}
point->next=new;
return head;
}
struct Test* creatLink(struct Test *head)
{
struct Test *new=NULL;
int i;
int num;
printf("please input link data\n");
scanf("%d",&num);
for(i=0;i<num;i++)
{
new=(struct Test*)malloc(sizeof(struct Test));
new->next=NULL;
printf("please input NO %d link data\n",i+1);
scanf("%d",&(new->data));
head=insertFormHead(head,new);
}
return head;
}
void printLink(struct Test *head)
{
struct Test *point=head;
while(point!=NULL)
{
printf("%d ",point->data);
point=point->next;
}
putchar('\n');
}
void saveLink(struct Test *head)
{
struct Test *point=head;
int fd;
fd=open("./file2",O_RDWR);
if(fd==-1)
{
printf("open file failed\n");
}
while(point!=NULL)
{
if((write(fd,&point->data,sizeof(struct Test)))==-1)
{
printf("write failed\n");
}
point=point->next;
}
close(fd);
}
void readLink(struct Test *head)
{
struct Test *point=head;
int fd;
int n_read;
int n_write;
int fd1;
struct Test *buf=NULL;
fd=open("./file2",O_RDWR);
if(fd==-1)
{
printf("open file failed\n");
}
int size=lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
buf=(struct Test*)malloc(sizeof(struct Test)*size+8);
printf("open file2 success\n");
while(point!=NULL)
{
n_read=read(fd,buf,sizeof(struct Test));
printf("buf:%d ",point->data);
if(n_read==-1)
{
printf("read failed\n");
}
fd1=open("./file3",O_RDWR);
if(fd1==-1)
{
printf("open failed\n");
}
n_write=write(fd1,buf,sizeof(struct Test));
if(n_write==-1)
{
printf("write failed\n");
}
point=point->next;
}
close(fd);
close(fd1);
}
int main()
{
struct Test *head=NULL;
head=creatLink(head);
printLink(head);
saveLink(head);
readLink(head);
return 0;
}
最后两个功能需求可以按照这两个demo整合;比如,把蜂鸣器的响的次数写进数据库和文件
demo
#include<stdio.h>
#include<sqlite3.h>
#include<wiringPi.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BEEP 2 // 设置2引脚为蜂鸣器控制引脚
void save_SQL(int cnt)
{
sqlite3 *db = NULL;
char *errmsg = NULL;
char buf[128] = {0};
int ret = 0;
ret = sqlite3_open("orange.db", &db);
if (ret)
{
fprintf(stderr, "Can't open orangebase: %s\n", sqlite3_errmsg(db));
exit(0);
}
else
{
fprintf(stdout, "Opened database successfully\n");
}
sprintf(buf, "create table orangebase (ID Integer)");
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("create table error:%s,ret=%d\n", errmsg, ret);
}
memset(buf, 0, 128);
sprintf(buf, "insert into orangebase values (%d)",cnt);
sqlite3_exec(db, buf, NULL, NULL, NULL);
sqlite3_close(db);
}
void save_File(int cnt)
{
int fd;
int n_write;
fd=open("./file2",O_RDWR);
if(fd==-1)
{
printf("open file failed\n");
}
n_write=write(fd,&cnt,sizeof(int));
if(n_write!=-1)
{
printf("write %d success\n",cnt);
}
close(fd);
}
int main()
{
int cnt=0;
int i;
wiringPiSetup(); // 初始化wriping库
pinMode(BEEP,OUTPUT); // 设置蜂鸣器为输出引脚
for(i=0;i<5;i++)
{
digitalWrite(BEEP, LOW);
cnt++;
save_SQL(cnt);
save_File(cnt);
sleep(1);
}
digitalWrite(BEEP, HIGH);
return 0;
}