Быстрое прототипирование алгоритма управления гирляндой
Быстрое прототипирование алгоритма управления гирляндой
В преддверии Нового года всегда хочется создать особую атмосферу. В этом примере показано, как с помощью КПМ РИТМ можно разработать алгоритм управления светодиодной гирляндой, которая будет менять свою яркость в зависимости от громкости музыки, создавая эффект "танцующих огоньков".
В данном примере показано, как использовать машину реального времени — КПМ РИТМ для быстрого прототипирования алгоритмов управления. Объектом управления является светодиодная гирлянда. Алгоритм управления регулирует яркость гирлянды пропорционально громкости музыки. Сначала аудиофайл обрабатывается с помощью скрипта, и затем полученный сигнал загружается в модель на КПМ РИТМ.
Модель, запускаемая на КПМ РИТМ, содержит подсистему Звуковой сигнал, в которой загружается вектор обработанных значений амплитуд аудиофайла из рабочей области. В первые 2 секунды подсистема выдает значение 1 для синхронизации звука. Воспроизведение сигнала происходит циклически — после достижения конца аудиофайла он воспроизводится с начала.
Амплитуда сигнала, имеющая значения от 0 до 1, умножается на коэффициент усиления по напряжению, равный -5. Коэффициент имеет отрицательное значение, поскольку на катод светодиода необходимо подать напряжение, меньшее, чем на анод.
Затем усиленный сигнал подаётся на блок GP-AD-24 DAC, который управляет встроенным модулем цифро-аналогового преобразования (ЦАП). Максимальное выходное напряжение ЦАП составляет ±10 В, однако рабочее напряжение гирлянды — 100 В. Поэтому гирлянда подключается к КПМ РИТМ через усилитель Ponovo PA460Bi, который усиливает выходное напряжение с ЦАП в 20 раз. Гирлянда состоит из двух цепочек светодиодов с общим анодом, подключённым к земле, а на катоды подается отрицательное напряжение.
Схема подключения гирлянды:
Ниже представлен скрипт для обработки аудиофайла в формате WAV. В скрипте выполняются следующие действия:
- Загрузка необходимых библиотек;
- Чтение аудиофайла;
- Извлечение данных;
- Разряжение данных к шагу 0,01 с;
- Нормализация амплитуды;
- Степенная компрессия для усиления слабых значений амплитуды;
- Экспоненциальное сглаживание;
- Нормализация после сглаживания.
using Pkg
!("FileIO" in [p.name for p in values(Pkg.dependencies())]) && Pkg.add("FileIO");
using Plots
using FileIO
# Чтение WAV файла с помощью FileIO
file_path = "$(@__DIR__)/nina-brodskaja-zvenit-janvarskaja-vjuga.wav"
audio = FileIO.load(file_path)
# Распаковка возвращаемого кортежа
audio_data, fs, num_channels, metadata = audio
# Шаг в 0.01 секунд
desired_step = 0.01 # Время между сэмплами в секундах
# Рассчитываем количество сэмплов для 0.01 секунды
desired_samples = round(Int, fs * desired_step) # Количество сэмплов для 0.01 секунды
# Разряжение данных: выбираем каждое desired_samples-е значение
downsampled_audio = audio_data[1:desired_samples:end]
# Пересчитываем время (в секундах) для разреженных данных
t = (0:length(downsampled_audio)-1) * desired_step
# Нормализуем амплитуду
normalized_audio = abs.(downsampled_audio) ./ maximum(abs.(downsampled_audio))
# 1. Усиленная компрессия для слабых значений (с использованием степени < 1)
function enhance_weak_values(data, exponent, min_val, max_val)
# Нормализуем данные в диапазоне от 0 до 1
normalized_data = (data .- minimum(data)) ./ (maximum(data) - minimum(data))
# Применяем степенную компрессию с показателем < 1 для усиления слабых значений
enhanced_data = normalized_data .^ exponent
# Масштабируем в диапазон от min_val до max_val
compressed_data = min_val .+ enhanced_data .* (max_val - min_val)
return compressed_data
end
# Применение усиленной компрессии для слабых значений (с exponent < 1)
exponent = 0.2 # Чем меньше значение, тем сильнее усиление слабых значений
compressed_audio = enhance_weak_values(abs.(downsampled_audio), exponent, 0, 1.0)
# ——————————————————————————————
# 2. Экспоненциальное сглаживание для замедления изменений яркости
function exponential_smoothing(data, alpha)
smoothed = [data[1]] # Начинаем с первого значения
for i in 2:length(data)
push!(smoothed, alpha * data[i] + (1 - alpha) * smoothed[end])
end
return smoothed
end
# Применяем экспоненциальное сглаживание с коэффициентом сглаживания 0.1 (замедляем изменения)
alpha = 0.2 # Чем меньше alpha, тем медленнее изменения
exponentially_smoothed_audio = exponential_smoothing(compressed_audio, alpha)
normalized_audio = normalized_data = abs.(exponentially_smoothed_audio .- 0.2) ./ (maximum(exponentially_smoothed_audio) - minimum(exponentially_smoothed_audio) - 0.2)
# Построение графика
gr()
plot(t, normalized_audio, title="Нормализованная амплитуда", xlabel="Время (с)", ylabel="Амплитуда", legend=false)
Переменные t и normalized_audio загружаются в модель с помощью блока Табличная функция одной переменной в подсистеме Звуковой сигнал. После подключения гирлянды к КПМ РИТМ и обработки аудиофайла получается такой результат:

Полное видео работы:
