基于Arduino的可扩展设备|电子词典|音乐播放器|By罗炫凌-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1907|回复: 0

基于Arduino的可扩展设备|电子词典|音乐播放器|By罗炫凌

[复制链接]
发表于 2021-1-23 14:18 | 显示全部楼层 |阅读模式
本帖最后由 东风早已破晓 于 2021-1-24 07:46 编辑

基于Arduino的可扩展设备
现有功能:电子词典、音乐播放器、人机交互界面

这个帖子包含:图片演示、作品介绍、创作历程、技术细节介绍、开源资料分享
————————— 先上图~———————————
主界面

主界面

主界面

电子词典(受词典文件影响,只能查单词)
31ed3eb5f23cb3dca8125fff44539f4.jpg
音乐播放器(这是音乐选择界面)
241f7abac53a9d34809d0f0e0ff86e1.jpg
机体上部分(SD卡槽、3.5mm耳机接口、显示屏模块接口(这个模块下文会提及
04d2e0f285baf0b23b32eee0f52a84d.jpg
机体下部分(Arduino的供电口&数据传输口、microUSB充电口
d96c00f3ec72b209746e9ef1854257c.jpg
挺想放视频的,但是没空去拍和剪辑啊(大概以后有空会搞罢
——————作品介绍—————————
      这是一个有着人机交互界面的设备,有着备着辣鸡搜索器的电子词典和只能播放怪异格式的音乐播放器的适合学生使用的设备
      这是一个拥有4800mAh锂聚合物电池和微动开关做成的按起来咔咔响的键盘的单线程设备
      这是一个你可以自己写应用程序的可扩展性设备
      如果你想深入了解的话,就请看下文吧!
——————创作历程—————————
本人高二,高一时看到眼前厚厚的英汉词典和正在吃灰的Mega2560,便萌生了制作电子词典的念头。从网上找到了词典文件txt后便开始想搜索词语的程序,把txt文件的词语排布搞得有规律之后,写出了词语搜索程序。然后就开始搞人机交互,先徒手焊了个键盘并做好了字符输入程序,再为了找合适的带字库的分辨率高的兼容Arduino的彩色的用起来不费力的显示屏,买了又退了N种显示屏,最终确定并一款显示屏,并读透了技术文档。之后为了加点功能,我又去找现成的音乐播放的库,历经各种对比和读文档,最终确定了一个库。最后在暑假的尾巴匆匆调试好3D打印机并不断改外壳的3D模型,最终做成了。
       这个想法我构思了快一年,最终在暑假转变为现实。
       为了制作这个我忽略了学习,所以我之后要全力投身学习,很少会更新这个帖子了(大概罢


————————技术细节—————————


一、词典文件
从网上下载的,原词典文件长这样
          捕获3.PNG
           然后我把它手动分成这样,这样就让词语搜索程序的编写变得简单了
          捕获2.PNG (很累啊
           这个词典文件只有单词,所以只能查单词

二、键盘布线和程序的设计
为了偷懒,键盘程序的设计我就直接搜社区内的现有想法了(笑
          [教程] 纯代码实现4*4矩阵键盘
            简单来说就是用坐标表示按钮位置
            我的源码中的函数Key_Input()就是键盘输入字符程序
            布线的话嘛......看图
             b3488bfa27a51d2307443b2d468192d.jpg 3cbdcd5372fb4cb565471d3b63378d7.jpg 17b9a0bf12765414c7ad34ab2478125.jpg
            简单来说,横着连竖着连,每横每竖都对应着一个引脚
             b3488bfa27a51d2307443b2d468192d.jpg

三、显示屏的选择
唉,往事不堪回首,被字库和兼容折磨死了
           最后选择了这款
            捕获4.PNG (我买的2.4寸,加运费60
              这个屏自带字库、串口通信为主、附带UI设计软件,省了很多麻烦

四、词语搜索程序
            一个词语分俩行,第一行单词,第二行音标和词性、词语释义(音标词性中一般含有四个空格,于是我就用第五个空格作为分界线分开词性和词语释义)     
             捕获.PNG             我的思路是用myFile.read()逐个读取文档中的字符,读取的字符直接输出(所以查词语的时候只能向下翻页,不能向上,且遇到co开头的词查询速度就很低。如果想要高效,可以把每个单词提取出来,一个单词一个txt,再用SD库的文件搜索来搜索单词(我没空搞))。第一行是单词,先存放在数组中,检测到单词后的回车就与要查找的单词进行比较,如果相同就输出,然后换行继续输出;如果不是,就清空这个临时数组,继续查找单词。第二行输出音标和释义,检测到第五个空格时换行。第三行输出释义,先输出200个字符,之后按一次方向下键就输出200个字符,输出完毕后等待一会,自动清屏,进入下一次单词查找。
代码如下         
  1. char SearchWord[20]={};//要找的词

  2. void Dictionary(){//查询词语------------------------------
  3.   
  4.   //char SearchWord[20]={'a','w','r','y'};//要找的词(这俩测试用的,免去了键盘输入)
  5. // char SearchWord[20]={'j','a','c','k','a','n','a','p','e','s'};//要找的词

  6.   String SearchWord0 = String(SearchWord[0]);//要查的单词的首字母
  7.   SearchWord0.toUpperCase();
  8.   //J K X  Z
  9.   String txt2Find;
  10.   if(SearchWord[0]!='j' && SearchWord[0]!='k' && SearchWord[0]!='x' && SearchWord[0]!='z'){//这四种字幕开头的词较少,故不分类
  11.     txt2Find = SearchWord0 + "-" + String(SearchWord[1]) + ".txt";
  12.   }else{
  13.     txt2Find = SearchWord0 + ".txt";
  14.   }
  15.   txt2Find = "/d/" + txt2Find;//要打开的文件名
  16.   Serial.println(txt2Find);
  17.   
  18.   myFile = SD.open(txt2Find);

  19.   int SearchWordLength = (strlen(SearchWord));
  20.   char ResultLine1[20]={};//单词缓冲区
  21.   int EnterSum=0;//回车的个数
  22.   int SpaceSum=0;//空格的个数
  23.   int letter=0,Length2=0;
  24.   char READ;
  25.   bool WhetherFoundWord = 0;
  26.   bool Whether2Enter1 = false;
  27.   bool Whether2Enter2 = false;
  28.   int WordOutPut = 0;

  29.   Serial.println(SearchWord);
  30.   if(myFile){
  31.       while(myFile.available()){
  32.          //Serial.write(myFile.read());
  33.           READ = myFile.read();
  34.          
  35.           if(READ == 10){
  36.             EnterSum++;
  37.           //  Serial.println("EnterSum++");
  38.           }
  39.          
  40.           if(EnterSum==0 && WhetherFoundWord == 0){//第一行-单词
  41.              ResultLine1[letter] = READ;
  42.              letter++;
  43.            //  Serial.println(ResultLine1);Serial.println(strlen(ResultLine1));
  44.             // Serial.println(SearchWord);Serial.println(SearchWordLength); Serial.println("  ");
  45.             
  46.           }
  47.           if(Whether2Enter1 = false && EnterSum==1){//第一次换行
  48.             Serial.println();Whether2Enter1 = true;
  49.           }
  50.           if(EnterSum==1){//来到第二行(读取2&3行用,免去strncmp时间)
  51.             ResultLine1[letter-1] = {};
  52.             if(strcmp(SearchWord, ResultLine1)==0){//辨别SearchWord  ResultLine1是否相同
  53.               WhetherFoundWord = 1;
  54.               if(READ != 10 && EnterSum == 1){
  55.                  if(READ != ' ' && SpaceSum <= 4){//第二行-音标&词性
  56.                     Serial.print(READ);Length2++;
  57.                   }
  58.                  if(READ == ' ') SpaceSum++;
  59.                  if(Whether2Enter2 == false && SpaceSum > 4 && READ != 10){//第二次换行
  60.                     Serial.println();Whether2Enter2 = true;
  61.                  }
  62.                  if(SpaceSum > 4 && READ != 10){//第三行-例句
  63.                      if(WordOutPut<=120){
  64.                        Serial.print(READ);WordOutPut++;
  65.                      }else{
  66.                        while(1){
  67.                          if(Key_Input() == Down){
  68.                            delay(400);
  69.                            if(Key_Input() == Down){
  70.                               WordOutPut=0;break;
  71.                            }
  72.                          }
  73.                          if(Key_Input() == Delete){
  74.                           delay(300);
  75.                           if(Key_Input() == Delete){
  76.                             return;  
  77.                           }
  78.                          }
  79.                        }
  80.                      }
  81.                  }
  82.                }
  83.             }
  84.             if(EnterSum==2){//读到第二个回车
  85.             letter=0;EnterSum=0;SpaceSum=0;
  86.             break;
  87.             }
  88.           }
  89.           if(EnterSum==2){//读到第二个回车
  90.               letter=0;EnterSum=0;SpaceSum=0;
  91.               for(int jeb=0;jeb<=20;jeb++) ResultLine1[jeb] = {};
  92.           }
  93.       }
  94.     if(Length2 < 1){
  95.       Serial.println("Word doesn't exist");
  96.     }

  97.     Length2 = 0;
  98.     WhetherFoundWord = 0;  
  99.     myFile.close();
  100.    }else{
  101.       Serial.println("Error opening or Word doesn't exist");
  102.    }

  103.    for(int jeb=0;jeb<=20;jeb++) SearchWord[jeb] = {};
  104.    
  105.      delay(2000);
  106.         GUI_eDictionary();     
  107.    if(Key_Input() == Exit){
  108.     delay(800);
  109.     if(Key_Input() == Exit){
  110.       loop();
  111.     }
  112.    }
  113. }
复制代码

五、音乐播放器
我找现成的音乐播放的方法,找到两种
          这个播放.wav  https://www.basemu.com/speaker-with-arduino-and-micro-sd.html
           这个播放起来很麻烦,但是功能多,我选择这种 https://www.arduino.cn/forum.php?mod=viewthread&tid=2944&highlight=%E9%9F%B3%E4%B9%90
           (感谢饺子分享的方法,但是讲的并不清楚,我最终还是读了官网的英文才搞懂的
         SimpleSDAudio虽然功能众多,但需要用自带的转换器转换格式,但借此可以输出高质量&双声道音乐(高质量音乐看官网好像还要加一个芯片,我就没有尝试
   对于音乐播放器的人机交互,当然最好是能把SD卡里的音乐表现成一个选择界面供选择,还有下一曲等功能,但是我找了试了很久都找不到能读取文件名并储存经数组的方法(有大佬知道可以在评论区里说出来,谢谢),而且我试了很多种方法,都不能做到在播放音乐时用按钮进行暂停播放等操作(在SimpleSDAudio的例程中是可以用串口监视器实现的,是不是因为arduino不能并行处理的原因?
   所以我就只能做到手动输入文件名和循环播放音乐的功能
360ae95f8a10d21819c744a887a46d4.jpg (亏我还画了个界面

——————————开源资料分享————————————
         我在这里把所有的资料源码都分享出来,秉承开源精神,并感谢社区的大佬们在提问区给我的帮助。
      若大家有好的想法,欢迎分享在本帖评论区 或者 单独发帖,把帖的地址留在本帖评论区。
         (其实就是想看看大家有没有做好的功能能塞进来用 FWNLSBWWUSX9I7DJ_@PNU]K.jpg

         下载地址:链接:https://pan.baidu.com/s/1sZpvYIQYGzGka4D9VcQvlw 提取码:jveu
         (3D文件、代码、显示屏使用教程都放里面了,懒得做索引了,写帖子写了两个半小时,累了.......

           最后来一张3D打印时的惨案
65eaa5cf9e91acb3ba1dfd0c1939785.jpg
感谢你的阅读






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

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 09:26 , Processed in 0.082087 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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