如何通过Arduino使用语音命令控制伺服电机

在本文中,我们将共同学习如何使用机器学习软件Wekinator,学习如何通过Wekinator连接到Arduino,并通过语音命令控制伺服电机。我们向Wekinator发送音频,通过Wekinator软件内部处理程序处理加工后,结果输出到Arduino,以此来控制伺服电机的运动。

音频文件如何在Wekinator软件中执行

首先,我们从Wekinator的示例页面:http://www.wekinator.org/examples/ 下载可执行的示例文件,并运行它。

选择Wekinator 例程

注意:请下载与你的操作系统相匹配的文件版本。例如,如果你使用的是64位操作系统,请选择64bit的版本。参考下面的截图。

按操作系统选择Wekinator 例程

下载解压缩文件后得“MFCCs_win64”文件夹,打开后可以看到“bin”文件夹,再打开bin文件夹,可以看到“MFCCs_13Inputs_RUN_THIS.exe”,运行MFCCs_13Inputs_RUN_THIS.exe,将打开两个窗口,如下所示。

MFCCs_13Inputs_RUN_THIS

Wekinator软件中创建项目

下一步是在Wekinator中建立一个新项目。首先,在Wekinator软件中将输入值设置为13,因为我们要运行的程序将在端口6448发送13个输入。接下来,将输出类型设置为“all dynamic time warp”,4种姿态类型作为Wekinator最终处理的4个语音命令。“all dynamic time warp”是Wekinator中的一种特殊模式,它允许程序比较不同的语音顺序。例如,如果你说:“打开LED”,Wekinator将测量语音序列之间的相似性。

wekinator 创建新项目

单击next按钮后,您将看到如下所示的新窗口。

wekinator 创建新项目

单击output_1前面的plus按钮,将音频输入到程序。这里我输入了“向右”,因为我已经为这个输出设置了伺服向右移动。同样的方法去设定语音命令output_2、output_3和output_4,比如可以分别输入“居中”、“向左”和“停止”。

wekinator 创建新项目

Processing代码

Processing代码主要是将经过处理的Wekinator值发送到Arduino。

import vsync.*; // 导入库,与Arduino完成发送和接收.
import processing.serial.*;  // 导入serial library

// 下面的库实现连接和发送Wekinator的值,并接收这些值
import oscP5.*;  
import netP5.*;

// 创建实例
OscP5 oscP5;
NetAddress dest;
ValueSender sender;

// 这个变量将与Arduino同步,与Arduino代码中完全一致.
public int output;

void setup() 
{
  // 开始串口通信时,波特率和串口端口号应与Arduino端相同.
  Serial serial = new Serial(this, "COM10", 19200);
  sender = new ValueSender(this, serial);
  
  // 与Arduino面同步变量.
  sender.observe("output");
  
  
  // 开始与wekinator进行通信。在端口12000上监听,在端口6448上返回消息
  oscP5 = new OscP5(this, 12000); 
  dest = new NetAddress("127.0.0.1", 6448);
}

//当接收到OSC消息时,将自动调用此函数
void oscEvent(OscMessage theOscMessage) {
 if (theOscMessage.checkAddrPattern("/output_1")==true) 
 {
        output = 1;
 } 
 else if (theOscMessage.checkAddrPattern("/output_2")==true) 
 {
     output = 2;
 } 
 else if (theOscMessage.checkAddrPattern("/output_3") == true) 
 {
     output = 3;
 } 
 else if (theOscMessage.checkAddrPattern("/output_4") == true) 
 {
     output = 4;
 } 
 else 
 {
   
 }
}

void draw() 
{
  //  Nothing to be drawn for this example
}

Arduino Code

Arduino接收后的通过输出控制伺服电机运动。在上传代码前,先将伺服电机与Arduino连接起来,如下图所示。

连接伺服电机至Arduino

#include <VSync.h> //包含VSync.h库,它帮助我们从processing接收和发送值.
ValueReceiver<1> receiver; /*创建接收器,在括号中设置要同步的值的数值*/
#include <Servo.h> //包括伺服电机库
Servo sg90; //包括一个名为sg90的servo变量

/* 下面的变量将会与 processing 同步,并且两边应该是相同的。*/
int output;
int angle = 90;
int servo_pin = 8;

void setup()
{
/* 启动串口通信的原因是我们是通过串口与Processing进行通信的。波特率应该与Processing的值相同。*/
Serial.begin(19200);
sg90.attach(servo_pin);

// 使变量与 processing 同步. 变量必须是int类型.
receiver.observe(output);
}

void loop()
{
// 接收来自 processing 的输出.
receiver.sync();

// 匹配接收到的输出来控制伺服电机
if (output == 1)
{
if(angle > 5){
sg90.write(angle);
angle--;
delay(100);
}
}
else if (output == 2)
{
angle = 90;
sg90.write(angle);
}
else if (output == 3)
{
if(angle < 180){
sg90.write(angle);
angle++;
delay(100);
}
}
else if (output == 4)
{
}
}

如何通过Wekinator运行代码

首先从Arduino IDE上传Arduino代码,然后在processing 软件中运行processing代码。此时,当你通过Wekinator发出语音命令时,伺服电机应该对应运动。如果你说”向右”,伺服电机应该会向右移动90度;如果你说“向左”,伺服电机应该会向左移动到180度。如果你停止伺服电机,可以说“停止”。如果觉得伺服电机的动作不够精确,可以进一步优化代码中用的值。同时可以通过邮件发送到basemu@126.com分享你使用Wekinator软件的经验。

标签: