Сгенерируйте синусоиду с предопределенной частотой и амплитудой через DAC0 или DAC1 с помощью Arduino Due.
Всем доброе утро, Я аспирант в области экспериментальной гидромеханики в Неаполитанском университете имени Федерико II, Италия. Я работаю над картой Arduino Due, и я новичок в приложениях, использующих ее. Во-первых, мне нужно сгенерировать синусоиду с переменной частотой и амплитудой. Я пытался скачать несколько кодов, которые способны генерировать синусоидальные волны с заданной частотой, но я хотел бы изменить это значение частоты в начале выполнения кода. Как я мог это сделать? Во-вторых, я хотел бы изменить в режиме реального времени выходное напряжение Arduino DAC0 или DAC1 на высокой скорости, чтобы генерировать произвольную форму волны. Возможно ли это? Заранее спасибо за ответы.
Доктор. Алессандро Скала
@AlessandroScala, 👍-1
1 ответ
Формула, обычно используемая для представления синусоидального сигнала
V = A cos(ωt)
где A — амплитуда, а ω — угловая частота. Эта формула должны хорошо справляться с переменной амплитудой. Однако он не подходит для сигнала с переменной частотой, потому что неоднородность частота не должна создавать разрыв в сигнале.
Правильная формула для сигнала, в котором и амплитуда, и частота может варьироваться
V = A(t) cos(φ(t))
где фаза вычисляется как
φ(t) = ∫ ω(t)dt
С точки зрения кода это означает, что вам нужна статическая переменная для отслеживания текущую фазу, и вы должны периодически обновлять ее, чтобы выполнить численное интегрирование.
Вот примерная реализация. Я квалифицировал некоторые переменные как
extern
только для того, чтобы намекнуть, что вы несете ответственность за их управление. Ты
можно удалить квалификатор, если вы интегрируете это в свой собственный код:
// Определено и обновлено в другом месте.
extern const uint8_t output_channel;
extern float angular_frequency; // в рад/нас
extern float amplitude, offset; // в шагах АЦП
// Вызывайте это как можно чаще.
void update_output()
{
// Вычислить временную дельту.
static uint32_t time_of_last_update;
uint32_t now = micros();
uint32_t dt = now - time_of_last_update;
time_of_last_update = now;
// Обновить фазу.
static float phase;
phase += angular_frequency * dt;
while (phase >= 2 * M_PI) phase -= 2 * M_PI; // разворачиваем
// Вывод сигнала.
float output = offset + amplitude * cos(phase);
analogWrite(output_channel, round(output));
}
Что касается второй части вопроса (о произвольных формах волн),
это, конечно, осуществимо. Вам просто нужно передать произвольные значения
analogWrite()
.
- Чтение частоты ввода в цифровых выводах
- Проблема с настройкой частоты ШИМ для Arduino Due
- Создание синусоидальной волны с помощью ЦАП и ее обратная передача
- Arduino должен генерировать синусоидальную волну 400 кГц
- Минимальная частота дискретизации в АЦП в Arduino?
- Светодиодный музыкальный визуализатор
- Изменение выходного напряжения через ЦАП Arduino Due
- NodeMCU - Vin контакт как выход 5V?
Большое спасибо за ваш ответ. Что касается второй части вопроса, вы утверждаете, что я мог бы изменить напряжение в зависимости от входного сигнала, полученного другими контактами? Например, измерение, выполняемое датчиком, считываемым через Arduino, а затем изменяющим напряжение, @AlessandroScala
@AlessandroScala: я заявляю, что вы можете изменить выходное напряжение, как вам нравится, и сделать его зависимым от всего, что вы хотите., @Edgar Bonet