Связь UART - серийный номер всегда пуст

У меня есть платежный терминал, использующий UART (или, проще говоря, контакты Rx, Tx, Gnd), и у меня есть Android приложение для планшета, которое подключается к терминалу с помощью адаптера USB to DB9 на базе чипа PL2303. Приложение для Android работает хорошо и использует https://github.com/felHR85/UsbSerial для поддержки последовательной связи. Протокол очень прост, в основном Android отправляет такие строки, как «REQINFO,4», «L2,xxx,xxx,*» и т. д., и возвращает строку статусов.

Я пытаюсь заменить Android-приложение на Arduino UNO, для которого, как я наивно полагал, будет достаточно просто подключить Tx,Rx терминала с контактами Rx, Tx Arduino, а также для подключения контактов Gnd. Но я не могу заставить его работать. Единственное, что я заметил, это то, что когда я подключаю Arduino Rx к терминалу Tx, на экранах терминала ненадолго отображается «Подключение ...», но это, вероятно, потому, что он обнаруживает какое-то входящее напряжение. Когда дело доходит до чтения Serial (или также я пробовал SoftwareSerial), ничего не возвращается.

String data = "";

void setup() {
  Serial.begin(9600);
  while (!Serial);
  delay(1000);
  Serial.println("REQINFO,4");
  delay(1000);
}

void loop() {
  if (Serial.available())  {
    char c = Serial.read(); // также я пробовал readString() и readStringUntil()
    if (c == '\n' || c == '\r') {
      Serial.println(data); // jsut, чтобы увидеть его в мониторе
    } else {
      data += c;
    }
  }
}

Значит, я что-то пропускаю, чтобы нормально общаться? Спасибо.

, 👍1

Обсуждение

Кажется, этот пакет поддерживает различные методы управления потоком (например, rts/dts и другие), которые используются двумя устройствами для координации связи. Если ваш терминал настроен на использование управления потоком, вам придется добавить больше в код Arduino для его поддержки в зависимости от характера управления потоком. Вы также должны учитывать формат сообщения (четность, стартовые/стоповые биты и скорость передачи). https://github.com/felHR85/UsbSerial/wiki/4.-Асинхронный API, @GMc

@GMc В управлении потоком кода Android установлено значение NONE, поэтому я полагаю, что могу это игнорировать. Кроме того, просто для проверки я отключил DB9 от COM-порта терминала и подключил только контакты Rx, Tx, и все продолжало работать., @Ivan


2 ответа


Лучший ответ:

0

Проверьте (например, мультиметром) напряжения DB9! В основном RS-232 используется в разъемах такого типа с напряжением +-12 Вольт (есть и другие варианты, до 15 В), но UART вашего Arduino использует уровни TTL (0 В как низкий логический уровень или 5 В как высокий на 5 В Arduino) . Вам нужно будет преобразовать их, возможно, с помощью чипа, такого как MAX232 или подобного.

Кроме того, для обратного проектирования я рекомендую использовать Arduino с несколькими последовательными портами (например, Mega) или, по крайней мере, с несколькими программными последовательными портами (конечно, с правильным сдвигом уровня). Вы подключаете свой Android-планшет к считывателю через Arduino, и когда вы получаете байт с одного устройства, отправляете его на другое, а также отправляете его на свой компьютер вместе с информацией о направлении. Таким образом, вы сможете понять все используемые команды, если будете нюхать достаточно долго. Вы также можете использовать SD-карту на SPI, если вам нужна мобильная система анализа данных (проходя по складу, сканируя товары).

Если у вас есть доступ к логическому анализатору, его также можно использовать в качестве сниффера. У этого есть дополнительное преимущество: вы можете изменить скорость BAUD позже, если ваше предположение было неверным.

(начало как комментарий, но не хватило символов, поэтому я решил объяснить это немного подробнее)

https://www.db9-pinout.com/db9-pinout/db9-pinout .gifpinout

Если это стандартный кабель для RS-232, на этой схеме показано, какой контакт какой. Кабели DCE-DCE и DCE-DTE тогда были разными (один соединяет ПК с модемом, другой — 2 ПК), поэтому следует проверить оба напряжения от 5 (GND) до 2 или 3. Пустая линия имеет высокий логический уровень. , то есть 5 В, если используется TTL, и -5 или ниже (например, -12 или -15) для RS-232.

Протестируйте также различные скорости передачи данных!

,

Я почти уверен, что вся система работает с использованием 5 В, но на самом деле это хорошая идея, чтобы перепроверить это. Что касается сниффинга, я на самом деле пробовал что-то подобное, подключив Arduino к планшету и глядя в окно монитора. По какой-то причине это тоже не показало мне никакой информации., @Ivan

Итак, вы предлагаете попробовать такой адаптер TTL - https://m.ebay.co.uk/itm/MAX232-RS232-Serial-to-TTL-Converter-Board-PIC-Adapter/302506517436?ul_ref=https ://rover.ebay.com/rover/1/710-53481-19255-0/1?ff3=2&pub=5575376664&toolid=10001&campid=5338268676&customid=CjwKCAjw5_DsBRBPEiwAIEDRWzVL2-w0CSoRPVgEt5tSf8n21 N6NC2qCud08araW72RE16h-KPUeZBoC6nwQAvD_BwE&lgeo=1&item=302506517436&srcrot=710-53481-19255-0&rvr_id =2136994577017&rvr_ts=aa3a806616d0a16ef8f4118afffc2a78&_mwBanner=1&_rdt=1&ul_noapp=true&pageci=c3e011ca-5fb3-4b66-b4f0-c31215a3f717?, @Ivan

Это оборудование сделает это, да. Вам может понадобиться 2 из них, один для планшета и один для ридера. Но сначала проверьте напряжения!, @Nyos

сегодня я попробовал ваше предложение с конвертером TTL, и он действительно работает хорошо. Теперь я могу прослушивать данные, поступающие с планшета на Arduino. Я использовал Arduino Mega, поэтому подключил терминал к Rx2, Tx2. Но по какой-то причине подключение еще одного TTL между этими контактами и терминалом не принесло никакой пользы. Интересно, нужен ли он мне вообще, так как без TTL для терминала я могу получить хотя бы какую-то тарабарщину -- Yu⸮Yucw⸮}⸮gaqmc⸮[uya[w⸮⸮ возможно, есть способ что-то настроить (скорость передачи?), чтобы увидеть реальный контент. В любом случае спасибо, вы мне очень помогли!, @Ivan

Если у вас есть доступ к даже дешевому ($8) логическому анализатору, вы можете определить скорость. Или вы можете проверить общие значения скорости. Вы также можете отправить на свой ПК шестнадцатеричные значения, данные могут быть двоичными, и они останутся тарабарщиной, даже если настройки правильные., @Nyos

на самом деле мне удалось добиться того, чего я хотел, поэтому понадобилось два TTL. Использовал это маленькое приложение для связи через последовательный порт на компьютере с Windows: http://www.hobbytronics.co.uk/ht-comm. И я смеялся, когда понял, в чем причина тарабарщины - слабый контакт. Пайка решила это полностью. Спасибо тебе, друг!, @Ivan


1

Уже есть ответ и комментарий о возможных проблемах с оборудованием/управлением потоком, поэтому этот ответ касается только вашего скетча Arduino. Я добавил пару операторов печати и библиотеку FreeMemory для проверки вашего скетча.

#include <MemoryFree.h>
String data = "";

void setup() {
  Serial.begin(9600);
  while (!Serial);
  delay(1000);
  Serial.println("REQINFO,4");
  delay(1000);
}

void loop() {
  if (Serial.available())  {
    char c = Serial.read(); // также я пробовал readString() и readStringUntil()
    if (c == '\n' || c == '\r') {
      Serial.println(data); // jsut, чтобы увидеть его в мониторе
      Serial.print("freeMemory()=");
      Serial.println(freeMemory());
    } else {
      data += c;
    }
  }
}

Когда я неоднократно ввожу следующий текст в последовательный монитор "1234567890", вот результаты операторов печати:

REQINFO,4
1234567890
freeMemory()=1770
1234567890
freeMemory()=1770
12345678901234567890
freeMemory()=1760
12345678901234567890
freeMemory()=1760
123456789012345678901234567890
freeMemory()=1750
123456789012345678901234567890
freeMemory()=1750
1234567890123456789012345678901234567890
freeMemory()=1740
1234567890123456789012345678901234567890
freeMemory()=1740
12345678901234567890123456789012345678901234567890

Каждый раз, когда вы получаете новые данные, они добавляются к строке data, что приводит к увеличению строки и исчезновению доступной памяти. Следует избегать использования объекта String.

Вот простой скетч, использующий массив char в качестве буфера для входящих данных:

// Устанавливаем размер буфера так, чтобы он вмещал самые большие
// "кусок" данных, которые вы будете получать.
const byte bufferSize = 64;
char inputBuffer[bufferSize + 1];

void setup(){
  Serial.begin(9600);
}

void loop(){
  if(Serial.available() > 0){
    Serial.readBytesUntil('\n', inputBuffer, bufferSize);
    Serial.print("inputBuffer=");
    Serial.println(inputBuffer);
    memset(inputBuffer, 0, sizeof(inputBuffer));
  }
}
,

Ах, да, этот скетч просто для проверки возможности коммуникации в целом. Но тем не менее, ценю ваш вклад., @Ivan