Декодирование PPM-сигнала RC-приёмника на Arduino: пошаговое руководство
Компоненты и материалы
- Arduino UNO — 1 шт.
- RC-приёмник с выходом PPM (например, 6-канальный) — 1 шт.
Программное обеспечение
- Arduino IDE
О проекте
Стандартные RC-приёмники выдают PWM-сигнал на каждый канал (3 провода: GND, VCC, Signal). Чтобы считывать все каналы, нужно много проводов и прерываний (на Uno только 2 внешних прерывания). Решение — использовать выход PPM (Pulse Position Modulation), где все каналы передаются последовательно по одному проводу.
Как устроен PPM-сигнал
PPM-пакет состоит из серии импульсов (обычно 7 для 6-канального приёмника: 6 каналов + синхроимпульс). Пауза между пакетами ≈ 11500 мкс. Длительность каждого импульса соответствует положению стика (1000–2000 мкс). На осциллограмме видно: длинная пауза (sync), затем 6 импульсов-каналов.
Алгоритм чтения
- Настроить прерывание по спаду (FALLING) на пине 2 (или 3).
- В ISR засекать время между спадами (
micros()), сохранять в массив. - После накопления 15 значений (запас) скопировать в рабочий массив.
- В основном цикле искать в массиве паузу > 10000 мкс — это синхро-пауза.
- Следующие 6 значений — длительности каналов. Вычесть 1000 мкс (база) для нормализации 0–1000.
Код (Arduino)
unsigned long int a, b, c;
int x[15], ch1[15], ch[7], i;
void setup() {
Serial.begin(9600);
pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), read_me, FALLING);
}
void loop() {
read_rc();
Serial.print(ch[1]); Serial.print("\t");
Serial.print(ch[2]); Serial.print("\t");
Serial.print(ch[3]); Serial.print("\t");
Serial.print(ch[4]); Serial.print("\t");
Serial.print(ch[5]); Serial.print("\t");
Serial.print(ch[6]); Serial.print("\n");
delay(100);
}
void read_me() {
a = micros();
c = a - b;
b = a;
x[i] = c;
i++;
if (i == 15) {
for (int j = 0; j < 15; j++) ch1[j] = x[j];
i = 0;
}
}
void read_rc() {
int i, j, k = 0;
for (k = 14; k > -1; k--) {
if (ch1[k] > 10000) { j = k; break; }
}
for (i = 1; i <= 6; i++) {
ch[i] = (ch1[i + j] - 1000);
}
}
Пояснения
read_me()— ISR, записывает 15 интервалов между спадами.read_rc()— ищет синхро-паузу (>10000 мкс), затем берёт 6 следующих значений как каналы 1–6.- Вывод в Serial Monitor: 6 чисел (0–1000) через табуляцию.
Этот метод использует только 1 пин прерывания и 1 провод от приёмника, освобождая ресурсы Arduino для других задач.
Производственный процесс
- Мониторинг домашней температуры с панелью управления на Raspberry Pi
- Создание DTMF-декодера на Arduino без внешних микросхем
- Создание потрясающей системы Ambilight для монитора на Arduino
- Создание ультразвукового левитатора на Arduino: пошаговое руководство
- Легкая прошивка микроконтроллеров Atmel AT89 с помощью Arduino Uno — пошаговое руководство
- Умный вольтметр на Arduino и смартфоне — простое DIY-проект
- IoT-монитор пульса в реальном времени на Arduino и MAX30100
- Веб-сервер на Arduino Uno WiFi: управление LED через браузер
- Умный счетчик парковки: Отслеживание машин в реальном времени (Arduino, Processing, PHP)
- Визуализация пульса в реальном времени: LED-кольцо + ECG (uECG) + Arduino Nano