Самодельный приемник для вспышек Elinchrom серии RX

У Elinchrom в середине 2000-х была серия вспышек серии RX: Style RX 300/600/1200, Ranger RX, Digital RX 1200/2400. Для управления у них есть разъем Remote или RT. Изначально управление было проводным через специальное устройство USB Multilink 19345 и ПО ERS System 19339 (если у кого-то осталось — напишите в личку). Также к разъему подключался проводной пульт RX Hand Remote 19340. Позже появились беспроводные адаптеры EL-Skyport transceiver RX 19353 и трансмиттеры EL-Skyport для камеры. Трансмиттер позволяет синхронизировать камеру со вспышкой при съемке, а также управлять мощностью, включать/выключать пилотный свет. Беспроводные адаптеры EL-Skyport transceiver RX 19353 достаточно редки и дороги, поэтому было решено создать свой на базе Arduino.

Сам разъем устроен просто. У него 5 контактов: общий, + 5В, синхронизация вспышки и два контакта A и B для обмена данными по RS-485.

Подробности протокола я описываю в ветке форума impulsite: https://impulsite.ru/viewtopic.php?f=39&t=2263

В основе устройства лежит Arduino Uno с контроллером Atmega328p но с минимальной обвязкой, чтобы устройство было компактным и удобным в использовании. Контроллер я программирую на плате Arduino Uno, а затем переставляю в свое устройство. Также использованы модули NRF24L01+ и RS485. Трансмиттер у меня EL-Skyport Transmitter Speed 19350, но должен работать с любым EL-Skyport Transmitter.

Принципиальная схема:

Переключение режимов “Speed” и “Standard”, канала и группы происходит с помощью тумблеров. Замкнутое положение тумблера S3 – режим “Standard”. Режимы нельзя сменить во время работы, считывание режима проходит в первые секунды после включения.
В качестве корпуса для я использовал корпус для РЭА К-4 (размеры 65х45х22) из Ozon. В качестве разъема Разъём DIN 7-0251 6p с удаленным центральным контактом.



Скетч:

/*
Трансивер для вспышек Elinchrom Style RX, Ranger RX. Данная версия программы работает 
только в качестве приемника в режимaх “Speed” и “Standard”.  Принимает следующие команды: запуск вспышки, увеличение 
мощности вспышки, уменьшение мощности вспышки, включение пилотного света, выключение пилотного света.
Не работает с EL-Skyport USB.

Transceiver for Elinchrom Style RX, Ranger RX flashes. This version of the program works
only as a receiver in “Speed” and “Standard” modes. Receive the following commands: trig flash, increase
flash power, reduce flash power, turn on modeling light, turn off modeling light.
Don't compatible with EL-Skyport USB.

2024 Andrei Kuzmik
instagram: @andrei_kuzmik
vk: https://vk.com/id709658769
e-mail: kuzmik.andrej@yandex.by
*/
#include <SPI.h>                             // Подключаем библиотеку для работы с шиной SPI
#include <nRF24L01.h>                        // Подключаем файл настроек из библиотеки RF24
#include <RF24.h>                            // Подключаем библиотеку для работы с nRF24L01+
RF24 radio(9, 10);                           // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)
byte radioBytes[2];                          // Команда по радио
byte serialAnswBytes[22];                    // Ответ по RS
byte pipeAddress[3] = { 0x8F, 0xCB, 0xAD };  // адрес pipe
unsigned long prevLedOff;                    // время предыдущего выключения светодиода
byte flAddr = 0;                             // Адрес вспышки
byte devGroup;                               // Группа приемника
byte devChannel;                             // Канал приемника
bool isSpeed;                                // Speed режим
#define txPin 2                              // Pin для передачи по RS485
#define ledPin 3                             // Pin светодиода
#define trigPin 16                           // Pin запуска вспышки
#define groupPin1 4                          // Pin переключателя группы 1
#define groupPin2 8                          // Pin переключателя группы 2
#define channelPin1 17                       // Pin переключателя канала 1
#define channelPin2 18                       // Pin переключателя канала 2
#define channelPin3 19                       // Pin переключателя канала 3
#define speedPin 15                          // Pin переключателя Speed/normal


void setup() {
  pinMode(txPin, OUTPUT);      // Устанавливаем Pin для нвправления передачи
  pinMode(ledPin, OUTPUT);     // Устанавливаем Pin для светодиода
  pinMode(trigPin, OUTPUT);    // Устанавливаем Pin запуска вспышки
  digitalWrite(trigPin, LOW);  // Выкл спуск
  digitalWrite(txPin, LOW);    // RS485 прием
  Serial.begin(9600);
  Serial.setTimeout(100);

  // Устанавливаем пины для переключателей группы, канала, скорости:
  pinMode(groupPin1, INPUT_PULLUP);
  pinMode(groupPin2, INPUT_PULLUP);
  pinMode(channelPin1, INPUT_PULLUP);
  pinMode(channelPin2, INPUT_PULLUP);
  pinMode(channelPin3, INPUT_PULLUP);
  pinMode(speedPin, INPUT_PULLUP);

  // Определяем группу:
  byte groupNumb = 0;
  bitWrite(groupNumb, 0, !digitalRead(groupPin1));
  bitWrite(groupNumb, 1, !digitalRead(groupPin2));
  switch (groupNumb) {
    case 0:
      devGroup = 0xC0;
      break;
    case 1:
      devGroup = 0xD0;
      break;
    case 2:
      devGroup = 0xE0;
      break;
    case 3:
      devGroup = 0xF0;
      break;
  }

  // Определяем канал:
  byte channelNumb = 0;
  bitWrite(channelNumb, 0, !digitalRead(channelPin1));
  bitWrite(channelNumb, 1, !digitalRead(channelPin2));
  bitWrite(channelNumb, 2, !digitalRead(channelPin3));
  switch (channelNumb) {
    case 0:
      devChannel = 0x38;  // 1 = 2456 MHz (0x38)
      break;
    case 1:
      devChannel = 0x3A;  // 2 = 2458 MHz (0x3A)
      break;
    case 2:
      devChannel = 0x3C;  // 3 = 2460 MHz (0x3C)
      break;
    case 3:
      devChannel = 0x3E;  // 4 = 2462 MHz (0x3E)
      break;
    case 4:
      devChannel = 0x45;  // 5 = 2469 MHz (0x45)
      break;
    case 5:
      devChannel = 0x47;  // 6 = 2471 MHz (0x47)
      break;
    case 6:
      devChannel = 0x49;  // 7 = 2473 MHz (0x49)
      break;
    case 7:
      devChannel = 0x4B;  // 8 = 2475 MHz (0x4B)
      break;
  }

  // Определяем скорость
  if (digitalRead(speedPin)) {  // Уровень высокий, выключатель отключен, режим Speed
    isSpeed = true;
  } else {
    isSpeed = false;
  }

  byte srchAddr = 128;

  do {                                // Поиск вспышки
    if (getFlashData(255) == true) {  // Обращение к вспышке через широковещательный адрес 255
      flAddr = 255;
    }
    delay(100);
  } while (flAddr == 0);

  digitalWrite(ledPin, HIGH);      // Светодиод включен
  radio.begin();                   // Инициируем работу nRF24L01+
  radio.setCRCLength(RF24_CRC_8);  // устанавливаем длину контрольной суммы
  delay(10);
  radio.setAutoAck(false);       // Отключаем auto-acknowledgement
  radio.setRetries(0, 0);        // Выключаем функцию auto-retry
  radio.setAddressWidth(3);      // Устанавливаем длину адреса pipe
  radio.setChannel(devChannel);  // Указываем канал передачи данных
  if (isSpeed) {                 // Устанавливаем скорость передачи данных (RF24_250KBPS стандартный режим, RF24_1MBPS для режима Speed)
    radio.setDataRate(RF24_1MBPS);
  } else {
    radio.setDataRate(RF24_250KBPS);
  }
  radio.setPALevel(RF24_PA_HIGH);          // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
  radio.openReadingPipe(0, pipeAddress);  // Открываем 0 трубу чтения с идентификатором
  radio.setPayloadSize(2);                // Устанавливаем размер payload в 2 байта
  radio.startListening();
}

void loop() {
  // включение светодиода, если время выключения вышло
  if (millis() - prevLedOff > 100) {
    digitalWrite(ledPin, HIGH);  // Светодиод включен
  }
  // Прием по радио и потправка по RS485
  if (radio.available()) {                                     // Если в буфере имеются принятые данные
    radio.read(&radioBytes, sizeof(radioBytes));               // Читаем данные в массив data и указываем сколько байт читать
    if (radioBytes[0] == devGroup || radioBytes[0] == 0xFF) {  // Если группа соответствует приемнику
      byte serialSendBytes[4] = { 0, 0, 0, 0 };
      serialSendBytes[0] = flAddr;
      switch (radioBytes[1]) {
        case 0x00:                      // Trig
          digitalWrite(trigPin, HIGH);  // Вкл спуск
          delay(1);
          digitalWrite(trigPin, LOW);  // Выкл спуск
          delay(99);
          break;
        case 0x01:  // Мощность вспышки +
          if (getFlashData(flAddr) == true) {
            serialSendBytes[1] = 80;
            serialSendBytes[2] = serialAnswBytes[6] + 1;
            send2Flash(serialSendBytes);
          }
          break;
        case 0x02:  // Мощность вспышки -
          if (getFlashData(flAddr) == true) {
            serialSendBytes[1] = 80;
            serialSendBytes[2] = serialAnswBytes[6] - 1;
            send2Flash(serialSendBytes);
          }
          break;
        case 0x10:  // Включить пилотный свет
          if (getFlashData(flAddr) == true) {
            serialSendBytes[1] = 88;
            serialSendBytes[2] = serialAnswBytes[2];
            bitSet(serialSendBytes[2], 3);
            bitClear(serialSendBytes[2], 4);
            send2Flash(serialSendBytes);
          }
          break;
        case 0x20:  // Выключить пилотный свет
          if (getFlashData(flAddr) == true) {
            serialSendBytes[1] = 88;
            serialSendBytes[2] = serialAnswBytes[2];
            bitClear(serialSendBytes[2], 3);
            bitClear(serialSendBytes[2], 4);
            send2Flash(serialSendBytes);
          }
          break;
      }
      radio.flush_rx();  // очистка приемного буфера т.к. передается несколько команд подряд
    }
    if (millis() - prevLedOff > 200) {
      digitalWrite(ledPin, LOW);  // Светодиод выключен
      prevLedOff = millis();      // Запомнить время выключения светодиода
    }
  }
}

bool getFlashData(byte addr) {
  byte getCommand[4] = { 0, 71, 1, 0 };
  getCommand[0] = addr;
  digitalWrite(txPin, HIGH);  // RS485 передача
  Serial.write(getCommand, sizeof(getCommand));
  delay(5);                                                                                                   // Задержка на время передачи по RS485
  digitalWrite(txPin, LOW);                                                                                   // RS485 прием
  if (Serial.readBytes(serialAnswBytes, 22) == 22 && serialAnswBytes[0] > 127 && serialAnswBytes[21] == 0) {  // Если пришел корректный ответ
    delay(5);
    return true;
  } else {
    delay(5);
    return false;
  }
}
void send2Flash(byte sndData[4]) {
  digitalWrite(txPin, HIGH);  // RS485 передача
  Serial.write(sndData, 4);
  delay(5);                  // Задержка на время передачи по RS485
  digitalWrite(txPin, LOW);  // RS485 прием
}

Все материалы для сборки можно скачать тут: Elinchrom_RX – Google Диск
Видео с демонстрацией работы: https://youtu.be/mE6DMrXS9lY

3 лайка