极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 8579|回复: 21

利用pc语音识别通过串口语音控制电路

[复制链接]
发表于 2012-10-14 00:03:29 | 显示全部楼层 |阅读模式
本帖最后由 绿林网页 于 2012-10-14 10:50 编辑

这是另一种语音控制,它不需要语音控制电路板,而是利用win7系统自带的语音识别功能,用上位机通过串口发送指令给Arduino,从而控制电路做相应动作
看图:
电脑 麦克 Arduino板子 发光二极管
QQ截图20121013235608.jpg
QQ截图20121013235626.jpg
在上位机上可以设置语音指令,对着电脑麦克风,说出语音指令,Arduino就会执行对应的指令,控制发光二极管的 点亮 熄灭 闪烁

微博地址:
http://weibo.com/1785094373/z0liAirpA
很容易扩展更多的指令来完成一些声控功能!
回复

使用道具 举报

发表于 2012-10-14 10:40:44 | 显示全部楼层
好东西,楼主是否介意开源一下呢,大家也好学习一下.哈哈
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-10-14 11:55:33 | 显示全部楼层
yimenwang 发表于 2012-10-14 10:40
好东西,楼主是否介意开源一下呢,大家也好学习一下.哈哈

当然可以,我还在测试中,先发上来大家一起研究吧
回复 支持 反对

使用道具 举报

发表于 2012-10-14 11:59:18 | 显示全部楼层
嗯,想法不错,目前手机上的读书语音功能都是利用电脑网络,arduino处理不了的东西发给电脑到是一个不错的方案
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-10-14 12:00:29 | 显示全部楼层
接线图就不需要了吧,哈很简单
直接上代码吧

上位机:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.IO.Ports;

  10. namespace pc
  11. {
  12.     public partial class Form1 : Form
  13.     {
  14.         private StringBuilder builder = new StringBuilder();
  15.         private SerialPort comm = new SerialPort();
  16.         private string[] commarr = null;
  17.         private int commmaxlen = 0;
  18.         public Form1()
  19.         {
  20.             InitializeComponent();
  21.         }

  22.         private void SerialInit()
  23.         {
  24.             string[] ports = SerialPort.GetPortNames();
  25.             Array.Sort(ports);
  26.             comboPortName.Items.AddRange(ports);
  27.             comboPortName.SelectedIndex = comboPortName.Items.Count > 0 ? 0 : -1;
  28.             comboBaudrate.SelectedIndex = comboBaudrate.Items.IndexOf("9600");
  29.             comm.RtsEnable = true;
  30.             comm.DataReceived += comm_DataReceived;
  31.         }
  32.         void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
  33.         {
  34.             int n = comm.BytesToRead;
  35.             byte[] buf = new byte[n];
  36.             comm.Read(buf, 0, n);
  37.             builder.Remove(0, builder.Length);
  38.             builder.Append(Encoding.ASCII.GetString(buf));
  39.             this.Invoke((EventHandler)(delegate
  40.             {
  41.                 txGet.AppendText(builder.ToString());
  42.                 txGet.ScrollToCaret();
  43.             }));
  44.         }
  45.         private void buttonSend_Click(object sender, EventArgs e)
  46.         {
  47.             if (comm.IsOpen)
  48.             {
  49.                 int n = 0;
  50.                 txGet.AppendText("-->" + txSend.Text + "\r\n");
  51.                 txGet.ScrollToCaret();
  52.                 if (newline_cb.Checked)
  53.                 {
  54.                     comm.Write(txSend.Text + "\r\n");
  55.                 }
  56.                 else
  57.                 {
  58.                     comm.Write(txSend.Text);
  59.                 }
  60.                 n = txSend.Text.Length;
  61.                 txSend.Clear();
  62.             }
  63.             else
  64.             {
  65.                 MessageBox.Show("请先打开端口");
  66.             }
  67.         }

  68.         private void buttonOpenClose_Click(object sender, EventArgs e)
  69.         {
  70.             if (comm.IsOpen)
  71.             {
  72.                 comm.Close();
  73.             }
  74.             else
  75.             {
  76.                 commarr = comm_tb.Lines;
  77.                 if (commarr.Length == 0) { MessageBox.Show("请先设置语音指令"); return; }
  78.                 foreach (string tstr in commarr)
  79.                 {
  80.                     if (tstr.IndexOf('@') > commmaxlen) commmaxlen = tstr.IndexOf('@');
  81.                 }
  82.                 try
  83.                 {
  84.                     comm.PortName = comboPortName.Text;
  85.                     comm.BaudRate = int.Parse(comboBaudrate.Text);
  86.                     comm.Open();
  87.                 }
  88.                 catch (Exception ex)
  89.                 {
  90.                     comm = new SerialPort();
  91.                     MessageBox.Show(ex.Message);
  92.                     return;
  93.                 }
  94.             }
  95.             buttonOpenClose.Text = comm.IsOpen ? "关闭" : "打开";
  96.         }

  97.         private void Form1_Load(object sender, EventArgs e)
  98.         {
  99.             SerialInit();
  100.             timer1.Enabled = true;
  101.         }

  102.         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  103.         {
  104.             if (comm.IsOpen)
  105.             {
  106.                 comm.Close();
  107.             }
  108.         }

  109.         private void timer1_Tick(object sender, EventArgs e)
  110.         {
  111.             if (comm.IsOpen)
  112.             {
  113.                 portstatus_lbl.Text = "已连接...";
  114.                 portstatus_lbl.ForeColor = Color.Blue;
  115.                 txSend.Focus();
  116.             }
  117.             else
  118.             {
  119.                 portstatus_lbl.Text = "未连接";
  120.                 portstatus_lbl.ForeColor = Color.Red;
  121.             }
  122.             //  movesend();
  123.         }

  124.         private void txSend_TextChanged(object sender, EventArgs e)
  125.         {
  126.             if (comm.IsOpen)
  127.             {
  128.                 string commstr = txSend.Text.Trim();
  129.                 if (string.IsNullOrEmpty(commstr)) return;
  130.                 if (commarr.Length == 0) { MessageBox.Show("请先设置语音指令"); return; }
  131.                 commstr = commstr + "@";
  132.                 string sendtxt = "";
  133.                 foreach (string tstr in commarr)
  134.                 {
  135.                     if (tstr.StartsWith(commstr))
  136.                     {
  137.                         sendtxt = tstr.Replace(commstr, "").Trim();
  138.                         break;
  139.                     }
  140.                 }
  141.                 if (sendtxt.Length>0)
  142.                 {
  143.                     comm.Write(sendtxt);// + "\r\n"
  144.                     txGet.AppendText("-->" + sendtxt + "\r\n");
  145.                     txGet.ScrollToCaret();                  
  146.                     sendtxt = "";
  147.                     txSend.Clear();
  148.                 }
  149.                 else
  150.                 {   
  151.                     if (commstr.Length-1 > commmaxlen)
  152.                     {
  153.                         txSend.Clear();
  154.                     }
  155.                 }                                                                                                                                               
  156.             }
  157.             else
  158.             {
  159.                 MessageBox.Show("请先打开端口");
  160.             }
  161.         }

  162.         private void comm_tb_TextChanged(object sender, EventArgs e)
  163.         {
  164.             commarr = comm_tb.Lines;
  165.             foreach (string tstr in commarr)
  166.             {
  167.                 if (tstr.IndexOf('@') - 1 > commmaxlen) commmaxlen = tstr.IndexOf('@') - 1;
  168.             }
  169.          }
  170.     }
  171. }
复制代码


Arduino代码
  1. String sdata="";
  2. String mode="out";
  3. void setup()
  4. {
  5.   Serial.begin(9600);
  6.   pinMode(12,OUTPUT);
  7.   digitalWrite(12,LOW);
  8.   Serial.println("start...");
  9. }

  10. void loop()
  11. {
  12.   while (Serial.available() > 0)  
  13.   {
  14.     sdata += char(Serial.read());
  15.     delay(2);
  16.   }
  17.   if(sdata.length()>0)
  18.   {
  19.     mode=sdata;       
  20.     sdata="";
  21.     Serial.print(">--");
  22.     Serial.println(mode);
  23.   }
  24.   modeshow();
  25. }
  26. void modeshow()
  27. {
  28.   if(mode=="light")
  29.   {
  30.     digitalWrite(12,HIGH);
  31.   }
  32.   else if(mode=="blink")
  33.   {
  34.     digitalWrite(12,HIGH);
  35.     delay(100);
  36.     digitalWrite(12,LOW);
  37.     delay(100);
  38.   }
  39.   else if(mode=="out")
  40.   {
  41.     digitalWrite(12,LOW);
  42.   }
  43. }




复制代码

在控制面板里,打开win7的语音识别功能,就可以啦,右边编辑框里输入好语音指令就可以测试了。
回复 支持 反对

使用道具 举报

发表于 2012-10-14 12:05:32 | 显示全部楼层
使用电脑mic收集资料的啊,我还以为你有板子收集语音发给电脑处理呢,电脑应该只做处理的工作,数据采集应该交给前端arduino
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-10-14 14:16:27 | 显示全部楼层
ttyp 发表于 2012-10-14 12:05
使用电脑mic收集资料的啊,我还以为你有板子收集语音发给电脑处理呢,电脑应该只做处理的工作,数据采集应该 ...

是的啊,就是为了省去语音板子,要是用语音板子,不用PC也可以直接实现控制呀
回复 支持 反对

使用道具 举报

发表于 2012-10-15 09:46:09 | 显示全部楼层
这是一个很有价值的尝试,支持楼主。
关于语音识别板子,它有特定的使用场合,那就是互动玩具,或者对体积、便携性有要求的场合,但是正因为其迷你,所以功能和PC上位机+arduino是有差别的。
所以,两个方向都应该尝试,适用于不同用途,有交叉但并不大。
回复 支持 反对

使用道具 举报

发表于 2012-10-15 10:29:18 | 显示全部楼层
绿林网页 发表于 2012-10-14 14:16
是的啊,就是为了省去语音板子,要是用语音板子,不用PC也可以直接实现控制呀

我的意思是你现在的麦克风只能接到电脑上,而电脑基本是固定的不能移动,我是想最好接在arduino上,用一块简单的声音采集板子(不带分析功能,只要录音就行),采集到声音上传给电脑分析,然后发出指令给arduino,这样麦克风就可以移动了,电脑甚至可以是部署在公网的服务器,只要保留接口就可以了
回复 支持 反对

使用道具 举报

发表于 2012-10-15 10:33:12 | 显示全部楼层
这样的好处是把界面层和底层分离了,pc就像一个云,方便部署,实用性强
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-10-15 14:15:29 | 显示全部楼层
ttyp 发表于 2012-10-15 10:33
这样的好处是把界面层和底层分离了,pc就像一个云,方便部署,实用性强

最好是通过把无线麦克风发射端安装到Arduino的设备上,麦克风接收端插入电脑,实现单独的无线控制音频传输,就和无线视频一样,不能直接借助arduino来传输视频!
回复 支持 反对

使用道具 举报

发表于 2012-12-2 17:22:20 | 显示全部楼层
上位机可以共享出来吗?光有代码不够吧
回复 支持 反对

使用道具 举报

发表于 2013-2-23 20:18:06 | 显示全部楼层
楼主,问一下上机位怎么搞啊,是什么意思啊 ,小白求教。。。。
回复 支持 反对

使用道具 举报

发表于 2013-2-25 17:56:54 | 显示全部楼层
这个帖子精湛啊!我喜欢
回复 支持 反对

使用道具 举报

发表于 2013-2-26 09:47:54 | 显示全部楼层
不错!现在android和iphone里面都有语音识别软件,今后扩展的话,可以考虑。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2020-7-4 21:01 , Processed in 0.052313 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表