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

来自Microduino Wikipedia
跳转至: 导航搜索
(Created page with "{| style="width: 800px;" |- | ==概述== *项目名称:Microduino语言情景灯 *目的:通过语音控制彩灯的各种亮法 *难度:中 *耗时:2小时 *制作者...")
 
搭建
 
(未显示同一用户的19个中间版本)
第53行: 第53行:
 
使用[Microduino-BM]电源管理模块和外接电池组合为语音灯供电
 
使用[Microduino-BM]电源管理模块和外接电池组合为语音灯供电
 
*中央处理器
 
*中央处理器
中央处理器是语音情景灯系统的核心。采用[Microduino-Core+]作为核心。
+
中央处理器是语音情景灯系统的核心。采用[[Microduino-Core+]]作为核心。
 
*无线通讯
 
*无线通讯
 
语音情景灯系统采用Bluetooth无线通讯方案,使用[Microduino-BT(4.0)]模块,通讯速度响应快,在空阔地域的控制范围大概8米左右。
 
语音情景灯系统采用Bluetooth无线通讯方案,使用[Microduino-BT(4.0)]模块,通讯速度响应快,在空阔地域的控制范围大概8米左右。
 
*语音控制
 
*语音控制
 
采集并识别语音内容。
 
采集并识别语音内容。
[[File:Emotionlightstruct.jpg||600px|center|thumb]]
+
[[File:Emotionlightstruct.jpg||600px|center]]
 
*主要传感器
 
*主要传感器
 
*[[Microduino-Lamp/zh]]
 
*[[Microduino-Lamp/zh]]
 
套件使用Microduino-Lamp模块作为发光设备,该模块级联了6盏RGB3色彩灯,并可以使用相应的库函数控制每盏彩灯的颜色,为了清晰说明彩灯的控制方法,用一个简单的程序举例。
 
套件使用Microduino-Lamp模块作为发光设备,该模块级联了6盏RGB3色彩灯,并可以使用相应的库函数控制每盏彩灯的颜色,为了清晰说明彩灯的控制方法,用一个简单的程序举例。
 
打开Arduino IDE,在文件(File)—>示例(Examples)—>_99_LCD_NeoPixel目录下,点开例程strandtest。
 
打开Arduino IDE,在文件(File)—>示例(Examples)—>_99_LCD_NeoPixel目录下,点开例程strandtest。
[[File:Emotionlightlib.jpg||600px|center|thumb]]
+
[[File:Emotionlightlib.jpg||600px|center]]
 
<source lang="cpp">
 
<source lang="cpp">
 
#include <Adafruit_NeoPixel.h> 
 
#include <Adafruit_NeoPixel.h> 
第151行: 第151行:
 
    } 
 
    } 
 
</source>
 
</source>
 +
 
==文档==
 
==文档==
 
==调试过程==
 
==调试过程==
 
*程序下载
 
*程序下载
将[[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|thumb]]
+
[[File:download1.jpg||400px|center]]
 
找到该程序的物理位置,"语音情景灯/ EGGROOM/ EGGROOM.ino",双击即可
 
找到该程序的物理位置,"语音情景灯/ EGGROOM/ EGGROOM.ino",双击即可
[[File:Emotionlightopen.jpg||600px|center|thumb]]
+
[[File:Emotionlightopen.jpg||500px|center]]
 
程序下载
 
程序下载
 
点击"√",编译程序。
 
点击"√",编译程序。
 
点击【工具】,选择正确的板+处理器+端口。
 
点击【工具】,选择正确的板+处理器+端口。
 
点击"→",进行上传。
 
点击"→",进行上传。
[[File:Downloadselectcore+.jpg||600px|center|thumb]]
+
[[File:Downloadselectcore+.jpg||500px|center]]
*搭建
+
*音频下载
搭建硬件电路,将用到的设备叠加起来(无上下顺序)
+
将TF卡安装到Audio模块上,之后使用USB线将Audio模块连接到电脑上。此时会识别出一个可移动磁盘。
Microduino-Core+
+
[[File:Tf1.png||600px|center]]
Microduino-USBTTL
+
在识别到的磁盘中新建文件夹命名为01,之后将语音按命名的数字顺序复制到文件夹01中。至此音频存储完毕。
Microduino-BT(4.0)
+
[[File:Tf2.png||600px|center]]
Microduino-BM
+
 
Microduino-Duo-H
+
[[File:Tf3.png||600px|center]]
 +
 
 +
==搭建==
 +
将Microduino-Duo-V底板用螺丝固定在顶板上,顶板与底板形状相同,可任选其一。
 +
[[File:Pp1.png||600px|center]]
 +
搭建硬件电路,将用到的设备叠加起来
 +
Microduino-Amplifier
 +
Microduino-Audio
 
Microduino-sensorhub
 
Microduino-sensorhub
 +
以上模块放置在Duo-V的一端
 +
Microduino-Duo-V
 +
以下模块放置在Duo-V的另一端
 
Microduino-Lamp
 
Microduino-Lamp
锂电池
+
Microduino-Core+
[[File:Emotionlight1.jpg||600px|center|thumb]]
+
Microduin-USBTTL
安装发光二极管
+
注:
将发光二极管的负极插在[[Microduino-Sensorhub/zh]]传感器扩展模块的A7管脚,正极插在SDA管脚
+
Microduino-DUO-V作为底板,降低整体高度,同时固定Lamp模块在一侧提供照明功能。Microduino-Lamp和Microduino-sensorhub放在两侧的最上面。拼装时,先不要装上Sensorhub,这样方便下面的安装。
[[File:Emotionlight2.jpg||600px|center|thumb]]
+
按照如图方式,将温湿度传感器、麦克风和ColorLED装在前面板上。用螺丝固定。
将传感器数据线插入第三行第一列插槽,观察这里插线的部分,4根线从左到右分别是GND,VCC,D2,D3接脚(不要看颜色,实物颜色可能与本例不同)
+
[[File:Pp2.png||600px|center]]
[[File:Voidsensor0.jpg||600px|center|thumb]]
+
使用如图所示的方式,用底座将喇叭固定在侧板上,喇叭的连线留在朝向图左侧的方向,方便后续安装。此时不要将左右两块板与前面板拼接在一起,先拿掉一侧的侧板,方便后续安装
[[File:Voidcesensor1.jpg||600px|center|thumb]]
+
[[File:Pp3.png||600px|center]]
安装语音话筒
+
使用连线连接语音模块,注意连线方向,左数第一个双头接口是GND及VCC,第二个双头端口是RX,DX,如果无法确定方向就按照图中的方向连接语音识别模块。
语音话筒无正负极,将两端分别插在语音传感器的MIP和MIN上即可
+
[[File:Pp4.png||350px|center]]
[[File:Voidesensor2.jpg||600px|center|thumb]]
+
注意:如果想直接使用USBTTL+Sensorhub测试语音识别模块,则语音模块端的RX和TX要和上图方向反过来连接。
[[File:Voidsensor3.jpg||600px|center|thumb]]
+
对应下图,使用传感器线连接传感器,ColorLED连接A2端口,温湿度传感器连接右下角SDASCL接口,语音模块连接D2/D3接口。连接好后,将Sensorhub插在Audio模块上面,置于最上端.
*手机APP
+
[[File:Microduino-sensorhub rule.JPG||600px|center]]
安装app
+
此时的状态应该是传感器都已经连接到Sensorhub上,所有模块都已经拼接在底板上。喇叭用卡子固定在侧板上。之后将剩下的底板插在侧板上,然后扣上另一块侧板。
将课件中“app-debug.apk”移动到手机上
+
[[File:Pp6.png||600px|center]]
安装该手机APP
+
之后将前板和后板插上用于固定两块侧板。最后将上下两个头部插好。
在提供的开发包中,包含安卓手机语音情景灯的app,安装app并打开
+
最后使用插销将所有固定扣固定住即可。
[[File:Emotionlightapp1.jpg||600px|center|thumb]]
+
[[File:Pp7.png||600px|center]]
屏幕右上方有两个按键,UPLOAD和NEW。首先介绍NEW,这个按键是用来新建或修改语音命令的
+
 
[[File:Emotionlightapp2.jpg||600px|center|thumb]]
+
==整体调试==
ff这行是这条语音指令的编号,16进制编码,范围从00-ff,编号不能重复。pin yin这行是语音识别的语音拼音,也就是这里输入什么,就要对着话筒说对应的内容才会触发该情景的灯光状态。名称这行是这个情景的描述。新建好后就可以点击save了,这时主界面就会多出一个情景,当要删除这个情景时,在主界面点击它,进入上图界面后,点击Delete即可。
+
打开语音情景灯的电源,首先等待指示灯亮起2-3秒钟,之后熄灭。这时对麦克风说“泡泡”,是语音输入的开关语句,也就是说要先说这句话,看到语音输入指示灯(ColorLED)亮起后,再说各种语音命令,每说一条指令后都有5秒时间继续说下一条指令,若没有语音输入则指示灯熄灭,需要重新说“泡泡”进入语音输出状态。
之后点击UPLOAD按键,会进入下图的界面
+
本例的语音开关指令是“泡泡”,所以请用普通话清晰发声“泡泡”,观察ColorLED是否点亮,如果点亮就继续说出命令,如“讲故事”,灯光模块就会被点亮,如果没有语音回复“hi,我是泡泡”,则继续说“泡泡”直到ColorLED点亮并有语音回复再说指令。
[[File:Emotionlightapp3.jpg||600px|center|thumb]]
+
 
进入到该界面后,打开语音灯系统,点击屏幕右上角的SCAN按钮,可以搜索到蓝牙的地址序列号,点击这个搜索到的蓝牙,进入下图界面
 
[[File:Emotionlightapp4.jpg||600px|center|thumb]]
 
在这个界面点击Upload,会将之前手机配置的各种命令上传到开发板中,上传完毕后,手机端的配置就结束了。
 
*整体调试
 
打开语音情景灯的电源,并点开手机App,使用默认的配置或者配置自己的语音命令,这里需要注意,f1编号的命令(默认为美科meike)是语音输入的开关语句,也就是说要先说这句话,看到语音输入指示灯(发光二极管)亮起后,再说各种语音命令,并且每次输入新命令都要先说f1里的内容。配置好后,点击UPLOAD,选择语音灯的蓝牙,之后上传配置到语音灯的系统。手机端的工作就完成了。
 
最后,拿起话筒,本例的语音开关f1指令用的是“美科”,所以请用普通话清晰发声“美科”,观察发光二极管是否点亮,如果点亮就继续说出命令,如“开灯”,灯光模块就会被点亮,如果发光二极管没有变化,则继续说“美科”直到二极管点亮再说指令。每次提出新的指令都需要先说“美科”。
 
 
==注意问题==
 
==注意问题==
 
*每次语音输入命令,都要先说f1对应的内容,本例是“美科”读者可根据自己的设置输入
 
*每次语音输入命令,都要先说f1对应的内容,本例是“美科”读者可根据自己的设置输入
 
*二极管极性的判断,反接的话二极管不会发光
 
*二极管极性的判断,反接的话二极管不会发光
 
==程序说明==
 
==程序说明==
*主函数
+
*语音模块配置
 
<source lang="cpp">
 
<source lang="cpp">
#include "Micromenu_user.h" 
+
void writecommand() 
#include <Servo.h> 
 
#include <Adafruit_NeoPixel.h> 
 
//EEPROM--------------------- 
 
#include <EEPROM.h>  
 
//用户自定义部分------------------------ 
 
#include <SoftwareSerial.h> 
 
 
 
void setup() 
 
 
    SETUP_begin();     //该函数定义于 Micromenu_user.h 
 
    //用户自定义部分======================== 
 
 
 
 
void loop() 
 
 
 
    { 
+
    VOICE.println("{d1}"); 
        LOOP_priority_1ST(); //该函数定义于 Micromenu_user.
+
    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); 
 
 
 
</source>
 
</source>
*Micromenu_user.h
+
*程序中的语音识别
 
<source lang="cpp">
 
<source lang="cpp">
#include "Arduino.h" 
+
if (VOICE.available()) 
//用户自定义部分------------------------ 
 
#include "def.h" 
 
#include "led.h" 
 
#include "eep.h" 
 
//用户自定义部分------------------------ 
 
 
 
int num_cache = 0; 
 
//用户自定义部分------------------------ 
 
//#include <Servo.h> 
 
//Servo myservo;   创建一个舵机对象 ,在本套件中没有涉及 
 
 
 
int card_sta = 0;    //nothing,true,false 
 
unsigned long door_time = 0; 
 
 
 
//用户自定义部分------------------------ 
 
char pkj[128]; 
 
int num = 0; 
 
boolean buffer_sta = false; 
 
boolean start = false; 
 
 
 
unsigned long timer_voice = millis()
 
boolean voice_sta = false; 
 
 
 
//SETUP=================================== 
 
void SETUP_begin(
 
 
 
    pinMode(SDA, OUTPUT);// 语音输入指示灯的正极 
+
    String cmd = ""
    pinMode(A7, OUTPUT); //语音输入指示灯的负极 
+
    if (VOICE.available()) //如果从语音芯片接收到用户的语音输入数据 
    DEBUG.begin(9600)
 
    VOICE.begin(9600); 
 
    FROM.begin(9600);  //串口通信波特率为9600 
 
 
 
    //EEPROM--------------------- 
 
    eeprom_READ(); 
 
 
 
    /*servo 用A3口控制舵机,本套件不涉及 
 
    myservo.attach(A3); 
 
    myservo.write(20); 
 
    */ 
 
    //led 
 
    strip.begin();    //初始化LED 
 
    for (int i = 0; i < 6; i++) // 初始化所有灯都为灭 
 
 
    { 
 
    { 
        strip.setPixelColor(i, strip.Color(0, 0, 0)); 
+
        cmd += char(VOICE.read()); //读出串口内的内容 
    } 
+
        delay(10); 
    strip.show(); 
+
        cmd += char(VOICE.read()); 
 
 
    analogWrite(A7, LOW); //将A7口设置为低电平,用作语音指示灯负极 
 
 
  
 
//LOOP==================================== 
 
void LOOP_priority_1ST(
 
 
    if (FROM.available())  //如果串口收到蓝牙发送的数据 
 
    { 
 
        char c = FROM.read()
 
 
 
        if (c == '{')  //如果接收到的是左括号,说明蓝牙有数据发过来而且是接收的开始 
 
            buffer_sta = true; 
 
        if (c == '}')  //如果接收到的是右括号说明传输结束了 
 
        { 
 
            start = true;   //标志位置为true,开始后续的处理 
 
            buffer_sta = false; //蓝牙状态接收结束,标志位置为false 
 
        } 
 
 
 
        if (buffer_sta) //当蓝牙正在传数据时 
 
            pkj[num++] = c; //将收到的字符存入字符数组保存 
 
 
 
        delay(1); 
 
    } 
 
 
 
    if (start)  //如果接收到了蓝牙的配置信息就显示在串口监视器上 
 
    { 
 
        DEBUG.print("pkj:"); //在串口打印出接收到的内容 
 
        for (int a = 1; a < num; a++) 
 
            DEBUG.print(pkj[a]); //打印出接收到的所有字符 
 
        DEBUG.println(); //打印一个空格 
 
 
 
        VOICE.write("{"); //向语音芯片中写入接收到的配置数据 
 
        for (int a = 1; a < num; a++) 
 
            VOICE.write(pkj[a]); 
 
        VOICE.write("}"); 
 
 
        delay(10); 
 
        delay(10); 
 
 
        for (int a = 0; a < num; a++)//清空接收的信息 
 
            pkj[a] = NULL; 
 
        num = 0; 
 
 
 
        DEBUG.println("Change OK!"); 
 
        start = false; //显示完把状态设为false避免重复处理 
 
    } 
 
 
 
    //--------------------------- 
 
    if (millis() < timer_voice) 
 
    { 
 
        timer_voice = millis();    //若计时器重新计时,同步 
 
    } 
 
    if (millis() - timer_voice < 5000)  //从有配置指令声音输入开始计时 
 
    { 
 
        voice_sta = true;   //5秒内语音输入指示灯点亮 
 
    } 
 
    else 
 
    { 
 
        voice_sta = false;  //超过5秒指示灯关闭 
 
    } 
 
    digitalWrite(SDA, voice_sta);//通过控制SDA电平的高低开关语音指示灯 
 
 
 
    if (VOICE.available()) //如果从语音芯片接收到用户的语音输入数据 
 
    { 
 
        int c = VOICE.read(); //读出串口内的内容 
 
        //DEBUG.print(c); 
 
        if (c == 0xf1)  //如果是语音开关指令f1对应的内容 
 
        { 
 
            DEBUG.println("Voice IN!");  //在串口提示 输入声音 
 
            timer_voice = millis(); //记录当前的系统运行时间 
 
        } 
 
 
 
        if (voice_sta)   //如果进入了语音输入状态 
 
        { 
 
            switch (c)  //根据不同的语音指令,选择对应的应答 
 
            { 
 
            case 0xa1: 
 
                DEBUG.println("Door Open!"); 
 
                timer_voice = 0; 
 
                // myservo.write(90); 本套件不涉及舵机 
 
                break; 
 
            case 0xa2: 
 
                DEBUG.println("Door Close!"); 
 
                timer_voice = 0; 
 
                // myservo.write(20); 本套件不涉及舵机 
 
                break; 
 
            case 0xb1: //点亮6盏彩灯 
 
                DEBUG.println("Light ON!"); 
 
                timer_voice = 0; 
 
                led_sta = true; 
 
                break; 
 
            case 0xb2: //关闭6盏彩灯 
 
                DEBUG.println("Light OFF!"); 
 
                timer_voice = 0; 
 
                led_sta = false; 
 
                break; 
 
            case 0xc1: 
 
                DEBUG.println("Light TemperatureA!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 1;//选择模式,1是冷暖色调,2是不同单种颜色, 
 
                //3是彩虹循环 
 
                led_style_vol = 1;  //各种颜色模式0-7分别对应灭红澄黄绿青蓝紫 
 
                break; 
 
            case 0xc2: 
 
                DEBUG.println("Light TemperatureB!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 1; 
 
                led_style_vol = 2; 
 
                break; 
 
            case 0xd1: 
 
                DEBUG.println("Light Colorful1!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 2; 
 
                led_style_vol = 1; 
 
                break; 
 
            case 0xd2: 
 
                DEBUG.println("Light Colorful2!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 2; 
 
                led_style_vol = 2; 
 
                break; 
 
            case 0xd3: 
 
                DEBUG.println("Light Colorful3!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 2; 
 
                led_style_vol = 3; 
 
                break; 
 
            case 0xd4: 
 
                DEBUG.println("Light Colorful4!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 2; 
 
                led_style_vol = 4; 
 
                break; 
 
            case 0xd5: 
 
                DEBUG.println("Light Colorful5!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 2; 
 
                led_style_vol = 5; 
 
                break; 
 
            case 0xd6: 
 
                DEBUG.println("Light Colorful6!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 2; 
 
                led_style_vol = 6; 
 
                break; 
 
            case 0xd7: 
 
                DEBUG.println("Light Colorful7!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 2; 
 
                led_style_vol = 7; 
 
                break; 
 
            case 0xe1: 
 
                DEBUG.println("Light RainbowA!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 3; 
 
                led_style_vol = 1; 
 
                break; 
 
            case 0xe2: 
 
                DEBUG.println("Light RainbowB!"); 
 
                timer_voice = 0; 
 
                eeprom_WRITE(); 
 
                led_style = 3; 
 
                led_style_vol = 2; 
 
                break; 
 
            } 
 
        } 
 
    } 
 
 
 
    if (millis() < led_time) led_time = millis();//和之前同理,同步时间 
 
    if (millis() - led_time > 50) 
 
    { 
 
        led_time = millis(); 
 
 
 
        if (led_sta)  //如果是亮灯状态 
 
        { 
 
            switch (led_style)   //根据LED的类型决定亮的方式 
 
            { 
 
            case 1://冷暖色 
 
                colorWipe(color_t[led_style_vol]); 
 
                break; 
 
            case 2://单色 
 
                colorWipe(color[led_style_vol]); 
 
                break; 
 
            case 3://彩虹循环 
 
                rainbowCycle((led_style_vol - 1) * 3); 
 
                break; 
 
            } 
 
        } 
 
        else 
 
        { 
 
            colorWipe(color[0]);   //如果是关灯状态 
 
        } 
 
 
    } 
 
    } 
 
 
 
</source>
 
</source>
*def.h
+
*功能实现(以温度为例)
 
<source lang="cpp">
 
<source lang="cpp">
#include "Arduino.h"  
+
case 5:                       //天气如何 
#include <SoftwareSerial.h> 
+
timer_voice = 0;        //重置计时 
//定义蓝牙通信串口 
+
am2321.read();           //读取传感器 
SoftwareSerial mySerial(4, 5); // RX, TX 
+
temperature = am2321.temperature / 10.0; 
 
+
Serial.println(temperature);    //Debug使用 
//定义串口 
+
if(temperature < 20)AUDIO.choose(15);   //根据温度播放不同语音 
#define FROM mySerial 
+
if(temperature >= 20 && temperature < 27)AUDIO.choose(14); 
//#define FROM Serial 
+
if(temperature >= 27)AUDIO.choose(16); 
#define VOICE Serial1 
+
timer_voice = millis();            //同步时间 
#define DEBUG Serial 
+
break
 
 
int led_style = 0; 
 
int led_style_vol = 0; 
 
//int led_style_cache=0; 
 
 
 
boolean led_sta = true; 
 
//定义亮度 
 
#define led_brightness  3 
 
unsigned long led_time; 
 
</source>
 
*eep.h
 
<source lang="cpp">
 
#include "Arduino.h" 
 
 
 
//USER----------------------------- 
 
#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_led_style_vol; 
 
    int EEPROM_led_style; 
 
}; 
 
 
 
//向EEPROM里写数据 
 
void eeprom_WRITE() 
 
 
    config_type config;    // 定义结构变量config,并定义config的内容 
 
 
 
    config.EEPROM_led_style_vol = led_style_vol; 
 
    config.EEPROM_led_style = led_style; 
 
 
 
    EEPROM_write(0, config); // 变量config存储到EEPROM,地址0写入 
 
 
//从EEPROM里读数据 
 
void eeprom_READ() 
 
 
    config_type config_readback; 
 
    EEPROM_read(0, config_readback); 
 
 
 
    led_style_vol = config_readback.EEPROM_led_style_vol
 
    led_style = config_readback.EEPROM_led_style; 
 
 
 
 
unsigned int freeRam () 
 
 
    extern unsigned int __heap_start, *__brkval; 
 
    unsigned int v; 
 
    return (unsigned int) &v - (__brkval == 0 ? 
 
(unsigned int) &__heap_start : (unsigned int) __brkval); 
 
}  
 
</source>
 
*Led.h
 
<source lang="cpp">
 
#include "arduino.h" 
 
#include <Adafruit_NeoPixel.h> 
 
//定义Lamp模块所用引脚 
 
#define LED_PIN A0 
 
//定义Lamp灯对象,控制6盏彩灯并通过A0口控制 
 
Adafruit_NeoPixel strip = 
 
Adafruit_NeoPixel(6, LED_PIN, NEO_GRB + NEO_KHZ800)
 
//先定义8种颜色,分别是灭,红,澄,黄,绿,青,蓝,紫 
 
uint32_t color[8] = 
 
 
    strip.Color(0, 0, 0), 
 
strip.Color(255 / led_brightness, 0, 0), 
 
strip.Color(255 / led_brightness, 165 / led_brightness, 0), 
 
strip.Color(255 / led_brightness, 255 / led_brightness, 0), 
 
strip.Color(0, 255 / led_brightness, 0), 
 
strip.Color(0, 127 / led_brightness, 255 / led_brightness)
 
strip.Color(0, 0, 255 / led_brightness), 
 
strip.Color(139 / led_brightness, 0, 255 / led_brightness) 
 
}; 
 
 
 
uint32_t color_t[3] = //3种颜色分别为,灭,暖色,冷色 
 
 
    strip.Color(0, 0, 0), 
 
strip.Color(255/led_brightness,137/led_brightness,18/led_brightness),
 
strip.Color(254/led_brightness,249/led_brightness,255/led_brightness) 
 
}; 
 
//设置全部彩灯颜色,参数c是strip.Color(int a, int b, int c)的返回值 
 
//相当于对应颜色的编码 
 
void colorWipe(uint32_t c) 
 
 
    for(uint16_t i = 0; i < strip.numPixels(); i++) 
 
//通过循环达到控制6盏灯的效果 
 
    { 
 
        strip.setPixelColor(i, c);//设置第i个彩灯为c编码对应的颜色 
 
    } 
 
    strip.show(); 
 
 
 
 
// 输入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); 
 
    } 
 
 
 
 
uint16_t i, j; 
 
//控制6盏彩灯以彩虹方式显示颜色 
 
void rainbowCycle(uint8_t wait) 
 
 
    if(j < 256 * 5) 
 
    { 
 
        j++; 
 
        for(i = 0; i < strip.numPixels(); i++) 
 
        { 
 
            strip.setPixelColor(i, 
 
Wheel(((i * 256 / strip.numPixels()) + j) & 255)); 
 
        } 
 
        strip.show(); 
 
        delay(wait); 
 
    } 
 
    else 
 
        j = 0; 
 
}
 
 
</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; 

视频