Funpack第二季第一期-Syntiant_TinyML-语音控制小灯
使用Syntiant TinyML开发板完成对于语音指令识别,并控制LED做出对应的动作
标签
嵌入式系统
Funpack
TinyML
Syntiant
语音控制
vic
更新2022-07-06
539

1.简介

本次选择的是任务一:用自带的麦克风,搭建机器学习模型,使板卡上的LED灯根据中文语音指令(不少于三个指令)呈现出不同效果,如开灯、关灯、闪烁、SOS、呼吸等。

在本项目中,一共训练了五个中文指令:

  • 芝麻开门:唤醒词,开发板在识别到唤醒词之后,才会对下一个识别出来的指令进行对应处理,用以减少误触发的情况;
  • 打开:板载蓝色LED常亮;
  • 关闭:板载蓝色LED熄灭;
  • 闪烁:板载蓝色LED以2秒为周期进行闪烁;
  • 呼吸:板载蓝色LED进入呼吸灯模式。

2.关键代码

2.1.代码初始化

如下代码为初始化函数代码,在里面主要进行如下操作:

  1. 调用syntiant_setup函数完成对于开发板的相关初始化(NDP101就是此初始化);
  2. 操作是将RGB LED三个灯全部设置为低电平,即:全部关闭;
  3. 使能定时器五并且使能定时器中断;
void setup(void)
{
    syntiant_setup();

    digitalWrite(LED_BLUE, LOW);
    digitalWrite(LED_GREEN, LOW);
    digitalWrite(LED_RED, LOW);

    s_timer5.enable(true);
    s_timer5.enableInterrupt(true);
}

2.2.LED状态控制

如下代码为定时器5的中断处理函数,该中断处理函数每隔1ms被触发一次,在该中断处理函数中根据当前led工作模式来执行对应的处理操作:

  • s_led_mode == 0:关闭,此时关闭蓝色LED
  • s_led_mode == 1:打开,此时开启蓝色LED
  • s_led_mode == 2:闪烁,蓝色LED以2秒为周期进行闪烁
  • s_led_mode == 3:呼吸,蓝色LED以呼吸灯方式点亮
void isrTimer5(struct tc_module *const module_inst)
{
    static unsigned int count = 0;
    static int pwm = 0;
    static bool direction = true;

    count++;

    switch (s_led_mode)
    {
        case 0:
            // close
            digitalWrite(LED_BLUE, LOW);
            break;
        case 1:
            // open
            digitalWrite(LED_BLUE, HIGH);
            break;
        case 2:
            // blink
            if ((count % 1000) == 0) {
                digitalWrite(LED_BLUE, !digitalRead(LED_BLUE));
            }
            break;
        case 3:
            // breathing
            if ((count % 5) == 0)
            {
                if (direction) {
                    pwm++;
                    if (pwm >= 255) {
                        direction = false;
                    }
                } else {
                    pwm--;
                    if (pwm <= 0) {
                        direction = true;
                    }
                }

                analogWrite(LED_BLUE, pwm);
            }
                
            break;
        default:
            break;
    }
}

static unsigned int s_led_mode = 0;      // 0:close, 1:open, 2:blink, 3:breathing
static SAMDtimer s_timer5 = SAMDtimer(5, isrTimer5, 1000); // In uS. Interrupt every 1ms

2.3.识别指令处理

如下代码为NDP 101处理完语音数据,获取匹配结果之后调用的回调函数,匹配结果通过event变量进行传递,具体处理流程如下所示:

  1. 如果匹配结果是唤醒词,则将s_awake设置为true;如果不是唤醒词,则检查s_awake是否为true,如果不满足,则直接退出处理;
  2. 在s_awake为true的情况下,判断当前是否noise(噪音)标签,如果是,则直接退出;否则设置s_awake为false之后继续执行;
  3. 依据标签是:open、close、blink、breathing修改s_mode为对应模式,由定时器回调函数中修改LED状态。
/**
 * @brief      Called when a inference matches 1 of the features
 *
 * @param[in]  event          The event
 * @param[in]  confidence     The confidence
 * @param[in]  anomaly_score  The anomaly score
 */
void on_classification_changed(const char *event, float confidence, float anomaly_score) {

    static bool s_awake = false;

    /* 检查是否是唤醒词,如果是唤醒词则对唤醒标志置位 */
    if (strcmp(event, "awake") == 0) {
        s_awake = true;

        return;
    }

    /* 如果之前未出现唤醒词则直接推出 */
    if (!s_awake) {
        Serial.println("no found awake");

        return;
    } else if (strcmp(event, "noise") == 0) {
        Serial.println("noise");
        
        return;
    } else {
        s_awake = false;
    }

    Serial.print("current mode: ");
    Serial.println(s_led_mode);

    if (strcmp(event, "blink") == 0) {
        if (s_led_mode != 2) {
            s_led_mode = 2;
            pinMode(LED_BLUE, OUTPUT);
        } else {
            return;
        }
    } else if (strcmp(event, "breathing") == 0) {
        if (s_led_mode != 3) {
            s_led_mode = 3;
            pinMode(LED_BLUE, OUTPUT);
        } else {
            return;
        }
    } else if (strcmp(event, "open") == 0) {
        if (s_led_mode != 1) {
            s_led_mode = 1;
            pinMode(LED_BLUE, OUTPUT);
        } else {
            return;
        }
    } else if (strcmp(event, "close") == 0) {
        if (s_led_mode != 0) {
            s_led_mode = 0;
            pinMode(LED_BLUE, OUTPUT);
        } else {
            return;
        }
    }

    Serial.print("new mode: ");
    Serial.println(s_led_mode);
}

3.功能展示

3.1.训练结果展示

Fud3MOC-kRGf276NT8aTCvKuPkaG

3.2.唤醒展示

FslIG91T2wZ0QXHJ8SJnUeImgUK_

3.3.实物展示

开发板实物图如下所示

FsJc9ix1iiSqlB6S1Nb4LXcIBr4fFl7FryvQO2aibre5LqAmPn0X2TbG

4.心得

通过本次活动,学习了edgeimpulse上采集数据、训练模型的方式,同时最终部署到具体的设备上工作起来,这个过程中充分展现出机器学习的魅力,可以轻易做到传统软件、算法很难实现的功能。

希望后续能够多多举办这方面的活动。

 

 

 

 

 

附件下载
firmware-syntiant-tinyml.7z
固件源码
chengqingyao-project-1-syntiant-ndp101-v5.zip
模型以及固件下载工具
syntiant-tinyml.zip
音频采样固件
团队介绍
致力于将Funapck第二季白嫖到底的白嫖怪
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号