Изменение рабочего цикла тона на AVR
Я пишу MIDI-преобразователь в квадратную волну, предназначенный для взаимодействия между MIDI-инструментом и музыкальной катушкой Теслы. По сути, это должно действовать как монофонический MIDI-синтезатор, но требования к большинству проектов немного отличаются:
- Я хочу только генерировать квадратные волны (слышимой частоты).
- Важно, чтобы время срабатывания импульса не превышало настраиваемого постоянного значения, например 160 микросекунд.
- Я хотел бы сопоставить "скорость" данной ноты с рабочим циклом, соответствующим образом масштабированным.
- В идеале я хотел бы генерировать огибающие для ширины импульса с настраиваемыми параметрами атаки, затухания, поддержания и высвобождения.
- Я хотел бы написать код генерации звука "с нуля" ради моего собственного понимания того, как работают регистры синхронизации.
Суть того, что мне нужно, - это (непроверенный) скетч, но он, очевидно, не позволяет контролировать время включения.
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
const static int out_pin = 9;
void handleNoteOn(byte channel, byte pitch, byte velocity)
{
tone(out_pin, pitch);
digitalWrite(13, HIGH); // включите светодиод (HIGH-уровень напряжения)
}
void handleNoteOff(byte channel, byte pitch, byte velocity)
{
noTone(out_pin);
digitalWrite(13, LOW); // turn the LED off
}
void setup() {
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
MIDI.begin(MIDI_CHANNEL_OMNI);
}
void loop() {
// поместите свой основной код здесь, чтобы запускать его повторно:
MIDI.read();
}
Мой вопрос, по сути, заключается в том, каков наилучший способ достижения такого рода музыкального контроля ширины импульса. Идеи, которые у меня были, были либо а) Большое количество ручных наборов регистров для битового выброса требуемого сигнала на самой высокой частоте, которую я могу получить, вероятно, в кГц б) Создайте каждый импульс с помощью пользовательской функции pulseOut, используя timer0 для микросекундных задержек.
Я также был бы открыт для использования внешних аналоговых схем, например, укорочителя импульсов с регулируемым напряжением.
Нагрузкой здесь является светодиод, поэтому никаких особых припусков к его поведению делать не нужно.
1 ответ
Я бы рекомендовал использовать аппаратный ШИМ-сигнал, генерируемый таймером 1, или другой 16-битный таймер, если у вас их несколько (как на Mega). 16 бит обеспечивают как приличный частотный диапазон, так и хорошее временное разрешение. Это должно обеспечить свободные от дрожания тайминги, в отличие от любого программного метода. Это также позволит избежать чрезмерной загрузки процессора.
Первое, что нужно сделать, - это выбрать прескалер и режим работы . Этот выбор повлияет как на самую низкую доступную частоту, так и на временное разрешение. Последнее влияет на точность самых высоких нот. Предполагая, что ваш Arduino работает на частоте 16 МГц, некоторые разумные варианты:
- прескалер = 64, нормальный ШИМ
- прескалер = 8, фазовая коррекция ШИМ
- прескалер = 8, нормальный ШИМ
прескалер | Режим ШИМ | разрешение по времени | самая низкая частота. | самая низкая нота |
---|---|---|---|---|
64 | Нормальный | 4 мкс | 3,81 Гц | C−1 (MIDI 0) |
8 | фаза правильная | 1 мкс | 15,26 Гц | B0 (MIDI 11) |
8 | Нормальный | 0,5 мкс | 30,52 Гц | B1 (MIDI 23) |
Ради того, чтобы иметь точные ноты, я бы выбрал самое низкое временное разрешение, совместимое с музыкой, которую вы хотите воспроизвести.
Как только это настроено, вы можете управлять музыкой, записывая ее в три регистра:
- TCR1A включает и выключает ШИМ
- регистр, удерживающий ВЕРХНЮЮ часть (OCR1A или ICR1, в зависимости от режима) контролирует частоту (высоту тона)
- регистр сравнения совпадений (OCR1A или OCR1B, в зависимости от канала) управляет длительностью импульсов
Затем ваша программа должна будет установить частоту в зависимости от запрашиваемой ноты, а затем непрерывно регулировать длительность импульса, чтобы создать желаемую огибающую, подчиняясь требуемой скорости и гарантируя, что значение 160 мкс никогда не будет превышено.
Основной код даже не нужно синхронизировать с таймером: режимы ШИМ гарантируют отсутствие сбоев ШИМ даже при изменении рабочего цикла. Однако будьте осторожны при изменении частоты: при увеличении частоты могут возникнуть огромные сбои . Безопаснее останавливать, очищать и перезапускать таймер при смене нот.
- Хочу создать Bluetooth audio control (увеличение/уменьшение громкости, воспроизведение, пауза и т.д.) для смартфона
- Как подключить ардуино к разъему для наушников?
- Подключить Arduino к телефонной линии?
- DFPlayer Noise: исследован, испытан и бип бип бип бип
- Генерация белого шума звуковой частоты с помощью Arduino Mini Pro
- Транзисторный усилитель для управления динамиком с использованием ШИМ Arduino
- Передавать аудио с Arduino на устройство по Wi-Fi
- Ардуино - Воспроизведение файлов WAV с помощью зуммера
Какую плату Arduino вы используете?, @chrisl
вы видели библиотеку arduino-toneac?, @Juraj
Arduino nano. Я не видел toneaclibrary - хотя он и не совсем способен на то, что мне нужно из коробки, он очень полезен для чтения!, @catalogue_number