智能垃圾分类系统

img

一、前言

如果喜欢我的作品或者喜欢电子创作可通过立创EDA开源平台搜索:”小辉辉”,相互交流,相互促进。

Arduino认识之路

这次制作的东西是智能垃圾桶,这次是智能分类垃圾桶的第二个版本,整体项目硬件部分大多是以模块为主,主要重心还是放在类软件部分。
说下自己学习硬件编程心路,就能明白我为什么做这个教程。大一的时候接触到编程,做的第一个作品是心型灯,使用51单片机的方案,其实就是自己焊接电路板,用现成的程序。后来寒假的时候自己想做一个扫地机器人,但是苦于C语言不熟练,51单片机编程复杂,中间走了很多弯路,一直被搁置,后来学习了STM32和实时操作系统,再到后来的树莓派等。

后来我想如果我能早点接触到Arduino,借助Arduino丰富的开源库,把精力放在好的创意上,而不是复杂的编程上,是不是能做出很多有趣的作品?通过有趣的作品获取信心然后再学习复杂的硬件编程,是不是能学的更加高效呢?

我想通过这个教程在没有任何软件以及硬件基础的前提,使用Arduino花费极低的代价学习软硬件编程基础知识,实现自己的创意。

第一次接触Arduino是在大一的时候,距离现在已经五年,当时一个简单的“电子琴”项目就让我抓耳挠腮,根本不具备“面向百度编程”能力的我,用老师提供的文档跟我的组员用了好几天,才让Arduino跟蜂鸣器想起 一首简单版的《小星星》。当时内心的喜悦以及在舍友面前装X的沙雕模样仿佛还在昨日。

因为Arduino容易入门,而且能让初学者快速体验到单片机开发的乐趣,因此用一个小栏目分享一些以前在学校里面做过的小项目,这个项目是智能垃圾桶的初级版本,后续还会用4G通信模组或者Wifi模块(Esp8266/Esp32)等远程控制的中级版本。完全可以完成一个好的课程设计甚至毕业设计。

Arduino之旅的初次见面,感谢批评指正,一起进步!

二、简介

这个一个基于Arduino做的一个语音识别分类智能垃圾桶,我这里用的是Arduino NANO 通过我们说话来对垃圾词语进行分类。比如:垃圾桶(一级指令)易拉罐(垃圾词语),我们通过说话 说出关键字 让语音模块 接收到 —— 语音模块通过串口发指令给Arduino NANO,针对指令Arduino NANO单片机发指令控制指令对应的舵机从而实现对垃圾桶开盖。实现起来其实不难。

本设计是基于单片机的垃圾桶系统,主要实现以下功能:

·可实现通过舵机完成垃圾桶盖的自动开关

·可实现OLED显示垃圾桶是否满了以及开盖状态

·可实现自动定时紫外线灯进行消毒。

·可实现检测人员手势,对垃圾桶盖进行开关。

·可实现当垃圾桶装满时LED灯提示显示:垃圾桶已满。清理完成后,正常运行。

标签:Arduino NANO,语音识别,红外对管,自动消毒

三、制作步骤

材料清单

序号 名称 数量 备注
1 舵机(SG90) 4 180°舵机
2 LD3320 1 语音识别模块
3 Arduino nano 1 主控MCU
4 小垃圾筒 4 小模型垃圾桶

接线

LD3320(语音模块)

*LD3320* *Arduino*
5V 5V
GND GND
RXD D5
TXD D6

舵机

*SG90* *Arduino*
红线 5V
棕线 GND
橙线 D9、D10

3.1硬件部分电路讲解

舵机(SG90)

img

舵机通过接收PWM信号,使其进入内部电路产生一个偏置电压,触发电机通过减速齿轮带动电位器移动,使电压差为零时,电机停转,从而达到伺服的效果。即给舵机一个特定的PWM信号,舵机旋转到特定角度。

舵机的控制,需要一个20ms的时基脉冲,控制高电平时间为0.5ms~2.5ms范围内即可控制舵机在0 ~ 180°转动。

t=0.5ms—————舵机转动到0°

t=1.0ms—————舵机转动到45°

t=1.5ms—————舵机转动到90°

t=2.0ms—————舵机转动到135°

t=2.5ms—————舵机转动到180°

我理解的时间与角度的换算关系为:

高电平时间=0.5ms+(角度/180°)*2ms

手扫感应开关模块

img

品名: 手扫感应开关模块 工作电压: 输入:5-24V,输出 :等于输入电压
输出形式: 开关+指示灯 感应范围: 30-80MM
感应原理: 红外 负载功率: 60W(MAX)
延时关闭时间: 无 即扫即开/关 适用范围: 直流、恒压
负载电流 阻性3A 待机电流 10-15mA VIN:5-24V

我们可以通过手势的遮挡或者手掌划过,使我们无接触的打开垃圾桶。我们通过高低电平来判断当前的状态。

LD3320模块的原理图

img

img

img

这东西就是接收到声音传感器(麦克风)传来的电压信号以后,通过语音芯片里面的寄存器操作,检测什么时候开始,什么时候结束。

代码里面也有特定的语音模块的DSP算法。他能够识别我们的声音是因为我们再发送指令之前就已经将指令写入芯片,然后在信号传送进去以后,信号与芯片里面写好的东西一个一个的进行匹配,然后输出一个相似度最高的信号,程序里面写一个switch语句检测一下指令。

原理图

img

3.2重要器件的说明(非必填项)

img

我这里使用的紫外线灯功率较大,一个灯板在0.8A,注意散热避免过热,或者更改阻值较大的电阻。

3.3原理图和PCB设计说明

img

考虑到供电线很多,我们需要把供电集中到背板上,设计了一个通用的集线板,放在背板上。

3.4结构设计说明

作品中比较重要的是舵机如何推动上方的盖章,从而控制实现打开盖和闭合盖。使用舵机旋转顶开盖子,等杆不顶起时,盖子通过重力盒盖。

img

img

四、软件(非必填项,无软件可不写)

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include <Servo.h>  
#include <Arduino.h>
#include <SoftwareSerial.h>



//--------------引脚定义---------------------

SoftwareSerial softSerial1(6,5); //6为RX,5为TX
SoftwareSerial softSerial2(3,2); //3为RX,5为TX
Servo myservo1; // 定义舵机一
Servo myservo2; // 定义舵机二
Servo myservo3; // 定义舵机一
Servo myservo4; // 定义舵机二


//--------------变量---------------------

unsigned int Trash_state=0; //状态

int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;

//ADC数据
int L_M_ADC1 = 0;
int L_M_ADC2 = 0;
int L_M_ADC3 = 0;
int L_M_ADC4 = 0;
int a; //定义缓存(串口数据)

//函数
void ADC_State(void); //数据更新

void setup() {
/******************舵机初始化********************/
myservo1.attach(10); // D9为舵机一信号口 1号舵机
myservo2.attach(11); // D10为舵机二信号口 2号舵机
myservo3.attach(12); // D9为舵机三信号口 3号舵机
myservo4.attach(13); // D10为舵机四信号口 4号舵机


Serial.begin(9600); //设置波特率
softSerial1.begin(9600); //监听软串口通信
softSerial2.begin(9600); //监听软串口通信


/*****************人体感应************************/
pinMode(4, INPUT); //按键
pinMode(7, INPUT); //按键
pinMode(8, INPUT); //按键
pinMode(9, INPUT); //按键

digitalWrite(4, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);

myservo1.write(90); //舵机一旋转90°
myservo2.write(90); //舵机一旋转90°
myservo3.write(90); //舵机一旋转90°
myservo4.write(90); //舵机一旋转90°

}

void loop() {

ADC_State();
Serial.println("A1:\n");
Serial.println(buttonState1);
Serial.println("\n");
Serial.println("A2:\n");
Serial.println(buttonState2);
Serial.println("\n");

Serial.println("A3:\n");
Serial.println(buttonState3);
Serial.println("\n");
Serial.println("A4:\n");
Serial.println(buttonState4);
Serial.println("\n");
delay(1000);

/***************按键读取********************/
buttonState1 = digitalRead(4);
buttonState2 = digitalRead(7);
buttonState3 = digitalRead(8);
buttonState4 = digitalRead(9);

if (buttonState1 == HIGH) {
// 点亮LED神灯
myservo1.write(90); //舵机一旋转90°
} else {
// 熄灭LED神灯
myservo1.write(0); //舵机一旋转90°
}

if (buttonState2 == HIGH) {
// 点亮LED神灯
myservo2.write(90); //舵机一旋转90°
} else {
// 熄灭LED神灯
myservo2.write(0); //舵机一旋转90°
}

if (buttonState3 == HIGH) {
// 点亮LED神灯
myservo3.write(90); //舵机一旋转90°
} else {
// 熄灭LED神灯
myservo3.write(0); //舵机一旋转90°
}

if (buttonState4 == HIGH) {
// 点亮LED神灯
myservo4.write(90); //舵机一旋转90°
} else {
// 熄灭LED神灯
myservo4.write(0); //舵机一旋转90°
}

ADC_State();
/***************语音设别********************/

softSerial1.listen();
a=softSerial1.read(); //读取串口1的值
switch(a)
{

case 0x01:
Serial.println("召唤");
break;

case 0x02:
Serial.println("可回收垃圾");
myservo1.write(0); //舵机一旋转90°
delay(3000);
myservo1.write(90); //舵机一旋转90°
break;

case 0x03:
Serial.println("厨余垃圾");
myservo2.write(0); //舵机一旋转90°
delay(3000);
myservo2.write(90); //舵机一旋转90°

break;

case 0x04:
Serial.println("有害垃圾");
myservo3.write(0); //舵机一旋转90°
delay(3000);
myservo3.write(90); //舵机一旋转90°

break;

case 0x05:
Serial.println("其他垃圾");
myservo3.write(0); //舵机一旋转90°
delay(3000);
myservo3.write(90); //舵机一旋转90°


default:

break;
}
}

//读取数据状态
void ADC_State()
{
buttonState1 = analogRead(A0);
buttonState2 = analogRead(A1);
buttonState3 = analogRead(A2);
buttonState4 = analogRead(A3);
}

LD3320识别数据汇总

*# 原始数据*

1
2
3
4
5
6
7
可回收垃圾:报纸、塑料瓶、玻璃、易拉罐;      0x01

厨余垃圾:果皮、菜叶、剩饭、骨头; 0x02

有害垃圾:电池、油漆、灯管、药品; 0x03

其他垃圾:烟头、牙签、毛巾、贝壳; 0x04
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

***\*## 拼音数据\****

ke hui shou la ji :

bao zhi 、su liao ping 、bo li 、yi la guan ;

chu yu la ji :

guo pi 、cai ye 、sheng fan 、gu tou ;

you hai la ji :

dian chi 、you qi 、deng guan 、yao pin ;

qi ta la ji :

yan tou 、ya qian 、mao jin 、bei ke ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 ***\*## 配置数据\****

\#define CODE_1 0x01 可回收垃圾:报纸、塑料瓶、玻璃、易拉罐;

\#define CODE_2 0x01

\#define CODE_3 0x01

\#define CODE_4 0x01

\#define CODE_5 0x02 厨余垃圾:果皮、菜叶、剩饭、骨头;

\#define CODE_6 0x02

\#define CODE_7 0x02

\#define CODE_8 0x02

\#define CODE_9 0x03 有害垃圾:电池、油漆、灯管、药品;

\#define CODE_10 0x03

\#define CODE_11 0x03

\#define CODE_12 0x03

\#define CODE_13 0x04 其他垃圾:烟头、牙签、毛巾、贝壳;

\#define CODE_14 0x04

\#define CODE_15 0x04

\#define CODE_16 0x04

LD3320进行配置,使用声调识别数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
***\*## 拼音分类配置\****

"la ji tong",\

"bao zhi",\ 1-4

"su liao ping",\

"bo li",\

"yi la guan",\

"guo pi",\ 5-8

"cai ye",\

"sheng fan",\

"gu tou",\

"dian chi",\ 9-12

"you qi",\

"deng guan",\

"yao pin",\

"yan tou",\ 13-16

"ya qian",\

"mao jin",\

"bei ke"\

五、制作注意事项

六、最终成品效果图

img

img

img img

*演示视频二维码* *原工程链接二维码*