»
Добавить статью

Индикатор уровня аудио сигнала

2018-07-27 в 13:48

Представляю вашему вниманию индикатор уровня аудио сигнала, так называемый VU Meter. Работает он на платформе Arduino и индикаторе ST7920. Ранее я уже знакомил вас со способом вывода картинки на такой дисплей. Теперь же немного усложним задачу.

Подготовка фонового рисунка

Фоном у нас считается шкала индикатора. Рисуем его, как и в предыдущем примере работы с индикатором, в Paint. Распечатываем пример обычных индикаторов и просто срисовываем. Да, попиксельно.

шкала индикатора аудио сигнала

Итоговый фон получается таким.

шкала индикатора arduino

Разработка программного кода

arduino индикатор уровня

Картинку преобразовываем в код по инструкции, которую указывал вначале. Сложная задача здесь заключается  в построении стрелки индикатора уровня. Необходимо, чтобы она изменяла свое положение в зависимости от уровня аудио сигнала. Здесь основной строкой является рисование линии "u8g.drawLine". Эта линия постоянно "прыгает" по дисплею. С помощью определенных математических функций мы ей задаем места, куда нужно "прыгать", то есть места, где она начинается и где заканчивается. Вот как раз эти значения и меняются относительно уровня звука. В итоге общий код получается таким.

Код

#include "U8glib.h"

U8GLIB_ST7920_128X64_1X u8g( 13, 11, 10);

int analogInput = A0;                 // analog input for outside audio source
int hMeter = 65;                      // horizontal center for needle animation
int vMeter = 85;                      // vertical center for needle animation (outside of dislay limits)
int rMeter = 80;                      // length of needle animation or arch of needle travel

const int sampleWindow = 50;          // sample window width in mS (50 mS = 20Hz)
unsigned int sample;

static unsigned char VUMeter[] {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x10, 0x00, 0x00, 0x10, 0xC0, 0x01, 0x00, 0x3C, 0x00, 0x00,
  0x00, 0x00, 0xC0, 0x1C, 0x00, 0x04, 0x10, 0x00, 0x00, 0x10, 0x20, 0x02, 0x00, 0x40, 0x00, 0x00,
  0x00, 0x00, 0x80, 0x22, 0x00, 0x02, 0x10, 0x00, 0x00, 0x10, 0x20, 0x02, 0x00, 0x40, 0x00, 0x00,
  0x00, 0x00, 0x80, 0x22, 0x00, 0x02, 0xF0, 0x01, 0x00, 0x0E, 0x20, 0x02, 0x00, 0x40, 0x80, 0x0F,
  0x3C, 0x0E, 0x80, 0x22, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x20, 0x02, 0x00, 0x38, 0x80, 0x00,
  0x40, 0x11, 0x80, 0x22, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x20, 0x02, 0x00, 0x40, 0x80, 0x00,
  0x40, 0x11, 0x80, 0x22, 0x80, 0x00, 0x00, 0x01, 0x00, 0x10, 0x20, 0x02, 0x00, 0x40, 0x80, 0x00,
  0x40, 0x11, 0x80, 0x22, 0x80, 0x00, 0xF0, 0x00, 0x00, 0x0F, 0x20, 0x02, 0x00, 0x40, 0x80, 0x0F,
  0x38, 0x11, 0x80, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x3C, 0x00, 0x08,
  0x04, 0x11, 0x80, 0x1C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x08,
  0x04, 0x11, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0x03, 0x00, 0x08,
  0x04, 0x11, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF9, 0xFF, 0x3F, 0x80, 0x07,
  0x7C, 0x0E, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x03, 0x00,
  0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x1F, 0x00,
  0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0x00,
  0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01,
  0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07,
  0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0F,
  0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F,
  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3F,
  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F,
  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x06, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x07, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x01, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x01, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
  0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x3E, 0x3C, 0x3A, 0x3A, 0x3C, 0x3A, 0x3C, 0x5C, 0x3C, 0x00, 0x3A, 0x42, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x42, 0x46, 0x46, 0x42, 0x46, 0x42, 0x22, 0x42, 0x00, 0x46, 0x42, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x42, 0x42, 0x42, 0x42, 0x42, 0x40, 0x22, 0x42, 0x00, 0x02, 0x42, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x22, 0x7E, 0x00, 0x02, 0x42, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x02, 0x42, 0x42, 0x42, 0x42, 0x42, 0x1C, 0x02, 0x00, 0x02, 0x42, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x02, 0x42, 0x42, 0x42, 0x42, 0x42, 0x04, 0x02, 0x00, 0x02, 0x42, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x42, 0x42, 0x42, 0x42, 0x46, 0x62, 0x3C, 0x42, 0x18, 0x02, 0x62, 0x00, 0x00,
  0x00, 0x00, 0x30, 0x3C, 0x42, 0x42, 0x3C, 0x3A, 0x5C, 0x42, 0x3C, 0x18, 0x02, 0x5C, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void setup(void) {
  pinMode(analogInput, INPUT);
}

void loop(void) {
  unsigned long startMillis = millis();                    // start of sample window
  unsigned int PeaktoPeak = 0;                             // peak-to-peak level
  unsigned int SignalMax = 0;
  unsigned int SignalMin = 1024;
  while ( millis() - startMillis < sampleWindow ) {

    sample = analogRead(analogInput);
    if (sample < 1024) {

      if (sample > SignalMax) {

        SignalMax = sample;                                // saves just the max levels
      }

      else if (sample < SignalMin) {

        SignalMin = sample;                                // saves just the min levels
      }
    }
  }

  PeaktoPeak = SignalMax - SignalMin;                      // max - min = peak-peak amplitude
  float MeterValue = PeaktoPeak * 330 / 1024;              // convert volts to arrow information

  MeterValue = MeterValue - 34;                            // shifts needle to zero position
  // refresh display for next step
  u8g.firstPage();
  do {
    u8g.drawXBM(0, 0, 128, 64, VUMeter);       // draws background
    int a1 = (hMeter + (sin(MeterValue / 57.296) * rMeter)); // meter needle horizontal coordinate
    int a2 = (vMeter - (cos(MeterValue / 57.296) * rMeter)); // meter needle vertical coordinate
    u8g.drawLine(a1, a2, hMeter, vMeter);         // draws needle
  } while ( u8g.nextPage() );
}

С таким дисплеем есть один нюанс. Как таковой очистки дисплея (на поподобии clear.display()) здесь нет. Чтобы картинка отображалась, нужно размещать команды внутри такого блока:

Код
u8g.firstPage();
  do {
    команды_на_отображение_пишем_здесь
  } while ( u8g.nextPage() );

 

Как сделать: http://tehnopage.ru/indikator_urovnua_audio_signala

Публикация от @ tehnopage.ru

Вам понравился наш материал? Поделитесь с друзьями!

Оценка статьи: 5.0 из 5. Уже оценило 1 читатель
Метки: arduino, vu meter, индикатор уровня, аудио сигнал.
Вам может быть это интересно

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]