Подключение Mega 2560 к COM порту. Непонятные грабли

vlanaz
Offline
Зарегистрирован: 13.10.2020

Коллеги добрый день.

Подскажите пожалуйста, кто-нибудь сталкивался с такой ситуацией при работе с COM портом компьютера (железо - GIGABYTE Z170X-Designare, Windows 7 / 64x. 4 COM порта, плата Orient XWT-PE4SV1LP, приемопередатчики MAXIM MAX3243). Все COM порты на большом брате проверены, давно в работе, также как и кабель.

Есть скетч на Uno, в котором используется SoftSerial. Затем Uno заменили на Mega 2560 R3 (Robotdyn), чтобы использовать аппаратный Serial.

SoftSerial на Mega работает без проблем, также как и на Uno. СКЕТЧ НЕ ИЗМЕНЯЛСЯ, за исключением SoftSerial настроек пинов: 2 и 3 пины для Uno заменены на 10 и 11 (rxPin/txPin) для MEGA 2560. То есть к скетчу вопросов нет. Он работает. Тем более, что ситуация проявляется и до запуска скетча.

Инициализация портов без особенностей. Все в режиме 8-N-1. Аппаратные порты 2 и 3 не подключены.

Serial.begin(SPEED115200); // Терминал в IDE на Serial0
Serial1.begin(19200);		// Подключен к COM3 PC
Serial2.begin(19200);		// NC
Serial3.begin(9600);		// NC
pinMode(rxPin, INPUT);         // режим ввода пин 10 для RX SoftSerial
pinMode(txPin, OUTPUT);     // режим вывода пин 11 для TX SoftSerial
mySerial.begin(SPEED19200);   // Инициализация SoftwareSerial на скорость 19200

При подключении выходов 19/18 UART (Rx1/Tx1), (в основном это имеет значение при подключении Tx1) терминал на ПК (RealTerm, CoolTerm и другие) начинает принимать бесконечную последовательность 0x00. То есть COM3 порт ПК, реагирующий на уровни, воспринимает выход Tx, как передающий данные. Но так как передачи фактически нет, определяет "принятые" данные в виде нулей (0x00), что и видно в терминале.

Если осциллографом или пробником смотреть на выход (Tx) аппаратного Serial, на выводе Tx, при отсутствии передачи, постоянно висит логическая единица (+5V) . Если начать передавать данные, последовательность переменных уровней 1 и 0 на порту хорошо видна. То есть передача идет. Похоже на то, что порт Tx UART (пин 11) работоспособен. Такой же прием последовательности нулей  происходит, если просто на вход порта COM3 (2 штырек DB9) подать напряжение питания +5V. Аналогичное поведение Tx на портах Serial2 и Serial3.

Если же смотреть на выходы SoftSerial, то при отсутствии передачи, на выводе Tx присутствует логический НОЛЬ, а во время передачи появляется смесь единиц и нулей/ Исходное состояние на пине - ноль. Данные без проблем принимаются терминалом.

В связи с этим есть вопрос - почему такая разница. И, самое главное, непонятно что с этим делать.

Вариантов немного.

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

2. Непорядок в плате Mega, но при этом видно, что порты Serial работоспособны. По крайне мере логические уровни порты выдают. Плата с PC работает нормально, программируется через USB, прикладная часть на SoftSerial работает.

3. Этот эффект дает плата расширения 4-х COM портов на MAX3243. То есть логика определения - есть передача или нет, получается обратная. Хотя плата использовалась до этого и работала с другим оборудованием корректно. Например, конвертор RS232C/RS485, ПЛК Segnetics, последовательный порт ноутбука и другие.

Буду благодарен любой помощи.

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, вот, я знаю, что на мегах с АлиЭкспресса бывает, что переставлены местами метки RX и TX на одном из Serial и люди долго об это бъются.

vlanaz
Offline
Зарегистрирован: 13.10.2020

Mega куплена не через Али. В магазине электроники. Может и они в Али отовариваются, не знаю. Но кнопка Reset  у платы в углу рядом  USB, а не посередине платы. Уже возникают мысли насчет происхождения. Rx и Tx на плате проставлены правильно.

Здесь дело даже не в меге. Вопрос - почему в SoftSerial вывод Tx с нулем в "покое" нормально работает с COM портом. То есть отсутствие передачи - ноль (0V) на пине. А HardSerial в "покое" выдает на порт единицу. То есть отсутствие передачи - единица (+5V) на пине. Логические уровни инвертированы. На COM порту я это сделать не могу, остается либо лезть в библиотеку, либо пока вопрос висит добавить аппаратные инверторы сразу на 3 порта.

Мегу убрать не могу, так как скетч уже больше 40кбайт и дальше будет расти. А городить двунаправленные инверторы в лом. Хочется чтобы имеющаяся плата как то заработала. Не менять же платформу на каждой непонятке.

Дальше еще предстоит переход на Due, а так как вся обвязка вокруг платы сделана на 5V, софт надо отладить на готовом макете с питанием 5 вольт. А потом уже двигать на 3,3V

sadman41
Offline
Зарегистрирован: 19.10.2016

Да вроде как SoftwareSerial выставляет ногу в HIGH штатно:

//
// Constructor
//
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) : 
  ...
  _inverse_logic(inverse_logic)
{
  setTX(transmitPin);
  setRX(receivePin);
}

...

void SoftwareSerial::setTX(uint8_t tx)
{
  // First write, then set output. If we do this the other way around,
  // the pin would be output low for a short while before switching to
  // output high. Now, it is input with pullup for a short while, which
  // is fine. With inverse logic, either order is fine.
  digitalWrite(tx, _inverse_logic ? LOW : HIGH);
  pinMode(tx, OUTPUT);
  ...
}

 

vlanaz
Offline
Зарегистрирован: 13.10.2020

В библиотеки пока смотреть не ходил. Но по факту, логический пробник на порту Tx SoftSerial при паузе в передаче давал четкий ноль. Специально делал тесты, чтобы убедиться. Потом проверил осциллографом. Я как увидел постоянную передачу нулей в паузе передачи, сразу полез на пины смотреть уровень. COM порт определяет передачу по стартовому биту, а его потенциал у передатчика может быть прямой, а может инвертированный. Я с этим сталкивался. Непонятно только почему у аппаратного и софтового Serial логика получилась разная.

Если смотреть на текст, то уровень при отсутствии передачи определяет _inverse_logic. Надо будет посмотреть в библиотеке на HardwareSerial. Может там можно инвертировать логику.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Я не знаю, какие именно 4 ком-порта на компьютере, сейчас, как правило, и один найти трудно, но обычно компьютерные ком-порты работают не с ТТЛ уровнями, а -12В и +12В. Причем, логической единице, если мне не изменяет память, является именно -12В.

vlanaz
Offline
Зарегистрирован: 13.10.2020

На материнке, той которая у меня стоит в компе, в списке устройств - COM1 у которого нет физического интерфейса. Но он гордо торчит в списке устройств. Поэтому для работы была поставлена плата расширения на 4 порта. (См. первый пост, там название мамы и платы расширения). Итого: COM2 - назначен на виртуальный порт, который обеспечивает драйвер USB для Arduino. А COM3, 4, 5 и 9 - дает плата расширения. Нумерация та, которая мне удобна, так как некоторые порты привычно подключаются на свои номера (6..8) - USB GSM модемы и прочее.

В современных платах давно не встречал +/-12V на последовательном порту (мы его привыкли назвать COM), что имеет отношение к стандарту RS-232C. А в большинстве и COM порта нет. Это еще было на заре в PC XT и PC AT, там в маме для организации работы по стандарту RS-232C стояли микросхемы приемопередатчиков  на которые подавались +/-12V с питания мамы. Сейчас это семейство микросхем MAXIM. MAX232, 3232, 13232 и т.д. Они умеют работать с внешним питанием. Есть микросхемы которые сами генерируют минусовое. Наш COM, особенно если это преобразователь USB-COM или плата расширения, работает в зоне 0-5V. Для передачи далеко это хреново, а для работы рядом вполне годится. Принцип передачи как у RS232C, а напряжения другие.

Сейчас все порты, если присутствуют внутренние, или навесные с плат расширения давно сидят на питании 5V. Поэтому 0 и +5V для них крайние напряжения. Если бы там было -12 или даже -5, наверно у меня давно бы лежала кучка Arduino с дохлыми цифровыми пинами. А они ничего, работают. Скорее надо говорить не COM порт, a UART с поддержкой протокола передачи, но с меньшими однополярными напряжениями. А логический "ноль" получает 0V вместо -12 или -5.

 

vlanaz
Offline
Зарегистрирован: 13.10.2020

Пока Arduino гуру молчат. Время идет, поэтому решил попробовать исправить ситуацию аппаратно и заодно подтвердить правильность хода мыслей по поводу фаз сигналов. На макетную плату между COM(PC) и UART(MEGA) поставил прокладку - микросхемку CD4069 с 6 инверторами (элементами "НЕ") на борту. Задействовал 2 инвертора на Serial1 и осталось еще 4. Как раз на Serial2 и Serial3. Питание пока 5V от MEGA, а когда перейду на DUE, питание инвертора можно изменить на 3,3V. У CD4069 диапазон Vdd 3V..18V.

Соединения:

TD(COM)->инвертор->Rx1(Mega)

Tx(Mega)->инвертор->RD(COM)

Результат - работает, как часы. Предположение по начальным фазам сигналов было верным. Стоимость решения 25р...60р в зависимости от жадности продавцов, не считая десятка соединительных проводков. Возможно есть и программное решение, но нет времени ждать. Надо забираться в библиотеку и искать возможность поправить код, чтобы изменить фазы сигналов. Может быть попозже.

 

b707
Offline
Зарегистрирован: 26.05.2017

бред какой-то.... вся тема.

Штатно на меге нет никакой инверсии на Сериалах.

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

Могу посоветовать ТС попробовать подключить Serial1 к обычному USb на компе, а не к своим расширителям КОМ

vlanaz
Offline
Зарегистрирован: 13.10.2020

Нет там никакого кода, я же писал. Подключаю Tx на вход COM, начинается прием. Подключаю +5V, то же самое. Как такого кода, который управляет Serial не использовалось, только Begin и подключение проводов. Их 2. Rx да Tx. Ошибиться сложно.

В плату расширения лезть нет необходимости. Ставится драйвер. На плате 4 DB9. Подключается кабель. С другой стороны стоит UART меги.  Все.

По задаче мне нужно подключение не к USB, а именно к COM портам, поэтому в совете смысла нет.

На один и тот же COM SoftSerial нормально работает, а HardSerial нет. Мне не интересно, есть там инверсия или нет. Я вижу, что библиотеки ведут себя по разному.

 

Upper
Offline
Зарегистрирован: 23.06.2020

Какой командой вы объявляете SoftSerial?

b707
Offline
Зарегистрирован: 26.05.2017

vlanaz пишет:

По задаче мне нужно подключение не к USB, а именно к COM портам, поэтому в совете смысла нет.

я вам написал "попробовать". Такой тест даст вам направление, где искать корень проблемы. Если Сериал1 на вашей Меге через USB будет работать нормально, а через КОМ - нет, значит проблема в плате расширения. А если и через USB будут проблемы - значит вам попалась глючная Мега

vlanaz
Offline
Зарегистрирован: 13.10.2020

#include <SoftwareSerial.h>

#define rxPin 10        // Порт приема данных SoftSerial для MEGA
#define txPin 11        // Порт передачи данных SoftSerial для MEGA

SoftwareSerial mySerial(rxPin, txPin, true); // Пин для RX, TX. Инверсная логика в данных порта

mySerial.begin(19200);   // Инициализируем SoftwareSerial порт и устанавливаем скорость

Выдержка из https://www.arduino.cc/en/Reference/SoftwareSerialConstructor , где описано управление поведением SoftSerial. Ориентировался на нее. Так как без 3-го параметра была ситуация, аналогичная текущей с аппаратным портом.

Parameters

rxPin: the pin on which to receive serial data

txPin: the pin on which to transmit serial data

inverse_logic: is used to invert the sense of incoming bits (the default is normal logic). If set, SoftwareSerial treats a LOW (0 volts on the pin, normally) on the Rx pin as a 1-bit (the idle state) and a HIGH (5 volts on the pin, normally) as a 0-bit. It also affects the way that it writes to the Tx pin. Default value is false.

Когда строка инициализации была SoftwareSerial mySerial(rxPin, txPin);, то есть по умолчанию 3-й параметр false,  была ситуация как с аппаратным UART. Терминал постоянно, якобы, принимал данные. Фактически определял прием байта 0x00. С 3-м параметром true все работает нормально. На этот же COM теперь поставлен аппаратный Serial.

У меня претензий к SoftSerial нет. Порты напрямую воткнуты в DB9 от COM, все работает. А вот с аппаратным Serial ситуация как у SoftSerial с параметром false. И как это исправить программно пока непонятно. Поэтому тупо воткнул аппаратную инверсию сигналов Rx и Tx между COM и UART.

 

b707
Offline
Зарегистрирован: 26.05.2017

vlanaz пишет:

Когда строка инициализации была SoftwareSerial mySerial(rxPin, txPin);, то есть по умолчанию 3-й параметр false,  была ситуация как с аппаратным UART. Терминал постоянно, якобы, принимал данные. Фактически определял прием байта 0x00. С 3-м параметром true все работает нормально. На этот же COM теперь поставлен аппаратный Serial.

У меня претензий к SoftSerial нет. Порты напрямую воткнуты в DB9 от COM, все работает. А вот с аппаратным Serial ситуация как у SoftSerial с параметром false. И как это исправить программно пока непонятно. Поэтому тупо воткнул аппаратную инверсию сигналов Rx и Tx между COM и UART.

Отделим мух от котлет. Из процитированного ясно,  что никакой разницы в логике аппаратного и программного Сериал не наблюдается. SoftSerial в нормальном режиме ТАК ЖЕ НЕ РАБОТАЕТ с вашей платой, как и аппаратный. Программный Сериал работает с платой только в инверсном режиме:

SoftwareSerial mySerial(rxPin, txPin, true); // Пин для RX, TX. Инверсная логика в данных порта

 

Какой вывод из этого напрашивается? - Сериалы Меги не при чем, инверсия происходит в вашей плате КОМ-портов, как я и предполагал.  Раъбирайтесь с вашей платой, скорее всего в ней есть настройки прямого/инверсного режима.

Upper
Offline
Зарегистрирован: 23.06.2020

vlanaz пишет:

Поэтому тупо воткнул аппаратную инверсию сигналов Rx и Tx между COM и UART.

Иначе никак, если драйвер платы не позволяет менять полярность (или может на плате есть переключатели.).

sadman41
Offline
Зарегистрирован: 19.10.2016

Что за люди... Ругают несчастных китайцев, ругают... А в конце выходит, что софтсериал изначально настраивался под кривую линию.

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:
Что за люди... Ругают несчастных китайцев, ругают... А в конце выходит, что софтсериал изначально настраивался под кривую линию.

в итоге окажется. что ТС сам и перестроил плату расширения на инверсные сигналы... полгода назад... и забыл. А виновата ардуина, конечно

vlanaz
Offline
Зарегистрирован: 13.10.2020

К плате доступа нет. Настроек нет. Переключателей нет. Там 4 стандартных приемопередатчика MAXIM и один ASIC. Как я понимаю у меня осталось три варианта действий. Разработку своего драйвера платы расширения в расчет не беру.

1 - Аппаратная инверсия в макете устройства, что сейчас сделано и работает.

2 - Заменить плату расширения. Но кто сказал, что другая плата будет вести себя "правильно".

3 - Подстройка под плату расширения HardwareSerial. Изменить инициализацию управляющих регистров портов ATmega2560. Этим приходилось заниматься, но сейчас проблематично со временем. Может попозже.

По затратам денег, времени и умственных усилий  вариант 1 рулит.

vlanaz
Offline
Зарегистрирован: 13.10.2020

Я Arduino не ругаю. Как платформа для отработки разных решений очень удобный вариант. Есть с чем сравнивать, начинать то приходилось не в таких условиях - оригинальный intel8008, отладочный пульт на тумблерах и программа написанная в двоичных кодах.

Мне все нравится, за исключением IDE. Как не было средств отладки, так и нет. Встроенный терминал не в счет.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

vlanaz пишет:

Мне все нравится, за исключением IDE. Как не было средств отладки, так и нет. 

Да кто же Вас заставляет ею пользоваться?

Не нравится водка - пейте уиски.

nevkon
Offline
Зарегистрирован: 20.01.2015

Открываем даташит на ваши MAX3243 которые стоят в плате: https://docviewer.yandex.ru/view/86891613/?page=5&*=vBfU%2BjWDRbyrpXEyoHFQfFioiht7InVybCI6Imh0dHBzOi8vd3d3LnRpLmNvbS9saXQvZHMvc3ltbGluay9tYXgzMjQzLnBkZiIsInRpdGxlIjoibWF4MzI0My5wZGYiLCJub2lmcmFtZSI6dHJ1ZSwidWlkIjoiODY4OTE2MTMiLCJ0cyI6MTYxNzE2MzQxMzY3MCwieXUiOiIzNzgwMDIwOTMxNjEzMzc0MTE0Iiwic2VycFBhcmFtcyI6Imxhbmc9ZW4mdG09MTYxNzE2MzQwNCZ0bGQ9cnUmbmFtZT1tYXgzMjQzLnBkZiZ0ZXh0PW1heDMyNDMrZGF0YXNoZWV0JnVybD1odHRwcyUzQS8vd3d3LnRpLmNvbS9saXQvZHMvc3ltbGluay9tYXgzMjQzLnBkZiZscj0xMTE0MyZtaW1lPXBkZiZsMTBuPXJ1JnNpZ249NzE3YzhiY2JhMDdhMGU4NDVlZTFhZDcwOWE4YzQzZDkma2V5bm89MCZub3N3PTEifQ%3D%3D&lang=en

Черным по белому:

Voh = 5 ... 5.4V

Vol = -5 ... -5.4V

Не вижу причин почему оно должно работать при прямом подключении без конверторов уровня.

Ради интереса можете посмотреть типовую схему включения и поинтересоваться зачем ставятся конденсаторы С1 и С2.

Green
Offline
Зарегистрирован: 01.10.2015

Абсолютно верно. Отродясь на COM-ах не было TTL уровней. Для этого и ставятся MAX-ы, обеспечивающие интерфейс RS232. Да, они могут не формировать -15в, но слаботочный -10в выдают. Вот и получается, что с одной стороны (ПК) у вас UART с инверсией, а с другой (Ардуино) без. Про уровни я уже сказал - минус просто давится входами Ардуино.