Мультиплексирование последовательной линии

Я построил этот идентификационный датчик для гусеничной тележки Scalextric на основе PIC12F629. Датчик идентификации отправляет идентификатор обнаруженного автомобиля в виде сигнала RS232 на один контакт (уровень TTL).

Мой вопрос в том, как я могу получать данные с четырех таких микроконтроллеров на USART другого микроконтроллера (PIC18F2550)?

Я придумал эти возможности:

  1. Просто подключите все последовательные линии «напрямую» к контакту RX PIC18 и надейтесь, что два автомобиля не пройдут ни один датчик, близкий по времени, поэтому сигналы перекрывают друг друга. На самом деле это может быть хорошим началом и, вероятно, сработает в 99,9% случаев. Я имею в виду, что математическая вероятность того, что две машины будут обнаружены так близко по времени, не может стоить усилий других предложений... в конце концов, это хобби-проект.
  2. Реализуйте сигнал «занято», который поднимается, когда датчики ID отправляют данные, и проверяется перед отправкой.
  3. Добавьте какой-нибудь причудливый чип-мультиплексор, который принимает последовательные сигналы и выводит их на одну линию.

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

Обновление: добавлена ​​дополнительная информация об оборудовании датчика.

Это действительно работа для CAN. Использование UART для этого кладж.
CAN тянет за собой много протокольного багажа и ограничивает ваш выбор микроконтроллеров, но, конечно, если вы можете его раскачать.
На самом деле, я думаю, что CAN — слишком избыточное решение для этого небольшого проекта. Я хотел бы, чтобы это было как можно проще.
Я ценю все ваши ответы и комментарии. Тем не менее, я все же хотел бы, чтобы это было намного проще (я не специалист по электронике, но я учусь...). Как я упоминал в своем первом варианте, вероятность того, что конфликт данных когда-либо произойдет, очень мала, и если это произойдет, это не конец света (в конце концов, это игрушка). Я могу обновить решение в будущем, если сочту его слишком "хрупким". Пожалуйста, приведите пример того, как просто подключить все эти датчики PIC к одному и тому же контакту RX на принимающей PIC. Спасибо!

Ответы (5)

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

Хитрость заключается в том, есть ли у вас настоящий RS-232 (с 1 = от -6 до -12 В и 0 = от 6 до 12 В) или просто стандартная логическая линия (1 = VCC, 0 = GND). Либо техпаспорт, либо область применения должны ответить на этот вопрос.

Если это стандартная логика, это может быть очень просто. Если ваши датчики могут управлять своими выходными драйверами, запрограммируйте их так, чтобы они не управляли выходом, если сообщение не выходит. Если вам приходится постоянно оставлять выходной драйвер включенным, пусть он управляет одним или двумя транзисторами, чтобы создать конфигурацию «открытый коллектор», соедините коллекторы всех датчиков вместе и подтяните подключенную линию к VCC и подключите ее к контакт RX вашего основного контроллера. Это работает, потому что протокол RS-232 бездействует в состоянии логической 1. Если используются уровни сигнала RS-232, то вам придется немного изменить конфигурацию транзистора, но в основе он все равно будет с открытым коллектором.

Главный контроллер просто последовательно запрашивает данные каждого датчика. Каждый датчик отвечает на запрос. Таким образом, у вас не будет больше одного управляющего линией RX одновременно, что является главной целью.

Теперь, если вы не можете заставить свои датчики говорить только тогда, когда с ними разговаривают... тогда ваша проблема сильно усложнилась. Настолько, что простой ответ состоит в том, чтобы дать каждому датчику свой собственный последовательный порт, возможно, используя 8-контактные контроллеры в качестве менеджеров датчиков, которые затем можно подключить к совместной последовательной шине. Другие методы, такие как обнаружение коллизий с повторной передачей сообщений (например, 10base-T Ethernet), намного сложнее.

Я ожидаю, очень кратко взглянув на опубликованную ссылку, что удаленным контроллерам будет сложно одновременно отслеживать команду от удаленного ЦП, пока они наблюдают за автомобилем. Однако они могли бы дождаться прибытия машины, а затем перестать следить за машинами, ожидая возможности послать ту, которую они видели.
@supercat Да, это тоже мое предположение. Тем не менее, я хотел бы использовать логику push, не опрашивая PIC датчика ID, чтобы каждый датчик имел одинаковую задержку от обнаружения до компьютера, поскольку это будет использоваться для хронометража автомобилей.
@Anttu: Если вы не возражаете против изменения кода для датчиков, вы можете расширить отчет от каждого датчика, чтобы передаваемые данные включали время между срабатыванием датчика и отправкой отчета. В противном случае, если скорость передачи данных и время отклика датчиков достаточно высоки, вы сможете опрашивать каждый датчик 100 или даже 1000 раз в секунду.
Вы должны заставить главный контроллер отправить сообщение синхронизации, которое устанавливает все встроенные таймеры датчиков, чтобы датчики могли ставить временные метки для своих данных. Что касается push-решения, см. мой последний абзац. Толчок придет к толчку; это только вопрос времени.
@MikeDeSimone эти автомобили в масштабе 1:32 или 1:45. Я уверен, что его контроллеры - это просто PIC с выходами логического уровня.

Если ваш датчик может разместить «готовую» линию и отложить любые события, которые приходят, когда он не подтвержден, и передать их, когда он есть, лучше всего послать отдельный провод «занято» к каждому датчику и использовать логический элемент «И» для объединить сигналы со всех датчиков. Я бы посоветовал, если у вас есть четыре датчика, вы должны циклически переключать «готовые» провода с некоторым «мертвым» временем между ними (когда никто не «готов»); если байт поступает в течение «мертвого» времени, предположим, что он был отправлен последним активным датчиком. Установите достаточное время «готовности», чтобы датчик мог среагировать, и время простоя, достаточное для того, чтобы у датчика было время завершить передачу события, которое происходит непосредственно перед тем, как его линия «готовности» была отменена.

Редактировать

Основываясь на дальнейших описаниях, учитывая, что, по-видимому, каждый датчик имеет отдельный известный идентификационный номер, я думаю, что лучшим подходом может быть наличие одной последовательной линии, которая подключена к выходу ШИМ через параллельный резистор и диод, так что он вытягивается поднимается на 1900 мкс каждые 2 мс, но снижается на 200 мкс (если бы можно было переключать ШИМ между активным-низким и плавающим, это было бы еще лучше). Как только машина будет замечена, датчик должен запустить следующий конечный автомат, отслеживая, сколько десятков микросекунд прошло с момента начала его выполнения.

  1. Подождите, пока линия данных не станет высокой.
  2. Подождите, пока линия данных станет низкой.
  3. Очистить таймер низкого уровня линии
  4. Подождите, пока линия данных перейдет в высокий уровень, увеличивая таймер низкого уровня линии (и основной таймер) во время ожидания.
  5. Если таймер показывает, что линия была низкой менее 200 мкс, вернитесь к шагу 2.
  6. Продолжайте увеличивать значение таймера линии, наблюдая за тем, как линия становится низкой, пока этот таймер не достигнет определенной длительности, которая уникальна для идентификатора узла. Если линия опустится за это время, вернитесь к шагу 3.
  7. Установите линию данных на выход, передавайте данные со скоростью 16 мкс/бит или около того (активно управляя линией как для высоких, так и для низких частот) и начинайте искать следующую машину. Обратите внимание, что данные должны включать количество интервалов в 10 мкс, прошедших между просмотром автомобиля и началом передачи.

Используя UART, этот подход должен позволять обрабатывать автомобили, поступающие на любой датчик в любом порядке, и разрешать их тайминги в пределах 10 мкс, при условии, что автомобили будут обрабатываться последовательно со скоростью один каждые 2 мс, а датчики будут «слепые» в промежутке между моментом, когда они видят машину, и временем, когда основной процессор начинает ее обрабатывать. Если нет действительно огромного количества датчиков, это не должно создавать проблемы. Обратите внимание, что основной ЦП не должен иметь точной синхронизации ни для чего, кроме ШИМ-выхода. Все остальное можно вывести из потока последовательных данных (включая «длинные перерывы», возникающие из-за «низких» импульсов ШИМ).

Как я писал в другом комментарии, я хотел бы иметь push-решение. Как насчет того, чтобы PIC датчиков вытягивали общую «передающую» линию вместо высокого уровня и проверяли эту линию перед отправкой данных?
@Anttu: Как отмечалось в моем комментарии к вашему предыдущему комментарию, наличие передатчика, отмечающего точное время между видимой машиной и началом передачи, должно обеспечить необходимую вам точность, даже если две машины одновременно поражают разные датчики. Можно разместить все узлы на внешней шине и использовать какой-либо протокол разрешения коллизий, но это, вероятно, добавит больше неопределенности во время передачи, чем опрос. Кстати, об опросе следует помнить одну вещь, о которой я забыл упомянуть выше: ...
@Anttu: микроконтроллерам часто проще генерировать согласованные тайминги для исходящих сигналов, чем точно измерять тайминги входящих сигналов. Если бы датчик ждал, пока передастся задний фронт его «передающей» линии, и если главный процессор генерировал задний фронт для каждого передатчика точно один раз каждые 40 мс (100 интервалов опроса в секунду, разделенных четырьмя способами), зная, когда он отправил импульс опроса и сообщаемое датчиком время между событием и импульсом позволят основному ЦП определять время с точностью до миллисекунды.
Вы, вероятно, правы в этом. Единственная проблема заключается в том, что принимающий PIC18F2550 имеет только 2 контакта. Так что в этом случае мне пришлось бы перейти на PIC18F4550 с большим количеством контактов ввода-вывода.
@Anttu: я бы посоветовал вам рассмотреть возможность использования микросхемы внешнего счетчика, управляемой одной из линий ШИМ PIC; возможно что-то вроде 74HC4017. Возможно, подайте один из его выходов на инвертор, который через резистор подключен к «шине» (так что он будет подтягиваться 9/10 времени и опускаться 1/10, что позволит вам определить, в каком состоянии находится «шина»). счетчик есть). Если вы можете настроить выход для работы с ШИМ, он может генерировать хорошие точные тайминги независимо от того, что делает код.

Вы можете реализовать протокол MODBUS в режиме RTU с интерфейсом RS485, который отлично работает на PIC (не уверен насчет вашего PIC).

У вас может быть многоточечная линия для размещения ваших различных микроконтроллерных устройств и хорошая связь между ними через последовательный UART.

Вы можете сделать свой PIC18F2550 мастером, который будет инициировать транзакцию с любых других 4 контроллеров.

Пожалуйста, перепишите свой ответ правильным языком; этот сайт направлен на создание постоянной ссылки, которая лучше, если правильно отформатирована.
Приносим свои извинения, если вы найдете язык неправильным. Я просто использовал формат по умолчанию. Можете ли вы сказать, где реальная проблема?
Просто следите за грамматикой и не используйте аббревиатуры и тому подобное. Я отредактировал ваш ответ для вас. Добро пожаловать!
@clabacchio Хорошо. Я буду осторожен со следующего раза.

Используйте мультиплексирование с временным разделением. Мастер посылает синхроимпульс по отдельной линии, которую ведомые используют для сброса таймера. Когда подчиненное устройство имеет данные для отправки, оно ждет, пока таймер не сравняется (номер подчиненного устройства * ширина временного интервала) перед отправкой. Временной интервал должен быть достаточно длинным для отправки пакета и учета неточности часов между датчиками.

Электрически вы можете захотеть подтянуть общую линию TX и переключаться между 0 и тройным состоянием для передачи вместо источника тока для утверждения 1.

Есть некоторое преимущество в том, что процессоры всех датчиков работают с одним и тем же кодом; есть также некоторое преимущество в том, что все подключено к одним и тем же проводам (вместо, например, использования 74HC4017 для последовательного стробирования каждого датчика). Одна сложность, которую я вижу для мультиплексирования с временным разделением, заключается в том, что я не уверен, сколько может сделать процессор датчика, пока он ожидает машину. Если бы кто-то использовал TDM, он, скорее всего, дождался бы автомобиля, затем дождался бы следующего синхроимпульса, а затем отправил бы данные. При желании провод данных мог бы легко обрабатывать и синхроимпульсы, если бы они были длиннее, чем данные.
Каждый датчик уже знает свой уникальный идентификатор. Не имеет значения, если микро пропустит синхроимпульс. Настройте 16-битный таймер микроконтроллера так, чтобы он имел тот же период, что и синхроимпульс, сбросьте таймер на синхроимпульсе и подождите, пока таймер не сравняется (идентификационный номер) * (такты таймера на временной интервал) перед отправкой.

Я нашел этот сайт с решением под названием BlackNet. Он основан на довольно простом протоколе, идея которого заключается в том, что каждый узел в сети имеет собственный временной интервал. Т.е. это какая-то круговая логика. Последнее изображение на странице показывает схему с наименьшим количеством компонентов, необходимых для ее работы.

Я воспользовался этой идеей и просто подключил два встроенных датчика непосредственно к контакту RX на PIC18F2550. Однако я не реализовал протокол циклического перебора, а просто передавал данные по битам в линию (и надеюсь, что только один передает за раз). До сих пор это действительно работало довольно хорошо...

Для будущих читателей: если важно, чтобы ваши данные всегда проходили, решение, которое я использовал, вероятно, не очень хорошая идея. Однако, если вы редко отправляете данные и можете смириться с возможностью их коллизий, и вам нужно самое простое решение, я думаю, что этого достаточно.