“语音情景灯/zh”的版本间的差异

来自Microduino Wikipedia
跳转至: 导航搜索
搭建
 
(未显示同一用户的11个中间版本)
第157行: 第157行:
 
将[[Microduino-Core+/zh]]、[[Microduino-USBTTL/zh]]堆叠在一起.用数据线将写好的程序通过[[Microduino-USBTTL/zh]]上传到[[Microduino-Core+/zh]]上。
 
将[[Microduino-Core+/zh]]、[[Microduino-USBTTL/zh]]堆叠在一起.用数据线将写好的程序通过[[Microduino-USBTTL/zh]]上传到[[Microduino-Core+/zh]]上。
 
注意:最好不要将所有模块堆叠在一起之后再上传程序
 
注意:最好不要将所有模块堆叠在一起之后再上传程序
[[File:download1.jpg||600px|center]]
+
[[File:download1.jpg||400px|center]]
 
找到该程序的物理位置,"语音情景灯/ EGGROOM/ EGGROOM.ino",双击即可
 
找到该程序的物理位置,"语音情景灯/ EGGROOM/ EGGROOM.ino",双击即可
[[File:Emotionlightopen.jpg||600px|center]]
+
[[File:Emotionlightopen.jpg||500px|center]]
 
程序下载
 
程序下载
 
点击"√",编译程序。
 
点击"√",编译程序。
 
点击【工具】,选择正确的板+处理器+端口。
 
点击【工具】,选择正确的板+处理器+端口。
 
点击"→",进行上传。
 
点击"→",进行上传。
[[File:Downloadselectcore+.jpg||600px|center]]
+
[[File:Downloadselectcore+.jpg||500px|center]]
 +
*音频下载
 +
将TF卡安装到Audio模块上,之后使用USB线将Audio模块连接到电脑上。此时会识别出一个可移动磁盘。
 +
[[File:Tf1.png||600px|center]]
 +
在识别到的磁盘中新建文件夹命名为01,之后将语音按命名的数字顺序复制到文件夹01中。至此音频存储完毕。
 +
[[File:Tf2.png||600px|center]]
 +
 
 +
[[File:Tf3.png||600px|center]]
 +
 
 
==搭建==
 
==搭建==
搭建硬件电路,将用到的设备叠加起来(无上下顺序)
+
将Microduino-Duo-V底板用螺丝固定在顶板上,顶板与底板形状相同,可任选其一。
Microduino-Core+
+
[[File:Pp1.png||600px|center]]
Microduino-USBTTL
+
搭建硬件电路,将用到的设备叠加起来
Microduino-BT(4.0)
+
Microduino-Amplifier
Microduino-BM
+
Microduino-Audio
Microduino-Duo-H
 
 
Microduino-sensorhub
 
Microduino-sensorhub
 +
以上模块放置在Duo-V的一端
 +
Microduino-Duo-V
 +
以下模块放置在Duo-V的另一端
 
Microduino-Lamp
 
Microduino-Lamp
锂电池
+
Microduino-Core+
[[File:Emotionlight1.jpg||600px|center]]
+
Microduin-USBTTL
安装发光二极管
+
注:
将发光二极管的负极插在[[Microduino-Sensorhub/zh]]传感器扩展模块的A7管脚,正极插在SDA管脚
+
Microduino-DUO-V作为底板,降低整体高度,同时固定Lamp模块在一侧提供照明功能。Microduino-Lamp和Microduino-sensorhub放在两侧的最上面。拼装时,先不要装上Sensorhub,这样方便下面的安装。
[[File:Emotionlight2.jpg||600px|center]]
+
按照如图方式,将温湿度传感器、麦克风和ColorLED装在前面板上。用螺丝固定。
将传感器数据线插入第三行第一列插槽,观察这里插线的部分,4根线从左到右分别是GND,VCC,D2,D3接脚(不要看颜色,实物颜色可能与本例不同)
+
[[File:Pp2.png||600px|center]]
[[File:Voidsensor0.jpg||600px|center]]
+
使用如图所示的方式,用底座将喇叭固定在侧板上,喇叭的连线留在朝向图左侧的方向,方便后续安装。此时不要将左右两块板与前面板拼接在一起,先拿掉一侧的侧板,方便后续安装
[[File:Voidcesensor1.jpg||600px|center]]
+
[[File:Pp3.png||600px|center]]
安装语音话筒
+
使用连线连接语音模块,注意连线方向,左数第一个双头接口是GND及VCC,第二个双头端口是RX,DX,如果无法确定方向就按照图中的方向连接语音识别模块。
语音话筒无正负极,将两端分别插在语音传感器的MIP和MIN上即可
+
[[File:Pp4.png||350px|center]]
[[File:Voidesensor2.jpg||600px|center]]
+
注意:如果想直接使用USBTTL+Sensorhub测试语音识别模块,则语音模块端的RX和TX要和上图方向反过来连接。
[[File:Voidsensor3.jpg||600px|center]]
+
对应下图,使用传感器线连接传感器,ColorLED连接A2端口,温湿度传感器连接右下角SDASCL接口,语音模块连接D2/D3接口。连接好后,将Sensorhub插在Audio模块上面,置于最上端.
 +
[[File:Microduino-sensorhub rule.JPG||600px|center]]
 +
此时的状态应该是传感器都已经连接到Sensorhub上,所有模块都已经拼接在底板上。喇叭用卡子固定在侧板上。之后将剩下的底板插在侧板上,然后扣上另一块侧板。
 +
[[File:Pp6.png||600px|center]]
 +
之后将前板和后板插上用于固定两块侧板。最后将上下两个头部插好。
 +
最后使用插销将所有固定扣固定住即可。
 +
[[File:Pp7.png||600px|center]]
 +
 
 +
==整体调试==
 +
打开语音情景灯的电源,首先等待指示灯亮起2-3秒钟,之后熄灭。这时对麦克风说“泡泡”,是语音输入的开关语句,也就是说要先说这句话,看到语音输入指示灯(ColorLED)亮起后,再说各种语音命令,每说一条指令后都有5秒时间继续说下一条指令,若没有语音输入则指示灯熄灭,需要重新说“泡泡”进入语音输出状态。
 +
本例的语音开关指令是“泡泡”,所以请用普通话清晰发声“泡泡”,观察ColorLED是否点亮,如果点亮就继续说出命令,如“讲故事”,灯光模块就会被点亮,如果没有语音回复“hi,我是泡泡”,则继续说“泡泡”直到ColorLED点亮并有语音回复再说指令。
 +
 
 
==注意问题==
 
==注意问题==
 
*每次语音输入命令,都要先说f1对应的内容,本例是“美科”读者可根据自己的设置输入
 
*每次语音输入命令,都要先说f1对应的内容,本例是“美科”读者可根据自己的设置输入
 
*二极管极性的判断,反接的话二极管不会发光
 
*二极管极性的判断,反接的话二极管不会发光
 
==程序说明==
 
==程序说明==
*主函数
+
*语音模块配置
 
<source lang="cpp">
 
<source lang="cpp">
#include "Arduino.h"
+
void writecommand() 
#include "audio.h"
+
{ 
#include "JQ6500.h"
+
    VOICE.println("{d1}"); 
#include "JQ6500_def.h"
+
    delay(200); 
#include "def.h"
+
    VOICE.println("{d1}");    //确认进入调试模式 
#include <Wire.h>
+
    delay(200); 
#include <AM2321.h>
+
    VOICE.println("{c0}");      //清除已有指令 
#include <Adafruit_NeoPixel.h>
+
    delay(200); 
//用户自定义部分------------------------
+
    VOICE.println("{a0pao pao|s0pp}");  //开启语音指令 
AM2321 am2321;
+
    delay(200); 
//用户自定义部分------------------------
+
    VOICE.println("{a0ni de ming zi|s0mz}"); //你的名字 
#define PIN A0
+
    delay(200); 
#define NOTICE A2
+
    VOICE.println("{a0ni de nian ling|s0nl}");  // 你的年龄 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(6, PIN, NEO_GRB + NEO_KHZ800);
+
    delay(200); 
 
+
    VOICE.println("{a0jiang gu shi|s0gs}");   //讲故事 
Adafruit_NeoPixel notice = Adafruit_NeoPixel(6, NOTICE, NEO_GRB + NEO_KHZ800);
+
    delay(200); 
uint32_t color[9] =
+
    VOICE.println("{a0bei shi|s0sg}"); //背诗 
{
+
    delay(200); 
  strip.Color(0, 0, 0), strip.Color(255, 0, 0), strip.Color(248, 141, 30), strip.Color(255, 255, 0),
+
    VOICE.println("{a0sha gua|s0sm}"); //傻瓜 
strip.Color(0, 255, 0), strip.Color(0, 127, 255),
+
    delay(200); 
strip.Color(0, 0, 255), strip.Color(139, 0, 255), strip.Color(255, 255, 255)
+
    VOICE.println("{a0tian qi ru he|s0wd}"); //天气如何 
};
+
    delay(200); 
//用户自定义部分------------------------
+
    VOICE.println("{a0hao hei|s0kd}");  //好黑 
int music_vol = 25;        //初始音量0~30
+
    delay(200); 
int music_Mode = MODE_ONE_STOP;
+
    VOICE.println("{a0guan deng|s0gd}");  //关灯 
JQ6500 AUDIO(&VOICE);        //声明audio类
+
    delay(200); 
//用户自定义部分------------------------
+
    VOICE.println("{a0zai jian|s0zj}");  //再见 
int num = 0;
+
    delay(200); 
boolean buffer_sta = false;
+
    VOICE.println("{a0xie xie|s0xx}");  //谢谢 
boolean start = false;
+
    delay(200); 
int brightness = 255;
+
    VOICE.println("{l0}");     //加载 
unsigned long timer_voice = millis();
+
    delay(200); 
int flag_on = 0;
+
    VOICE.println("{d0}");    //退出调试 
 
+
    delay(200); 
int c = 0;
+
} 
int DHTPIN = 8;
 
int temperature;
 
//func===================================
 
int judge(String cmd);
 
void writecommand();
 
void colorWipe(uint32_t c);
 
void dht11();
 
void tempsound();
 
//SETUP===================================
 
void SETUP_begin()
 
{
 
  DEBUG.begin(9600);
 
  VOICE.begin(9600);
 
  VOICE.begin(9600);
 
  pinMode(DHTPIN,INPUT);
 
  //EEPROM---------------------
 
  config = eeprom_READ();
 
  music_Mode = config.EEPROM_music_mode;
 
  music_vol = config.EEPROM_music_vol;
 
  AUDIO.init(DEVICE_TF, music_Mode, music_vol);
 
  delay(1000);
 
//  AUDIO.choose(1);
 
  AUDIO.pause();
 
  strip.begin(); //初始化LED
 
  notice.begin();
 
  pinMode(6,OUTPUT);
 
    notice.setPixelColor(0, strip.Color(0, 0, 0));
 
    notice.show();
 
  for (int i = 0; i < 6; i++) // 初始化所有灯都为灭
 
  {
 
    strip.setPixelColor(i, strip.Color(0, 0, 0));
 
    strip.show();
 
  }
 
writecommand();    //语音模块配置
 
}
 
//LOOP====================================
 
void LOOP_priority_1ST()
 
{
 
  if (millis() < timer_voice) {
 
    timer_voice = millis();  //同步
 
  }
 
  if (millis() - timer_voice < 10000)  //从有配置指令声音输入开始计时
 
  {
 
    notice.setPixelColor(0,notice.Color(255, 255, 255));
 
    notice.show();
 
  }
 
  else
 
  {
 
    notice.setPixelColor(0,notice.Color(0, 0, 0));
 
    notice.show();
 
    flag_on = 0;
 
  }
 
 
 
  if (VOICE.available())
 
  {
 
    String cmd = "";
 
    if (VOICE.available()) //如果从语音芯片接收到用户的语音输入数据
 
    {
 
      cmd += char(VOICE.read()); //读出串口内的内容
 
      delay(10);
 
      cmd += char(VOICE.read());
 
      delay(10);
 
    }
 
    Serial.println(flag_on);
 
    Serial.println(cmd);
 
    if (cmd == "pp") //如果是语音开关指令对应的内容
 
    {
 
      DEBUG.println("Voice IN!");  //在串口提示 输入声音
 
      AUDIO.choose(1);
 
      delay(2000);
 
      AUDIO.pause();
 
      flag_on = 1;
 
      notice.Color(0, 0, 0);
 
      timer_voice = millis(); //记录当前的系统运行时间
 
    }
 
    if (flag_on)  //如果进入了语音输入状态
 
    {
 
      c = judge(cmd);
 
      DEBUG.print("C is :");
 
      DEBUG.println(c);
 
      switch (c)  //根据不同的语音指令,选择对应的应答
 
      {
 
        case 1:          //名字
 
          timer_voice = 0;
 
          AUDIO.choose(4);
 
          timer_voice = millis();
 
          break;
 
        case 2:        //年龄
 
          timer_voice = 0;
 
          AUDIO.choose(6);
 
          timer_voice = millis();
 
          break;
 
        case 3:                      //讲故事
 
          timer_voice = 0;
 
          AUDIO.choose(3);
 
          timer_voice = millis();
 
          delay(9000);    //防止误触发打断
 
          break;
 
        case 4:                //背诗
 
          timer_voice = 0;
 
          AUDIO.choose(2);
 
          delay(3000);
 
          AUDIO.choose(5);
 
          delay(10000);
 
          timer_voice = millis();
 
          break;
 
        case 5:                      //天气如何
 
          timer_voice = 0;
 
          am2321.read();
 
          temperature = am2321.temperature/10.0;
 
          Serial.println(temperature);
 
          if(temperature<20)AUDIO.choose(15);
 
          if(temperature>=20&&temperature<27)AUDIO.choose(14);
 
          if(temperature>=27)AUDIO.choose(16);
 
          timer_voice = millis();
 
          break;
 
        case 6:                    //好黑
 
          timer_voice = 0;
 
          AUDIO.choose(9);
 
          colorWipe(color[8]);
 
          timer_voice = millis();
 
          break;
 
        case 7:                      //再见
 
          timer_voice = 0;
 
          AUDIO.choose(11);
 
          timer_voice = millis();
 
          break;
 
        case 8:              //傻瓜
 
          timer_voice = 0;
 
          AUDIO.choose(12);
 
          timer_voice = millis();
 
          break;
 
        case 9:                    //关灯
 
          timer_voice = 0;
 
          AUDIO.choose(10);        //好的
 
          colorWipe(color[0]);
 
          timer_voice = millis();
 
          break;
 
        case 10:                  //谢谢
 
          timer_voice = 0;
 
          AUDIO.choose(13);        //不客气
 
          timer_voice = millis();
 
          break;
 
          case 11:                  //吹泡
 
          timer_voice = 0;
 
          digitalWrite(6,HIGH);
 
          delay(8000);
 
          digitalWrite(6,LOW);
 
          timer_voice = millis();
 
          break;
 
        case 0:
 
          timer_voice = 0;
 
          AUDIO.pause();
 
          timer_voice = millis();
 
          break;
 
      }
 
      while (VOICE.available()){
 
      VOICE.read();}
 
    }
 
  }
 
}
 
 
 
 
 
int judge(String cmd)
 
{
 
  int c;
 
  if (cmd == mz)c = 1;
 
  if (cmd == nl)c = 2;
 
  if (cmd == gs)c = 3;
 
  if (cmd == sg)c = 4;
 
  if (cmd == wd)c = 5;
 
  if (cmd == kd)c = 6;
 
  if (cmd == zj)c = 7;
 
  if (cmd == sm)c = 8;
 
  if (cmd == gd)c = 9;
 
  if (cmd == xx)c = 10;
 
  if(cmd == cp)c = 11;
 
  if (cmd == "pp") {
 
    c = 0;
 
  }
 
  return c;
 
}
 
 
 
void writecommand()
 
{
 
  VOICE.println("{d1}");
 
  delay(200);
 
  VOICE.println("{d1}");   //确认进入调试模式
 
  delay(200);
 
  VOICE.println("{c0}");     //清除已有指令
 
  delay(200);
 
  VOICE.println("{a0pao pao|s0pp}"); //开启语音指令
 
  delay(200);
 
  VOICE.println("{a0ni de ming zi|s0mz}"); //你的名字
 
  delay(200);
 
  VOICE.println("{a0ni de nian ling|s0nl}"); // 你的年龄
 
  delay(200);
 
  VOICE.println("{a0jiang gu shi|s0gs}");   //讲故事
 
  delay(200);
 
  VOICE.println("{a0bei shi|s0sg}"); //背诗
 
  delay(200);
 
  VOICE.println("{a0sha gua|s0sm}"); //傻瓜
 
  delay(200);
 
//  VOICE.println("{a0tian qi ru he|s0wd}"); //天气如何
 
//  delay(200);
 
  VOICE.println("{a0kai deng|s0kd}"); //开灯
 
  delay(200);
 
  VOICE.println("{a0guan deng|s0gd}"); //关灯
 
  delay(200);
 
  VOICE.println("{a0zai jian|s0zj}"); //再见
 
  delay(200);
 
  VOICE.println("{a0xie xie|s0xx}"); //谢谢
 
  delay(200);
 
  VOICE.println("{l0}");     //加载
 
  delay(200);
 
  VOICE.println("{d0}");   //退出调试
 
  delay(200);
 
}
 
void colorWipe(uint32_t c) {
 
  for (uint16_t i = 0; i < strip.numPixels(); i++)
 
  {
 
    strip.setPixelColor(i, c);
 
    strip.show();
 
  }
 
}
 
 
</source>
 
</source>
*def.h
+
*程序中的语音识别
 
<source lang="cpp">
 
<source lang="cpp">
#include "Arduino.h"
+
if (VOICE.available()
 
+
 
+
    String cmd = ""; 
#include <SoftwareSerial.h>
+
    if (VOICE.available()) //如果从语音芯片接收到用户的语音输入数据 
//定义蓝牙通信串口
+
    { 
//SoftwareSerial mySerial(4, 5); // RX, TX
+
        cmd += char(VOICE.read()); //读出串口内的内容 
 
+
        delay(10); 
//定义串口
+
        cmd += char(VOICE.read()); 
//#define YUYIN mySerial   
+
        delay(10); 
#define VOICE Serial1
+
    } 
#define DEBUG Serial
+
 
 
String mz = "mz";
 
String nl = "nl";
 
String gs = "gs";
 
String sg = "sg";
 
String wd = "wd";
 
String kd = "kd";
 
String zj = "zj";
 
String sm = "sm";
 
String gd = "gd";
 
String xx = "xx";
 
String zl = "zl";
 
String cp = "cp";
 
 
 
int led_style=2;
 
int led_style_vol=2;
 
//int led_style_cache=0;
 
 
 
boolean led_sta=true;
 
//定义亮度
 
#define led_brightness  3
 
unsigned long led_time;
 
 
</source>
 
</source>
*JQ6500.cpp
+
*功能实现(以温度为例)
 
<source lang="cpp">
 
<source lang="cpp">
//  
+
case 5:                       //天气如何 
// JQ6500 audio library for Arduino
+
timer_voice = 0;        //重置计时 
//
+
am2321.read();           //读取传感器 
 
+
temperature = am2321.temperature / 10.0; 
#include "JQ6500.h"
+
Serial.println(temperature);    //Debug使用 
#include "JQ6500_def.h"
+
if(temperature < 20)AUDIO.choose(15);   //根据温度播放不同语音 
#include <SoftwareSerial.h>
+
if(temperature >= 20 && temperature < 27)AUDIO.choose(14); 
 
+
if(temperature >= 27)AUDIO.choose(16); 
JQ6500::JQ6500(SoftwareSerial *ser) {
+
timer_voice = millis();            //同步时间 
    common_init();
+
break; 
audioSwSerial = ser;
 
}
 
 
 
JQ6500::JQ6500(HardwareSerial *ser) {
 
    common_init();
 
audioHwSerial = ser;
 
}
 
 
 
void JQ6500::common_init(void){
 
audioSwSerial = NULL;
 
audioHwSerial = NULL;
 
 
}
 
 
 
void JQ6500::begin(uint16_t baud){
 
if(audioSwSerial) audioSwSerial->begin(baud);
 
else   audioHwSerial->begin(baud);
 
delay(10);
 
}
 
 
 
void JQ6500::sendCommand(uint8_t cmd, uint8_t *buf, uint16_t len){
 
sendBuffer[0] = STX;
 
sendBuffer[1] = len+2;
 
sendBuffer[2] = cmd;
 
if(len > 0)
 
memcpy(sendBuffer+3, buf, len);
 
sendBuffer[len+3] = ETX;
 
if(audioSwSerial)
 
audioSwSerial->write(sendBuffer, 4+len);
 
else
 
audioHwSerial->write(sendBuffer, 4+len);
 
delay(100);
 
}
 
 
 
void JQ6500::next(){
 
 
sendCommand(CMD_NEXT, NULL, 0);
 
}
 
 
 
void JQ6500::prev(){
 
 
sendCommand(CMD_PREV, NULL, 0);
 
}
 
 
 
void JQ6500::choose(uint16_t num){
 
cmdBuffer[0] = num>>8;
 
cmdBuffer[1] = num&0x00FF;
 
sendCommand(CMD_CHOOSE, cmdBuffer, 2);
 
}
 
 
 
void JQ6500::volUp(){
 
 
sendCommand(CMD_UP, NULL, 0);
 
}
 
 
 
void JQ6500::volDown(){
 
 
sendCommand(CMD_DOWN, NULL, 0);
 
}
 
 
 
void JQ6500::volumn(uint8_t vol){
 
cmdBuffer[0] = vol;
 
sendCommand(CMD_VOL, cmdBuffer, 1);
 
}
 
 
 
void JQ6500::eq(uint8_t eq){
 
cmdBuffer[0] = eq;
 
sendCommand(CMD_EQ, cmdBuffer, 1);
 
}
 
 
 
void JQ6500::setDevice(uint8_t device){
 
cmdBuffer[0] = device;
 
sendCommand(CMD_DEVICE, cmdBuffer, 1);
 
}
 
 
 
void JQ6500::sleep(){
 
 
sendCommand(CMD_SLEEP, NULL, 0);
 
}
 
 
 
void JQ6500::reset(){
 
 
sendCommand(CMD_RESET, NULL, 0);
 
}
 
 
 
void JQ6500::play(){
 
 
sendCommand(CMD_PLAY, NULL, 0);
 
}
 
 
 
void JQ6500::pause(){
 
 
sendCommand(CMD_PAUSE, NULL, 0);
 
}
 
 
 
void JQ6500::folder(uint8_t temp){
 
cmdBuffer[0] = temp;
 
sendCommand(CMD_FOLDER, cmdBuffer, 1);
 
}
 
 
 
void JQ6500::setMode(uint8_t temp){
 
cmdBuffer[0] = temp;
 
sendCommand(CMD_MODE, cmdBuffer, 1);
 
}
 
 
 
void JQ6500::chooseFile(uint8_t folder, uint8_t file){
 
cmdBuffer[0] = folder;
 
cmdBuffer[1] = file;
 
sendCommand(CMD_FILE, cmdBuffer, 2);
 
}
 
 
 
void JQ6500::init(uint8_t device, uint8_t mode, uint8_t vol){
 
begin(9600);
 
delay(300);
 
reset();
 
setDevice(device);
 
setMode(mode);
 
volumn(vol);
 
}
 
 
 
 
 
uint16_t JQ6500::dataParse(){
 
uint16_t sum = 0;
 
uint8_t temp;
 
if(audioSwSerial){
 
while(audioSwSerial->available()){
 
temp = char(audioSwSerial->read());
 
if(temp>47&&temp<58){
 
temp -=48; 
 
}else if(temp>96&&temp<103){
 
temp -=87; 
 
}
 
sum = sum*16+temp;
 
}
 
}else{
 
while(audioHwSerial->available()){
 
temp = char(audioHwSerial->read());
 
if(temp>47&&temp<58){
 
temp -=48; 
 
}else if(temp>96&&temp<103){
 
temp -=87; 
 
}
 
sum = sum*16+temp;
 
}
 
}
 
return sum;
 
}
 
 
 
uint16_t JQ6500::queryNum(uint8_t cmd){
 
if(audioSwSerial)
 
audioSwSerial->flush();
 
else
 
audioHwSerial->flush();
 
sendCommand(cmd, NULL, 0);
 
    delay(100);
 
return dataParse();
 
}
 
 
 
uint16_t JQ6500::queryTF(){
 
return queryNum(QUERY_TF);
 
}
 
 
 
uint16_t JQ6500::queryTFFile(){
 
    return queryNum(QUERY_TF_FILE);
 
}
 
 
 
uint16_t JQ6500::queryFlash(){
 
    return queryNum(QUERY_FLASH);
 
}
 
 
 
uint16_t JQ6500::queryFlashFile(){
 
    return queryNum(QUERY_FLASH_FILE);
 
}
 
 
 
uint16_t JQ6500::queryTotalTime(){
 
    return queryNum(QUERY_TTIME);
 
}
 
 
 
uint16_t JQ6500::queryPlayTime(){
 
    return queryNum(QUERY_PTIME);
 
}
 
 
 
String JQ6500::queryName(){
 
String nameCache = "";
 
char temp;
 
uint16_t i = 0;
 
if(audioSwSerial)
 
audioSwSerial->flush();
 
else
 
audioHwSerial->flush();
 
sendCommand(QUERY_NAME, NULL, 0);
 
    delay(100);
 
if(audioSwSerial){
 
while(audioSwSerial->available()){
 
temp = audioSwSerial->read();
 
nameCache += temp;
 
if(temp == 32){
 
i++;
 
}else{
 
i = 0;
 
}
 
if(i >= 3){
 
i = 0;
 
nameCache.replace("  ", ".");
 
}
 
}
 
}else{
 
while(audioHwSerial->available()){
 
temp = audioHwSerial->read();
 
nameCache += temp;
 
if(temp == 32){
 
i++;
 
}else{
 
i = 0;
 
}
 
if(i >= 3){
 
i = 0;
 
nameCache.replace("  ", ".");
 
}
 
}
 
}
 
return nameCache;
 
}
 
 
 
//
 
// END OF FILE
 
//
 
</source>
 
*JQ6500.h
 
<source lang="cpp">
 
//
 
// JQ6500 audio library for Arduino
 
// VERSION: 0.1.0
 
//
 
 
 
#ifndef __JQ6500_H__
 
#define __JQ6500_H__
 
 
 
#include <Arduino.h>
 
#include <SoftwareSerial.h>
 
 
#define AUDIO_VERSION "0.1.0"
 
 
 
#define STX 0x7E
 
#define ETX 0xEF
 
 
 
#define CMD_NEXT    0x01
 
#define CMD_PREV    0x02
 
#define CMD_CHOOSE  0x03
 
#define CMD_UP      0x04
 
#define CMD_DOWN    0x05
 
#define CMD_VOL    0x06
 
#define CMD_EQ      0x07
 
#define CMD_DEVICE  0x09
 
#define CMD_SLEEP  0x0A
 
#define CMD_RESET  0x0C
 
#define CMD_PLAY    0x0D
 
#define CMD_PAUSE  0x0E
 
#define CMD_FOLDER  0x0F
 
#define CMD_MODE    0x11
 
#define CMD_FILE    0x12
 
 
 
#define QUERY_STA  0x42
 
#define QUERY_VOL  0x43
 
#define QUERY_EQ    0x44
 
#define QUERY_MODE  0x45
 
#define QUERY_VERSION 0x46
 
#define QUERY_TF    0x47
 
#define QUERY_DISK  0x48
 
#define QUERY_FLASH 0x49
 
#define QUERY_TF_FILE 0x4B
 
#define QUERY_DISK_FILE 0x4C
 
#define QUERY_FLASH_FILE 0x4D
 
#define QUERY_PTIME 0x50
 
#define QUERY_TTIME 0x51
 
#define QUERY_NAME  0x52
 
#define QUERY_FILES 0x53
 
 
 
 
 
class JQ6500{
 
public:
 
JQ6500(SoftwareSerial *ser);
 
JQ6500(HardwareSerial *ser);
 
 
void begin(uint16_t baud);
 
void next();
 
void prev();
 
void choose(uint16_t num);
 
void volUp();
 
void volDown();
 
void volumn(uint8_t vol);
 
void eq(uint8_t eq);
 
void setDevice(uint8_t device);
 
void sleep();
 
void reset();
 
void play();
 
void pause();
 
void folder(uint8_t temp);
 
void setMode(uint8_t temp);
 
void chooseFile(uint8_t folder, uint8_t file);
 
void init(uint8_t device, uint8_t mode, uint8_t vol);
 
 
uint16_t queryTF();
 
uint16_t queryTFFile();
 
uint16_t queryFlash();
 
uint16_t queryFlashFile();
 
uint16_t queryTotalTime();
 
 
 
uint16_t queryPlayTime();
 
String queryName();
 
 
private:
 
uint8_t sendBuffer[8];
 
uint8_t cmdBuffer[8];
 
 
 
SoftwareSerial *audioSwSerial;
 
HardwareSerial *audioHwSerial;
 
 
 
void common_init(void);
 
void sendCommand(uint8_t cmd, uint8_t *buf, uint16_t len);
 
uint16_t dataParse();
 
uint16_t queryNum(uint8_t cmd);
 
};
 
 
 
#endif
 
//
 
// END OF FILE
 
//
 
</source>
 
JQ6500_def.h
 
<source lang="cpp">
 
//
 
// AM2321 Temperature & Humidity Sensor library for Arduino
 
// VERSION: 0.1.0
 
//
 
// The MIT License (MIT)
 
//
 
// Copyright (c) 2013 Wang Dong
 
//
 
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
// of this software and associated documentation files (the "Software"), to deal
 
// in the Software without restriction, including without limitation the rights
 
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
// copies of the Software, and to permit persons to whom the Software is
 
// furnished to do so, subject to the following conditions:
 
//
 
// The above copyright notice and this permission notice shall be included in
 
// all copies or substantial portions of the Software.
 
//
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
// THE SOFTWARE.
 
//
 
 
 
#ifndef __JQ6500_DEF_H__
 
#define __JQ6500_DEF_H__
 
 
 
#define EQ_NORMAL    0x00
 
#define EQ_POP    0x01
 
#define EQ_ROCK  0x02
 
#define EQ_JAZZ      0x03
 
#define EQ_CLASSIC    0x04
 
#define EQ_BASE 0x05
 
 
 
#define DEVICE_U    0x00
 
#define DEVICE_TF    0x01
 
#define DEVICE_AUX  0x02
 
#define DEVICE_SLEEP    0x03
 
#define DEVICE_FLASH    0x04
 
 
 
#define MODE_ALL 0x00
 
#define MODE_FOL 0x01
 
#define MODE_ONE 0x02
 
#define MODE_RAM 0x03
 
#define MODE_ONE_STOP 0x04
 
 
 
 
 
#endif
 
//
 
// END OF FILE
 
//
 
</source>
 
Audio.h
 
<source lang="cpp">
 
#include "arduino.h"
 
#include <EEPROM.h>
 
 
 
#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp[i]);}
 
#define EEPROM_read(address, p)  {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp[i]=EEPROM.read(address+i);}
 
 
 
struct config_type
 
{
 
  int EEPROM_music_mode;
 
  int EEPROM_music_vol;
 
};
 
 
 
config_type config;      // 定义结构变量config,并定义config的内容
 
 
 
void eeprom_WRITE(int mode, int vol)
 
{
 
  config_type config;      // 定义结构变量config,并定义config的内容
 
  config.EEPROM_music_mode=mode;
 
  config.EEPROM_music_vol=vol;
 
 
 
  EEPROM_write(0, config); // 变量config存储到EEPROM,地址0写入
 
}
 
 
 
config_type eeprom_READ()
 
{
 
  config_type config_readback;
 
  EEPROM_read(0, config_readback);
 
  return config_readback;
 
}
 
</cpp>
 
<source lang="cpp">
 
#include "arduino.h"
 
 
 
int vol,volCache;
 
unsigned long time_cache=0;
 
 
 
int keyRead()
 
{
 
  if(analogRead(A6)<10)
 
  {
 
    delay(50);
 
    if(analogRead(A6)<10)
 
      return 1;
 
  }
 
  if(analogRead(A6)>200 && analogRead(A6)<300)
 
  {
 
    delay(50);
 
    if(analogRead(A6)>200 && analogRead(A6)<300)
 
      return 2;
 
  }
 
  if(analogRead(A6)>300 && analogRead(A6)<400)
 
  {
 
    delay(50);
 
    if(analogRead(A6)>300 && analogRead(A6)<400)
 
      return 3;
 
  }
 
  return 0;
 
}
 
 
 
int keyGet()
 
{
 
  int key = 0;
 
  vol = keyRead(); //检测输入动作
 
  if(vol==0){
 
      if(volCache == 1){
 
          key = 1;
 
      }else if(volCache > 1){
 
          key = volCache + 3;
 
      }else{
 
          key = 0;
 
      }
 
      time_cache=millis();
 
  }
 
  volCache = vol;
 
  if(millis() > time_cache + 1000){
 
      key = vol + 1;
 
      volCache = 0;
 
  } 
 
  return key;
 
}
 
 
</source>
 
</source>
  
 
==视频==
 
==视频==

2015年12月15日 (二) 10:53的最新版本

概述

  • 项目名称:Microduino语言情景灯
  • 目的:通过语音控制彩灯的各种亮法
  • 难度:中
  • 耗时:2小时
  • 制作者:
  • 简介:

本次教程我们使用Microduino产品模块快速搭建一个可以识别人类语音的灯光控制系统,玩家可以迅速上手,并且可以通过说话,控制灯光模块的亮灭,选色等功能。

材料清单

  • Microduino设备
模块 数量 功能
Microduino-Core+/zh 1 核心板
Microduino-USBTTL/zh 1 下载程序
Microduino-BM/zh 1 供电
Microduino-BT/zh 1 无线通信
Microduino-Duo-H/zh 1 平面扩展
Microduino-Sensorhub/zh 1 连接传感器
Microduino-Lamp/zh 1 连接传感器
  • 其他设备
模块 数量 功能
锂电池 1 供电
Sensor连接线 1 下载程序
语音识别版和输入话筒 1 语音套件,识别声音
发光二极管 1 语音输入指示
Micro USB数据线 1 下载程序

实验原理

语音情景灯模块的原理是记录语音和情景的一一映射关系,通过拼音识别输入的语音,返回给核心对应的情景编号,核心根据得到的情景编号,通过模拟口控制灯光模块每盏led灯的亮灭,实现不同情境下的不同颜色组合。 整个灯光控制系统包括四个部分:

  • 供电系统

使用[Microduino-BM]电源管理模块和外接电池组合为语音灯供电

  • 中央处理器

中央处理器是语音情景灯系统的核心。采用Microduino-Core+作为核心。

  • 无线通讯

语音情景灯系统采用Bluetooth无线通讯方案,使用[Microduino-BT(4.0)]模块,通讯速度响应快,在空阔地域的控制范围大概8米左右。

  • 语音控制

采集并识别语音内容。

套件使用Microduino-Lamp模块作为发光设备,该模块级联了6盏RGB3色彩灯,并可以使用相应的库函数控制每盏彩灯的颜色,为了清晰说明彩灯的控制方法,用一个简单的程序举例。 打开Arduino IDE,在文件(File)—>示例(Examples)—>_99_LCD_NeoPixel目录下,点开例程strandtest。

Emotionlightlib.jpg
#include <Adafruit_NeoPixel.h> 
#define PIN 6 //定义控制引脚
// 参数 1 = strip中彩灯的数目 
// 参数 2 = 引脚号
// 参数 3 = 彩灯类型, 可多选(前两个中选一个,后两个中选一个): 
//   NEO_RGB     Pixels are wired for RGB bitstream 
//   NEO_GRB     Pixels are wired for GRB bitstream 
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels) 
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip) 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800); 
void setup() 
{ 
    strip.begin(); 
    strip.show(); //初始化所有彩灯都为灭
} 
void loop() 
{ 
    // 点亮彩灯的方法 
    colorWipe(strip.Color(255, 0, 0), 50); // 点亮红色
    colorWipe(strip.Color(0, 255, 0), 50); // 点亮绿色
    colorWipe(strip.Color(0, 0, 255), 50); // 点亮蓝色
    rainbow(20); 
    rainbowCycle(20); 
} 
//用“c”所代表的颜色依次点亮各盏彩灯,每点亮一盏等“wait”秒
void colorWipe(uint32_t c, uint8_t wait) 
{ 
    for(uint16_t i = 0; i < strip.numPixels(); i++)  //依次点亮
    { 
       strip.setPixelColor(i, c); //这个函数用于把第i盏灯用“c”所指颜色点亮
        strip.show(); //这个函数会将setPixelColor函数所写入的控制信息显示
                        //出来,也就是靠它点亮LAMP模块 
        delay(wait); 
    } 
} 

void rainbow(uint8_t wait) //彩虹显示
{ 
    uint16_t i, j; 
 
    for(j = 0; j < 256; j++)  //渐变255种颜色
    { 
      for(i = 0; i < strip.numPixels(); i++) //依次点亮彩灯,间隔wait毫秒
        { 
            strip.setPixelColor(i, Wheel((i + j) & 255)); 
        } 
        strip.show(); 
        delay(wait); 
    } 
} 
// 与上面的函数稍有区别,添加了彩虹的循环
void rainbowCycle(uint8_t wait) 
{ 
    uint16_t i, j; 
 
    for(j = 0; j < 256 * 5; j++) //彩虹循环5次
    { 
        for(i = 0; i < strip.numPixels(); i++) 
        { 
            strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));  //为了循环而添加的数学变换
        } 
        strip.show(); 
        delay(wait); 
    } 
} 
// 输入0-255任意一个数得到对应的唯一的一种颜色 
// 颜色会从红-绿->蓝->红依次渐变循环 
uint32_t Wheel(byte WheelPos) 
{ 
    if(WheelPos < 85) 
    { 
        return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 
    } 
    else if(WheelPos < 170) 
    { 
        //因为WheelPos * 3在85到170的情况下会超过255,因此要先自减85 
        WheelPos -= 85; 
        return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); 
    } 
    else 
    { 
        //因为WheelPos * 3在170以上的情况下会超过255,因此要先自减170 
        WheelPos -= 170; 
        return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); 
    } 

文档

调试过程

  • 程序下载

Microduino-Core+/zhMicroduino-USBTTL/zh堆叠在一起.用数据线将写好的程序通过Microduino-USBTTL/zh上传到Microduino-Core+/zh上。 注意:最好不要将所有模块堆叠在一起之后再上传程序

Download1.jpg

找到该程序的物理位置,"语音情景灯/ EGGROOM/ EGGROOM.ino",双击即可

Emotionlightopen.jpg

程序下载 点击"√",编译程序。 点击【工具】,选择正确的板+处理器+端口。 点击"→",进行上传。

Downloadselectcore+.jpg
  • 音频下载

将TF卡安装到Audio模块上,之后使用USB线将Audio模块连接到电脑上。此时会识别出一个可移动磁盘。

Tf1.png

在识别到的磁盘中新建文件夹命名为01,之后将语音按命名的数字顺序复制到文件夹01中。至此音频存储完毕。

Tf2.png
Tf3.png

搭建

将Microduino-Duo-V底板用螺丝固定在顶板上,顶板与底板形状相同,可任选其一。

Pp1.png

搭建硬件电路,将用到的设备叠加起来 Microduino-Amplifier Microduino-Audio Microduino-sensorhub 以上模块放置在Duo-V的一端 Microduino-Duo-V 以下模块放置在Duo-V的另一端 Microduino-Lamp Microduino-Core+ Microduin-USBTTL 注: Microduino-DUO-V作为底板,降低整体高度,同时固定Lamp模块在一侧提供照明功能。Microduino-Lamp和Microduino-sensorhub放在两侧的最上面。拼装时,先不要装上Sensorhub,这样方便下面的安装。 按照如图方式,将温湿度传感器、麦克风和ColorLED装在前面板上。用螺丝固定。

Pp2.png

使用如图所示的方式,用底座将喇叭固定在侧板上,喇叭的连线留在朝向图左侧的方向,方便后续安装。此时不要将左右两块板与前面板拼接在一起,先拿掉一侧的侧板,方便后续安装

Pp3.png

使用连线连接语音模块,注意连线方向,左数第一个双头接口是GND及VCC,第二个双头端口是RX,DX,如果无法确定方向就按照图中的方向连接语音识别模块。

Pp4.png

注意:如果想直接使用USBTTL+Sensorhub测试语音识别模块,则语音模块端的RX和TX要和上图方向反过来连接。 对应下图,使用传感器线连接传感器,ColorLED连接A2端口,温湿度传感器连接右下角SDASCL接口,语音模块连接D2/D3接口。连接好后,将Sensorhub插在Audio模块上面,置于最上端.

Microduino-sensorhub rule.JPG

此时的状态应该是传感器都已经连接到Sensorhub上,所有模块都已经拼接在底板上。喇叭用卡子固定在侧板上。之后将剩下的底板插在侧板上,然后扣上另一块侧板。

Pp6.png

之后将前板和后板插上用于固定两块侧板。最后将上下两个头部插好。 最后使用插销将所有固定扣固定住即可。

Pp7.png

整体调试

打开语音情景灯的电源,首先等待指示灯亮起2-3秒钟,之后熄灭。这时对麦克风说“泡泡”,是语音输入的开关语句,也就是说要先说这句话,看到语音输入指示灯(ColorLED)亮起后,再说各种语音命令,每说一条指令后都有5秒时间继续说下一条指令,若没有语音输入则指示灯熄灭,需要重新说“泡泡”进入语音输出状态。 本例的语音开关指令是“泡泡”,所以请用普通话清晰发声“泡泡”,观察ColorLED是否点亮,如果点亮就继续说出命令,如“讲故事”,灯光模块就会被点亮,如果没有语音回复“hi,我是泡泡”,则继续说“泡泡”直到ColorLED点亮并有语音回复再说指令。

注意问题

  • 每次语音输入命令,都要先说f1对应的内容,本例是“美科”读者可根据自己的设置输入
  • 二极管极性的判断,反接的话二极管不会发光

程序说明

  • 语音模块配置
void writecommand() 
{ 
    VOICE.println("{d1}"); 
    delay(200); 
    VOICE.println("{d1}");    //确认进入调试模式 
    delay(200); 
    VOICE.println("{c0}");      //清除已有指令 
    delay(200); 
    VOICE.println("{a0pao pao|s0pp}");  //开启语音指令 
    delay(200); 
    VOICE.println("{a0ni de ming zi|s0mz}"); //你的名字 
    delay(200); 
    VOICE.println("{a0ni de nian ling|s0nl}");  // 你的年龄 
    delay(200); 
    VOICE.println("{a0jiang gu shi|s0gs}");   //讲故事 
    delay(200); 
    VOICE.println("{a0bei shi|s0sg}"); //背诗 
    delay(200); 
    VOICE.println("{a0sha gua|s0sm}"); //傻瓜 
    delay(200); 
    VOICE.println("{a0tian qi ru he|s0wd}"); //天气如何 
    delay(200); 
    VOICE.println("{a0hao hei|s0kd}");  //好黑 
    delay(200); 
    VOICE.println("{a0guan deng|s0gd}");  //关灯 
    delay(200); 
    VOICE.println("{a0zai jian|s0zj}");  //再见 
    delay(200); 
    VOICE.println("{a0xie xie|s0xx}");  //谢谢 
    delay(200); 
    VOICE.println("{l0}");     //加载 
    delay(200); 
    VOICE.println("{d0}");    //退出调试 
    delay(200); 
} 
  • 程序中的语音识别
if (VOICE.available()) 
{ 
    String cmd = ""; 
    if (VOICE.available()) //如果从语音芯片接收到用户的语音输入数据 
    { 
        cmd += char(VOICE.read()); //读出串口内的内容 
        delay(10); 
        cmd += char(VOICE.read()); 
        delay(10); 
    } 
} 
  • 功能实现(以温度为例)
case 5:                       //天气如何 
timer_voice = 0;        //重置计时 
am2321.read();           //读取传感器 
temperature = am2321.temperature / 10.0; 
Serial.println(temperature);    //Debug使用 
if(temperature < 20)AUDIO.choose(15);   //根据温度播放不同语音 
if(temperature >= 20 && temperature < 27)AUDIO.choose(14); 
if(temperature >= 27)AUDIO.choose(16); 
timer_voice = millis();            //同步时间 
break; 

视频