全志H3垃圾桶

该系统使用全志H616芯片,集成超声波模块检测距离、舵机控制垃圾桶开关、语音模块、蜂鸣器以及OLED显示屏。功能包括手接近自动开启、延时警报、语音控制和远程Socket通信。同时,系统记录开关盖次数,存储到SQLite数据库和文件中。
摘要由CSDN通过智能技术生成

基于全志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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值