回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

“ai党史”(2) - 党史机器人 简单

头像 szjuliet 2021.06.11 937 2

材料清单

  • Arduino UNO X1 链接
  • 掌控板 X1 链接
  • Gravity: UART MP3语音模块 X1 链接
  • 2.0" 320x240 IPS广视角TFT显示屏 X1 链接
  • Gravity: 二哈识图(HuskyLens)AI 视觉传感器 X1 链接
  • Gravity: I2C语音识别模块 X1 链接
  • 小喇叭 X1

兔子的演变

将机器人用兔子的形象来表现是深受《那免》的影响,只是TB上没有现成的“好”兔子。最后买了萌萌的兔子和穿 了军服的其他玩偶,回来之后进行了改装。

把器材放进兔子里费老劲了,将兔子“开膛破肚”,将里面的填充棉花全部掏出来,用连接件搭了个“骨架”,再把器材分别固定进去,还要注意各部件的位置。机器视觉传感器的摄像头放在鼻子的位置,TFT显示屏放在兔子的肚子位置。语音识别的咪头在兔子后面开个小孔露出来,否则拾音不灵敏。掌控板的显示是调试用的,所以没有把掌控板外置。因为掌控板和UNO需要进行引脚实时通信,是共用电源的,所以给UNO的供电采用了电池盒。器材固定后将棉花填充进去。为了方便在兔子背后缝了条拉链,所有工作完成后将拉链拉上即可。

project-image

思维导图

project-image

任务分析

因为其他模块都有IoT,所以党史机器人只做离线版的应用,没有做IoT的应用,当然要加上也简单,通过掌控板连接就可以了,在本项目中不做讨论。

从上面的思维导图可以看到,党史机器人分为了4个部分。想实现的功能是:

· 通过语音识别可以识别百年精神的关键字;

· 通过二哈可以识别百年精神的标签;

· 当识别语音或标签成功后,通过mp3模块朗读对应精神的解读;

· 当识别语音或标签成功后,通过TFT屏幕显示对应精神的图片;

这4个部分都不简单,每一部分对学生来说都是一个挑战。我没有让学生一开始就动手做。而是针对每个部分先进行学习。这个项目是两个学生负责的,我把他们两人的座位编排在一起,这样方便他们可以随时进行讨论。根据wiki及示例先跑demo,遇到问题再问老师。

刚开始的方案是主控用UNO,再加上人工智能三剑客:语音合成、语音识别和二哈一起来完成这个项目。后来发现语音合成的工作量太大了,文字太多就没法实现。所以就把离线的语音合成模块去掉,将文字转语音的功能使用电脑完成,转为mp3文件后通过MP3模块来实现朗读。而原来的主控UNO跑太多代码内存也会爆,最后主控改用掌控板,但是掌控板没有TFT屏的扩展和示例,迁移对学生来说难度太大也太耗时。最后决定用一个取巧的办法,掌控板接语音识别和二哈,UNO接TFT,两个板子之间通过引脚相连。只要掌控板有空闲5个引脚就可以有32种不同的状态,除去全0,可以有31种状态,我们一共28种精神,足够使用了。

本帖为了方便描述任务功能,28种精神选取了其中的三种来实现,但是实现方法全部采用模块的方式,扩展极为简单。

本任务很好的培养了计算思维的四个维度:分解、抽象、模块化及算法设计。主要体现在:

· 使用列表使判断和操作能够自动的进行

· 使用带参数的函数让代码做到最大化的复用

步骤1 线路连接

本说明了所有模块的连接方式,但是在实际进行时不要一次性的全部把线接好。而是每个功能单独连线,测试成功后再进行下一个功能的测试。当全部功能都实现后再将线全部接好,测试完整功能。

掌控板连接了语音识别传感器、机器视觉传感器和MP3语音播放模块。

1. 语音识别使用I2C通讯方式,SDA接P18,SCL接P17。在步骤2时进行。

2. 视觉识别使用I2C通讯方式,SDA接P20,SCL接P19。在步骤3时进行。

3. MP3模块RX接P6,TX接P1。在步骤4时进行。在步骤4时进行。

4. UNO连接TFT屏,接线方式见步骤5。在步骤5时进行。

5. 掌控板的引脚0,7接UNO的引脚8和引脚7。

前面所述,可以使用5个引脚来发送28种精神的状态。本贴为了方便描述,使用两个引脚。两个引脚可以有4种状态00,01,10,11,除去00,可以表达三种有效状态,即可以传递三种不同的精神类别。本贴中,01表示向UNO传送“红船”信号,10表示向UNO传送“铁人”信号,11表示向UNO传送“延安”信号。

在步骤2~步骤5中,都需要对每种功能进行测试,测试的目的是确定每个模块都可以独立正常工作。

计算思维的“实验与迭代”,先做一点点,测试一下,再做一点点,不断的前进和优化。

project-image

步骤2 语音播放准备

语音播放使用MP3模块,需要:

1.   将文字转换为语音

28种精神的内涵及解读全部来自官方网站:共gong产chan党dang员网。将每个中国精神的内涵进行提炼,使用工具将文字转换为语音

2.  将语音文件保存到MP3模块中。

3.  将MP3模块的RX接掌控板的P6,TX接掌控板的P1。

4.   编写代码测试语音文件是否可以正常播放。如果能够正常播放则进行到下一步。

project-image

步骤3 二哈标签识别准备

1. 二哈默认可以识别35种标签,将标签在泡沫棉上打印出来并切割成一小块备用。

2. 二哈学习标签,方法参见文末的参考资料,二哈的wIki。

3. 视觉识别使用I2C通讯方式,SDA接掌控板的P20,SCL接掌控板的P19。

4. 编写代码测试标签是否可以识别正常。识别正常则进行下一步骤。

project-image

步骤4 语音识别

1. 语音识别使用I2C通讯方式,SDA接掌控板的P18,SCL接掌控板的P17。

2. 编写代码测试语音识别功能是否正常,如果正常则进行下一步。

步骤5 TFT显示屏显示图片

1. 搜索百年精神相关图片。

2. 将图片转换为BMP格式。

这款TFT屏幕可以显示 bmp / jpg / jpeg格式的图片。 jpg 图片仅支持JFIF格式。网上搜索的图片大部分都是JPG格式的,但很多不支持JFIF,所以最稳妥的方法是使用Windows自带的画图程序将图片转换为BMP格式,或者重新保存为JPG格式。经过这样折腾一圈就可以在屏幕上正常显示图片了。

* @brief Read pictures in bmp / jpg / jpeg format from the SD card and display them on the screen. bmp supports 16-bit / 24-bit / 32-bit.
* @n jpg only supports JFIF format, you can open with windows drawing and save it as this format.

3. 将图片保存到SD卡中,并将卡插到TFT卡槽中。

4. 将TFT与UNO如下图相连。

5. 将改写好的DEMO程序烧录到UNO中,测试图片能否正常显示。如果能够正常显示则进行到下一步。

TFT屏幕与UNO连接图

project-image

将JPG转换为BMP

选择24位图是因为如果选择16位图,这些图片的颜色信息会部分丢失。

图片通过画图程序另存为jpg格式也是可以的。

project-image

已经转换好的三张BMP范图:红船、铁人、延安。

project-image

步骤6 编写程序

所有子模块测试完毕后,开始编写代码,实现语音识别、标签识别精神关键字并朗读对应精神文本,同时TFT屏幕显示对应精神图片。

掌控板程序(总)

project-image

函数:初始化精神列表

为方便描述,仅将3种精神加入列表。28种精神可以原样操作。

project-image

函数:初始化语音识别

· “铁人”和“王进喜”是同一种精神,因此编号相同。

· 识别模式为“循环模式”时表示语音识别传感器一直处于拾音状态,不停的拾取环境中的声音进行分析识别。

· 麦克风模式为“默认”时,表明此时板载咪头和3.5mm输入接口工作。

project-image

函数:初始化mp3


project-image

函数:初始化二哈

代码被遮住的部分是“HuskyLens切换到‘标签识别’算法直到成功”。

project-image

函数:语音识别

调用带参数的函数“播放”,参数为每种精神对应的序号。

project-image

函数:播放(序号)

通过语音或标签识别到精神关键字后,播放对应精神内容,掌控板屏幕显示精神名称。

project-image

函数:停止

通过语音或标签识别到“停止”命令后,停止播放语音,掌控板屏幕“停止播放”。

project-image

函数:标签识别

标签识别的逻辑与语音识别的逻辑一样,加上5秒钟等待是避免因为标签没有及时拿开造成重复识别。

project-image

函数:UNO信号_红船

函数:UNO信号_延安

函数:UNO信号_铁人

使用2个引脚可以传送三种不同的精神,同理使用5个引脚可以传送2的5次方种不同信号。

project-image

Arduino代码

代码

/*!
   @file SD.ino
   @brief 从SD卡上读取bmp / jpg / jpeg格式的图片,显示在屏幕上。bmp支持16位/ 24位/ 32位。
   @n jpg只支持JFIF格式,可以用windows drawing打开并保存为这种格式。
   @n 这个演示的图片存储在example-> SD-> picture下;只需将图片文件夹复制到SD卡上
   @n 该演示支持主板ESP8266、FireBetele-M0、MAGE2560和UNO。
   @copyright 版权所有(c) 2010德国机器人有限公司(http://www.dfrobot.com)
   @licence The MIT License (MIT)
   @author [YeHangYu] (hangyu.ye@dfrobot.com)
   @version V0.1
   @date 2020-03-20
   @url https://github.com/DFRobot/DFRobot_GDL
*/
#include <SD.h>
#include <SPI.h>
#include "DFRobot_GDL.h"
#include "DFRobot_Picdecoder_SD.h"

DFRobot_Picdecoder_SD decoder;
/* AVR series mainboard */
#define TFT_DC  2
#define TFT_CS  3
#define TFT_RST 4
#define TFT_SD  5
/**
   @brief 硬件串行接口通信的构造函数
   @param 用于SPI通信的直流命令/数据线引脚
   @param 用于SPI通信的cs芯片选择引脚
   @param 屏幕的rst复位引脚
*/
//DFRobot_ST7789_240x240_HW_SPI screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
DFRobot_ST7789_240x320_HW_SPI screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
//DFRobot_ILI9341_240x320_HW_SPI  screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
//DFRobot_ILI9488_320x480_HW_SPI screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
/* M0 mainboard DMA transfer */
//DFRobot_ST7789_240x240_DMA_SPI screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
//DFRobot_ST7789_240x320_DMA_SPI screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
//DFRobot_ILI9341_240x320_DMA_SPI screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
//DFRobot_ILI9488_320x480_DMA_SPI screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
/*
  用户可选择的宏定义颜色
  COLOR_RGB565_BLACK   COLOR_RGB565_NAVY    COLOR_RGB565_DGREEN   COLOR_RGB565_DCYAN 
  COLOR_RGB565_MAROON  COLOR_RGB565_PURPLE  COLOR_RGB565_OLIVE    COLOR_RGB565_LGRAY
  COLOR_RGB565_DGRAY   COLOR_RGB565_BLUE    COLOR_RGB565_GREEN    COLOR_RGB565_CYAN  
  COLOR_RGB565_RED     COLOR_RGB565_MAGENTA COLOR_RGB565_YELLOW   COLOR_RGB565_ORANGE           
  COLOR_RGB565_WHITE
*/
void setup()
{
  //初始化串行端口
  
  pinMode(8, INPUT);
  pinMode(7, INPUT);
  Serial.begin(115200);
  //初始化screen
  screen.begin();
  //初始化SD卡,等待初始化成功
  while (1)
  {
#if defined ARDUINO_SAM_ZERO
    if (SD.begin(/*sdcs=*/TFT_SD,/*type = */TYPE_NONBOARD_SD_MOUDLE)) {
#else
    if (SD.begin(/*sdcs=*/TFT_SD)) {
#endif
      Serial.println("initialization done.");
      break;
    }
    Serial.println("initialization failed!");
  }
}



void loop()
{
  if ((digitalRead(8)==0 && digitalRead(7)==0)) 
  {
  screen.fillScreen(COLOR_RGB565_WHITE);
 }
  else 
  {
   if ((digitalRead(8)== 1 && digitalRead(7)== 1))
  {
    screen.fillScreen(COLOR_RGB565_WHITE);
    decoder.drawPicture(/*filename=*/"ya24.bmp",/*sx=*/0,/*sy=*/0,/*ex=*/screen.width(),/*ey=*/screen.height(),/*screenDrawPixel=*/screenDrawPixel);
    delay(1000);
  }
  if (digitalRead(8) == 1 && digitalRead(7) == 0)
  {
    screen.fillScreen(COLOR_RGB565_WHITE);
    decoder.drawPicture(/*filename=*/"wjx24.bmp",/*sx=*/0,/*sy=*/0,/*ex=*/screen.width(),/*ey=*/screen.height(),/*screenDrawPixel=*/screenDrawPixel);
    delay(1000);
  }
  if (digitalRead(7) == 1 && digitalRead(8) == 0)
  {
    screen.fillScreen(COLOR_RGB565_WHITE);
    decoder.drawPicture(/*filename=*/"hc24.bmp",/*sx=*/0,/*sy=*/0,/*ex=*/screen.width(),/*ey=*/screen.height(),/*screenDrawPixel=*/screenDrawPixel);
    delay(1000);
  }
 }
}

//对于解码函数调用,这个函数的作用是在屏幕上画一个像素
void screenDrawPixel(int16_t x, int16_t y, uint16_t color)
{
  //在屏幕上画一个点
  screen.writePixel(x, y, color);
}

参考资料

https://wiki.dfrobot.com.cn/index.php?title=(SKU:DFR0534)Voice_Module

https://wiki.dfrobot.com.cn/_SKU_DFR0664_2.0_240x320_LCD

https://wiki.dfrobot.com.cn/_SKU_DFR0715_Gravity_I2C_%E7%A6%BB%E7%BA%BF%E8%AF%AD%E9%9F%B3%E8%AF%86%E5%88%AB%E6%A8%A1%E5%9D%97

https://wiki.dfrobot.com.cn/index.php?title=(SKU:SEN0305)Gravity:_HUSKYLENS_%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD%E6%91%84%E5%83%8F%E5%A4%B4

子项目链接:

“ai党史”(1) - 项目总体介绍

“ai党史”(2) - 党史机器人

“ai党史”(3) - 互动灯座

“ai党史”(4) - 互动沙盘

“ai党史”(5) - APP

评论

user-avatar
  • MakingForGood创善

    MakingForGood创善2021.11.16

    您好,我是盲童福利机构的志愿者,要为机构的孩子们用树莓派做一款智能寻物眼镜,希望与您取得进一步交流

    0
    • hnyzcj

      hnyzcj2021.07.09

      老板下血本了

      0