Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Компоненты и материалы

Arduino UNO × 1
SG90 Micro-servo motor × 2

О проекте

Проект содержит универсальный эффективный код для чтения RC-приёмника (или любого PWM-сигнала) на любом входном пине Arduino с применением fail-safe при потере сигнала передатчика.

Видео ниже демонстрирует Arduino Uno как миксер серв с кодом PWMread_RCfailsafe.ino (в разделе «Код»).

Функции автоматически настраивают регистры прерываний и легко переносятся между проектами с разными пинами.

В примере видео:

Содержание

Как сервоприводы и регуляторы скорости управляются PWM?

Предполагается понимание PWM-сигналов (1–2 мс импульс, период ~20 мс). Хорошее видео-объяснение здесь.

Также нужны базовые знания: Arduino IDE, переменные float/boolean/int, циклы if/for, массивы, библиотека Servo.

Примеры использования Arduino в RC/роботах

Обзор кода: декодирование PWM с fail-safe

Код измеряет PWM через прерывания по изменению пина (Pin Change Interrupts). Функции автоматизируют настройку прерываний и извлечение данных с любого цифрового/аналогового пина (кроме A6, A7) на Uno, Nano, Pro Mini. Удобно для новичков.

Цель — универсальный «модуль» RC-приёмника с fail-safe для быстрого переноса между проектами. Пример кода в разделе «Как использовать» — лишь демонстрация.

Важно: код несовместим с SoftwareSerial и другими библиотеками, использующими pin change interrupts.

Как работает (для заинтересованных):

На YouTube Joop Brokking (первые 8 мин) понятно объясняет этот метод для другого проекта.

Вся эта деталь скрыта в PWMread_RCfailsafe.ino (скачивается ниже).

Полезно о манипуляции портами: tronixstuff.com

Помимо прерываний, функция RC_decode() конвертирует ширину импульса (1000–2000 мкс) в ±100% сигнал управления. Fail-safe проверяет валидность сигнала по толерансам 10–330 Гц и 500–2500 мкс. При потере возвращает заданное fail-safe значение.

Калибровочные значения для конкретного пульта и fail-safe позиции настраиваются в PWMread_RCfailsafe.ino.

Как использовать PWMread_RCfailsafe.ino

Шаг 1: Пример железа с Arduino Uno

Если повторяете пример:

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Шаг 2: Копируйте PWMread_RCfailsafe.ino в папку скетча

Пример скетча RC_Read_Example доступен для скачивания. Используйте его как основной.

Скопируйте файл PWMread_RCfailsafe.ino в папку с основным скетчем. При следующем открытии в IDE появится вторая вкладка с кодом.

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Шаг 3: Укажите входные пины

Откройте основной скетч в IDE. Перейдите на вкладку PWMread_RCfailsafe, прокрутите к «USER DEFINED VARIABLES», введите пины в массив pwmPIN[].

Любое количество пинов, любой порядок. Чем больше входов, больше времени тратится на ISR. A6 и A7 — только аналоговые, нельзя использовать. Arduino MEGA пока не поддерживается (можно добавить при необходимости).

Первый элемент массива — канал 1, второй — канал 2 и т.д. Лучше соответствовать нумерации каналов приёмника.

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Шаг 4: Изучите доступные функции

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Шаг 5: Вывод сырых данных PWM в Serial

Загрузите RC_Read_Example, включите пульт, выведите сырые данные. Используйте RC_avail() для проверки новых данных на всех каналах, затем print_RCpwm() для отправки в Serial.

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Шаг 6: Калибровка пульта

По данным из print_RCpwm() вручную скорректируйте массивы RC_min[], RC_mid[], RC_max[] для приведения каждого канала к диапазону ±100%.

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Шаг 7: Вывод откалиброванных каналов

Закомментируйте print_RCpwm(). Используйте RC_decode(channel) для получения значения ±1. Выводите через decimal2percentage() и Serial.println().

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Шаг 8: Установка fail-safe

Настройте позиции fail-safe в массиве RC_failsafe[] для каждого канала (диапазон ±1). Включите/выключите пульт — проверьте срабатывание.

Теперь RC-вход готов к использованию в скетче.

Возможно, нужно отключить fail-safe в самом приёмнике, иначе Arduino не сможет среагировать на потерю сигнала.

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Отображение частоты и периода кадров приёмника

Период и частота кадров можно вывести в Serial. Проверьте новые данные на выбранном канале функцией PWM_read(номер канала), затем используйте PWM_period() и PWM_freq(). Пример в RC_FrameRate.ino.

Лучше использовать первый канал — он первый в кадре. PWM_read() использует те же флаги, что RC_decode(), поэтому вызывайте PWM_read() первым.

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Период полезен: если RC_avail() не видит новых данных за заданное время (напр. 21 мс), запустите RC_decode() для триггера fail-safe или поддержания работы программы (ПИД-контроллер) на стабильной частоте.

Реализовано в RC_Read_Example.ino:

now = millis();
if(RC_avail() || now - rc_update > 21) {
    rc_update = now;
    // update RC input data using RC_decode()
    // run a PID controller
    // apply servo mixing
    // position the servos
}

Пример микширования серв

Включён RC_ServoMixer_Example.ino — микширование двух каналов (2 и 3: элеватор и элерон). Показаны настройка направления, rates, sub-trim. Библиотека Servo управляет сервами на пинах 9 и 10.

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Микширование: сложение/вычитание каналов, ограничение выхода ±1.

mix1 = channel 2 - channel 3 (elv - ail)
mix2 = channel 2 + channel 3 (elv + ail)

Перед подачей на серво конвертируем ±100% в импульс мкс. В примере используется функция calc_uS().

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Формула: pulse, uS = 1500 + (servo_position_% * rates * direction + sub trim) * 500.

Направление, rates, sub trim могут быть статическими или динамически меняться по другому каналу пульта.

Обоснование подхода

Можно читать RC через pulseIn(PIN, HIGH), но она блокирует loop() в ожидании импульса — теряется процессорное время. При нескольких входах теряются данные.

Для скорости лучше pin change interrupts + прямая манипуляция портами — loop() работает с минимальной задержкой. Но это сложнее и дольше, чем pulseIn().

Поэтому написан универсальный код: копируете .ino файл в папку скетча, указываете пины, используете функции. Получаем преимущества обоих подходов.

Ограничения

Функция micros()

micros() считает шагами 4 мкс → точность 4 мкс при измерении 1000–2000 мкс. Практически достаточно. Можно улучшить до 0.5 мкс через таймерные прерывания: инструкция.

Эффективность PWMread_RCfailsafe.ino

При чтении 6–9 каналов 1.4–2.0% процессорного времени уходит на ISR — вполне приемлемо.

Время работы ISR в зависимости от числа каналов:

Чем больше каналов, дольше ISR (цикл FOR проходит все каналы при каждом вызове). При низких частотах (50 Гц) это незначительно.

Вход/выход из ISR ~4 мкс. На один импульс ISR срабатывает 2 раза (вверх/вниз).

Время измерения 1 импульса при 6 входах: 2 × (4 + 24) = 56 мкс (мин. измеряемая ширина).
Чтение всех 6 каналов: 336 мкс (6 × 56).
При периоде 20 мс прерывания активны 1.68% времени (0.000336/0.02) — намного лучше pulseIn() (блокирует до 20 мс на пин).
При 2 входах — всего 0.16%.

Максимальная практическая частота (Гц)

Для других целей макс. ~2.5 кГц (100 шагов разрешения micros()). При 1 входе на этой частоте 3% времени в прерывании → мин. скважность 0.03 → мин. импульс 12 мкс. Для выше частот перепишите ISR под задачу.

Код

PWMread_RCfailsafe Arduino

Содержит функции и ISR для декодирования RC-приёмника с fail-safe. Скопируйте в папку основного скетча (появится как вторая вкладка). Следуйте инструкциям в файле.

/* Kelvin Nelson 24/07/2019
 * Pulse Width Modulation (PWM) decoding of RC Receiver with failsafe
 * ... (полный код из оригинала) ...
*/
RC_Read_Example Arduino

Пример для калибровки и проверки fail-safe. Требует PWMread_RCfailsafe.ino в той же папке.

// ... (код из оригинала) ...
RC_FrameRate Arduino

Вывод частоты и периода кадров RC-приёмника. Требует PWMread_RCfailsafe.ino.

// ... (код из оригинала) ...
RC_ServoMixer_Example Arduino

Пример микширования двух каналов на две сервы. Требует PWMread_RCfailsafe.ino.

// ... (код из оригинала) ...

Схемы

RC-приёмник питается от 5V и GND ICSP, 6 сигнальных выходов → пины 2–7.
Микро-серво 1: 5V, GND, сигнал → пин 9.
Микро-серво 2: 3.3V, GND, сигнал → пин 10.

Эффективный читатель PWM и декодер RC-приёмника на Arduino с встроенным Fail-Safe

Производственный процесс

  1. Ввод-вывод в C: stdio.h, потоки stdin/stdout/stderr, функции getchar/putchar, gets/puts, scanf/printf
  2. Создание анимации и игр на LCD 16×2 с Arduino UNO
  3. Умный вольтметр на Arduino и смартфоне — простое DIY-проект
  4. Логгер температуры и влажности на Arduino с DHT11 и Ethernet Shield
  5. Чтение температуры и влажности DHT11 через Blynk — пошаговый урок для Arduino
  6. Управление Arduino Uno из Python 3: команды через последовательный порт и демонстрация с LED
  7. Клеточный автомат «Жизнь» Конвея на Arduino Nano с OLED 128x64
  8. Сборка компактного FM-радио на Arduino Nano и RDA5807M
  9. FM-радиоприемник на Arduino и модуле TEA5767
  10. Гальванически разделённый аналоговый вход для Arduino на LM331 и оптопаре 4N25