树莓派控制的智能垃圾桶项目

技术不断的革新,对于生活的享受也越来越注重了。下面我们开始今天的主题。

项目用到的硬件:
树莓派3b
HC-SRO4超声波模块
sg90舵机
ds18b20温度模块
oled模块
两个电机
l9110s桥两路直流电机驱动板
垃圾桶一个

项目总体步骤和规划:
架构:
树莓派(服务端)
linux虚拟机(客户端)
功能设计:
1移动的功能:
通过虚拟机的指令来操控垃圾桶的移动
2 oled显示屏功能
温湿度 , 时间 , 树莓派IP
3 超声波模块
识别手扔垃圾的动作
识别障碍物
4温湿度传感器
读取当前环境的温湿度
5 SG90舵机
打开清洁桶的盖子
6. 马达及轮子
通过热熔胶黏在筒底部,

项目用到的知识:
多线程及锁
将(温度模块,oled模块)和(超声波模块,舵机,l9110s模块)分别用线程。

tcpip网络编程
在Linux虚拟机和树莓派中实现,树莓派作为服务端,虚拟机作为客服端发送命令

文件操作——日志模块
遇到问题可以查询出现问题的所在地。

下面开始我们项目的实现:
首先我开始实现oled模块:详细的实现过程
https://blog.csdn.net/weixin_43664986/article/details/100110422
实现了温度,树莓派ip和时间的显示
下面是个人在实现中遇到的问题和解决:
1在操作过程中,无法获取i2c地址,可以尝试开开模块的接触问题

ds18b20模块实现的详细过程:
https://blog.csdn.net/jcdjx/article/details/23338239
可将上文地址中的代码改动,将温度传给oled模块显示实现温度模块的功能
个人在实现中遇到的问题和解决:
1在进行配置是未能显示和不能找的w1的文件夹,通过找的资料明白需要打开
串口1-wire
2在进行内核升级是网速过慢,可以进行更换国内的镜像源

超声波模块的测距实现识别障碍物和识别扔垃圾的动作:
超声波详情参考:https://blog.csdn.net/weixin_43664986/article/details/100072558
同超声波得到的距离,分别进行垃圾桶的前进转弯停止和识别扔东西的动作。
l9110s详细参考:
https://blog.csdn.net/weixin_43664986/article/details/100147723

通过得到距离进行判断,如果距离大于1小于10进行左转弯操作,如果距离小于1和小于1900 进行停止操作(这里说一下当紧贴这超声波模块的时候传出来的距离是小于1或者非常大的,这个可能和她模块有关,这里就不深究了),其他进行停止操作

问题和解决:
1用l9110s模块的时候需要用5v的电源,3v的电源无法供应。这个一定要注意,不能即使自己操作没错,电机也不会旋转的。

sg90舵机详细参考:
https://blog.csdn.net/weixin_43664986/article/details/100170170
通过判断距离,如果大于0小于20进行sg90舵机180读旋转打开垃圾桶的盖子

通过客户端输入命令1(前进),2(后退),3(左),4(右),0(停止)
服务端接收命令实行以上的操作

架构client代码:
#include
#include
#include
#include
#include
#include
#include
#include “log.h”
#include “msg.h”
#include “utils.h”
#define SERVER_PORT 8888

int main(int argc, char **argv) {
log_create(“myclient.txt”);
int c_fd;
int ret;
int data;
struct sockaddr_in c_addr;
c_fd = socket(AF_INET, SOCK_STREAM, 0);
// 2. 初始化服务端地址, ip, port
memset(&c_addr, 0, sizeof(c_addr));
c_addr.sin_family = AF_INET;
c_addr.sin_port = SERVER_PORT;
c_addr.sin_addr.s_addr = inet_addr(“172.20.10.3”);
//连接
ret = connect(c_fd, (struct sockaddr *)&c_addr, sizeof(struct sockaddr));
if (ret < 0) {
log_write(“connect fail ,ret=%d”, ret);
return -1;
}
while (1) {
// 1.等待用户输入
printf(“指令介绍:1前进,2后退,3左,4右,0停止\n”);
printf(“请输入指令\n”);
scanf("%d",&data);
// 2.发送
ret = send(c_fd, &data, sizeof(int), 0);
log_write(“send ret=%d\n”, ret);
// 3.接受
//ret = recv(c_fd, msg_recv, sizeof(struct Msg), 0);
//log_write(“msg_recv->cmd=%d\n”, msg_recv->cmd);
}
log_destroy();
return 0;
}
服务端:
#include
#include
#include
#include
#define SERVER_PORT 8888
float wd;
float dis;
void *fun1(void *arg) {
while (1) {
wd = wendu();
oled(wd);
}
}
void *fun2(void *arg) {
while (1) {
dis = csb();
sg90();
}
}

int main() {
int ret;
pthread_t t1;
pthread_t t2;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
int data;
memset(&s_addr, 0, sizeof(struct sockaddr_in));
int s_fd;
int c_fd;
log_create(“myserve.txt”);
s_fd = socket(AF_INET, SOCK_STREAM, 0);
if (s_fd == -1) {
log_write(“socket error\n”);
exit(-1);
}
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = SERVER_PORT;
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int on = 1;
setsockopt(s_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
ret = bind(s_fd, (struct sockaddr *)&s_addr, sizeof(s_addr));
if (ret < 0) {
log_write(“bind failed, ret=%d\n”, ret);
return -1;
}
ret = listen(s_fd, 10);
if (ret < 0) {
log_write(“listen failed, ret=%d\n”, ret);
return -1;
}
int clen = sizeof(struct sockaddr_in);
c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &clen);
if (c_fd == -1) {
log_write(“write faail ,ret=%d\n”, ret);
return -1;
}
log_write(“client connect\n”);
ret = pthread_create(&t1, NULL, fun1, NULL);
if (ret != 0) {
printf(“t1 create fail\n”);
}
ret = pthread_create(&t2, NULL, fun2, NULL);
if (ret != 0) {
printf(“t2 create fail\n”);
}
while (1) {
// 1.接受客户端命令
ret = recv(c_fd, &data, sizeof(int), 0);
log_write(“ret=%d\n”, ret);
// 2.处境客户端命令
if(data1){
l9110(1);
}else if(data
2){
l9110(2);
}else if(data0){
l9110(0);
}else if(data
3){
l9110(3);
}else if(data==4){
l9110(4);
}else{
return -1;
}
}
pthread_join(t1, NULL);
pthread_join(t2, NULL);
log_destroy();
return 0;
}

你可能感兴趣的:(树莓派控制的智能垃圾桶项目)