Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Цветомузыка

Сообщений 1 страница 16 из 16

1

Не скажу что я имею большой опыт конструирования цветомузык. Просто решил немного попрактиковаться и заодно получить опыт программирования STM32. Были у меня мысли написать программу на mikroBasic, но посмотрев справку и примеры так и не разобрался как работать с таймерами (похоже нужно взаимодействовать непосредственно с регистрами МК) и DMA. Поэтому писал на Си, где большую часть кода сгенерировала программа STM32Cube.
Программа работает следующим образом. По таймеру каждые 50 микросекунд запускается АЦП и по окончанию измерения с помощью DMA (по нашему ПДП - прямой доступ к памяти) результат записывается в буфер в памяти. При заполнении буфера происходит прерывание (примерно каждые 50 миллисекунд (20 раз в секунду)) и производится копирование данных в другой буфер (чтобы не спеша обрабатывать данные пока в основной буфер записываются новые данные).

Код:
void ADC_CopyAdata(void) // Копирование данных из DMA буфера. Выззывается из DMA прерывания.
{
    if (ADC_FlagData != 1) // Ожидается копирование новых данных.
    {
        uint16_t i;
        for (i=0; i<ADC_BuffSize; i++)
        {
            ADC_Buff[i].Real = (short)(ADC_Buff_DMA[i] - 0x8000);
        }
        ADC_FlagData = 1; // В буфер скопированы новые данные.
    }
}

Размер буфера (массива) 1024 элемента (2 байта каждый, т. к. АПЦ 12-ти битный) и соответственно БПФ (быстрое преобразование) рассчитывается на основании 1024 точек (часть кода из функции main).

Код:
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

        if (ADC_FlagData == 1) // В буфер скопированы новые данные с АЦП.
        {
            HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // Мигаем светодиодом.
            ClearMemory32((uint32_t*)&FFT_Buff, ADC_BuffSize); // Обнуляем память под результат БПФ.
            fftR4((short*)&FFT_Buff, (short*)&ADC_Buff, ADC_BuffSize); // Выполняем БПФ.
            ClearMemory32((uint32_t*)&ADC_Buff, ADC_BuffSize);         // Обнуляем память.
            ADC_FlagData = 0;                                          // Т. к. БПФ провели, разрешаем копирование новых данных.

            for (i=0;i<16;i++) SpectrChannel[i]=0; // Обнуляем память для данных спектра.

            GetSpectr((FFT_Data*)&FFT_Buff, ADC_BuffSize, (uint16_t*)&SpectrChannel, 16);
            SetPWM((uint16_t*)&SpectrChannel);
        }

  }
  /* USER CODE END 3 */

После этого вычисляются амплитуды для 16 точек (1024 делится на 16 путем вычисления среднего арифметического)

Код:
// Получение спектра из результата БПФ.
void GetSpectr(FFT_Data *Data, uint16_t Size, uint16_t *OutData, uint16_t OutSize)
{
  uint16_t x=0;
  uint16_t s=Size/OutSize;
  uint16_t i;
  double tmp=0;

  for (i=0;i<Size;i++)
  {
      tmp=tmp+sqrt(Data[i].Real*Data[i].Real+Data[i].Imag*Data[i].Imag);

      if (i % s == s-1)
      {
          tmp = tmp / s;
          if (tmp<10) tmp=0;  // Это шум.
          OutData[x] = (uint16_t)tmp;
          tmp = 0;
          x++;
      }
  }
}

а затем загружается в ШИМ регистры таймеров (4 таймера по 4 канала в каждом, т. е. 16 каналов ШИМ).

Код:
void SetPWM_Tim(TIM_TypeDef *htim, uint16_t *Spectr)
{
  htim->CCR1 = Spectr[0];
  htim->CCR2 = Spectr[1];
  htim->CCR3 = Spectr[2];
  htim->CCR4 = Spectr[3];
}

void SetPWM(uint16_t *Spectr) // Загрузка данных ШИМ в таймеры.
{
  SetPWM_Tim(TIM1, &Spectr[0]);
  SetPWM_Tim(TIM2, &Spectr[4]);
  SetPWM_Tim(TIM3, &Spectr[8]);
  SetPWM_Tim(TIM4, &Spectr[12]);
}

Звуковой сигнал нужно подавать на вывод A0 (амплитуда до трех вольт).
Светодиоды нужно подключить к выводам A8, A9, A10, A11, A15, B3, A2, A3, A6, A7, B0, B1, B6, B7, B8, B9.
Файлы. http://pure-basic.narod.ru/forum_files/ … Lights.zip

+1

2

Спасибо!
Я только отладчик получил, как только платы придут, сразу попробую.
Сразу вопрос - уровень входного сигнала обязательно до 3 вольт усиливать, или от линейного выхода тоже работать будет?

0

3

АЦП оцифровывает диапазон напряжений от 0 до 3 вольта. Меньшее напряжение подать можно, но тогда скорее всего придется программно корректировать данные загружаемые в регистры ШИМ таймеров чтобы светодиоды светили не очень тускло. Вообще, по нормальному нужно сделать что-то типа автоматической регулировки усиления чтобы результат корректировался относительно средней амплитуды сигнала.

0

4

Пётр написал(а):

Вообще, по нормальному нужно сделать что-то типа автоматической регулировки усиления чтобы результат корректировался относительно средней амплитуды сигнала.

Да, было бы неплохо.

0

5

Вот обзорная статья:
http://lightportal.at.ua/publ/cvetomuzy … /3-1-0-133
Вот видео:

+2

6

Вот блин наспамили тем.)

0

7

RDW написал(а):

Вот блин наспамили тем.)

Старался  :D

0

8

Спектроанализатор на STM32F103RBT6 и управляемых светодиодах.
DIY LED Music Spectrum using NeoPixel RGB LEDs and ARM Microcontroller

http://circuitdigest.com/microcontroller-projects/led-music-spectrum-using-neopixels-arm-controller?utm_source=pushengage&utm_medium=push_notification&utm_campaign=pushengage
http://musiccolor.d-lan.dp.ua/index.php … icseen#new

0

9

А что у него та на видео один WS всё время не в кассу светится/мерцает?

0

10

RDW написал(а):

А что у него та на видео один WS всё время не в кассу светится/мерцает?

Или тест, или косяк.

0

11

Доброго дня! Я хочу повторить конструкцию. Есть и модуль STM и чем программировать. Но, как всегда, хочется некоторые вещи сделать "под себя". Мне не совсем понятно, какие цвета назначать каким каналам. Да и цветов, в принципе, достаточно 4-х (для меня). Кроме того, хочется, чтобы при отсутствии сигнала на входе работал канал фона. Все бы хорошо, есть исходники...но я  - чайник, и в коде, хотя он и содержит комментарии, я  не могу понять, как задается диапазон частоты для каждого выхода. Кроме того, как сделать канал фона - тоже для меня проблема.
Буду признателен автору, если подробнее пояснит, как происходит разделение частот. Ну и про канал фона.
Я бы для себя делал такую конструкцию - 15 выходов разделил на 4 канала частотно-зависимых, и канал фона, 5 групп по три светодиода в каждой.
Не зависимо от того, будет ответ, или нет - автору большое спасибо. Конструкция интересная.

0

12

access777 написал(а):

Мне не совсем понятно, какие цвета назначать каким каналам.

У каждого свои предпочтения.

0

13

@Пётр
Я правильно понял, что Вы не выделяли определенные частоты, а разделили все, что входило на вход на 15 равных частей?
У меня конкретный вопрос - можете ли Вы ... (хотел написать, как все обычно - помочь, посоветовать...но буду совсем честным) - написать код, который будет выделять из входного сигнала определенный диапазон, и разбить его на строго определенные участки? Возможно ли это вообще при быстродействии STM32F103?
Диапазоны интересуют такие:
  90  -  500   гц - красный
500  - 1800  гц - желтый
1800 - 4000 гц - зеленый
4000 - 7500 гц - синий
В идеале, очень хорош был бы канал фона (подсветки), фиолетового цвета, зависящий от суммы  остальных, и загорающийся по мере их затухания.
У аналоговых полосовых фильтров на границе диапазона есть серьезные завалы. Они позволяют разделить каналы. Вероятно, для цифрового разделения нужны чуть уже границы диапазонов.
Если у Вас нет желания или возможности, может быть покажете направление, которым двигаться? Что из Вашего кода может подойти без переделок для такой задачи?

0

14

У меня сейчас нет времени дорабатывать этот проект...

0

15

Понятно со второго раза. Пояснений - не будет (

0

16

А... вот ты где "попрошайничаешь" то   :D
Ну чо, низавидую,  Z80 как-никак.  :no:
А я то думал...  :tomato:

0