Множественная связь Arduino (1 мастер, n ведомых)

Я хотел бы разработать сеть master/slave, состоящую из:

  • 1 мастер Arduino, который считывает датчики и генерирует профили рампы скорости на основе сигналов датчиков, а затем отправляет эти рампы ведомым устройствам

  • 3 (или более) ведомых устройства Arduino, которые контролируют скорость 12-вольтовых серводвигателей в соответствии с линейными изменениями, отправленными ведущим устройством.

Что такое хороший протокол связи для достижения этой цели? Серийный (SPI)? I2C? Что-то другое? Если это серийный, то новый Arduino Leonardo хороший выбор? Какие вопросы следует учитывать при выборе протокола?

Я представляю что-то вроде:

Владелец:

void loop() {
    update_ramps()
    for(int i=0; i< num_slaves; i++) {
        send_to_all(i, ramps[i]);
    }
}

Раб 1:

const int id = 1;
int recived_id, recived_value;
void loop() {
    read_data();
    if(recived_id == id) { 
        do_motor_step(recived_value);
    }
}

И последовательная связь, при которой RX/TX от ведущего отправляется всем ведомым.

Это кажется разумным решением?

Вы просто хотите отправить одну и ту же информацию всем рабам? Должны ли рабы вообще реагировать?
нет, им не нужно отвечать!
как далеко будут рабы?
я думаю не более 15 метров

Ответы (5)

Насколько я понимаю, вы хотите отправлять разные данные каждому из ведомых устройств, но ведомые устройства не должны отправлять данные обратно.

I2C — это адресная шина, поэтому, если вы назначите разные адреса I2C каждому из ведомых устройств, вам потребуется всего два провода для отправки данных. При необходимости вы также можете запросить данные обратно. AVR Arduino имеют последовательную шину, совместимую с I2C. И вы можете расширить до более чем 3 ведомых устройств без дополнительного оборудования, максимум до 127.

У UART нет адресации, поэтому вам понадобятся либо 3 UART (которых нет у AVR), либо добавление внешней логики для переключения между линиями UART (что стоит денег). Каждое дополнительное ведомое устройство означает дополнительную стоимость. Не рекомендуется.
edit
Как говорит Крис, вы можете использовать UART для создания многоточечной шины. И тогда вам придется добавить адресацию, которая заставит ваш UART работать немного как I2C, но затем асинхронно и без аппаратного сопоставления адресов, как у I2C. Так что все равно не преимущество. конец редактирования

SPI также использует общие линии для данных: один MOSI и соединенные линии MISO. Для индивидуальной адресации каждого подчиненного устройства вам потребуется одна линия SS (Slave Select) на каждое подчиненное устройство. Так что это как минимум 5 вводов/выводов: MOSI, SCK, 3 × SS и MISO, если вы также хотите читать данные с ведомых устройств. Каждое дополнительное ведомое устройство добавляет 1 контакт ввода-вывода на ведущее устройство.

введите описание изображения здесь

Я думаю, что I2C — лучшее решение, требующее наименьшего количества проводов. Этот протокол немного сложнее, чем UART или SPI, но, поскольку у AVR есть аппаратное обеспечение для него, его должно быть легко использовать.

Заявление о том, что потребуется несколько UART или внешняя логика, неверно. Связь по шине UART осуществляется постоянно с использованием программной адресации. При совместном приеме и передаче для этого требуется не больше контактов, чем I2C.
@Chris - Хороший вопрос, я обновлю свой ответ.
Я все еще изучаю, как это работает, и меня интересует SPI. Когда вы сказали, что для подключения трех подчиненных устройств требуется только один вывод MOSI и один вывод MISO, я немного запутался. Будут ли выводы MOSI и MISO для каждого ведомого Arduino подключены к ведущему Arduino? Итак, будет ли у ведущего Arduino три провода, выходящие из его вывода MOSI, и три, входящие в его вывод MISO? А с контактом SS вы просто выбираете, на какое ведомое устройство вы хотите отправить данные? Спасибо.
@capcom - я добавил блок-схему для SPI. MOSI выводится для ведущего и является входом для ведомых. MISO выводится для ведомых и вводится для ведущего. Да, вы устанавливаете низкий уровень SS для ведомого устройства, которому хотите отправить данные. SS служит не только для указания начала и окончания связи, но также невыбранный ведомый должен сделать свой MISO высокоимпедансным для предотвращения конфликтов на шине.
спасибо за точный и ясный ответ, как обычно, стив. вы не упомянули серийный номер программного обеспечения, который, я думаю, должен быть вариантом ... что вы думаете? и: я должен управлять двигателями в подчиненных устройствах, поэтому любая задержка может изменить скорость двигателей (и это плохо).. некоторые проблемы с задержкой при использовании одного из этих протоколов?
Еще ошибся на UART. Для подключения к шине не требуется никаких внешних аппаратных средств, так как вывод UART TX может быть настроен в программном обеспечении. Обычно сигнализация типа UART по шинной сети будет рассматриваться как выгодная при обмене данными между отдельными шасси - в отличие от I2C, она предназначена для этой цели и стандартно используется там. Если вы добавите линейные драйверы / приемники, вы сможете работать с довольно длинными кабелями.
@ Крис - снова верно. Я не знаю, что я курил, когда писал это, я делал это часто! :-(
извините, еще одна вещь: я должен подключить раб на расстоянии 8 м. какие-то рекомендации для этого расстояния? у меня проблемы с i2c
@nkint - 8 м будет иметь емкость около 800 пФ, а I2C позволяет только 400 пФ для получения требуемой граничной скорости. Вам придется использовать удлинитель шины, такой как P82B715 , который протянет шину по кабелю длиной до 50 м.
как было предложено в другом вопросе, я попытался замедлить скорость передачи данных i2c, изменив некоторую строку библиотеки, которую я использую с Arduino (Wire). вроде работает.. может с другими протоколами такой проблемы нет?
@stevenvh P82B715 отлично работает, и его очень легко подключить!

Я предполагаю, что под серийным номером вы имеете в виду UART? Обратите внимание, что UART, SPI, I2C — все это последовательные протоколы.

Для этого подойдет SPI или I2C, поскольку они оба используют архитектуру ведущий/ведомый.
Не включая землю, для 3 ведомых устройств для SPI потребуется 6 контактов (MOSI, MISO, CLK + 3 контакта SS), а для I2C всего два (SDA и SCK).
Я бы, вероятно, выбрал I2C, предполагая, что вам не нужна очень высокая скорость передачи данных. скорости (<400 кГц)

Чем больше ведомых вы добавляете, тем менее удобным является SPI, так как вам нужен еще один SS (выбор ведомого) для каждого нового ведомого. С I2C это не проблема, поскольку адресация является частью протокола, поэтому вам по-прежнему нужны только 2 линии (плюс земля).

Для Arduino должен быть целый ряд руководств с библиотеками I2C/SPI и примерами кода для обоих вышеперечисленных, что должно сделать его довольно безболезненным для запуска и запуска.

Вы правы, данные разные для каждого раба. Меня ввело в заблуждение название функции «send_to_all», но, похоже, для каждой из них используется разная рампа (они проиндексированы). Я удалил свой первый ответ.

Также должны быть возможны общие схемы асинхронной сигнализации, подобные RS485.

Если вы не используете линейные драйверы/приемники (только голые контакты ATMEGA), вы должны сделать UART TX входом, когда не ваша очередь говорить. Если вы используете линейные драйверы, вам нужно использовать дополнительный контакт для управления включением три состояния на линейном драйвере, когда не ваша очередь говорить.

Также имейте в виду, что вы не можете просто выполнить три состояния передатчика, когда последний байт принят в регистр передачи (точка, когда вы можете отправить другой символ), вместо этого вы должны убедиться, что передатчик или линейный драйвер включены до тех пор, пока слово не будет полностью сдвинулся.

В схемах, где вы передаете и принимаете по одному и тому же проводу (или дифференциальной паре), учитывайте, что вы будете слышать свои собственные передачи.

В особых случаях, когда вы хотите подключиться через UART , вы можете использовать UART RS485 MODBUS . Это протокол связи с программными адресами, функциями, контрольной суммой.

Я ДУМАЮ : он более надежен, чем I²C или SPI, благодаря RS-485 и использует меньше проводов, чем SPI.

ПРИМЕЧАНИЕ. Он может быть реализован как стандарт с некоторыми библиотеками , но это может быть дорого, так как вам нужен модуль RS485 для каждого ведомого устройства и один для ведущего, НО он совместим с существующей сетью. Но вы можете сделать это дешевле, используя устаревшие компоненты и создавая собственное устройство. MAX 485 может быть базовым компонентом для создания аппаратной шины 485 или с использованием программного обеспечения RS485 .

Простейшим решением для конкретных требований будет передатчик RS-422 на линии TX на главном устройстве (контроллере шины). Это будет разветвлено на несколько приемников (удаленных терминалов).

Все RT будут слышать широковещательные сообщения, но будут аутентифицировать и выполнять только те команды, которые направлены ему через адрес RT.

Если бы использовался шинный протокол, аналогичный 1553, его было бы легко реализовать.