随着上海市垃圾分类的正式实施,“垃圾分类”一下子成为了一个热词。而要把垃圾的种类彻底搞清楚,有时候也还真是个烧脑的事儿。
不知道是哪位有才之人想出了根据小猪能不能吃来进行垃圾分类的办法,一下子就把垃圾的问题解决了。于是也就有了今天这个开脑洞的作品——垃圾分类小达人。
材料清单
- Arduino UNO X1
- 9g舵机 X4
- Arduino舵机接线板 X1
- 垃圾桶模型(一套四个) X1
- M6语音交互模块 X1
- 底板 X1
- 杜邦插头线 X1
这个作品的思路是这样的:通过交互式语音提示的方法来引导用户完成垃圾的模拟投递过程。假设用户拿着一样垃圾来到一排垃圾桶前准备扔垃圾,这时有两种情况:用户知道或不知道自己提的是哪种垃圾。于是:
步骤1 首先询问用户是否知道自己手里提的是哪种垃圾?
步骤2 如果用户知道,则只需直接说出垃圾的种类,系统自动打开对应的垃圾桶盖,帮助用户完成垃圾投放的过程。
步骤3 否则,则用户回答“不清楚”,然后由系统用语音向导的方式与用户互动,通过“小猪佩琪吃不吃”的问答来引导用户选择正确的垃圾桶投放。
硬件制作:首先把垃圾桶盖下方的凸台切掉,使得桶盖可以自如开关。然后用螺丝把舵机固定在垃圾桶背面。再在垃圾桶盖的臂上钻一个小孔,用直径0.8mm的钢丝做成顶杆,连接舵机臂和垃圾桶盖。这样就可以通过舵机来操纵桶盖了。最后把四个垃圾桶、一个控制板、一个语音模块和一个喇叭全部固定在底板上。
接下来是编写剧本:把要提的问题和回答的内容以及逻辑关系都在草稿纸上列出来,包括流程图。
再下来是准备素材:本来想用语音合成直接TTS的,结果Arduino的编译器不支持串口直接发送中文字符,Mind+对数组的处理也不十分完美,折腾了两个晚上还是不成功,只好退而求其次:播放mp3。于是在网上找了一个TTS引擎,直接把文字转成mp3文件。所有的mp3全部放入TF卡内,插入语音模块内。
再然后是Mind+的一个小问题整整找了我两个晚上:程序写到一定规模之后会莫名其妙地把我写的固定的某两个函数的传递参数给删除掉,在函数定义的位置和函数的位置,但是函数内的内容正常。于是每次修改代码后都要手动在“自动生成”区全选复制代码,再粘贴到“手动编辑”区,然后找到那四个位置,手工把缺少的参数填进去,然后才能编译上传(此处可求心理阴影面积)。
#include <DFRobot_Servo.h>
double _8BA1_65F6_5668;
String _6536_5230_7684_62A5_6587;
double _7B2C_4E00_6B21_542F_52A8;
Servo myservo4;
Servo myservo5;
Servo myservo6;
Servo myservo7;
void _6254_5783_573E(double _5783_573E_79CD_7C7B);
void _64AD_653E_8BED_97F3(double _8BED_97F3_7F16_53F7);
void _6253_5F00_5783_573E_6876(double _5F00_6876_7F16_53F7);
void _63A5_6536_4E32_53E3_4FE1_606F();
void _5173_95ED_5783_573E_6876();
void _8BED_97F3_5408_6210(double _8BED_97F3_6587_672C);
void _6254_5783_573E(double _5783_573E_79CD_7C7B)
{
_64AD_653E_8BED_97F3(16);
delay(2000);
_64AD_653E_8BED_97F3(_5783_573E_79CD_7C7B);
if ((_5783_573E_79CD_7C7B == 3)) {
delay(1000);
}
if ((_5783_573E_79CD_7C7B == 4)) {
delay(1000);
}
if ((_5783_573E_79CD_7C7B == 5)) {
delay(1500);
}
if ((_5783_573E_79CD_7C7B == 6)) {
delay(1800);
}
_64AD_653E_8BED_97F3(17);
delay(2000);
_64AD_653E_8BED_97F3(9);
delay(5000);
_6253_5F00_5783_573E_6876((_5783_573E_79CD_7C7B-2));
_8BA1_65F6_5668 = 10;
while ((!((_8BA1_65F6_5668 == 20) || ((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("8")) != -1))))) {
_63A5_6536_4E32_53E3_4FE1_606F();
delay(1000);
_8BA1_65F6_5668 = _8BA1_65F6_5668 + 1;
}
_64AD_653E_8BED_97F3(10);
delay(4000);
_5173_95ED_5783_573E_6876();
delay(1000);
_64AD_653E_8BED_97F3(11);
delay(9000);
}
void _64AD_653E_8BED_97F3(double _8BED_97F3_7F16_53F7)
{
if ((_8BED_97F3_7F16_53F7 == 0)) {
Serial.println("@StopPlaying#$");
}
else {
Serial.print("@PlayTF#");
if ((_8BED_97F3_7F16_53F7 < 10)) {
Serial.print((String("000") + String((String((String(_8BED_97F3_7F16_53F7).toInt()))))));
}
else {
if ((_8BED_97F3_7F16_53F7 < 100)) {
Serial.print((String("00") + String((String((String(_8BED_97F3_7F16_53F7).toInt()))))));
}
else {
if ((_8BED_97F3_7F16_53F7 < 1000)) {
Serial.print((String("0") + String((String((String(_8BED_97F3_7F16_53F7).toInt()))))));
}
else {
Serial.print((String((String(_8BED_97F3_7F16_53F7).toInt()))));
}
}
}
Serial.println("$");
}
}
void _6253_5F00_5783_573E_6876(double _5F00_6876_7F16_53F7)
{
if ((_5F00_6876_7F16_53F7 == 1)) {
myservo4.angle(abs(160));
}
if ((_5F00_6876_7F16_53F7 == 2)) {
myservo5.angle(abs(158));
}
if ((_5F00_6876_7F16_53F7 == 3)) {
myservo6.angle(abs(165));
}
if ((_5F00_6876_7F16_53F7 == 4)) {
myservo7.angle(abs(128));
}
}
void _63A5_6536_4E32_53E3_4FE1_606F()
{
while (!(((Serial.available()) || (!digitalRead(2))) || (_7B2C_4E00_6B21_542F_52A8 == 1))) {
}
_6536_5230_7684_62A5_6587 = "9";
if ((Serial.available())) {
_6536_5230_7684_62A5_6587 = Serial.read();
}
else {
_6536_5230_7684_62A5_6587 = "0";
}
digitalWrite(13, HIGH);
delay(300);
digitalWrite(13, LOW);
if ((_6536_5230_7684_62A5_6587 == 9)) {
delay(4000);
}
else {
delay(1500);
}
}
void _5173_95ED_5783_573E_6876()
{
myservo4.angle(abs(78));
myservo5.angle(abs(70));
myservo6.angle(abs(78));
myservo7.angle(abs(70));
}
void _8BED_97F3_5408_6210(double _8BED_97F3_6587_672C)
{
Serial.print("@TextToSpeech#");
Serial.print(_8BED_97F3_6587_672C);
Serial.println("$");
}
void setup() {
myservo4.attach(4);
myservo5.attach(5);
myservo6.attach(6);
myservo7.attach(7);
Serial.begin(9600);
_6536_5230_7684_62A5_6587 = "0";
myservo4.angle(abs(78));
myservo5.angle(abs(70));
myservo6.angle(abs(78));
myservo7.angle(abs(70));
_7B2C_4E00_6B21_542F_52A8 = 1;
delay(3000);
}
void loop() {
_63A5_6536_4E32_53E3_4FE1_606F();
if (((_7B2C_4E00_6B21_542F_52A8 == 1) || ((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("9")) != -1)))) {
_6536_5230_7684_62A5_6587 = "0";
_7B2C_4E00_6B21_542F_52A8 = 0;
_64AD_653E_8BED_97F3(1);
delay(15000);
_64AD_653E_8BED_97F3(2);
delay(6500);
_64AD_653E_8BED_97F3(3);
delay(1200);
_64AD_653E_8BED_97F3(4);
delay(1000);
_64AD_653E_8BED_97F3(5);
delay(1500);
_64AD_653E_8BED_97F3(7);
delay(700);
_64AD_653E_8BED_97F3(6);
delay(1800);
_64AD_653E_8BED_97F3(8);
delay(9500);
_63A5_6536_4E32_53E3_4FE1_606F();
if (((((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("3")) != -1)) || ((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("4")) != -1))) || (((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("5")) != -1)) || ((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("6")) != -1))))) {
digitalWrite(13, HIGH);
delay(300);
digitalWrite(13, LOW);
_6254_5783_573E((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).toInt()));
}
else {
if (((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("7")) != -1))) {
_64AD_653E_8BED_97F3(12);
delay(6000);
_64AD_653E_8BED_97F3(14);
delay(14000);
_64AD_653E_8BED_97F3(13);
delay(4000);
_63A5_6536_4E32_53E3_4FE1_606F();
if (((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("1")) != -1))) {
_6254_5783_573E(5);
}
else {
_64AD_653E_8BED_97F3(18);
delay(10000);
_64AD_653E_8BED_97F3(13);
delay(4000);
_63A5_6536_4E32_53E3_4FE1_606F();
if (((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("1")) != -1))) {
_6254_5783_573E(4);
}
else {
_64AD_653E_8BED_97F3(19);
delay(11000);
_64AD_653E_8BED_97F3(13);
delay(4000);
_63A5_6536_4E32_53E3_4FE1_606F();
if (((String((String(_6536_5230_7684_62A5_6587).charAt(1 - 1))).indexOf(String("1")) != -1))) {
_6254_5783_573E(6);
}
else {
_6254_5783_573E(3);
}
}
}
}
}
}
}
12121221122020.07.27
eqwe
Echo12020.04.14
老师,您好“播放mp3。于是在网上找了一个TTS引擎,直接把文字转成mp3文件。所有的mp3全部放入TF卡内,插入语音模块内。”这句话是怎么咱们怎么处理播报语音的呢?谢谢您,打扰您啦。
Echo12020.04.14
作者您好,求救啊,小白不知道这个语音模块咋个实现的。
浮尘2020.01.31
也想试一下。但是arduino串口发送数据过去,语音模块没反应,能否加个qq解决下:1774590818
teacherm2020.01.25
可以说一下语音模块怎么使用的嘛?我用的是 LDV5就是不行呢?请教一下你是怎么转换的
teacherm2020.01.19
四个舵机直接连在扩展板上吗?
freemantjp2019.11.27
不错不错,就说语音交互感觉慢,哈哈
TR-SHA2020.01.03
哈哈,是的,快了又怕听不清楚。语音合成的快语速感觉有点奇怪的。
gsym2019.11.19
Mind+支持M6语音交互模块吗?
TR-SHA2020.01.03
Mind+没有直接支持。我是通过间接的方法来实现的。
clatterrr2019.09.30
有的app可以拍照识别垃圾种类啊,弄个接口应该更好玩吧,但这样传感器又得买一堆了qwq
TR-SHA2020.01.03
垃圾桶的玩法多多 :P