基于树莓派上实现的智能垃圾桶

基于树莓派上实现的智能垃圾桶

整体功能

垃圾桶分为移动模式和清洁桶模式,移动模式垃圾桶通过电机操作马达轮子进行移动,清洁桶模式则LED屏幕亮起,检测温度,自动拉起桶盖,整体通过远程利用客户端进行控制。

LED屏的实现

oled.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "wd.h"
int fd;
unsigned char  yi[4][16]={
"                ",//第一行
"                ",//第二行
"                ",//第三行
"                " //第四行
};               //显示内容
const unsigned char zi[];
void initoled(void)//初始化
{
	wiringPiSetup();
        fd=wiringPiI2CSetup(0x3c);//i2c初始化 0x3c是oled的从机地址
        wiringPiI2CWriteReg8(fd,0x00,0xa1);//图像反了修改成0xa0
        wiringPiI2CWriteReg8(fd,0x00,0xc8);//行输出反了修改成0xc0
        wiringPiI2CWriteReg8(fd,0x00,0x8d);//允许电荷泵
        wiringPiI2CWriteReg8(fd,0x00,0x14);
        wiringPiI2CWriteReg8(fd,0x00,0xa6);//想反相显示改成0xa7
	wiringPiI2CWriteReg8(fd,0x00,0x21);//重置列地址
	wiringPiI2CWriteReg8(fd,0x00,0x00);
	wiringPiI2CWriteReg8(fd,0x00,0x7f);
    wiringPiI2CWriteReg8(fd,0x00,0xaf);//开显示
	
	 system("sudo modprobe w1-gpio");
	 system("sudo modprobe w1-therm");
}
void qingping(void)//清屏
{
	char zt1,zt2;
	for(zt1=0;zt1<8;zt1++)
	{
		wiringPiI2CWriteReg8(fd,0x00,0xb0+zt1);
	        for(zt2=0;zt2<128;zt2++) wiringPiI2CWriteReg8(fd,0x40,0x00);
	}
}
void ascii(void)//显示ASCII码8*16
{
	int zt;
        char zt3,zt4;
	for(zt3=0;zt3<4;zt3++)
        {
		wiringPiI2CWriteReg8(fd,0x00,0xb0+(zt3*2));
                for(zt4=0;zt4<16;zt4++)
			for(zt=0;zt<8;zt++)
                wiringPiI2CWriteReg8(fd,0x40,zi[yi[zt3][zt4]*16+zt]);
                wiringPiI2CWriteReg8(fd,0x00,0xb0+(zt3*2)+1);
                for(zt4=0;zt4<16;zt4++)
                	for(zt=0;zt<8;zt++)
                        	wiringPiI2CWriteReg8(fd,0x40,zi[yi[zt3][zt4]*16+zt+8]);
	}
}
void wendu(void)//调用温度函数
{
	float value;
	char buf[100];
	value=wd();
	gcvt(value, 5, buf);
	
    strcpy(yi[0],buf);
}

void shijian(void)//当前时间
{
    struct tm *ptr;
    time_t lt;
	FILE *f;
	char data[255];
    lt=time(<);
    ptr=localtime(<);
    strftime(yi[1],16,"%m/%d %a",ptr); //月/日 周几
	strftime(yi[2],16,"%R %p",ptr);//时:分 am或pm
	
	
}
void oled(void)
{
	while(1)
	{
		
		
		shijian();
		wendu();
		ascii();
		delay(100);
	}
	
}

这是利用SSD1306的0.91OLED模块通过以上代码实现显示在LED屏幕,温度函数这是利用DS18B20通过以下代码显示在LED屏
wd.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 

float wd(void)
{
        char path[50] = "/sys/bus/w1/devices/";
        FILE *f;
        char rom[20];
        char buf[100];
        char cat[100];
        DIR *dirp;
        struct dirent *direntp;
        float value;
        char *get;
        get=malloc(sizeof(char));
        memset(cat,0,100);
        memset(buf,0,100);
        stpcpy(cat,"cat ");
        if((dirp = opendir(path)) == NULL)
        {
                printf("opendir error\n");
                exit(-1);
        }
        while((direntp = readdir(dirp)) != NULL)
        {
                if(strstr(direntp->d_name,"28-0"))
                {
                        strcpy(rom,direntp->d_name);
                }
        }
        closedir(dirp);
        strcat(path,rom);
        strcat(path,"/w1_slave");
        strcat(cat,path);
        if((f = popen(cat,"r")) < 0)
        {
                printf("open error\n");
                exit(-1);
        }
        fread(buf,1,100,f);
        get=strstr(buf,"t=");
        fclose(f);
        get++;
        get++;
        value = atof(get)/1000;
        return value;
}

电机

dj.c

#include 
#include 
int i;
void initdj()
{
        pinMode(22,OUTPUT);
        pinMode(23,OUTPUT);
        pinMode(24,OUTPUT);
        pinMode(25,OUTPUT);

        digitalWrite(22,LOW);
        digitalWrite(23,LOW);
        digitalWrite(24,LOW);
        digitalWrite(25,LOW);
}
void qian()
{
        digitalWrite(22,HIGH);
        digitalWrite(23,LOW);
        digitalWrite(24,HIGH);
        digitalWrite(25,LOW);
        while(1)
        {
                if(i==1)
                {
                        digitalWrite(22,LOW);
                        digitalWrite(23,LOW);
                        digitalWrite(24,LOW);
                        digitalWrite(25,LOW);
                        break;
                }
        }
}
void hou()
{
        digitalWrite(22,LOW);
        digitalWrite(23,HIGH);
        digitalWrite(24,LOW);
        digitalWrite(25,HIGH);
        delay(10000);
        digitalWrite(22,LOW);
        digitalWrite(23,LOW);
        digitalWrite(24,LOW);
        digitalWrite(25,LOW);


}
void zhou
{
		  digitalWrite(22,LOW);
	      digitalWrite(23,HIGH);
	      delay(10000);
	      digitalWrite(22,LOW);
       	  digitalWrite(23,LOW);
}
void you 
{
		  digitalWrite(24,LOW);
	      digitalWrite(25,HIGH);
	      delay(10000);
	      digitalWrite(24,LOW);
       	  digitalWrite(25,LOW);
}

舵机

sg.c

#include 
#include 
#include 
#include 
extern int i;
extern int o;

void initsg()
{
        pinMode(1,PWM_OUTPUT);
        pwmSetMode(PWM_MODE_MS);
        pwmSetRange(2000);
        pwmSetClock(192);
}
void sg()
{
        while(1)
        {
                if(i==1)
                pwmWrite(1,100);
                else if(i==0)
                pwmWrite(1,200);
                if(o==0)
                pthread_exit((void*)0);
        }
}

客户端

#include 
#include  "log.h"
#include 
#include          
#include 
#include 
#include 
#include 
#include 
#include "msg.h"
#include "util.h"


int get_cmd(char *buf)
{
	if (memcmp(buf,"yd",2)==0)
	{
	   	return 0;
	}
	else if (memcmp(buf,"qjt",3)==0)
	{
	   	return 1;
	}
	else if (memcmp(buf,"qian",4)==0)
	{
	   	return 2;
	}
	else if (memcmp(buf,"quit",4)==0)
	{
	   	return 4;
	}
	else if (memcmp(buf,"hou",3)==0)
	{
	   	return 3;
	}
	else 
	{
	   	return 5;

	}	

    
}



int main()
{
	int c_fd;
    enum FTP_CMD cmd;
    int	ret;
	struct sockaddr_in c_addr;
	int con;

	logcreate("./client.txt");

	struct Msg *msg_send;
	struct Msg *msg_recv;
	msg_send = (struct Msg *)malloc(sizeof(struct Msg));
    msg_recv = (struct Msg *)malloc(sizeof(struct Msg));
	c_fd=socket(AF_INET,SOCK_STREAM,0);
	if (c_fd==-1) 	
	{
		logwrite("perror connect: %s",c_fd);
		exit(-1);
	}

	c_addr.sin_family=AF_INET;
	c_addr.sin_port=htons(8989);
	inet_aton("192.168.43.60", &c_addr.sin_addr);



	con=connect(c_fd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr));
	if (con==-1)
	{
		logwrite("perror connect: %d",con);
		exit(-1);
	}

	struct password dl;
	printf("name:");
	scanf("%s",dl.name);
	printf("pass:");
	scanf("%s",dl.pass);
	logwrite("nmae:%s  pass%s\n",dl.name,dl.pass);
	ret=send2(c_fd,(char *)&dl,sizeof(struct password));
	logwrite("perror send: %d\n",ret);
	ret=recv(c_fd,&dl,sizeof(struct password),0);
	logwrite("perror recv: %d\n",ret);
	if (FTP_CMD_ERROR==dl.cmd)
	{
		printf("name or pass error\n");
		return -1;
	}
	while(1)
	{

		char buf[256];
		memset(msg_send,0,sizeof(struct Msg));
		memset(msg_recv,0,sizeof(struct Msg));
        // 等待用户输入
        fgets(buf,sizeof(buf),stdin);
        logwrite("get:%s",buf);
        // buf转为FTP_CMD
        cmd = get_cmd(buf);
        logwrite("cmd %d\n", cmd);		
		msg_send->cmd=cmd;		
		send2(c_fd,(char *)msg_send,sizeof(struct Msg));
		recv2(c_fd,(char *)msg_recv,sizeof(struct Msg));
		printf("%s\n",msg_recv->data);
		if (cmd==FTP_CMD_QUIT)
		{
			break;
		}
	}
	
	
	logout();
	close(c_fd);
	return 0;
}

服务端

#include 
#include "a.h"
#include "dj.h"
#include "oled.h"
#include "log.h"
#include "msg.h"
#include "util.h"
#include "sg.h"
#include 
#include          
#include 
#include 
#include 
#include 
#include 
#include 


int i=0;
int o=1;

void yd(int c_fd)//移动模式
{
	struct Msg *msg_send;
	struct Msg *msg_recv;
	msg_send = (struct Msg *)malloc(sizeof(struct Msg));
    msg_recv = (struct Msg *)malloc(sizeof(struct Msg));
    memset(msg_send,0,sizeof(struct Msg));
	memset(msg_recv,0,sizeof(struct Msg));
	strcpy(msg_send->data,"please output qian or hou or quit");
	send2(c_fd,(char *)msg_send,sizeof(struct Msg));
	while(1)
	{
		memset(msg_send,0,sizeof(struct Msg));
		memset(msg_recv,0,sizeof(struct Msg));
		recv2(c_fd,(char *)msg_recv,sizeof(struct Msg));
		if (msg_recv->cmd==2)
		{
			qian();
			send2(c_fd,(char *)msg_send,sizeof(struct Msg));
		}
		else if (msg_recv->cmd==3)
		{
			hou();
			send2(c_fd,(char *)msg_send,sizeof(struct Msg));
		}
		else if (msg_recv->cmd==4)
		{
			msg_recv->cmd=9;
			break;
		}
		else 
		{
			strcpy(msg_send->data,"please output qian or hou or quit");
			send2(c_fd,(char *)msg_send,sizeof(struct Msg));			
		}
	}

}

void qjt(int c_fd)//清洁桶模式
{	
	pthread_t thread1;
	pthread_t thread2;
	struct Msg *msg_send;
	struct Msg *msg_recv;
	msg_send = (struct Msg *)malloc(sizeof(struct Msg));
    msg_recv = (struct Msg *)malloc(sizeof(struct Msg));
    memset(msg_send,0,sizeof(struct Msg));
	memset(msg_recv,0,sizeof(struct Msg));
	strcpy(msg_send->data,"please output qian or hou or quit");
	send2(c_fd,(char *)msg_send,sizeof(struct Msg));
	pthread_create(&thread1,NULL,(void *)oled,NULL);
	pthread_create(&thread2,NULL,(void *)sg,NULL);
	while(1)
	{
		memset(msg_send,0,sizeof(struct Msg));
		memset(msg_recv,0,sizeof(struct Msg));
		printf("1111\n");
		recv2(c_fd,(char *)msg_recv,sizeof(struct Msg));
		printf("1111\n");
		if (msg_recv->cmd==FTP_CMD_QUIT)
		{
			msg_recv->cmd=9;
			o=0;
			break;
		}

	}
}

void chuli(struct Msg * get_cmd,int c_fd)
{

	switch(get_cmd->cmd)
	{
	case FTP_CMD_YD:
		yd(c_fd);
		break;
	case FTP_CMD_QJT:
		qjt(c_fd);
		break;
	default:
		break;		
	}
}


int main()
{
	int s_fd;
	int c_fd;
	int ret;
	int ret2;
	struct sockaddr_in s_addr;
	struct sockaddr_in c_addr;
	struct Msg *msg_send;
	struct Msg *msg_recv;
	msg_send = (struct Msg *)malloc(sizeof(struct Msg));
    msg_recv = (struct Msg *)malloc(sizeof(struct Msg));
    memset(msg_send,0,sizeof(struct Msg));
	memset(msg_recv,0,sizeof(struct Msg));
	pthread_t thread;
	
	logcreate("./server.txt");
	//1.socket
	s_fd=socket(AF_INET,SOCK_STREAM,0);
	if(s_fd==-1)
	{
		logwrite("perror bind: %s",s_fd);
		exit(-1);
	}
	int on=1;
	if((setsockopt(s_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)))<0)
	{
		perror("setsockopt failed");
		exit(EXIT_FAILURE);
	}
	//2.bind
	s_addr.sin_family=AF_INET;
	s_addr.sin_port=htons(8989);
	s_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	ret=bind(s_fd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr_in));
	if (ret==-1)
	{
		logwrite("perror bind: %s",ret);
		exit(-1);
	}
	//3.listen
	ret2=listen(s_fd,10);
	if (ret2==-1)
	{
		logwrite("perror listen: %s",ret2);
		exit(-1);
	}
	//4.accpet
	int len=sizeof(struct sockaddr);
	c_fd=accept(s_fd,(struct sockaddr*)&c_addr, (socklen_t *)&len);
		if (c_fd==-1)
		{
			logwrite("perror accpet: %s",c_fd);
			exit(-1);
		}
	struct  password *dl;
	dl=malloc(sizeof(struct  password ));
	char name[64];
	char passw[64];
	recv2(c_fd,(char *)dl,sizeof(struct password));
	printf("%s   %s\n",dl->name,dl->pass);
	dl->cmd=FTP_CMD_YD;
	logwrite("nmae:%s  pass%s\n",dl->name,dl->pass);
	FILE *fd=fopen("passw.txt","r");

	if (NULL!=fd)
	{
		fscanf(fd,"%s %s",name,passw);
		
		fclose(fd);
	}
	if (strcmp(name,dl->name)!=0||strcmp(passw,dl->pass)!=0)
	{
		dl->cmd=FTP_CMD_ERROR;
	}
	send2(c_fd,(char *)dl,sizeof(struct password));
	if (dl->cmd==FTP_CMD_ERROR)
	{
		exit(-1);
	}
	initoled();//初始化
	qingping();
	initcsb();
	initdj();
	initsg();
	pthread_create(&thread,NULL,(void *)csb,NULL);
	while(1)
	{
	
		memset(msg_send,0,sizeof(struct Msg));
		memset(msg_recv,0,sizeof(struct Msg));
		recv2(c_fd,(char *)msg_recv,sizeof(struct Msg));
		chuli(msg_recv,c_fd);
		strcpy(msg_send->data,"please output yd or qjt ");
		send2(c_fd,(char *)msg_send,sizeof(struct Msg));
		if (msg_recv->cmd==FTP_CMD_QUIT)
		{
			printf("client quit\n");
			logwrite("client quit\n");
			break;
		}

	}
	
	close(s_fd);
	logout();
	
	return 0;
}

整套程序通过用户登录服务端,服务端接收指令来对垃圾桶进行操作。

感想

这个项目做了三天,三天来最大的问题在与一开始对于每个模块的不熟悉,以及网上对这些模块资料的不多,大多数都是用python写的C的资料较少,必须通过更多的实验来了解这些模块,还有就是对于线程的一些不熟悉导致有些问题会不能迅速解决,但幸好有日志,可以通过日志迅速的了解问题出在哪,在改程序的时候省下了不少时间。

你可能感兴趣的:(基于树莓派上实现的智能垃圾桶)