Связь 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;
}
}
}
Значит, я что-то пропускаю, чтобы нормально общаться? Спасибо.
@Ivan, 👍1
Обсуждение2 ответа
Лучший ответ:
Проверьте (например, мультиметром) напряжения 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 .gif
Если это стандартный кабель для 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
Уже есть ответ и комментарий о возможных проблемах с оборудованием/управлением потоком, поэтому этот ответ касается только вашего скетча 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
- SIM800L не отвечает на AT-команды
- Проблема последовательной связи с общей землей SIM800L
- AT-команда не отвечает на последовательный монитор
- Как отправить команду AT на sim800l с помощью SoftwareSerial
- Ардуино для чтения с преобразователя RS232 в последовательный модуль TTL
- Чтение SMS с помощью Arduino Uno и SIM800L и печать на LCD (16x2 буквенно-цифровых) с использованием последовательного соединения
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
- myserial.available() возвращает нулевой байт
Кажется, этот пакет поддерживает различные методы управления потоком (например, rts/dts и другие), которые используются двумя устройствами для координации связи. Если ваш терминал настроен на использование управления потоком, вам придется добавить больше в код Arduino для его поддержки в зависимости от характера управления потоком. Вы также должны учитывать формат сообщения (четность, стартовые/стоповые биты и скорость передачи). https://github.com/felHR85/UsbSerial/wiki/4.-Асинхронный API, @GMc
@GMc В управлении потоком кода Android установлено значение NONE, поэтому я полагаю, что могу это игнорировать. Кроме того, просто для проверки я отключил DB9 от COM-порта терминала и подключил только контакты Rx, Tx, и все продолжало работать., @Ivan