极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12651|回复: 1

Arduino 制作的音量计

[复制链接]
发表于 2015-4-13 09:31:05 | 显示全部楼层 |阅读模式
根据上一次的LM386的设计【参考1】,以及网上的设计【参考2】,用Arduino做一个音量计。首先,音频从MIC进入,经过LM386的放大后接入到Arduino的模拟输入上,经过 DAC 量化之后显示在 1602上。

电路方面,和【参考1】差别在于我们不再使用喇叭而是直接将放大后的OUT信号接入到 Arduino的A5上。

显示方面,我们使用【参考3】提到的方法来自定义字符充当强度指示。

下面的图片与其说是原理图不如说是连接图更合适





  1. //www.lab-z.com
  2. //在 1602 上显示音量的小程序

  3. #include <Wire.h>
  4. #include "LiquidCrystal_I2C.h"

  5. int value=100;

  6. // custom charaters

  7. LiquidCrystal_I2C lcd(0x27,16,2);

  8. //定义进度块
  9. byte p1[8] = {
  10.                 0x10,
  11.                 0x10,
  12.                 0x10,
  13.                 0x10,
  14.                 0x10,
  15.                 0x10,
  16.                 0x10,
  17.                 0x10};

  18. byte p2[8] = {
  19.                 0x18,
  20.                 0x18,
  21.                 0x18,
  22.                 0x18,
  23.                 0x18,
  24.                 0x18,
  25.                 0x18,
  26.                 0x18};

  27. byte p3[8] = {
  28.                 0x1C,
  29.                 0x1C,
  30.                 0x1C,
  31.                 0x1C,
  32.                 0x1C,
  33.                 0x1C,
  34.                 0x1C,
  35.                 0x1C};

  36. byte p4[8] = {
  37.                 0x1E,
  38.                 0x1E,
  39.                 0x1E,
  40.                 0x1E,
  41.                 0x1E,
  42.                 0x1E,
  43.                 0x1E,
  44.                 0x1E};

  45. byte p5[8] = {
  46.                 0x1F,
  47.                 0x1F,
  48.                 0x1F,
  49.                 0x1F,
  50.                 0x1F,
  51.                 0x1F,
  52.                 0x1F,
  53.                 0x1F};

  54. void setup() {
  55.                lcd.init();           //初始化LCD
  56.                lcd.backlight();                 //打开背光
  57.                                
  58.                         //将自定义的字符块发送给LCD
  59.                         //P1 是第一个,P2 是第二个,以此类推
  60.                 lcd.createChar(0, p1);                         
  61.                 lcd.createChar(1, p2);
  62.                 lcd.createChar(2, p3);
  63.                 lcd.createChar(3, p4);
  64.                 lcd.createChar(4, p5);
  65.             //MIC输入放大之后在 A0 输入Arduino   
  66.                 pinMode(A0, INPUT);
  67. }

  68. //显示音量强度
  69. //从左到右一共有 5 * 16 =80 点,一共是 80+1=81 个状态
  70. void showprg(int value)
  71. {
  72.         //第一行显示当前VU值
  73.                 lcd.setCursor(0,0);
  74.                 lcd.print("     VU=");
  75.                 lcd.print(value);

  76.                
  77.                 //移动光标到第二行
  78.                 lcd.setCursor(0,1);

  79.         //显示全黑的块
  80.                 for (int i=1;i<value / 5;i++) {
  81.                                 lcd.write(4);
  82.                         } //for (int i=1;i<a;i++)


  83.                 // drawing charater's colums
  84.                 // 显示除去全黑块之后的零头
  85.                 switch (value % 5) {
  86.                   case 0:
  87.                         break;
  88.                   case 1:
  89.                         lcd.write(0);
  90.                         break;
  91.                   case 2:
  92.                         lcd.write(1);
  93.                         break;
  94.                   case 3:
  95.                         lcd.write(2);
  96.                         break;
  97.                   case 4:
  98.                         lcd.write(3);
  99.                         break;
  100.                   } //switch (peace)

  101.                // 用空格填充剩下的位置
  102.               for (int i =0;i<(16-value / 5);i++) {
  103.                 lcd.print(" ");   }
  104. }

  105. void loop()
  106. {
  107.      //输入的是0-1023,用函数将这个值对应到[0,80]上
  108.         showprg(map(analogRead(A0),0,1023,0,80));
  109.                 delay(100);
  110.               
  111. }
复制代码


测试方法,在右边用一个手机播放声音,MIC将音频信号转化为电平信号,经过LM386放大后,通过Arduino A5进行量化,最终显示在LCD1602上。




工作视频:



这个还只是一个模型,很粗糙,对于VU的动态显示范围不大,如果想让人类更容易理解需要考虑将现在的线性显示改为非线性的。

另外,工作时我发现比较奇怪的事情,就是如果静音的时候,会显示UV 大约 35左右,但是如果有动态声音播放的时候反而会出现 16 这样值,不清楚原因。

另外的另外,研究了一下前面那个口哨开关的模拟输出。下面是电路图,右下角红色框起来的是模拟输出电路部分



查了一下,发现这种用法是电压跟随器,下图来自【参考4】。


电压跟随器,顾名思义,是实现输出电压跟随输入电压的变化的一类电子元件。也就是说,电压跟随器的电压放大倍数恒小于且接近1【参考5】。
多少输入就是多少输出…….这也就是为什么这个模块驱动能力很差带不动喇叭的原因。
参考:

1. http://www.lab-z.com/lm386-with-mic/    LM386 with MIC
2.http://www.arduino-hacks.com/ard ... crophone-condenser/ Arduino VU meter – LM386+electret microphone condenser
3. http://www.lab-z.com/1602progressbar/ 用 1602实现进度条
4. http://www.geek-workshop.com/thread-551-1-1.html LM358双运算放大器
5. http://baike.baidu.com/link?url= ... GxnAYakSmmjM-9nhsz_ 电压跟随器

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2015-4-14 08:54:41 | 显示全部楼层
谢谢分享学习一下
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-27 10:22 , Processed in 0.039118 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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