文章目录
- 写在前面
- 器件
- 连接
- 部分代码
- 运行结果
- 小结
写在前面
接上一篇文章,这次是集合了语音识别+语音合成(就是语音播报实现一种反馈)+SG90舵机实现垃圾桶的开与闭,给出上篇文章链接,如果对LD3320语音识别还有问题的朋友可以看看:LD3320语音识别模块与Arduino软串口通讯实现开关灯功能
发现还是有好多人都在做这个,当玩具也好,毕设也好,这个都是一个好玩又有趣的项目。因为这只是现在的一门小课设,就拿来当玩具玩玩,后期看情况会加入WIFI(或者蓝牙?)实现无线通讯,顺便学习一下物联网,用Android Studio开发一个APP就可以实现手机控制。还是一样,这篇文章仅作为参考。如有做得不足或者不对的地方,欢迎一起交流学习。
器件
-
SG90舵机*2(我这只实现2个分类,就可回收垃圾与其他垃圾,道理都一样)
-
LD3320语音识别模块
-
SYN6288语音合成模块
-
Arduino UNO R3 328p
-
小垃圾筒*2 (这里我没用到)
连接
我是这么接,当然这个不是绝对。
LD3320 | Arduino |
---|---|
5V | 5V |
GND | GND |
RXD | D5 |
TXD | D6 |
SYN6288 | Arduino |
---|---|
5V | 5V |
GND | GND |
RXD | D2 |
TXD | D3 |
两个舵机,所以
SG90 | Arduino |
---|---|
红线 | 5V |
棕线 | GND |
橙线 | D9、D10 |
两个舵机,分别9号跟10号。
部分代码
LD3320可以通过串口与产品中的单片机进行串口通信达到控制效果,如采用这种方式进行控制,用户可以对main.c函数中的处理函数进行修改,将输出的信息更改为输出识别码,那么在每次识别成功后串口都将打印输出对应的识别码,产品中的单片机就可以对该识别码进行操作以达到控制效果。
给出LD3320模块的原理图
厂家给的文件:
LDChip.c
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 | uint8 LD_AsrAddFixed() { uint8 k, flag; uint8 nAsrAddLength; #define DATE_A 11 /*数组二维数值*/ #define DATE_B 20 /*数组一维数值*/ uint8 code sRecog[DATE_A][DATE_B] = { "la ji tong",\ //一级口令设为“垃圾桶” "fei zhi",\ "su liao",\ "bo li",\ "yi la guan",\ "bao zhi",\ "yi wu",\ "wei sheng zhi",\ "guo ke",\ "luo ye",\ "chen tu" }; /*添加关键词,用户修改*/ uint8 code pCode[DATE_A] = { CODE_CMD,\ CODE_1,\ CODE_2,\ CODE_3,\ CODE_4,\ CODE_5,\ CODE_6,\ CODE_7,\ CODE_8,\ CODE_9,\ CODE_10 }; /*添加识别码,用户修改*/ .......... |
文件:main.c
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 | void User_handle(uint8 dat) { if(0==dat) { G0_flag=ENABLE; UARTSendByte(0x01); //将识别到的识别码传到串口输出,以下同理 PrintCom("1/r/n"); LED=0; } else if(ENABLE==G0_flag) { G0_flag=DISABLE; LED=1; switch(dat) { case CODE_1: UARTSendByte(0x02); PrintCom("2/r/n"); SRD1 = 1; break; case CODE_2: UARTSendByte(0x02); PrintCom("2/r/n"); SRD1 = 0; break; ........... |
给出SYN6288原理图:
关于SYN6288得多说几句,主控制器和SYN6288语音合成芯片之间通过UART接口连接,控制器可通过通讯接口向SYN6288语音合成芯片发送控制命令和文本,SYN6288语音合成芯片把接收到的文本合成为语音信号输出,输出的信号经功率放大器进行放大后连接到喇叭进行播放。
使用之前得要把发送的文本转换文本编码格式
我们与这个芯片“对话”用的不是中文,得首先把中文转换它才能“念出来”,网上有很多这些转换的方法,这里就不再纂述。
Arduino代码
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 | #include <Servo.h> //调用这个库,控制舵机的 #include <SoftwareSerial.h> //定义软串口的 SoftwareSerial softSerial1(6,5); //6为RX,5为TX SoftwareSerial softSerial2(3,2); //3为RX,5为TX Servo myservo1; // 定义舵机一 Servo myservo2; // 定义舵机二 int a; void speech1(){ //播放:提示音msgd unsigned char i = 0; unsigned char head[10]; head[0] = 0xFD; head[1] = 0x00; head[2] = 0x07; head[3] = 0x01; head[4] = 0x00; head[5] = 0x6D; head[6] = 0x73; head[7] = 0x67; head[8] = 0x64; head[9] = 0xE6; for(i=0; i<10; i++){ softSerial2.write(head[i]); } } void speech2(){ //播放:可回收垃圾 unsigned char j = 0; unsigned char head1[16]; head1[0] = 0xFD; head1[1] = 0x00; head1[2] = 0x0D; head1[3] = 0x01; head1[4] = 0x00; head1[5] = 0xBF; head1[6] = 0xC9; head1[7] = 0xBB; head1[8] = 0xD8; head1[9] = 0xCA; head1[10] = 0xD5; head1[11] = 0xC0; head1[12] = 0xAC; head1[13] = 0xBB; head1[14] = 0xF8; head1[15] = 0xD4; for(j=0; j<16; j++){ softSerial2.write(head1[j]); } } void speech3(){ //播放:其他垃圾 unsigned char k = 0; unsigned char head2[14]; head2[0] = 0xFD; head2[1] = 0x00; head2[2] = 0x0B; head2[3] = 0x01; head2[4] = 0x00; head2[5] = 0xC6; head2[6] = 0xE4; head2[7] = 0xCB; head2[8] = 0xFB; head2[9] = 0xC0; head2[10] = 0xAC; head2[11] = 0xBB; head2[12] = 0xF8; head2[13] = 0xCA; for(k=0; k<14; k++){ softSerial2.write(head2[k]); } } void setup() { myservo1.attach(9); // D9为舵机一信号口 myservo2.attach(10); // D10为舵机二信号口 Serial.begin(9600); //串口初始化 softSerial1.begin(9600); softSerial2.begin(9600); } void loop() { softSerial1.listen(); //监听第一个串口 a=softSerial1.read(); //读取串口1的值 switch(a) { case 1: speech1(); //播放提示音 break; case 2: speech2(); //识别到是可回收垃圾,并播报出来 delay(1000); myservo1.write(90); //舵机一旋转90° delay(3000); //延迟一段时间,也就是扔垃圾的时间 myservo1.write(0); delay(5); //给舵机一个转动的时间 break; case 3: speech3(); delay(1000); //识别到是其他垃圾,并播报出来 myservo2.write(90); //舵机二旋转90° delay(3000); myservo2.write(0); delay(5); break; default: break; } } |
关于softSerial1.listen(); 要说几句,之前一直发现一个问题,就是我在用着两个软串口进行通讯,发现语音播报的功能就显示不出来,但是我分着来用,却可以实现,这里提出串口监听的方法,按我的目前的理解就是,只运行第一个软串口,即语音识别模块的串口通讯,这样程序就能完好的运行了。
运行结果
因为这里不能直接上传视频,总的来说是可以正常运行的了,-.-
那我就用串口监视器来说明吧
小结
(估计也没人看总结)总的来说,基本的功能已经实现了,接下来就是提升或者想想怎么提高识别率以及增加几句“垃圾语”,因为目前时不时还是会乱识别到不该识别到的对话。用Arduino控制舵机就几句代码就可以实现,这比STM32或者51方便好多好多。
这是玩具,这是玩具,这是玩具。 文章中肯定有很多不足的地方,有很多交代不来的东西,我说怎么做这东西的人很多,但是在CSDN上没有,可能就是很多东西不知道怎么用语言表达。
希望能帮到做这个项目方向的朋友,也希望能帮到偶然点进来的朋友。