4.04.1. Лабораторная работа №4.4.1.md


Генерация аналоговых сигналов

Тема работы

В предыдущих параграфах мы научились имитировать аналоговый сигнал с помощью ШИМ. Теперь пришло время использовать всю мощь цифро-аналогового преобразователя (ЦАП) Рудирона для генерации настоящего, «честного» аналогового сигнала. В этой лабораторной работе мы напишем программу, которая будет генерировать на выходе ЦАП плавную синусоидальную волну и визуализировать её с помощью плоттера.

Цель

  • Научиться программно генерировать аналоговый сигнал с помощью ЦАП.
  • Использовать математические функции (sin()) для создания сигналов сложной формы.
  • Применить analogRead() и Плоттер по последовательному соединению для визуализации и проверки сгенерированного сигнала.

Оборудование и материалы

  • Отладочная плата Рудирон.
  • 1 соединительный провод.
  • USB-кабель для подключения Рудирона к компьютеру.
  • Компьютер с настроенной средой Arduino IDE.

Ход работы

  1. Как создать синусоиду?

    Синусоида — это идеальная, плавная волна, которая описывает множество процессов в природе, от колебаний маятника до звуковых волн. Математически она описывается функцией sin(x). Эта функция принимает на вход угол (в радианах) и возвращает значение в диапазоне от -1 до 1.

    Наша задача — заставить напряжение на выходе ЦАП изменяться по этому закону. Для этого мы: 1. Будем в цикле плавно изменять угол от 0 до 2π (360 градусов). 2. На каждом шаге вычислять sin() от текущего угла. 3. Масштабировать полученное значение (-1 до 1) в диапазон ЦАП (0 до 4095). 4. Отправлять это значение на выход ЦАП.

  2. Сборка схемы

    Схема, как и в работе по визуализации ШИМ, очень проста. Мы соединим выход ЦАП с аналоговым входом, чтобы сразу же измерять то, что мы генерируем.

    • Возьмите соединительный провод.
    • Один его конец подключите к пину 27 (это единственный пин с функцией ЦАП).
    • Другой конец подключите к аналоговому входу A0.
  3. Написание и загрузка кода

    • Установите перемычку PRG | RUN в положение PRG.
    • В Arduino IDE введите следующий код:

      // Подключаем библиотеку для прямого управления ЦАП
      #include "rudiron/dac.h"
      
      // Пины для генерации и чтения сигнала
      const int dacPin = 27; // Пин ЦАП (аппаратно это PORT_PIN_E0)
      const int adcPin = A0; // Пин АЦП для проверки
      
      // Параметры нашей синусоиды
      float amplitude = 2047.0; // Амплитуда (половина от 4095)
      float offset = 2048.0;    // Смещение, чтобы сигнал был в диапазоне 0-4095
      float period = 1000.0;    // Период волны в миллисекундах (1 секунда)
      
      void setup() {
        Serial.begin(115200); // Используем высокую скорость для плоттера
      }
      
      void loop() {
        // Вычисляем текущий угол в радианах
        // millis() % (int)period даёт нам текущее положение внутри периода
        float angle = (2.0 * PI) * (millis() % (int)period) / period;
      
        // Вычисляем значение синуса и масштабируем его
        int dacValue = offset + amplitude * sin(angle);
      
        // Отправляем значение на ЦАП
        Rudiron::DAC::getDAC2().write_pin_single(Rudiron::PORT_PIN_E0, dacValue);
      
        // Считываем результат с АЦП
        int adcValue = analogRead(adcPin);
      
        // Выводим данные для плоттера
        Serial.println(adcValue);
      }
      
    • Нажмите кнопку «Upload», чтобы загрузить код на плату.
  4. Проверка работы в Плоттере

    • После загрузки откройте Плоттер по последовательному соединению (Tools → Serial Plotter).
    • Вы увидите на экране красивую, плавную синусоидальную волну! Она будет колебаться в диапазоне от 0 до 4095 с периодом в 1 секунду.

Результаты

Вы успешно сгенерировали настоящий, «честный» аналоговый сигнал сложной формы с помощью ЦАП и смогли визуализировать его. Вы увидели, как математические формулы могут превращаться в реальные физические процессы.

Анализ результатов

  • #include "rudiron/dac.h". Эта директива необходима для доступа к низкоуровневым функциям управления ЦАП.
  • float angle = .... Эта строка — сердце генератора. Мы используем функцию millis() для получения текущего времени, а оператор остатка от деления % позволяет нам циклически проходить по периоду волны. 2.0 * PI — это полный круг в радианах.
  • int dacValue = offset + amplitude * sin(angle);. Здесь происходит магия. sin(angle) даёт значение от -1 до 1. Мы умножаем его на amplitude (2047), получая диапазон от -2047 до 2047. Затем прибавляем offset (смещение) 2048, чтобы сместить этот диапазон вверх и получить итоговые значения от 1 до 4095.
  • Rudiron::DAC::getDAC2().... Эта команда напрямую записывает рассчитанное значение в регистр ЦАП.
  • Serial.println(analogRead(adcPin)). Мы тут же считываем сгенерированное напряжение с помощью АЦП и отправляем на компьютер для визуализации.

Выводы

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

Вопросы для самопроверки

  1. В чём принципиальное отличие ЦАП от ШИМ?
  2. Какой пин на Рудироне предназначен для работы с ЦАП?
  3. Зачем в коде нужны переменные amplitude и offset?
  4. Как изменить код, чтобы частота синусоиды была 2 Гц (период 0.5 секунды)?
  5. Как изменить код, чтобы амплитуда волны была в два раза меньше (колебалась от 1024 до 3071)?
  6. Задача со звёздочкой. Подключите светодиод (через резистор 220 Ом) к пину 27. Что вы увидите? Как его свечение будет отличаться от эффекта «дыхания» из лабораторной работы 4.2.1?

Вы научились генерировать сигналы сложной формы! В следующей лабораторной работе мы применим эти знания для управления реальным устройством — мотором вентилятора, и сравним «честное» аналоговое управление с тем, что мы делали с помощью ШИМ.